'Internal code for creating a course or library'

def _create_courselike(self, locator, user_id, master_branch, fields=None, versions_dict=None, search_targets=None, root_category='course', root_block_id=None, **kwargs):

    index = self.get_course_index(locator, ignore_case=True)
    if (index is not None):
        raise DuplicateCourseError(locator, index)
    partitioned_fields = self.partition_fields_by_scope(root_category, fields)
    block_fields = partitioned_fields[Scope.settings]
    if (Scope.children in partitioned_fields):
        block_fields.update(partitioned_fields[Scope.children])
    definition_fields = self._serialize_fields(root_category, partitioned_fields.get(Scope.content, {}))
    if ((versions_dict is None) or (master_branch not in versions_dict)):
        definition_id = self.create_definition_from_data(locator, definition_fields, root_category, user_id).definition_id
        draft_structure = self._new_structure(user_id, BlockKey(root_category, (root_block_id or SplitMongoModuleStore.DEFAULT_ROOT_COURSE_BLOCK_ID)), block_fields, definition_id)
        new_id = draft_structure['_id']
        if (versions_dict is None):
            versions_dict = {master_branch: new_id}
        else:
            versions_dict[master_branch] = new_id
    elif (block_fields or definition_fields):
        draft_version = CourseLocator(version_guid=versions_dict[master_branch])
        draft_structure = self._lookup_course(draft_version).structure
        draft_structure = self.version_structure(locator, draft_structure, user_id)
        new_id = draft_structure['_id']
        root_block = draft_structure['blocks'][draft_structure['root']]
        if (block_fields is not None):
            root_block.fields.update(self._serialize_fields(root_category, block_fields))
        if (definition_fields is not None):
            old_def = self.get_definition(locator, root_block.definition)
            new_fields = old_def['fields']
            new_fields.update(definition_fields)
            definition_id = self._update_definition_from_data(locator, old_def, new_fields, user_id).definition_id
            root_block.definition = definition_id
            root_block.edit_info.edited_on = datetime.datetime.now(UTC)
            root_block.edit_info.edited_by = user_id
            root_block.edit_info.previous_version = root_block.edit_info.update_version
            root_block.edit_info.update_version = new_id
        versions_dict[master_branch] = new_id
    else:
        new_id = versions_dict[master_branch]
        draft_version = CourseLocator(version_guid=new_id)
        draft_structure = self._lookup_course(draft_version).structure
    locator = locator.replace(version_guid=new_id)
    with self.bulk_operations(locator):
        self.update_structure(locator, draft_structure)
        index_entry = {'_id': ObjectId(), 'org': locator.org, 'course': locator.course, 'run': locator.run, 'edited_by': user_id, 'edited_on': datetime.datetime.now(UTC), 'versions': versions_dict, 'schema_version': self.SCHEMA_VERSION, 'search_targets': (search_targets or {})}
        if (fields is not None):
            self._update_search_targets(index_entry, fields)
        self.insert_course_index(locator, index_entry)
        if isinstance(locator, LibraryLocator):
            course = self.get_library(locator, **kwargs)
        else:
            course = self.get_course(locator, **kwargs)
        return self.update_item(course, user_id, **kwargs)
