'create or update the xblock and all of its children. The xblock\'s location must specify a course.
If it doesn\'t specify a usage_id, then it\'s presumed to be new and need creation. This function
descends the children performing the same operation for any that are xblocks. Any children which
are block_ids just update the children pointer.
All updates go into the same course version (bulk updater).
Updates the objects which came in w/ updated location and definition_location info.
returns the post-persisted version of the incoming xblock. Note that its children will be ids not
objects.
:param xblock: the head of the dag
:param user_id: who\'s doing the change'

def persist_xblock_dag(self, xblock, user_id, force=False):

    course_key = xblock.location.course_key
    with self.bulk_operations(course_key):
        index_entry = self._get_index_if_valid(course_key, force)
        structure = self._lookup_course(course_key).structure
        new_structure = self.version_structure(course_key, structure, user_id)
        new_id = new_structure['_id']
        is_updated = self._persist_subdag(course_key, xblock, user_id, new_structure['blocks'], new_id)
        if is_updated:
            self.update_structure(course_key, new_structure)
            if (index_entry is not None):
                self._update_head(course_key, index_entry, xblock.location.branch, new_id)
            return self.get_item(xblock.location.for_version(new_id))
        else:
            return xblock
