'Constructor - not to be called directly, use resolve() instead
@param resource: the S3Resource
@param table: the table
@param tokens: the tokens as list'

def __init__(self, resource, table, tokens):

    s3db = current.s3db
    if (table is None):
        table = resource.table
    self.original = None
    tname = self.tname = table._tablename
    self.fname = None
    self.field = None
    self.method = None
    self.ftype = None
    self.virtual = False
    self.colname = None
    self.joins = {}
    self.distinct = False
    self.multiple = True
    head = tokens.pop(0)
    tail = None
    if (head and (head[0] == '(') and (head[(-1)] == ')')):
        head = head.strip('()')
        self.fname = head
        self.ftype = 'context'
        if (not resource):
            resource = s3db.resource(table, components=[])
        context = resource.get_config('context')
        if (context and (head in context)):
            tail = self.resolve(resource, context[head], tail=tokens)
        else:
            pass
    elif tokens:
        op = tokens.pop(0)
        if tokens:
            if (op == '.'):
                if (not resource):
                    resource = s3db.resource(table, components=[])
                (ktable, join, m, d) = self._resolve_alias(resource, head)
                self.multiple = m
                self.distinct = d
            else:
                (ktable, join) = self._resolve_key(table, head)
                self.distinct = True
            if (join is not None):
                self.joins[ktable._tablename] = join
            tail = S3FieldPath(None, ktable, tokens)
        else:
            raise SyntaxError('trailing    operator')
    if (tail is None):
        if (self.ftype != 'context'):
            (field, method) = self._resolve_field(table, head)
            if (not field):
                self.virtual = True
                self.field = None
                self.method = method
                self.ftype = 'virtual'
            else:
                self.virtual = False
                self.field = field
                self.method = None
                self.ftype = str(field.type)
            self.fname = head
            self.colname = ('%s.%s' % (tname, head))
    else:
        self.tname = tail.tname
        self.fname = tail.fname
        self.field = tail.field
        self.method = tail.method
        self.ftype = tail.ftype
        self.virtual = tail.virtual
        self.colname = tail.colname
        self.distinct |= tail.distinct
        self.multiple |= tail.multiple
        self.joins.update(tail.joins)
