'Find referenced elements in the tree
@param element: the element
@param table: the DB table
@param fields: the FK fields in the table
@param tree: the import tree
@param directory: a dictionary to lookup elements in the tree
(will be filled in by this function)'

def lookahead(self, element, table=None, fields=None, tree=None, directory=None, lookup=None):

    db = current.db
    s3db = current.s3db
    xml = current.xml
    import_uid = xml.import_uid
    ATTRIBUTE = xml.ATTRIBUTE
    TAG = xml.TAG
    UID = xml.UID
    reference_list = []
    root = None
    if (tree is not None):
        if isinstance(tree, etree._Element):
            root = tree
        else:
            root = tree.getroot()
    if lookup:
        references = [lookup]
    else:
        references = element.findall('reference')
    for reference in references:
        if lookup:
            tablename = element.get(ATTRIBUTE.name, None)
            (ktable, field, uid) = reference
            attr = UID
            uids = [import_uid(uid)]
        else:
            field = reference.get(ATTRIBUTE.field, None)
            if ((not field) or (field not in fields) or (field not in table)):
                continue
            (ktablename, key, multiple) = s3_get_foreign_key(table[field])
            if (not ktablename):
                continue
            try:
                ktable = s3db[ktablename]
            except:
                continue
            tablename = reference.get(ATTRIBUTE.resource, None)
            if (UID not in ktable.fields):
                continue
            if (not tablename):
                tablename = ktablename
            if (tablename != ktablename):
                field = (ktable._id.name, field)
            if ((tablename == ktablename) and (ktable._id.name != 'id')):
                continue
            uids = reference.get(UID, None)
            attr = UID
            if (not uids):
                uids = reference.get(ATTRIBUTE.tuid, None)
                attr = ATTRIBUTE.tuid
            if (uids and multiple):
                uids = json.loads(uids)
            elif uids:
                uids = [uids]
        relements = []
        id_map = Storage()
        if ((attr == UID) and uids):
            _uids = map(import_uid, uids)
            query = ktable[UID].belongs(_uids)
            records = db(query).select(ktable.id, ktable[UID])
            id_map = dict(((r[UID], r.id) for r in records))
        if (not uids):
            expr = ('.//%s[@%s="%s"]' % (TAG.resource, ATTRIBUTE.name, tablename))
            relements = reference.xpath(expr)
            if (relements and (not multiple)):
                relements = relements[:1]
        elif (root is not None):
            for uid in uids:
                entry = None
                if (directory is not None):
                    entry = directory.get((tablename, attr, uid), None)
                if (not entry):
                    expr = ('.//%s[@%s="%s"    and    @%s=$uid]' % (TAG.resource, ATTRIBUTE.name, tablename, attr))
                    e = root.xpath(expr, uid=uid)
                    if e:
                        relements.append(e[0])
                    else:
                        _uid = import_uid(uid)
                        if (_uid and (_uid in id_map)):
                            _id = id_map[_uid]
                            entry = Storage(tablename=tablename, element=None, uid=uid, id=_id, item_id=None)
                            reference_list.append(Storage(field=field, element=reference, entry=entry))
                        else:
                            continue
                else:
                    reference_list.append(Storage(field=field, element=reference, entry=entry))
        for relement in relements:
            uid = relement.get(attr, None)
            if (attr == UID):
                _uid = import_uid(uid)
                _id = ((_uid and id_map and id_map.get(_uid, None)) or None)
            else:
                _uid = None
                _id = None
            entry = Storage(tablename=tablename, element=relement, uid=uid, id=_id, item_id=None)
            if (uid and (directory is not None)):
                directory[(tablename, attr, uid)] = entry
            reference_list.append(Storage(field=field, element=reference, entry=entry))
    return reference_list
