'Create the real index from the collected index entries.'

def create_index(self, builder, group_entries=True, _fixre=re.compile('(.*)    ([(][^()]*[)])')):

    from sphinx.environment import NoUri
    new = {}
    def add_entry(word, subword, main, link=True, dic=new, key=None):
        word = text_type(word)
        entry = dic.get(word)
        if (not entry):
            dic[word] = entry = [[], {}, key]
        if subword:
            add_entry(subword, '', main, link=link, dic=entry[1], key=key)
        elif link:
            try:
                uri = ((builder.get_relative_uri('genindex', fn) + '#') + tid)
            except NoUri:
                pass
            else:
                bisect.insort(entry[0], (main, uri))
    for (fn, entries) in iteritems(self.env.indexentries):
        for (type, value, tid, main, index_key) in entries:
            try:
                if (type == 'single'):
                    try:
                        (entry, subentry) = split_into(2, 'single', value)
                    except ValueError:
                        (entry,) = split_into(1, 'single', value)
                        subentry = ''
                    add_entry(entry, subentry, main, key=index_key)
                elif (type == 'pair'):
                    (first, second) = split_into(2, 'pair', value)
                    add_entry(first, second, main, key=index_key)
                    add_entry(second, first, main, key=index_key)
                elif (type == 'triple'):
                    (first, second, third) = split_into(3, 'triple', value)
                    add_entry(first, ((second + '    ') + third), main, key=index_key)
                    add_entry(second, ((third + ',    ') + first), main, key=index_key)
                    add_entry(third, ((first + '    ') + second), main, key=index_key)
                elif (type == 'see'):
                    (first, second) = split_into(2, 'see', value)
                    add_entry(first, (_('see    %s') % second), None, link=False, key=index_key)
                elif (type == 'seealso'):
                    (first, second) = split_into(2, 'see', value)
                    add_entry(first, (_('see    also    %s') % second), None, link=False, key=index_key)
                else:
                    logger.warning('unknown    index    entry    type    %r', type, location=fn)
            except ValueError as err:
                logger.warning(str(err), location=fn)
    def keyfunc(entry):
        (key, (void, void, category_key)) = entry
        if category_key:
            key = category_key
        lckey = unicodedata.normalize('NFD', key.lower())
        if lckey.startswith(u'\u200f'):
            lckey = lckey[1:]
        if (lckey[0:1].isalpha() or lckey.startswith('_')):
            lckey = (chr(127) + lckey)
        return (lckey, entry[0])
    newlist = sorted(new.items(), key=keyfunc)
    if group_entries:
        oldkey = ''
        oldsubitems = None
        i = 0
        while (i < len(newlist)):
            (key, (targets, subitems, _key)) = newlist[i]
            if (not subitems):
                m = _fixre.match(key)
                if m:
                    if (oldkey == m.group(1)):
                        oldsubitems.setdefault(m.group(2), [[], {}, _key])[0].extend(targets)
                        del newlist[i]
                        continue
                    oldkey = m.group(1)
                else:
                    oldkey = key
            oldsubitems = subitems
            i += 1
    def keyfunc2(item):
        (k, v) = item
        v[1] = sorted(((si, se) for (si, (se, void, void)) in iteritems(v[1])))
        if (v[2] is None):
            if k.startswith(u'\u200f'):
                k = k[1:]
            letter = unicodedata.normalize('NFD', k[0])[0].upper()
            if (letter.isalpha() or (letter == '_')):
                return letter
            else:
                return _('Symbols')
        else:
            return v[2]
    return [(key_, list(group)) for (key_, group) in groupby(newlist, keyfunc2)]
