'Process course for indexing
Arguments:
modulestore - modulestore object to use for operations
structure_key (CourseKey|LibraryKey) - course or library identifier
triggered_at (datetime) - provides time at which indexing was triggered;
useful for index updates - only things changed recently from that date
(within REINDEX_AGE above ^^) will have their index updated, others skip
updating their index but are still walked through in order to identify
which items may need to be removed from the index
If None, then a full reindex takes place
Returns:
Number of items that have been added to the index'

@classmethod
def index(cls, modulestore, structure_key, triggered_at=None, reindex_age=REINDEX_AGE):

    error_list = []
    searcher = SearchEngine.get_search_engine(cls.INDEX_NAME)
    if (not searcher):
        return
    structure_key = cls.normalize_structure_key(structure_key)
    location_info = cls._get_location_info(structure_key)
    indexed_count = {'count': 0}
    indexed_items = set()
    items_index = []
    def get_item_location(item):
        '\n                                                Gets    the    version    agnostic    item    location\n                                                '
        return item.location.version_agnostic().replace(branch=None)
    def prepare_item_index(item, skip_index=False, groups_usage_info=None):
        '\n                                                Add    this    item    to    the    items_index    and    indexed_items    list\n\n                                                Arguments:\n                                                item    -    item    to    add    to    index,    its    children    will    be    processed    recursively\n\n                                                skip_index    -    simply    walk    the    children    in    the    tree,    the    content    change    is\n                                                                older    than    the    REINDEX_AGE    window    and    would    have    been    already    indexed.\n                                                                This    should    really    only    be    passed    from    the    recursive    child    calls    when\n                                                                this    method    has    determined    that    it    is    safe    to    do    so\n\n                                                Returns:\n                                                item_content_groups    -    content    groups    assigned    to    indexed    item\n                                                '
        is_indexable = hasattr(item, 'index_dictionary')
        item_index_dictionary = (item.index_dictionary() if is_indexable else None)
        if ((not item_index_dictionary) and (not item.has_children)):
            return
        item_content_groups = None
        if (item.category == 'split_test'):
            split_partition = item.get_selected_partition()
            for split_test_child in item.get_children():
                if split_partition:
                    for group in split_partition.groups:
                        group_id = unicode(group.id)
                        child_location = item.group_id_to_child.get(group_id, None)
                        if (child_location == split_test_child.location):
                            groups_usage_info.update({unicode(get_item_location(split_test_child)): [group_id]})
                            for component in split_test_child.get_children():
                                groups_usage_info.update({unicode(get_item_location(component)): [group_id]})
        if groups_usage_info:
            item_location = get_item_location(item)
            item_content_groups = groups_usage_info.get(unicode(item_location), None)
        item_id = unicode(cls._id_modifier(item.scope_ids.usage_id))
        indexed_items.add(item_id)
        if item.has_children:
            skip_child_index = (skip_index or ((triggered_at is not None) and ((triggered_at - item.subtree_edited_on) > reindex_age)))
            children_groups_usage = []
            for child_item in item.get_children():
                if modulestore.has_published_version(child_item):
                    children_groups_usage.append(prepare_item_index(child_item, skip_index=skip_child_index, groups_usage_info=groups_usage_info))
            if (None in children_groups_usage):
                item_content_groups = None
        if (skip_index or (not item_index_dictionary)):
            return
        item_index = {}
        try:
            item_index.update(location_info)
            item_index.update(item_index_dictionary)
            item_index['id'] = item_id
            if item.start:
                item_index['start_date'] = item.start
            item_index['content_groups'] = (item_content_groups if item_content_groups else None)
            item_index.update(cls.supplemental_fields(item))
            items_index.append(item_index)
            indexed_count['count'] += 1
            return item_content_groups
        except Exception as err:
            log.warning('Could    not    index    item:    %s    -    %r', item.location, err)
            error_list.append(_('Could    not    index    item:    {}').format(item.location))
    try:
        with modulestore.branch_setting(ModuleStoreEnum.RevisionOption.published_only):
            structure = cls._fetch_top_level(modulestore, structure_key)
            groups_usage_info = cls.fetch_group_usage(modulestore, structure)
            cls.supplemental_index_information(modulestore, structure)
            for item in structure.get_children():
                prepare_item_index(item, groups_usage_info=groups_usage_info)
            searcher.index(cls.DOCUMENT_TYPE, items_index)
            cls.remove_deleted_items(searcher, structure_key, indexed_items)
    except Exception as err:
        log.exception('Indexing    error    encountered,    courseware    index    may    be    out    of    date    %s    -    %r', structure_key, err)
        error_list.append(_('General    indexing    error    occurred'))
    if error_list:
        raise SearchIndexingError('Error(s)    present    during    indexing', error_list)
    return indexed_count['count']
