'Decode the locator into the right series of db access. Does not
return the CourseDescriptor! It returns the actual db json from
structures.
Semantics: if course id and branch given, then it will get that branch. If
also give a version_guid, it will see if the current head of that branch == that guid. If not
it raises VersionConflictError (the version now differs from what it was when you got your
reference) unless you specify head_validation = False, in which case it will return the
revision (if specified) by the course_key.
:param course_key: any subclass of CourseLocator'

def _lookup_course(self, course_key, head_validation=True):

    if (not course_key.version_guid):
        head_validation = True
    if (head_validation and course_key.org and course_key.course and course_key.run):
        if (course_key.branch is None):
            raise InsufficientSpecificationError(course_key)
        index = self.get_course_index(course_key)
        if (index is None):
            raise ItemNotFoundError(course_key)
        if (course_key.branch not in index['versions']):
            raise ItemNotFoundError(course_key)
        version_guid = index['versions'][course_key.branch]
        if ((course_key.version_guid is not None) and (version_guid != course_key.version_guid)):
            raise VersionConflictError(course_key, version_guid)
    elif (course_key.version_guid is None):
        raise InsufficientSpecificationError(course_key)
    else:
        version_guid = course_key.version_guid
    entry = self.get_structure(course_key, version_guid)
    if (entry is None):
        raise ItemNotFoundError('Structure:    {}'.format(version_guid))
    return CourseEnvelope(course_key.replace(version_guid=version_guid), entry)
