'A wrapper for functions wanting to manipulate assets. Gets and versions the structure,
passes the mutable array for either \'assets\' or \'thumbnails\' as well as the idx to the function for it to
update, then persists the changed data back into the course.
The update function can raise an exception if it doesn\'t want to actually do the commit. The
surrounding method probably should catch that exception.'

def _update_course_assets(self, user_id, asset_key, update_function):

    with self.bulk_operations(asset_key.course_key):
        original_structure = self._lookup_course(asset_key.course_key).structure
        index_entry = self._get_index_if_valid(asset_key.course_key)
        new_structure = self.version_structure(asset_key.course_key, original_structure, user_id)
        course_assets = new_structure.setdefault('assets', {})
        asset_type = asset_key.asset_type
        all_assets = SortedAssetList(iterable=[])
        all_assets.extend(course_assets.setdefault(asset_type, []))
        asset_idx = all_assets.find(asset_key)
        all_assets_updated = update_function(all_assets, asset_idx)
        new_structure['assets'][asset_type] = all_assets_updated.as_list()
        self.update_structure(asset_key.course_key, new_structure)
        if (index_entry is not None):
            self._update_head(asset_key.course_key, index_entry, asset_key.branch, new_structure['_id'])
