Given a message with different plural translations separated by a
    pipe (|), this method returns the correct portion of the message based
    on the given number, locale and the pluralization rules in the message
    itself.

    The message supports two different types of pluralization rules:

    interval: {0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples
    indexed:  There is one apple|There are %count% apples

    The indexed solution can also contain labels (e.g. one: There is one apple).
    This is purely for making the translations more clear - it does not
    affect the functionality.

    The two methods can also be mixed:
        {0} There are no apples|one: There is one apple|more: There are %count% apples

    @type message: str
    @param message: The message being translated

    @type number: int
    @param number: The number of items represented for the message

    @type locale: st
    @param locale: The locale to use for choosing

    @rtype: str
    @raises: ValueError

def select_message(message, number, locale):
    """
    Given a message with different plural translations separated by a
    pipe (|), this method returns the correct portion of the message based
    on the given number, locale and the pluralization rules in the message
    itself.

    The message supports two different types of pluralization rules:

    interval: {0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples
    indexed:  There is one apple|There are %count% apples

    The indexed solution can also contain labels (e.g. one: There is one apple).
    This is purely for making the translations more clear - it does not
    affect the functionality.

    The two methods can also be mixed:
        {0} There are no apples|one: There is one apple|more: There are %count% apples

    @type message: str
    @param message: The message being translated

    @type number: int
    @param number: The number of items represented for the message

    @type locale: st
    @param locale: The locale to use for choosing

    @rtype: str
    @raises: ValueError
    """
    parts = message.split("|")
    explicit_rules = OrderedDict()
    standard_rules = []
    for part in parts:
        part = part.strip()

        match_interval = INTERVAL_MESSAGE_REGEX.match(part)
        match_standard = STANDARD_RULES_REGEX.match(part)
        if match_interval:
            explicit_rules[match_interval.group('interval')] = match_interval.group('message')
        elif match_standard:
            standard_rules.append(match_standard.groups()[0])
        else:
            standard_rules.append(part)

    # try to match an explicit rule, then to the standard ones
    for interval, m in list(explicit_rules.items()):
        if test_interval(number, interval):
            return m

    position = PluralizationRules.get(number, locale)
    if len(standard_rules) <= position:
        # when there's exactly one rule given, and that rule is a standard
        # rule, use this rule
        if len(parts) == 1 and len(standard_rules) > 0:
            return standard_rules[0]
        raise ValueError('Unable to choose a translation for "%s" with locale "%s" for value "%s". '
                         'Double check that this translation has the correct plural options (e.g. '
                         '"There is one apple|There are {{count}} apples").' % (message, locale, number))

    return standard_rules[position]