'Walks the names path and turns them PathInfo tuples. Note that a
single name in \'names\' can generate multiple PathInfos (m2m for
example).
\'names\' is the path of names to travle, \'opts\' is the model Options we
start the name resolving from, \'allow_many\' and \'allow_explicit_fk\'
are as for setup_joins().
Returns a list of PathInfo tuples. In addition returns the final field
(the last used join field), and target (which is a field guaranteed to
contain the same value as the final field).'

def names_to_path(self, names, opts, allow_many, allow_explicit_fk):

    (path, names_with_path) = ([], [])
    for (pos, name) in enumerate(names):
        cur_names_with_path = (name, [])
        if (name == 'pk'):
            name = opts.pk.name
        try:
            (field, model, direct, m2m) = opts.get_field_by_name(name)
        except FieldDoesNotExist:
            for f in opts.fields:
                if (allow_explicit_fk and (name == f.attname)):
                    (field, model, direct, m2m) = opts.get_field_by_name(f.name)
                    break
            else:
                available = (opts.get_all_field_names() + list(self.aggregate_select))
                raise FieldError(('Cannot    resolve    keyword    %r    into    field.    Choices    are:    %s' % (name, ',    '.join(available))))
        if model:
            proxied_model = opts.concrete_model
            for int_model in opts.get_base_chain(model):
                if (int_model is proxied_model):
                    opts = int_model._meta
                else:
                    final_field = opts.parents[int_model]
                    targets = (final_field.rel.get_related_field(),)
                    opts = int_model._meta
                    path.append(PathInfo(final_field.model._meta, opts, targets, final_field, False, True))
                    cur_names_with_path[1].append(PathInfo(final_field.model._meta, opts, targets, final_field, False, True))
        if hasattr(field, 'get_path_info'):
            pathinfos = field.get_path_info()
            if (not allow_many):
                for (inner_pos, p) in enumerate(pathinfos):
                    if p.m2m:
                        cur_names_with_path[1].extend(pathinfos[0:(inner_pos + 1)])
                        names_with_path.append(cur_names_with_path)
                        raise MultiJoin((pos + 1), names_with_path)
            last = pathinfos[(-1)]
            path.extend(pathinfos)
            final_field = last.join_field
            opts = last.to_opts
            targets = last.target_fields
            cur_names_with_path[1].extend(pathinfos)
            names_with_path.append(cur_names_with_path)
        else:
            final_field = field
            targets = (field,)
            break
    if (pos != (len(names) - 1)):
        if (pos == (len(names) - 2)):
            raise FieldError(('Join    on    field    %r    not    permitted.    Did    you    misspell    %r    for    the    lookup    type?' % (name, names[(pos + 1)])))
        else:
            raise FieldError(('Join    on    field    %r    not    permitted.' % name))
    return (path, final_field, targets)
