diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp
index a36f9364b696be79ca1ba297627a651f5193f257..8833822c40d8497bf4eed409a7b1c12f7ba251d7 100644
--- a/src/libs/cplusplus/FindUsages.cpp
+++ b/src/libs/cplusplus/FindUsages.cpp
@@ -29,29 +29,27 @@
 
 #include "FindUsages.h"
 #include "Overview.h"
-
+#include <AST.h>
+#include <TranslationUnit.h>
 #include <Control.h>
-#include <Literals.h>
 #include <Names.h>
-#include <Scope.h>
 #include <Symbols.h>
-#include <AST.h>
-#include <TranslationUnit.h>
-
-#include <QtCore/QDir>
-#include <QtCore/QDebug>
+#include <CoreTypes.h>
+#include <Literals.h>
+#include <Scope.h>
+#include <QDebug>
 
 using namespace CPlusPlus;
 
 FindUsages::FindUsages(Document::Ptr doc, const Snapshot &snapshot)
     : ASTVisitor(doc->translationUnit()),
+      _id(0),
+      _declSymbol(0),
       _doc(doc),
       _snapshot(snapshot),
       _context(doc, snapshot),
       _source(_doc->source()),
-      _sem(doc->translationUnit()),
-      _inSimpleDeclaration(0),
-      _inQProperty(false)
+      _currentScope(0)
 {
     _snapshot.insert(_doc);
     typeofExpression.init(_doc, _snapshot, _context.bindings());
@@ -59,13 +57,13 @@ FindUsages::FindUsages(Document::Ptr doc, const Snapshot &snapshot)
 
 FindUsages::FindUsages(const LookupContext &context)
     : ASTVisitor(context.thisDocument()->translationUnit()),
+      _id(0),
+      _declSymbol(0),
       _doc(context.thisDocument()),
       _snapshot(context.snapshot()),
       _context(context),
       _source(_doc->source()),
-      _sem(_doc->translationUnit()),
-      _inSimpleDeclaration(0),
-      _inQProperty(false)
+      _currentScope(0)
 {
     typeofExpression.init(_doc, _snapshot, _context.bindings());
 }
@@ -89,14 +87,14 @@ void FindUsages::operator()(Symbol *symbol)
     _processed.clear();
     _references.clear();
     _usages.clear();
+    _declSymbol = symbol;
     _declSymbolFullyQualifiedName = LookupContext::fullyQualifiedName(symbol);
-    _inSimpleDeclaration = 0;
-    _inQProperty = false;
 
     // get the canonical id
     _id = _doc->control()->findOrInsertIdentifier(_id->chars(), _id->size());
 
-    accept(_doc->translationUnit()->ast());
+    if (AST *ast = _doc->translationUnit()->ast())
+        translationUnit(ast->asTranslationUnit());
 }
 
 QString FindUsages::matchingLine(const Token &tk) const
@@ -120,6 +118,26 @@ QString FindUsages::matchingLine(const Token &tk) const
     return matchingLine;
 }
 
+void FindUsages::reportResult(unsigned tokenIndex, const Name *name, Scope *scope)
+{
+    if (! (tokenIndex && name != 0))
+        return;
+
+    if (name->identifier() != _id)
+        return;
+
+    if (! scope)
+        scope = _currentScope;
+
+    const QList<LookupItem> candidates = _context.lookup(name, scope);
+    reportResult(tokenIndex, candidates);
+}
+
+void FindUsages::reportResult(unsigned tokenIndex, const Identifier *id, Scope *scope)
+{
+    reportResult(tokenIndex, control()->nameId(id), scope);
+}
+
 void FindUsages::reportResult(unsigned tokenIndex, const QList<LookupItem> &candidates)
 {
     if (_processed.contains(tokenIndex))
@@ -185,13 +203,18 @@ bool FindUsages::compareName(const Name *name, const Name *other)
     return false;
 }
 
-
 bool FindUsages::checkCandidates(const QList<LookupItem> &candidates) const
 {
     for (int i = candidates.size() - 1; i != -1; --i) {
         const LookupItem &r = candidates.at(i);
 
         if (Symbol *s = r.declaration()) {
+            if (_declSymbol->scope() && (_declSymbol->scope()->isPrototypeScope() || _declSymbol->scope()->isBlockScope())) {
+                if (s->scope() != _declSymbol->scope())
+                    return false;
+
+            }
+
             if (compareFullyQualifiedName(LookupContext::fullyQualifiedName(s), _declSymbolFullyQualifiedName))
                 return true;
         }
@@ -200,367 +223,1911 @@ bool FindUsages::checkCandidates(const QList<LookupItem> &candidates) const
     return false;
 }
 
-void FindUsages::ensureNameIsValid(NameAST *ast)
+void FindUsages::checkExpression(unsigned startToken, unsigned endToken, Scope *scope)
 {
-    if (ast && ! ast->name)
-        ast->name = _sem.check(ast, /*scope = */ 0);
+    const unsigned begin = tokenAt(startToken).begin();
+    const unsigned end = tokenAt(endToken).end();
+
+    const QString expression = _source.mid(begin, end - begin);
+    // qDebug() << "*** check expression:" << expression;
+
+    if (! scope)
+        scope = _currentScope;
+
+    const QList<LookupItem> results = typeofExpression(expression, scope,
+                                                       TypeOfExpression::Preprocess);
+
+    reportResult(endToken, results);
 }
 
-bool FindUsages::visit(FunctionDefinitionAST *ast)
+Scope *FindUsages::switchScope(ScopedSymbol *symbol)
 {
-    AST *thisFunction = _astStack.takeLast();
-    accept(ast->decl_specifier_list);
-    _astStack.append(thisFunction);
+    if (! symbol)
+        return _currentScope; // ### assert?
 
-    accept(ast->declarator);
-    accept(ast->ctor_initializer);
-    accept(ast->function_body);
-    return false;
+    return switchScope(symbol->members());
 }
 
-bool FindUsages::visit(NamespaceAST *ast)
+Scope *FindUsages::switchScope(Scope *scope)
 {
-    const Identifier *id = identifier(ast->identifier_token);
-    if (id == _id && ast->symbol) {
-        const QList<LookupItem> candidates = _context.lookup(ast->symbol->name(), enclosingScope());
-        reportResult(ast->identifier_token, candidates);
-    }
-    return true;
+    Scope *previousScope = _currentScope;
+    _currentScope = scope;
+    return previousScope;
 }
 
-bool FindUsages::visit(MemInitializerAST *ast)
+void FindUsages::statement(StatementAST *ast)
 {
-    if (ast->name && ast->name->asSimpleName() != 0) {
-        ensureNameIsValid(ast->name);
+    accept(ast);
+}
 
-        SimpleNameAST *simple = ast->name->asSimpleName();
-        if (identifier(simple->identifier_token) == _id) {
-            const QList<LookupItem> candidates = _context.lookup(simple->name, enclosingScope());
-            reportResult(simple->identifier_token, candidates);
-        }
-    }
-    accept(ast->expression_list);
-    return false;
+void FindUsages::expression(ExpressionAST *ast)
+{
+    accept(ast);
 }
 
-bool FindUsages::visit(MemberAccessAST *ast)
+void FindUsages::declaration(DeclarationAST *ast)
 {
-    if (ast->member_name) {
-        if (SimpleNameAST *simple = ast->member_name->asSimpleName()) {
-            if (identifier(simple->identifier_token) == _id) {
-                checkExpression(ast->firstToken(), simple->identifier_token);
-                return false;
-            }
-        }
+    accept(ast);
+}
+
+const Name *FindUsages::name(NameAST *ast)
+{
+    if (ast) {
+        accept(ast);
+        return ast->name;
     }
 
-    return true;
+    return 0;
 }
 
-void FindUsages::checkExpression(unsigned startToken, unsigned endToken)
+void FindUsages::specifier(SpecifierAST *ast)
 {
-    const unsigned begin = tokenAt(startToken).begin();
-    const unsigned end = tokenAt(endToken).end();
-
-    const QString expression = _source.mid(begin, end - begin);
-    // qDebug() << "*** check expression:" << expression;
+    accept(ast);
+}
 
-    unsigned line, column;
-    getTokenStartPosition(startToken, &line, &column);
-    Scope *scope = _doc->scopeAt(line, column);
+void FindUsages::ptrOperator(PtrOperatorAST *ast)
+{
+    accept(ast);
+}
 
-    const QList<LookupItem> results = typeofExpression(expression, scope,
-                                                       TypeOfExpression::Preprocess);
+void FindUsages::coreDeclarator(CoreDeclaratorAST *ast)
+{
+    accept(ast);
+}
 
-    reportResult(endToken, results);
+void FindUsages::postfixDeclarator(PostfixDeclaratorAST *ast)
+{
+    accept(ast);
 }
 
-bool FindUsages::visit(QualifiedNameAST *ast)
+// AST
+bool FindUsages::visit(ObjCSelectorArgumentAST *ast)
 {
-    for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) {
-        NestedNameSpecifierAST *nested_name_specifier = it->value;
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
 
-        if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) {
-            SimpleNameAST *simple_name = class_or_namespace_name->asSimpleName();
+void FindUsages::objCSelectorArgument(ObjCSelectorArgumentAST *ast)
+{
+    if (! ast)
+        return;
 
-            TemplateIdAST *template_id = 0;
-            if (! simple_name) {
-                template_id = class_or_namespace_name->asTemplateId();
+    // unsigned name_token = ast->name_token;
+    // unsigned colon_token = ast->colon_token;
+}
 
-                if (template_id) {
-                    for (TemplateArgumentListAST *arg_it = template_id->template_argument_list; arg_it; arg_it = arg_it->next) {
-                        accept(arg_it->value);
-                    }
-                }
-            }
+bool FindUsages::visit(AttributeAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
 
-            if (simple_name || template_id) {
-                const unsigned identifier_token = simple_name
-                           ? simple_name->identifier_token
-                           : template_id->identifier_token;
+void FindUsages::attribute(AttributeAST *ast)
+{
+    if (! ast)
+        return;
 
-                if (identifier(identifier_token) == _id)
-                    checkExpression(ast->firstToken(), identifier_token);
-            }
-        }
+    // unsigned identifier_token = ast->identifier_token;
+    // unsigned lparen_token = ast->lparen_token;
+    // unsigned tag_token = ast->tag_token;
+    for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+        this->expression(it->value);
     }
+    // unsigned rparen_token = ast->rparen_token;
+}
 
-    if (NameAST *unqualified_name = ast->unqualified_name) {
-        unsigned identifier_token = 0;
-
-        if (SimpleNameAST *simple_name = unqualified_name->asSimpleName())
-            identifier_token = simple_name->identifier_token;
-
-        else if (DestructorNameAST *dtor_name = unqualified_name->asDestructorName())
-            identifier_token = dtor_name->identifier_token;
-
-        TemplateIdAST *template_id = 0;
-        if (! identifier_token) {
-            template_id = unqualified_name->asTemplateId();
-
-            if (template_id) {
-                identifier_token = template_id->identifier_token;
+bool FindUsages::visit(DeclaratorAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
 
-                for (TemplateArgumentListAST *template_arguments = template_id->template_argument_list;
-                     template_arguments; template_arguments = template_arguments->next) {
-                    accept(template_arguments->value);
-                }
-            }
-        }
+void FindUsages::declarator(DeclaratorAST *ast)
+{
+    if (! ast)
+        return;
 
-        if (identifier_token && identifier(identifier_token) == _id)
-            checkExpression(ast->firstToken(), identifier_token);
+    for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    for (PtrOperatorListAST *it = ast->ptr_operator_list; it; it = it->next) {
+        this->ptrOperator(it->value);
+    }
+    this->coreDeclarator(ast->core_declarator);
+    for (PostfixDeclaratorListAST *it = ast->postfix_declarator_list; it; it = it->next) {
+        this->postfixDeclarator(it->value);
     }
+    for (SpecifierListAST *it = ast->post_attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    // unsigned equals_token = ast->equals_token;
+    this->expression(ast->initializer);
+}
 
+bool FindUsages::visit(QtPropertyDeclarationItemAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
     return false;
 }
 
-bool FindUsages::visit(EnumeratorAST *ast)
+void FindUsages::qtPropertyDeclarationItem(QtPropertyDeclarationItemAST *ast)
 {
-    const Identifier *id = identifier(ast->identifier_token);
-    if (id == _id) {
-        const QList<LookupItem> candidates = _context.lookup(control()->nameId(id), enclosingScope());
-        reportResult(ast->identifier_token, candidates);
-    }
+    if (! ast)
+        return;
 
-    accept(ast->expression);
+    // unsigned item_name_token = ast->item_name_token;
+    this->expression(ast->expression);
+}
 
+bool FindUsages::visit(QtInterfaceNameAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
     return false;
 }
 
-bool FindUsages::visit(SimpleNameAST *ast)
+void FindUsages::qtInterfaceName(QtInterfaceNameAST *ast)
 {
-    const Identifier *id = identifier(ast->identifier_token);
-    if (id == _id) {
-        const QList<LookupItem> candidates = _context.lookup(ast->name, enclosingScope());
-        reportResult(ast->identifier_token, candidates);
+    if (! ast)
+        return;
+
+    /*const Name *interface_name =*/ this->name(ast->interface_name);
+    for (NameListAST *it = ast->constraint_list; it; it = it->next) {
+        /*const Name *value =*/ this->name(it->value);
     }
+}
 
+bool FindUsages::visit(BaseSpecifierAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
     return false;
 }
 
-bool FindUsages::visit(DestructorNameAST *ast)
+void FindUsages::baseSpecifier(BaseSpecifierAST *ast)
 {
-    const Identifier *id = identifier(ast->identifier_token);
-    if (id == _id) {
-        const QList<LookupItem> candidates = _context.lookup(ast->name, enclosingScope());
-        reportResult(ast->identifier_token, candidates);
-    }
+    if (! ast)
+        return;
 
+    // unsigned virtual_token = ast->virtual_token;
+    // unsigned access_specifier_token = ast->access_specifier_token;
+    /*const Name *name =*/ this->name(ast->name);
+    // BaseClass *symbol = ast->symbol;
+}
+
+bool FindUsages::visit(CtorInitializerAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
     return false;
 }
 
-bool FindUsages::visit(TemplateIdAST *ast)
+void FindUsages::ctorInitializer(CtorInitializerAST *ast)
 {
-    if (_id == identifier(ast->identifier_token)) {
-        const QList<LookupItem> candidates = _context.lookup(ast->name, enclosingScope());
-        reportResult(ast->identifier_token, candidates);
-    }
+    if (! ast)
+        return;
 
-    for (TemplateArgumentListAST *template_arguments = ast->template_argument_list;
-         template_arguments; template_arguments = template_arguments->next) {
-        accept(template_arguments->value);
+    // unsigned colon_token = ast->colon_token;
+    for (MemInitializerListAST *it = ast->member_initializer_list; it; it = it->next) {
+        this->memInitializer(it->value);
     }
+    // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+}
 
+bool FindUsages::visit(EnumeratorAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
     return false;
 }
 
-bool FindUsages::visit(ParameterDeclarationAST *ast)
+void FindUsages::enumerator(EnumeratorAST *ast)
 {
-    for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next)
-        accept(it->value);
-
-    if (DeclaratorAST *declarator = ast->declarator) {
-        for (SpecifierListAST *it = declarator->attribute_list; it; it = it->next)
-            accept(it->value);
-
-        for (PtrOperatorListAST *it = declarator->ptr_operator_list; it; it = it->next)
-            accept(it->value);
+    if (! ast)
+        return;
 
-        if (! _inSimpleDeclaration) // visit the core declarator only if we are not in simple-declaration.
-            accept(declarator->core_declarator);
+    // unsigned identifier_token = ast->identifier_token;
+    reportResult(ast->identifier_token, identifier(ast->identifier_token));
+    // unsigned equal_token = ast->equal_token;
+    this->expression(ast->expression);
+}
 
-        for (PostfixDeclaratorListAST *it = declarator->postfix_declarator_list; it; it = it->next)
-            accept(it->value);
+bool FindUsages::visit(ExceptionSpecificationAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
 
-        for (SpecifierListAST *it = declarator->post_attribute_list; it; it = it->next)
-            accept(it->value);
+void FindUsages::exceptionSpecification(ExceptionSpecificationAST *ast)
+{
+    if (! ast)
+        return;
 
-        accept(declarator->initializer);
+    // unsigned throw_token = ast->throw_token;
+    // unsigned lparen_token = ast->lparen_token;
+    // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+    for (ExpressionListAST *it = ast->type_id_list; it; it = it->next) {
+        this->expression(it->value);
     }
-
-    accept(ast->expression);
-    return false;
+    // unsigned rparen_token = ast->rparen_token;
 }
 
-bool FindUsages::visit(ExpressionOrDeclarationStatementAST *ast)
+bool FindUsages::visit(MemInitializerAST *ast)
 {
-    accept(ast->declaration);
+    (void) ast;
+    Q_ASSERT(!"unreachable");
     return false;
 }
 
-bool FindUsages::visit(FunctionDeclaratorAST *ast)
+void FindUsages::memInitializer(MemInitializerAST *ast)
 {
-    accept(ast->parameters);
+    if (! ast)
+        return;
 
-    for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next)
-        accept(it->value);
+    if (_currentScope->isPrototypeScope()) {
+        Scope *classScope = _currentScope->enclosingClassScope();
+        if (! classScope) {
+            if (ClassOrNamespace *binding = _context.lookupType(_currentScope->owner())) {
+                foreach (Symbol *s, binding->symbols()) {
+                    if (Class *k = s->asClass()) {
+                        classScope = k->members();
+                        break;
+                    }
+                }
+            }
+        }
 
-    accept(ast->exception_specification);
+        if (classScope) {
+            Scope *previousScope = switchScope(classScope);
+            /*const Name *name =*/ this->name(ast->name);
+            (void) switchScope(previousScope);
+        }
+    }
+    // unsigned lparen_token = ast->lparen_token;
+    for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+        this->expression(it->value);
+    }
+    // unsigned rparen_token = ast->rparen_token;
+}
 
+bool FindUsages::visit(NestedNameSpecifierAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
     return false;
 }
 
-bool FindUsages::visit(SimpleDeclarationAST *ast)
+void FindUsages::nestedNameSpecifier(NestedNameSpecifierAST *ast)
 {
-    for  (SpecifierListAST *it = ast->decl_specifier_list; it; it = it->next)
-        accept(it->value);
+    if (! ast)
+        return;
 
-    ++_inSimpleDeclaration;
-    for (DeclaratorListAST *it = ast->declarator_list; it; it = it->next)
-        accept(it->value);
-    --_inSimpleDeclaration;
+    /*const Name *class_or_namespace_name =*/ this->name(ast->class_or_namespace_name);
+    // unsigned scope_token = ast->scope_token;
+}
+
+bool FindUsages::visit(NewPlacementAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
     return false;
 }
 
-bool FindUsages::visit(ObjCSelectorAST *ast)
+void FindUsages::newPlacement(NewPlacementAST *ast)
 {
-    if (ast->name) {
-        const Identifier *id = ast->name->identifier();
-        if (id == _id) {
-            const QList<LookupItem> candidates = _context.lookup(ast->name, enclosingScope());
-            reportResult(ast->firstToken(), candidates);
-        }
+    if (! ast)
+        return;
+
+    // unsigned lparen_token = ast->lparen_token;
+    for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+        this->expression(it->value);
     }
+    // unsigned rparen_token = ast->rparen_token;
+}
 
+bool FindUsages::visit(NewArrayDeclaratorAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
     return false;
 }
 
-bool FindUsages::visit(QtPropertyDeclarationAST *)
+void FindUsages::newArrayDeclarator(NewArrayDeclaratorAST *ast)
 {
-    _inQProperty = true;
-    return true;
-}
+    if (! ast)
+        return;
 
-void FindUsages::endVisit(QtPropertyDeclarationAST *)
-{ _inQProperty = false; }
+    // unsigned lbracket_token = ast->lbracket_token;
+    this->expression(ast->expression);
+    // unsigned rbracket_token = ast->rbracket_token;
+}
 
-bool FindUsages::visit(TypenameTypeParameterAST *ast)
+bool FindUsages::visit(NewInitializerAST *ast)
 {
-    accept(ast->name);
-    accept(ast->type_id);
+    (void) ast;
+    Q_ASSERT(!"unreachable");
     return false;
 }
 
-bool FindUsages::visit(TemplateTypeParameterAST *ast)
+void FindUsages::newInitializer(NewInitializerAST *ast)
+{
+    if (! ast)
+        return;
+
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->expression);
+    // unsigned rparen_token = ast->rparen_token;
+}
+
+bool FindUsages::visit(NewTypeIdAST *ast)
 {
-    accept(ast->name);
-    accept(ast->type_id);
+    (void) ast;
+    Q_ASSERT(!"unreachable");
     return false;
 }
 
-FunctionDefinitionAST *FindUsages::enclosingFunctionDefinition() const
+void FindUsages::newTypeId(NewTypeIdAST *ast)
 {
-    for (int index = _astStack.size() - 1; index != -1; --index) {
-        AST *ast = _astStack.at(index);
+    if (! ast)
+        return;
 
-        if (FunctionDefinitionAST *funDef = ast->asFunctionDefinition())
-            return funDef;
+    for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    for (PtrOperatorListAST *it = ast->ptr_operator_list; it; it = it->next) {
+        this->ptrOperator(it->value);
+    }
+    for (NewArrayDeclaratorListAST *it = ast->new_array_declarator_list; it; it = it->next) {
+        this->newArrayDeclarator(it->value);
     }
-
-    return 0;
 }
 
-TemplateDeclarationAST *FindUsages::enclosingTemplateDeclaration() const
+bool FindUsages::visit(OperatorAST *ast)
 {
-    for (int index = _astStack.size() - 1; index != -1; --index) {
-        AST *ast = _astStack.at(index);
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
 
-        if (TemplateDeclarationAST *funDef = ast->asTemplateDeclaration())
-            return funDef;
-    }
+void FindUsages::cppOperator(OperatorAST *ast)
+{
+    if (! ast)
+        return;
 
-    return 0;
+    // unsigned op_token = ast->op_token;
+    // unsigned open_token = ast->open_token;
+    // unsigned close_token = ast->close_token;
 }
 
-Scope *FindUsages::enclosingScope()
+bool FindUsages::visit(ParameterDeclarationClauseAST *ast)
 {
-    for (int index = _astStack.size() - 1; index != -1; --index) {
-        AST *ast = _astStack.at(index);
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
 
-        if (NamespaceAST *ns = ast->asNamespace()) {
-            if (ns->symbol)
-                return ns->symbol->members();
+void FindUsages::parameterDeclarationClause(ParameterDeclarationClauseAST *ast)
+{
+    if (! ast)
+        return;
 
-        } else if (ClassSpecifierAST *classSpec = ast->asClassSpecifier()) {
-            if (classSpec->symbol)
-                return classSpec->symbol->members();
+    for (DeclarationListAST *it = ast->parameter_declaration_list; it; it = it->next) {
+        this->declaration(it->value);
+    }
+    // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+}
 
-        } else if (FunctionDefinitionAST *funDef = ast->asFunctionDefinition()) {
-            if (funDef->symbol)
-                return funDef->symbol->members();
+bool FindUsages::visit(TranslationUnitAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
 
-        } else if (CompoundStatementAST *blockStmt = ast->asCompoundStatement()) {
-            if (blockStmt->symbol)
-                return blockStmt->symbol->members();
+void FindUsages::translationUnit(TranslationUnitAST *ast)
+{
+    if (! ast)
+        return;
 
-        } else if (IfStatementAST *ifStmt = ast->asIfStatement()) {
-            if (ifStmt->symbol)
-                return ifStmt->symbol->members();
+    Scope *previousScope = switchScope(_doc->globalSymbols());
+    for (DeclarationListAST *it = ast->declaration_list; it; it = it->next) {
+        this->declaration(it->value);
+    }
+    (void) switchScope(previousScope);
+}
 
-        } else if (WhileStatementAST *whileStmt = ast->asWhileStatement()) {
-            if (whileStmt->symbol)
-                return whileStmt->symbol->members();
+bool FindUsages::visit(ObjCProtocolRefsAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
 
-        } else if (ForStatementAST *forStmt = ast->asForStatement()) {
-            if (forStmt->symbol)
-                return forStmt->symbol->members();
+void FindUsages::objCProtocolRefs(ObjCProtocolRefsAST *ast)
+{
+    if (! ast)
+        return;
 
-        } else if (ForeachStatementAST *foreachStmt = ast->asForeachStatement()) {
-            if (foreachStmt->symbol)
-                return foreachStmt->symbol->members();
+    // unsigned less_token = ast->less_token;
+    for (NameListAST *it = ast->identifier_list; it; it = it->next) {
+        /*const Name *value =*/ this->name(it->value);
+    }
+    // unsigned greater_token = ast->greater_token;
+}
 
-        } else if (SwitchStatementAST *switchStmt = ast->asSwitchStatement()) {
-            if (switchStmt->symbol)
-                return switchStmt->symbol->members();
+bool FindUsages::visit(ObjCMessageArgumentAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
 
-        } else if (CatchClauseAST *catchClause = ast->asCatchClause()) {
-            if (catchClause->symbol)
-                return catchClause->symbol->members();
+void FindUsages::objCMessageArgument(ObjCMessageArgumentAST *ast)
+{
+    if (! ast)
+        return;
 
-        }
-    }
+    this->expression(ast->parameter_value_expression);
+}
 
-    return _doc->globalSymbols();
+bool FindUsages::visit(ObjCTypeNameAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
 }
 
-bool FindUsages::preVisit(AST *ast)
+void FindUsages::objCTypeName(ObjCTypeNameAST *ast)
 {
-    _astStack.append(ast);
-    return true;
+    if (! ast)
+        return;
+
+    // unsigned lparen_token = ast->lparen_token;
+    // unsigned type_qualifier_token = ast->type_qualifier_token;
+    this->expression(ast->type_id);
+    // unsigned rparen_token = ast->rparen_token;
 }
 
-void FindUsages::postVisit(AST *)
+bool FindUsages::visit(ObjCInstanceVariablesDeclarationAST *ast)
 {
-    _astStack.takeLast();
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
 }
+
+void FindUsages::objCInstanceVariablesDeclaration(ObjCInstanceVariablesDeclarationAST *ast)
+{
+    if (! ast)
+        return;
+
+    // unsigned lbrace_token = ast->lbrace_token;
+    for (DeclarationListAST *it = ast->instance_variable_list; it; it = it->next) {
+        this->declaration(it->value);
+    }
+    // unsigned rbrace_token = ast->rbrace_token;
+}
+
+bool FindUsages::visit(ObjCPropertyAttributeAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
+
+void FindUsages::objCPropertyAttribute(ObjCPropertyAttributeAST *ast)
+{
+    if (! ast)
+        return;
+
+    // unsigned attribute_identifier_token = ast->attribute_identifier_token;
+    // unsigned equals_token = ast->equals_token;
+    /*const Name *method_selector =*/ this->name(ast->method_selector);
+}
+
+bool FindUsages::visit(ObjCMessageArgumentDeclarationAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
+
+void FindUsages::objCMessageArgumentDeclaration(ObjCMessageArgumentDeclarationAST *ast)
+{
+    if (! ast)
+        return;
+
+    this->objCTypeName(ast->type_name);
+    for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    /*const Name *param_name =*/ this->name(ast->param_name);
+    // Argument *argument = ast->argument;
+}
+
+bool FindUsages::visit(ObjCMethodPrototypeAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
+
+void FindUsages::objCMethodPrototype(ObjCMethodPrototypeAST *ast)
+{
+    if (! ast)
+        return;
+
+    // unsigned method_type_token = ast->method_type_token;
+    this->objCTypeName(ast->type_name);
+    /*const Name *selector =*/ this->name(ast->selector);
+    Scope *previousScope = switchScope(ast->symbol);
+    for (ObjCMessageArgumentDeclarationListAST *it = ast->argument_list; it; it = it->next) {
+        this->objCMessageArgumentDeclaration(it->value);
+    }
+    // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+    for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    // ObjCMethod *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+}
+
+bool FindUsages::visit(ObjCSynthesizedPropertyAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
+
+void FindUsages::objCSynthesizedProperty(ObjCSynthesizedPropertyAST *ast)
+{
+    if (! ast)
+        return;
+
+    // unsigned property_identifier_token = ast->property_identifier_token;
+    // unsigned equals_token = ast->equals_token;
+    // unsigned alias_identifier_token = ast->alias_identifier_token;
+}
+
+bool FindUsages::visit(LambdaIntroducerAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
+
+void FindUsages::lambdaIntroducer(LambdaIntroducerAST *ast)
+{
+    if (! ast)
+        return;
+
+    // unsigned lbracket_token = ast->lbracket_token;
+    this->lambdaCapture(ast->lambda_capture);
+    // unsigned rbracket_token = ast->rbracket_token;
+}
+
+bool FindUsages::visit(LambdaCaptureAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
+
+void FindUsages::lambdaCapture(LambdaCaptureAST *ast)
+{
+    if (! ast)
+        return;
+
+    // unsigned default_capture_token = ast->default_capture_token;
+    for (CaptureListAST *it = ast->capture_list; it; it = it->next) {
+        this->capture(it->value);
+    }
+}
+
+bool FindUsages::visit(CaptureAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
+
+void FindUsages::capture(CaptureAST *ast)
+{
+    if (! ast)
+        return;
+
+}
+
+bool FindUsages::visit(LambdaDeclaratorAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
+
+void FindUsages::lambdaDeclarator(LambdaDeclaratorAST *ast)
+{
+    if (! ast)
+        return;
+
+    // unsigned lparen_token = ast->lparen_token;
+    this->parameterDeclarationClause(ast->parameter_declaration_clause);
+    // unsigned rparen_token = ast->rparen_token;
+    for (SpecifierListAST *it = ast->attributes; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    // unsigned mutable_token = ast->mutable_token;
+    this->exceptionSpecification(ast->exception_specification);
+    this->trailingReturnType(ast->trailing_return_type);
+}
+
+bool FindUsages::visit(TrailingReturnTypeAST *ast)
+{
+    (void) ast;
+    Q_ASSERT(!"unreachable");
+    return false;
+}
+
+void FindUsages::trailingReturnType(TrailingReturnTypeAST *ast)
+{
+    if (! ast)
+        return;
+
+    // unsigned arrow_token = ast->arrow_token;
+    for (SpecifierListAST *it = ast->attributes; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    for (SpecifierListAST *it = ast->type_specifiers; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    this->declarator(ast->declarator);
+}
+
+
+// StatementAST
+bool FindUsages::visit(QtMemberDeclarationAST *ast)
+{
+    // unsigned q_token = ast->q_token;
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->type_id);
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(CaseStatementAST *ast)
+{
+    // unsigned case_token = ast->case_token;
+    this->expression(ast->expression);
+    // unsigned colon_token = ast->colon_token;
+    this->statement(ast->statement);
+    return false;
+}
+
+bool FindUsages::visit(CompoundStatementAST *ast)
+{
+    // unsigned lbrace_token = ast->lbrace_token;
+    Scope *previousScope = switchScope(ast->symbol);
+    for (StatementListAST *it = ast->statement_list; it; it = it->next) {
+        this->statement(it->value);
+    }
+    // unsigned rbrace_token = ast->rbrace_token;
+    // Block *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(DeclarationStatementAST *ast)
+{
+    this->declaration(ast->declaration);
+    return false;
+}
+
+bool FindUsages::visit(DoStatementAST *ast)
+{
+    // unsigned do_token = ast->do_token;
+    this->statement(ast->statement);
+    // unsigned while_token = ast->while_token;
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->expression);
+    // unsigned rparen_token = ast->rparen_token;
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+bool FindUsages::visit(ExpressionOrDeclarationStatementAST *ast)
+{
+    this->statement(ast->expression);
+    this->statement(ast->declaration);
+    return false;
+}
+
+bool FindUsages::visit(ExpressionStatementAST *ast)
+{
+    this->expression(ast->expression);
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+bool FindUsages::visit(ForeachStatementAST *ast)
+{
+    // unsigned foreach_token = ast->foreach_token;
+    // unsigned lparen_token = ast->lparen_token;
+    Scope *previousScope = switchScope(ast->symbol);
+    for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    this->declarator(ast->declarator);
+    this->expression(ast->initializer);
+    // unsigned comma_token = ast->comma_token;
+    this->expression(ast->expression);
+    // unsigned rparen_token = ast->rparen_token;
+    this->statement(ast->statement);
+    // Block *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(ForStatementAST *ast)
+{
+    // unsigned for_token = ast->for_token;
+    // unsigned lparen_token = ast->lparen_token;
+    Scope *previousScope = switchScope(ast->symbol);
+    this->statement(ast->initializer);
+    this->expression(ast->condition);
+    // unsigned semicolon_token = ast->semicolon_token;
+    this->expression(ast->expression);
+    // unsigned rparen_token = ast->rparen_token;
+    this->statement(ast->statement);
+    // Block *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(IfStatementAST *ast)
+{
+    // unsigned if_token = ast->if_token;
+    // unsigned lparen_token = ast->lparen_token;
+    Scope *previousScope = switchScope(ast->symbol);
+    this->expression(ast->condition);
+    // unsigned rparen_token = ast->rparen_token;
+    this->statement(ast->statement);
+    // unsigned else_token = ast->else_token;
+    this->statement(ast->else_statement);
+    // Block *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(LabeledStatementAST *ast)
+{
+    // unsigned label_token = ast->label_token;
+    // unsigned colon_token = ast->colon_token;
+    this->statement(ast->statement);
+    return false;
+}
+
+bool FindUsages::visit(BreakStatementAST *ast)
+{
+    (void) ast;
+    // unsigned break_token = ast->break_token;
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+bool FindUsages::visit(ContinueStatementAST *ast)
+{
+    (void) ast;
+    // unsigned continue_token = ast->continue_token;
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+bool FindUsages::visit(GotoStatementAST *ast)
+{
+    (void) ast;
+    // unsigned goto_token = ast->goto_token;
+    // unsigned identifier_token = ast->identifier_token;
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+bool FindUsages::visit(ReturnStatementAST *ast)
+{
+    // unsigned return_token = ast->return_token;
+    this->expression(ast->expression);
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+bool FindUsages::visit(SwitchStatementAST *ast)
+{
+    // unsigned switch_token = ast->switch_token;
+    // unsigned lparen_token = ast->lparen_token;
+    Scope *previousScope = switchScope(ast->symbol);
+    this->expression(ast->condition);
+    // unsigned rparen_token = ast->rparen_token;
+    this->statement(ast->statement);
+    // Block *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(TryBlockStatementAST *ast)
+{
+    // unsigned try_token = ast->try_token;
+    this->statement(ast->statement);
+    for (CatchClauseListAST *it = ast->catch_clause_list; it; it = it->next) {
+        this->statement(it->value);
+    }
+    return false;
+}
+
+bool FindUsages::visit(CatchClauseAST *ast)
+{
+    // unsigned catch_token = ast->catch_token;
+    // unsigned lparen_token = ast->lparen_token;
+    Scope *previousScope = switchScope(ast->symbol);
+    this->declaration(ast->exception_declaration);
+    // unsigned rparen_token = ast->rparen_token;
+    this->statement(ast->statement);
+    // Block *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(WhileStatementAST *ast)
+{
+    // unsigned while_token = ast->while_token;
+    // unsigned lparen_token = ast->lparen_token;
+    Scope *previousScope = switchScope(ast->symbol);
+    this->expression(ast->condition);
+    // unsigned rparen_token = ast->rparen_token;
+    this->statement(ast->statement);
+    // Block *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(ObjCFastEnumerationAST *ast)
+{
+    // unsigned for_token = ast->for_token;
+    // unsigned lparen_token = ast->lparen_token;
+    Scope *previousScope = switchScope(ast->symbol);
+    for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    this->declarator(ast->declarator);
+    this->expression(ast->initializer);
+    // unsigned in_token = ast->in_token;
+    this->expression(ast->fast_enumeratable_expression);
+    // unsigned rparen_token = ast->rparen_token;
+    this->statement(ast->statement);
+    // Block *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(ObjCSynchronizedStatementAST *ast)
+{
+    // unsigned synchronized_token = ast->synchronized_token;
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->synchronized_object);
+    // unsigned rparen_token = ast->rparen_token;
+    this->statement(ast->statement);
+    return false;
+}
+
+
+// ExpressionAST
+bool FindUsages::visit(IdExpressionAST *ast)
+{
+    /*const Name *name =*/ this->name(ast->name);
+    return false;
+}
+
+bool FindUsages::visit(CompoundExpressionAST *ast)
+{
+    // unsigned lparen_token = ast->lparen_token;
+    this->statement(ast->statement);
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(CompoundLiteralAST *ast)
+{
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->type_id);
+    // unsigned rparen_token = ast->rparen_token;
+    this->expression(ast->initializer);
+    return false;
+}
+
+bool FindUsages::visit(QtMethodAST *ast)
+{
+    // unsigned method_token = ast->method_token;
+    // unsigned lparen_token = ast->lparen_token;
+    this->declarator(ast->declarator);
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(BinaryExpressionAST *ast)
+{
+    this->expression(ast->left_expression);
+    // unsigned binary_op_token = ast->binary_op_token;
+    this->expression(ast->right_expression);
+    return false;
+}
+
+bool FindUsages::visit(CastExpressionAST *ast)
+{
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->type_id);
+    // unsigned rparen_token = ast->rparen_token;
+    this->expression(ast->expression);
+    return false;
+}
+
+bool FindUsages::visit(ConditionAST *ast)
+{
+    for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    this->declarator(ast->declarator);
+    return false;
+}
+
+bool FindUsages::visit(ConditionalExpressionAST *ast)
+{
+    this->expression(ast->condition);
+    // unsigned question_token = ast->question_token;
+    this->expression(ast->left_expression);
+    // unsigned colon_token = ast->colon_token;
+    this->expression(ast->right_expression);
+    return false;
+}
+
+bool FindUsages::visit(CppCastExpressionAST *ast)
+{
+    // unsigned cast_token = ast->cast_token;
+    // unsigned less_token = ast->less_token;
+    this->expression(ast->type_id);
+    // unsigned greater_token = ast->greater_token;
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->expression);
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(DeleteExpressionAST *ast)
+{
+    // unsigned scope_token = ast->scope_token;
+    // unsigned delete_token = ast->delete_token;
+    // unsigned lbracket_token = ast->lbracket_token;
+    // unsigned rbracket_token = ast->rbracket_token;
+    this->expression(ast->expression);
+    return false;
+}
+
+bool FindUsages::visit(ArrayInitializerAST *ast)
+{
+    // unsigned lbrace_token = ast->lbrace_token;
+    for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+        this->expression(it->value);
+    }
+    // unsigned rbrace_token = ast->rbrace_token;
+    return false;
+}
+
+bool FindUsages::visit(NewExpressionAST *ast)
+{
+    // unsigned scope_token = ast->scope_token;
+    // unsigned new_token = ast->new_token;
+    this->newPlacement(ast->new_placement);
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->type_id);
+    // unsigned rparen_token = ast->rparen_token;
+    this->newTypeId(ast->new_type_id);
+    this->newInitializer(ast->new_initializer);
+    return false;
+}
+
+bool FindUsages::visit(TypeidExpressionAST *ast)
+{
+    // unsigned typeid_token = ast->typeid_token;
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->expression);
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(TypenameCallExpressionAST *ast)
+{
+    // unsigned typename_token = ast->typename_token;
+    /*const Name *name =*/ this->name(ast->name);
+    // unsigned lparen_token = ast->lparen_token;
+    for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+        this->expression(it->value);
+    }
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(TypeConstructorCallAST *ast)
+{
+    for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    // unsigned lparen_token = ast->lparen_token;
+    for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+        this->expression(it->value);
+    }
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(SizeofExpressionAST *ast)
+{
+    // unsigned sizeof_token = ast->sizeof_token;
+    // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->expression);
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(NumericLiteralAST *ast)
+{
+    (void) ast;
+    // unsigned literal_token = ast->literal_token;
+    return false;
+}
+
+bool FindUsages::visit(BoolLiteralAST *ast)
+{
+    (void) ast;
+    // unsigned literal_token = ast->literal_token;
+    return false;
+}
+
+bool FindUsages::visit(ThisExpressionAST *ast)
+{
+    (void) ast;
+    // unsigned this_token = ast->this_token;
+    return false;
+}
+
+bool FindUsages::visit(NestedExpressionAST *ast)
+{
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->expression);
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(StringLiteralAST *ast)
+{
+    // unsigned literal_token = ast->literal_token;
+    this->expression(ast->next);
+    return false;
+}
+
+bool FindUsages::visit(ThrowExpressionAST *ast)
+{
+    // unsigned throw_token = ast->throw_token;
+    this->expression(ast->expression);
+    return false;
+}
+
+bool FindUsages::visit(TypeIdAST *ast)
+{
+    for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    this->declarator(ast->declarator);
+    return false;
+}
+
+bool FindUsages::visit(UnaryExpressionAST *ast)
+{
+    // unsigned unary_op_token = ast->unary_op_token;
+    this->expression(ast->expression);
+    return false;
+}
+
+bool FindUsages::visit(ObjCMessageExpressionAST *ast)
+{
+    // unsigned lbracket_token = ast->lbracket_token;
+    this->expression(ast->receiver_expression);
+    /*const Name *selector =*/ this->name(ast->selector);
+    for (ObjCMessageArgumentListAST *it = ast->argument_list; it; it = it->next) {
+        this->objCMessageArgument(it->value);
+    }
+    // unsigned rbracket_token = ast->rbracket_token;
+    return false;
+}
+
+bool FindUsages::visit(ObjCProtocolExpressionAST *ast)
+{
+    (void) ast;
+    // unsigned protocol_token = ast->protocol_token;
+    // unsigned lparen_token = ast->lparen_token;
+    // unsigned identifier_token = ast->identifier_token;
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(ObjCEncodeExpressionAST *ast)
+{
+    // unsigned encode_token = ast->encode_token;
+    this->objCTypeName(ast->type_name);
+    return false;
+}
+
+bool FindUsages::visit(ObjCSelectorExpressionAST *ast)
+{
+    // unsigned selector_token = ast->selector_token;
+    // unsigned lparen_token = ast->lparen_token;
+    /*const Name *selector =*/ this->name(ast->selector);
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(LambdaExpressionAST *ast)
+{
+    this->lambdaIntroducer(ast->lambda_introducer);
+    this->lambdaDeclarator(ast->lambda_declarator);
+    this->statement(ast->statement);
+    return false;
+}
+
+bool FindUsages::visit(BracedInitializerAST *ast)
+{
+    // unsigned lbrace_token = ast->lbrace_token;
+    for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+        this->expression(it->value);
+    }
+    // unsigned comma_token = ast->comma_token;
+    // unsigned rbrace_token = ast->rbrace_token;
+    return false;
+}
+
+
+// DeclarationAST
+bool FindUsages::visit(SimpleDeclarationAST *ast)
+{
+    // unsigned qt_invokable_token = ast->qt_invokable_token;
+    for (SpecifierListAST *it = ast->decl_specifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    for (DeclaratorListAST *it = ast->declarator_list; it; it = it->next) {
+        this->declarator(it->value);
+    }
+    // unsigned semicolon_token = ast->semicolon_token;
+    // List<Declaration *> *symbols = ast->symbols;
+    return false;
+}
+
+bool FindUsages::visit(EmptyDeclarationAST *ast)
+{
+    (void) ast;
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+bool FindUsages::visit(AccessDeclarationAST *ast)
+{
+    (void) ast;
+    // unsigned access_specifier_token = ast->access_specifier_token;
+    // unsigned slots_token = ast->slots_token;
+    // unsigned colon_token = ast->colon_token;
+    return false;
+}
+
+bool FindUsages::visit(QtObjectTagAST *ast)
+{
+    (void) ast;
+    // unsigned q_object_token = ast->q_object_token;
+    return false;
+}
+
+bool FindUsages::visit(QtPrivateSlotAST *ast)
+{
+    // unsigned q_private_slot_token = ast->q_private_slot_token;
+    // unsigned lparen_token = ast->lparen_token;
+    // unsigned dptr_token = ast->dptr_token;
+    // unsigned dptr_lparen_token = ast->dptr_lparen_token;
+    // unsigned dptr_rparen_token = ast->dptr_rparen_token;
+    // unsigned comma_token = ast->comma_token;
+    for (SpecifierListAST *it = ast->type_specifiers; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    this->declarator(ast->declarator);
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(QtPropertyDeclarationAST *ast)
+{
+    // unsigned property_specifier_token = ast->property_specifier_token;
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->type_id);
+    /*const Name *property_name =*/ this->name(ast->property_name);
+    for (QtPropertyDeclarationItemListAST *it = ast->property_declaration_items; it; it = it->next) {
+        this->qtPropertyDeclarationItem(it->value);
+    }
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(QtEnumDeclarationAST *ast)
+{
+    // unsigned enum_specifier_token = ast->enum_specifier_token;
+    // unsigned lparen_token = ast->lparen_token;
+    for (NameListAST *it = ast->enumerator_list; it; it = it->next) {
+        /*const Name *value =*/ this->name(it->value);
+    }
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(QtFlagsDeclarationAST *ast)
+{
+    // unsigned flags_specifier_token = ast->flags_specifier_token;
+    // unsigned lparen_token = ast->lparen_token;
+    for (NameListAST *it = ast->flag_enums_list; it; it = it->next) {
+        /*const Name *value =*/ this->name(it->value);
+    }
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(QtInterfacesDeclarationAST *ast)
+{
+    // unsigned interfaces_token = ast->interfaces_token;
+    // unsigned lparen_token = ast->lparen_token;
+    for (QtInterfaceNameListAST *it = ast->interface_name_list; it; it = it->next) {
+        this->qtInterfaceName(it->value);
+    }
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(AsmDefinitionAST *ast)
+{
+    (void) ast;
+    // unsigned asm_token = ast->asm_token;
+    // unsigned volatile_token = ast->volatile_token;
+    // unsigned lparen_token = ast->lparen_token;
+    // unsigned rparen_token = ast->rparen_token;
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+bool FindUsages::visit(ExceptionDeclarationAST *ast)
+{
+    for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    this->declarator(ast->declarator);
+    // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+    return false;
+}
+
+bool FindUsages::visit(FunctionDefinitionAST *ast)
+{
+    // unsigned qt_invokable_token = ast->qt_invokable_token;
+    for (SpecifierListAST *it = ast->decl_specifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    Scope *previousScope = switchScope(ast->symbol); // ### not exactly.
+    this->declarator(ast->declarator);
+    this->ctorInitializer(ast->ctor_initializer);
+    this->statement(ast->function_body);
+    // Function *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(LinkageBodyAST *ast)
+{
+    // unsigned lbrace_token = ast->lbrace_token;
+    for (DeclarationListAST *it = ast->declaration_list; it; it = it->next) {
+        this->declaration(it->value);
+    }
+    // unsigned rbrace_token = ast->rbrace_token;
+    return false;
+}
+
+bool FindUsages::visit(LinkageSpecificationAST *ast)
+{
+    // unsigned extern_token = ast->extern_token;
+    // unsigned extern_type_token = ast->extern_type_token;
+    this->declaration(ast->declaration);
+    return false;
+}
+
+bool FindUsages::visit(NamespaceAST *ast)
+{
+    // unsigned namespace_token = ast->namespace_token;
+    // unsigned identifier_token = ast->identifier_token;
+    reportResult(ast->identifier_token, identifier(ast->identifier_token));
+    Scope *previousScope = switchScope(ast->symbol);
+    for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    this->declaration(ast->linkage_body);
+    // Namespace *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(NamespaceAliasDefinitionAST *ast)
+{
+    // unsigned namespace_token = ast->namespace_token;
+    // unsigned namespace_name_token = ast->namespace_name_token;
+    // unsigned equal_token = ast->equal_token;
+    /*const Name *name =*/ this->name(ast->name);
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+bool FindUsages::visit(ParameterDeclarationAST *ast)
+{
+    for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    this->declarator(ast->declarator);
+    // unsigned equal_token = ast->equal_token;
+    this->expression(ast->expression);
+    // Argument *symbol = ast->symbol;
+    return false;
+}
+
+bool FindUsages::visit(TemplateDeclarationAST *ast)
+{
+    // unsigned export_token = ast->export_token;
+    // unsigned template_token = ast->template_token;
+    // unsigned less_token = ast->less_token;
+    for (DeclarationListAST *it = ast->template_parameter_list; it; it = it->next) {
+        this->declaration(it->value);
+    }
+    // unsigned greater_token = ast->greater_token;
+    this->declaration(ast->declaration);
+    return false;
+}
+
+bool FindUsages::visit(TypenameTypeParameterAST *ast)
+{
+    // unsigned classkey_token = ast->classkey_token;
+    // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+    /*const Name *name =*/ this->name(ast->name);
+    // unsigned equal_token = ast->equal_token;
+    this->expression(ast->type_id);
+    // TypenameArgument *symbol = ast->symbol;
+    return false;
+}
+
+bool FindUsages::visit(TemplateTypeParameterAST *ast)
+{
+    // unsigned template_token = ast->template_token;
+    // unsigned less_token = ast->less_token;
+    for (DeclarationListAST *it = ast->template_parameter_list; it; it = it->next) {
+        this->declaration(it->value);
+    }
+    // unsigned greater_token = ast->greater_token;
+    // unsigned class_token = ast->class_token;
+    // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+    /*const Name *name =*/ this->name(ast->name);
+    // unsigned equal_token = ast->equal_token;
+    this->expression(ast->type_id);
+    // TypenameArgument *symbol = ast->symbol;
+    return false;
+}
+
+bool FindUsages::visit(UsingAST *ast)
+{
+    // unsigned using_token = ast->using_token;
+    // unsigned typename_token = ast->typename_token;
+    /*const Name *name =*/ this->name(ast->name);
+    // unsigned semicolon_token = ast->semicolon_token;
+    // UsingDeclaration *symbol = ast->symbol;
+    return false;
+}
+
+bool FindUsages::visit(UsingDirectiveAST *ast)
+{
+    // unsigned using_token = ast->using_token;
+    // unsigned namespace_token = ast->namespace_token;
+    /*const Name *name =*/ this->name(ast->name);
+    // unsigned semicolon_token = ast->semicolon_token;
+    // UsingNamespaceDirective *symbol = ast->symbol;
+    return false;
+}
+
+bool FindUsages::visit(ObjCClassForwardDeclarationAST *ast)
+{
+    for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    // unsigned class_token = ast->class_token;
+    for (NameListAST *it = ast->identifier_list; it; it = it->next) {
+        /*const Name *value =*/ this->name(it->value);
+    }
+    // unsigned semicolon_token = ast->semicolon_token;
+    // List<ObjCForwardClassDeclaration *> *symbols = ast->symbols;
+    return false;
+}
+
+bool FindUsages::visit(ObjCClassDeclarationAST *ast)
+{
+    for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    // unsigned interface_token = ast->interface_token;
+    // unsigned implementation_token = ast->implementation_token;
+    /*const Name *class_name =*/ this->name(ast->class_name);
+
+    Scope *previousScope = switchScope(ast->symbol);
+
+    // unsigned lparen_token = ast->lparen_token;
+    /*const Name *category_name =*/ this->name(ast->category_name);
+    // unsigned rparen_token = ast->rparen_token;
+    // unsigned colon_token = ast->colon_token;
+    /*const Name *superclass =*/ this->name(ast->superclass);
+    this->objCProtocolRefs(ast->protocol_refs);
+    this->objCInstanceVariablesDeclaration(ast->inst_vars_decl);
+    for (DeclarationListAST *it = ast->member_declaration_list; it; it = it->next) {
+        this->declaration(it->value);
+    }
+    // unsigned end_token = ast->end_token;
+    // ObjCClass *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(ObjCProtocolForwardDeclarationAST *ast)
+{
+    for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    // unsigned protocol_token = ast->protocol_token;
+    for (NameListAST *it = ast->identifier_list; it; it = it->next) {
+        /*const Name *value =*/ this->name(it->value);
+    }
+    // unsigned semicolon_token = ast->semicolon_token;
+    // List<ObjCForwardProtocolDeclaration *> *symbols = ast->symbols;
+    return false;
+}
+
+bool FindUsages::visit(ObjCProtocolDeclarationAST *ast)
+{
+    for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    // unsigned protocol_token = ast->protocol_token;
+    /*const Name *name =*/ this->name(ast->name);
+
+    Scope *previousScope = switchScope(ast->symbol);
+
+    this->objCProtocolRefs(ast->protocol_refs);
+    for (DeclarationListAST *it = ast->member_declaration_list; it; it = it->next) {
+        this->declaration(it->value);
+    }
+    // unsigned end_token = ast->end_token;
+    // ObjCProtocol *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(ObjCVisibilityDeclarationAST *ast)
+{
+    (void) ast;
+    // unsigned visibility_token = ast->visibility_token;
+    return false;
+}
+
+bool FindUsages::visit(ObjCPropertyDeclarationAST *ast)
+{
+    for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    // unsigned property_token = ast->property_token;
+    // unsigned lparen_token = ast->lparen_token;
+    for (ObjCPropertyAttributeListAST *it = ast->property_attribute_list; it; it = it->next) {
+        this->objCPropertyAttribute(it->value);
+    }
+    // unsigned rparen_token = ast->rparen_token;
+    this->declaration(ast->simple_declaration);
+    // List<ObjCPropertyDeclaration *> *symbols = ast->symbols;
+    return false;
+}
+
+bool FindUsages::visit(ObjCMethodDeclarationAST *ast)
+{
+    this->objCMethodPrototype(ast->method_prototype);
+    this->statement(ast->function_body);
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+bool FindUsages::visit(ObjCSynthesizedPropertiesDeclarationAST *ast)
+{
+    // unsigned synthesized_token = ast->synthesized_token;
+    for (ObjCSynthesizedPropertyListAST *it = ast->property_identifier_list; it; it = it->next) {
+        this->objCSynthesizedProperty(it->value);
+    }
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+bool FindUsages::visit(ObjCDynamicPropertiesDeclarationAST *ast)
+{
+    // unsigned dynamic_token = ast->dynamic_token;
+    for (NameListAST *it = ast->property_identifier_list; it; it = it->next) {
+        /*const Name *value =*/ this->name(it->value);
+    }
+    // unsigned semicolon_token = ast->semicolon_token;
+    return false;
+}
+
+// NameAST
+bool FindUsages::visit(ObjCSelectorAST *ast)
+{
+    if (ast->name)
+        reportResult(ast->firstToken(), ast->name);
+
+    for (ObjCSelectorArgumentListAST *it = ast->selector_argument_list; it; it = it->next) {
+        this->objCSelectorArgument(it->value);
+    }
+    return false;
+}
+
+bool FindUsages::visit(QualifiedNameAST *ast)
+{
+#if 0
+    // unsigned global_scope_token = ast->global_scope_token;
+    for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) {
+        this->nestedNameSpecifier(it->value);
+    }
+    const Name *unqualified_name = this->name(ast->unqualified_name);
+#endif
+
+    for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) {
+        NestedNameSpecifierAST *nested_name_specifier = it->value;
+
+        if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) {
+            SimpleNameAST *simple_name = class_or_namespace_name->asSimpleName();
+
+            TemplateIdAST *template_id = 0;
+            if (! simple_name) {
+                template_id = class_or_namespace_name->asTemplateId();
+
+                if (template_id) {
+                    for (TemplateArgumentListAST *arg_it = template_id->template_argument_list; arg_it; arg_it = arg_it->next) {
+                        this->expression(arg_it->value);
+                    }
+                }
+            }
+
+            if (simple_name || template_id) {
+                const unsigned identifier_token = simple_name
+                           ? simple_name->identifier_token
+                           : template_id->identifier_token;
+
+                if (identifier(identifier_token) == _id)
+                    checkExpression(ast->firstToken(), identifier_token);
+            }
+        }
+    }
+
+    if (NameAST *unqualified_name = ast->unqualified_name) {
+        unsigned identifier_token = 0;
+
+        if (SimpleNameAST *simple_name = unqualified_name->asSimpleName())
+            identifier_token = simple_name->identifier_token;
+
+        else if (DestructorNameAST *dtor_name = unqualified_name->asDestructorName())
+            identifier_token = dtor_name->identifier_token;
+
+        TemplateIdAST *template_id = 0;
+        if (! identifier_token) {
+            template_id = unqualified_name->asTemplateId();
+
+            if (template_id) {
+                identifier_token = template_id->identifier_token;
+
+                for (TemplateArgumentListAST *template_arguments = template_id->template_argument_list;
+                     template_arguments; template_arguments = template_arguments->next) {
+                    this->expression(template_arguments->value);
+                }
+            }
+        }
+
+        if (identifier_token && identifier(identifier_token) == _id)
+            checkExpression(ast->firstToken(), identifier_token);
+    }
+
+    return false;
+
+    return false;
+}
+
+bool FindUsages::visit(OperatorFunctionIdAST *ast)
+{
+    // unsigned operator_token = ast->operator_token;
+    this->cppOperator(ast->op);
+    return false;
+}
+
+bool FindUsages::visit(ConversionFunctionIdAST *ast)
+{
+    // unsigned operator_token = ast->operator_token;
+    for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    for (PtrOperatorListAST *it = ast->ptr_operator_list; it; it = it->next) {
+        this->ptrOperator(it->value);
+    }
+    return false;
+}
+
+bool FindUsages::visit(SimpleNameAST *ast)
+{
+    // unsigned identifier_token = ast->identifier_token;
+    reportResult(ast->identifier_token, ast->name);
+    return false;
+}
+
+bool FindUsages::visit(DestructorNameAST *ast)
+{
+    // unsigned tilde_token = ast->tilde_token;
+    // unsigned identifier_token = ast->identifier_token;
+    reportResult(ast->identifier_token, ast->name);
+    return false;
+}
+
+bool FindUsages::visit(TemplateIdAST *ast)
+{
+    // unsigned identifier_token = ast->identifier_token;
+    reportResult(ast->identifier_token, ast->name);
+    // unsigned less_token = ast->less_token;
+    for (ExpressionListAST *it = ast->template_argument_list; it; it = it->next) {
+        this->expression(it->value);
+    }
+    // unsigned greater_token = ast->greater_token;
+    return false;
+}
+
+
+// SpecifierAST
+bool FindUsages::visit(SimpleSpecifierAST *ast)
+{
+    (void) ast;
+    // unsigned specifier_token = ast->specifier_token;
+    return false;
+}
+
+bool FindUsages::visit(AttributeSpecifierAST *ast)
+{
+    // unsigned attribute_token = ast->attribute_token;
+    // unsigned first_lparen_token = ast->first_lparen_token;
+    // unsigned second_lparen_token = ast->second_lparen_token;
+    for (AttributeListAST *it = ast->attribute_list; it; it = it->next) {
+        this->attribute(it->value);
+    }
+    // unsigned first_rparen_token = ast->first_rparen_token;
+    // unsigned second_rparen_token = ast->second_rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(TypeofSpecifierAST *ast)
+{
+    // unsigned typeof_token = ast->typeof_token;
+    // unsigned lparen_token = ast->lparen_token;
+    this->expression(ast->expression);
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(ClassSpecifierAST *ast)
+{
+    // unsigned classkey_token = ast->classkey_token;
+    for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    /*const Name *name =*/ this->name(ast->name);
+
+    Scope *previousScope = switchScope(ast->symbol);
+
+    // unsigned colon_token = ast->colon_token;
+    for (BaseSpecifierListAST *it = ast->base_clause_list; it; it = it->next) {
+        this->baseSpecifier(it->value);
+    }
+    // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+    // unsigned lbrace_token = ast->lbrace_token;
+    for (DeclarationListAST *it = ast->member_specifier_list; it; it = it->next) {
+        this->declaration(it->value);
+    }
+    // unsigned rbrace_token = ast->rbrace_token;
+    // Class *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+bool FindUsages::visit(NamedTypeSpecifierAST *ast)
+{
+    /*const Name *name =*/ this->name(ast->name);
+    return false;
+}
+
+bool FindUsages::visit(ElaboratedTypeSpecifierAST *ast)
+{
+    // unsigned classkey_token = ast->classkey_token;
+    for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    /*const Name *name =*/ this->name(ast->name);
+    return false;
+}
+
+bool FindUsages::visit(EnumSpecifierAST *ast)
+{
+    // unsigned enum_token = ast->enum_token;
+    /*const Name *name =*/ this->name(ast->name);
+    // unsigned lbrace_token = ast->lbrace_token;
+    Scope *previousScope = switchScope(ast->symbol);
+    for (EnumeratorListAST *it = ast->enumerator_list; it; it = it->next) {
+        this->enumerator(it->value);
+    }
+    // unsigned rbrace_token = ast->rbrace_token;
+    // Enum *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    return false;
+}
+
+
+// PtrOperatorAST
+bool FindUsages::visit(PointerToMemberAST *ast)
+{
+    // unsigned global_scope_token = ast->global_scope_token;
+    for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) {
+        this->nestedNameSpecifier(it->value);
+    }
+    // unsigned star_token = ast->star_token;
+    for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    return false;
+}
+
+bool FindUsages::visit(PointerAST *ast)
+{
+    // unsigned star_token = ast->star_token;
+    for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    return false;
+}
+
+bool FindUsages::visit(ReferenceAST *ast)
+{
+    (void) ast;
+    // unsigned reference_token = ast->reference_token;
+    return false;
+}
+
+
+// PostfixAST
+bool FindUsages::visit(CallAST *ast)
+{
+    this->expression(ast->base_expression);
+    // unsigned lparen_token = ast->lparen_token;
+    for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+        this->expression(it->value);
+    }
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+bool FindUsages::visit(ArrayAccessAST *ast)
+{
+    this->expression(ast->base_expression);
+    // unsigned lbracket_token = ast->lbracket_token;
+    this->expression(ast->expression);
+    // unsigned rbracket_token = ast->rbracket_token;
+    return false;
+}
+
+bool FindUsages::visit(PostIncrDecrAST *ast)
+{
+    this->expression(ast->base_expression);
+    // unsigned incr_decr_token = ast->incr_decr_token;
+    return false;
+}
+
+bool FindUsages::visit(MemberAccessAST *ast)
+{
+    this->expression(ast->base_expression);
+    // unsigned access_token = ast->access_token;
+    // unsigned template_token = ast->template_token;
+
+    if (ast->member_name) {
+        if (SimpleNameAST *simple = ast->member_name->asSimpleName()) {
+            if (identifier(simple->identifier_token) == _id) {
+                checkExpression(ast->firstToken(), simple->identifier_token);
+                return false;
+            }
+        }
+    }
+
+    return false;
+}
+
+
+// CoreDeclaratorAST
+bool FindUsages::visit(DeclaratorIdAST *ast)
+{
+    // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
+    /*const Name *name =*/ this->name(ast->name);
+    return false;
+}
+
+bool FindUsages::visit(NestedDeclaratorAST *ast)
+{
+    // unsigned lparen_token = ast->lparen_token;
+    this->declarator(ast->declarator);
+    // unsigned rparen_token = ast->rparen_token;
+    return false;
+}
+
+
+// PostfixDeclaratorAST
+bool FindUsages::visit(FunctionDeclaratorAST *ast)
+{
+    // unsigned lparen_token = ast->lparen_token;
+    this->parameterDeclarationClause(ast->parameters);
+    // unsigned rparen_token = ast->rparen_token;
+    for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) {
+        this->specifier(it->value);
+    }
+    this->exceptionSpecification(ast->exception_specification);
+    this->trailingReturnType(ast->trailing_return_type);
+    this->expression(ast->as_cpp_initializer);
+    // Function *symbol = ast->symbol;
+    return false;
+}
+
+bool FindUsages::visit(ArrayDeclaratorAST *ast)
+{
+    // unsigned lbracket_token = ast->lbracket_token;
+    this->expression(ast->expression);
+    // unsigned rbracket_token = ast->rbracket_token;
+    return false;
+}
+
+
diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h
index 5d57a0c287634db20a151906ac3f42531ef82d54..f48ac945829a9edbb3ea398bdc8313b24a493ca0 100644
--- a/src/libs/cplusplus/FindUsages.h
+++ b/src/libs/cplusplus/FindUsages.h
@@ -68,67 +68,239 @@ public:
     QList<int> references() const;
 
 protected:
-    using ASTVisitor::visit;
-    using ASTVisitor::endVisit;
+    using ASTVisitor::translationUnit;
+
+    Scope *switchScope(Scope *scope);
+    Scope *switchScope(ScopedSymbol *symbol);
 
     QString matchingLine(const Token &tk) const;
 
+    void reportResult(unsigned tokenIndex, const Name *name, Scope *scope = 0);
+    void reportResult(unsigned tokenIndex, const Identifier *id, Scope *scope = 0);
     void reportResult(unsigned tokenIndex, const QList<LookupItem> &candidates);
     void reportResult(unsigned tokenIndex);
 
     bool checkCandidates(const QList<LookupItem> &candidates) const;
-    void checkExpression(unsigned startToken, unsigned endToken);
+    void checkExpression(unsigned startToken, unsigned endToken, Scope *scope = 0);
 
-    void ensureNameIsValid(NameAST *ast);
+    static bool compareFullyQualifiedName(const QList<const Name *> &path, const QList<const Name *> &other);
+    static bool compareName(const Name *name, const Name *other);
 
-    FunctionDefinitionAST *enclosingFunctionDefinition() const;
-    TemplateDeclarationAST *enclosingTemplateDeclaration() const;
-    Scope *enclosingScope();
+    void statement(StatementAST *ast);
+    void expression(ExpressionAST *ast);
+    void declaration(DeclarationAST *ast);
+    const Name *name(NameAST *ast);
+    void specifier(SpecifierAST *ast);
+    void ptrOperator(PtrOperatorAST *ast);
+    void coreDeclarator(CoreDeclaratorAST *ast);
+    void postfixDeclarator(PostfixDeclaratorAST *ast);
 
-    bool preVisit(AST *ast);
-    void postVisit(AST *);
+    void objCSelectorArgument(ObjCSelectorArgumentAST *ast);
+    void attribute(AttributeAST *ast);
+    void declarator(DeclaratorAST *ast);
+    void qtPropertyDeclarationItem(QtPropertyDeclarationItemAST *ast);
+    void qtInterfaceName(QtInterfaceNameAST *ast);
+    void baseSpecifier(BaseSpecifierAST *ast);
+    void ctorInitializer(CtorInitializerAST *ast);
+    void enumerator(EnumeratorAST *ast);
+    void exceptionSpecification(ExceptionSpecificationAST *ast);
+    void memInitializer(MemInitializerAST *ast);
+    void nestedNameSpecifier(NestedNameSpecifierAST *ast);
+    void newPlacement(NewPlacementAST *ast);
+    void newArrayDeclarator(NewArrayDeclaratorAST *ast);
+    void newInitializer(NewInitializerAST *ast);
+    void newTypeId(NewTypeIdAST *ast);
+    void cppOperator(OperatorAST *ast);
+    void parameterDeclarationClause(ParameterDeclarationClauseAST *ast);
+    void translationUnit(TranslationUnitAST *ast);
+    void objCProtocolRefs(ObjCProtocolRefsAST *ast);
+    void objCMessageArgument(ObjCMessageArgumentAST *ast);
+    void objCTypeName(ObjCTypeNameAST *ast);
+    void objCInstanceVariablesDeclaration(ObjCInstanceVariablesDeclarationAST *ast);
+    void objCPropertyAttribute(ObjCPropertyAttributeAST *ast);
+    void objCMessageArgumentDeclaration(ObjCMessageArgumentDeclarationAST *ast);
+    void objCMethodPrototype(ObjCMethodPrototypeAST *ast);
+    void objCSynthesizedProperty(ObjCSynthesizedPropertyAST *ast);
+    void lambdaIntroducer(LambdaIntroducerAST *ast);
+    void lambdaCapture(LambdaCaptureAST *ast);
+    void capture(CaptureAST *ast);
+    void lambdaDeclarator(LambdaDeclaratorAST *ast);
+    void trailingReturnType(TrailingReturnTypeAST *ast);
 
-    virtual bool visit(NamespaceAST *ast);
+    // AST
+    virtual bool visit(ObjCSelectorArgumentAST *ast);
+    virtual bool visit(AttributeAST *ast);
+    virtual bool visit(DeclaratorAST *ast);
+    virtual bool visit(QtPropertyDeclarationItemAST *ast);
+    virtual bool visit(QtInterfaceNameAST *ast);
+    virtual bool visit(BaseSpecifierAST *ast);
+    virtual bool visit(CtorInitializerAST *ast);
+    virtual bool visit(EnumeratorAST *ast);
+    virtual bool visit(ExceptionSpecificationAST *ast);
     virtual bool visit(MemInitializerAST *ast);
-    virtual bool visit(MemberAccessAST *ast);
+    virtual bool visit(NestedNameSpecifierAST *ast);
+    virtual bool visit(NewPlacementAST *ast);
+    virtual bool visit(NewArrayDeclaratorAST *ast);
+    virtual bool visit(NewInitializerAST *ast);
+    virtual bool visit(NewTypeIdAST *ast);
+    virtual bool visit(OperatorAST *ast);
+    virtual bool visit(ParameterDeclarationClauseAST *ast);
+    virtual bool visit(TranslationUnitAST *ast);
+    virtual bool visit(ObjCProtocolRefsAST *ast);
+    virtual bool visit(ObjCMessageArgumentAST *ast);
+    virtual bool visit(ObjCTypeNameAST *ast);
+    virtual bool visit(ObjCInstanceVariablesDeclarationAST *ast);
+    virtual bool visit(ObjCPropertyAttributeAST *ast);
+    virtual bool visit(ObjCMessageArgumentDeclarationAST *ast);
+    virtual bool visit(ObjCMethodPrototypeAST *ast);
+    virtual bool visit(ObjCSynthesizedPropertyAST *ast);
+    virtual bool visit(LambdaIntroducerAST *ast);
+    virtual bool visit(LambdaCaptureAST *ast);
+    virtual bool visit(CaptureAST *ast);
+    virtual bool visit(LambdaDeclaratorAST *ast);
+    virtual bool visit(TrailingReturnTypeAST *ast);
+
+    // StatementAST
+    virtual bool visit(QtMemberDeclarationAST *ast);
+    virtual bool visit(CaseStatementAST *ast);
+    virtual bool visit(CompoundStatementAST *ast);
+    virtual bool visit(DeclarationStatementAST *ast);
+    virtual bool visit(DoStatementAST *ast);
+    virtual bool visit(ExpressionOrDeclarationStatementAST *ast);
+    virtual bool visit(ExpressionStatementAST *ast);
+    virtual bool visit(ForeachStatementAST *ast);
+    virtual bool visit(ForStatementAST *ast);
+    virtual bool visit(IfStatementAST *ast);
+    virtual bool visit(LabeledStatementAST *ast);
+    virtual bool visit(BreakStatementAST *ast);
+    virtual bool visit(ContinueStatementAST *ast);
+    virtual bool visit(GotoStatementAST *ast);
+    virtual bool visit(ReturnStatementAST *ast);
+    virtual bool visit(SwitchStatementAST *ast);
+    virtual bool visit(TryBlockStatementAST *ast);
+    virtual bool visit(CatchClauseAST *ast);
+    virtual bool visit(WhileStatementAST *ast);
+    virtual bool visit(ObjCFastEnumerationAST *ast);
+    virtual bool visit(ObjCSynchronizedStatementAST *ast);
+
+    // ExpressionAST
+    virtual bool visit(IdExpressionAST *ast);
+    virtual bool visit(CompoundExpressionAST *ast);
+    virtual bool visit(CompoundLiteralAST *ast);
+    virtual bool visit(QtMethodAST *ast);
+    virtual bool visit(BinaryExpressionAST *ast);
+    virtual bool visit(CastExpressionAST *ast);
+    virtual bool visit(ConditionAST *ast);
+    virtual bool visit(ConditionalExpressionAST *ast);
+    virtual bool visit(CppCastExpressionAST *ast);
+    virtual bool visit(DeleteExpressionAST *ast);
+    virtual bool visit(ArrayInitializerAST *ast);
+    virtual bool visit(NewExpressionAST *ast);
+    virtual bool visit(TypeidExpressionAST *ast);
+    virtual bool visit(TypenameCallExpressionAST *ast);
+    virtual bool visit(TypeConstructorCallAST *ast);
+    virtual bool visit(SizeofExpressionAST *ast);
+    virtual bool visit(NumericLiteralAST *ast);
+    virtual bool visit(BoolLiteralAST *ast);
+    virtual bool visit(ThisExpressionAST *ast);
+    virtual bool visit(NestedExpressionAST *ast);
+    virtual bool visit(StringLiteralAST *ast);
+    virtual bool visit(ThrowExpressionAST *ast);
+    virtual bool visit(TypeIdAST *ast);
+    virtual bool visit(UnaryExpressionAST *ast);
+    virtual bool visit(ObjCMessageExpressionAST *ast);
+    virtual bool visit(ObjCProtocolExpressionAST *ast);
+    virtual bool visit(ObjCEncodeExpressionAST *ast);
+    virtual bool visit(ObjCSelectorExpressionAST *ast);
+    virtual bool visit(LambdaExpressionAST *ast);
+    virtual bool visit(BracedInitializerAST *ast);
+
+    // DeclarationAST
+    virtual bool visit(SimpleDeclarationAST *ast);
+    virtual bool visit(EmptyDeclarationAST *ast);
+    virtual bool visit(AccessDeclarationAST *ast);
+    virtual bool visit(QtObjectTagAST *ast);
+    virtual bool visit(QtPrivateSlotAST *ast);
+    virtual bool visit(QtPropertyDeclarationAST *ast);
+    virtual bool visit(QtEnumDeclarationAST *ast);
+    virtual bool visit(QtFlagsDeclarationAST *ast);
+    virtual bool visit(QtInterfacesDeclarationAST *ast);
+    virtual bool visit(AsmDefinitionAST *ast);
+    virtual bool visit(ExceptionDeclarationAST *ast);
+    virtual bool visit(FunctionDefinitionAST *ast);
+    virtual bool visit(LinkageBodyAST *ast);
+    virtual bool visit(LinkageSpecificationAST *ast);
+    virtual bool visit(NamespaceAST *ast);
+    virtual bool visit(NamespaceAliasDefinitionAST *ast);
+    virtual bool visit(ParameterDeclarationAST *ast);
+    virtual bool visit(TemplateDeclarationAST *ast);
+    virtual bool visit(TypenameTypeParameterAST *ast);
+    virtual bool visit(TemplateTypeParameterAST *ast);
+    virtual bool visit(UsingAST *ast);
+    virtual bool visit(UsingDirectiveAST *ast);
+    virtual bool visit(ObjCClassForwardDeclarationAST *ast);
+    virtual bool visit(ObjCClassDeclarationAST *ast);
+    virtual bool visit(ObjCProtocolForwardDeclarationAST *ast);
+    virtual bool visit(ObjCProtocolDeclarationAST *ast);
+    virtual bool visit(ObjCVisibilityDeclarationAST *ast);
+    virtual bool visit(ObjCPropertyDeclarationAST *ast);
+    virtual bool visit(ObjCMethodDeclarationAST *ast);
+    virtual bool visit(ObjCSynthesizedPropertiesDeclarationAST *ast);
+    virtual bool visit(ObjCDynamicPropertiesDeclarationAST *ast);
+
+    // NameAST
+    virtual bool visit(ObjCSelectorAST *ast);
     virtual bool visit(QualifiedNameAST *ast);
-    virtual bool visit(EnumeratorAST *ast);
+    virtual bool visit(OperatorFunctionIdAST *ast);
+    virtual bool visit(ConversionFunctionIdAST *ast);
     virtual bool visit(SimpleNameAST *ast);
     virtual bool visit(DestructorNameAST *ast);
     virtual bool visit(TemplateIdAST *ast);
-    virtual bool visit(ParameterDeclarationAST *ast);
-    virtual bool visit(ExpressionOrDeclarationStatementAST *ast);
-    virtual bool visit(FunctionDeclaratorAST *ast);
-    virtual bool visit(SimpleDeclarationAST *);
-    virtual bool visit(ObjCSelectorAST *ast);
-    virtual bool visit(QtPropertyDeclarationAST *);
-    virtual void endVisit(QtPropertyDeclarationAST *);
 
-    virtual bool visit(TypenameTypeParameterAST *ast);
-    virtual bool visit(TemplateTypeParameterAST *ast);
+    // SpecifierAST
+    virtual bool visit(SimpleSpecifierAST *ast);
+    virtual bool visit(AttributeSpecifierAST *ast);
+    virtual bool visit(TypeofSpecifierAST *ast);
+    virtual bool visit(ClassSpecifierAST *ast);
+    virtual bool visit(NamedTypeSpecifierAST *ast);
+    virtual bool visit(ElaboratedTypeSpecifierAST *ast);
+    virtual bool visit(EnumSpecifierAST *ast);
 
-    virtual bool visit(FunctionDefinitionAST *ast);
+    // PtrOperatorAST
+    virtual bool visit(PointerToMemberAST *ast);
+    virtual bool visit(PointerAST *ast);
+    virtual bool visit(ReferenceAST *ast);
 
-    static bool compareFullyQualifiedName(const QList<const Name *> &path, const QList<const Name *> &other);
-    static bool compareName(const Name *name, const Name *other);
+    // PostfixAST
+    virtual bool visit(CallAST *ast);
+    virtual bool visit(ArrayAccessAST *ast);
+    virtual bool visit(PostIncrDecrAST *ast);
+    virtual bool visit(MemberAccessAST *ast);
+
+    // CoreDeclaratorAST
+    virtual bool visit(DeclaratorIdAST *ast);
+    virtual bool visit(NestedDeclaratorAST *ast);
+
+    // PostfixDeclaratorAST
+    virtual bool visit(FunctionDeclaratorAST *ast);
+    virtual bool visit(ArrayDeclaratorAST *ast);
 
 private:
     const Identifier *_id;
+    Symbol *_declSymbol;
     QList<const Name *> _declSymbolFullyQualifiedName;
     Document::Ptr _doc;
     Snapshot _snapshot;
     LookupContext _context;
     QByteArray _source;
-    Semantic _sem;
-    QList<AST *> _astStack;
     QList<int> _references;
     QList<Usage> _usages;
-    int _inSimpleDeclaration;
-    bool _inQProperty;
     QSet<unsigned> _processed;
     TypeOfExpression typeofExpression;
+    Scope *_currentScope;
 };
 
 } // end of namespace CPlusPlus
 
 #endif // CPLUSPLUS_FINDUSAGES_H
+
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 8b80fb356f3eddf707cc6daff2abb28b973019b9..e067cb37b0869744c4ce8f866b1e28cf31f185c8 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -739,12 +739,14 @@ void CPPEditor::markSymbolsNow()
     setExtraSelections(CodeSemanticsSelection, selections);
 }
 
-static QList<int> lazyFindReferences(Scope *scope, QString code, const LookupContext &context)
+static QList<int> lazyFindReferences(Scope *scope, QString code, Document::Ptr doc, Snapshot snapshot)
 {
     TypeOfExpression typeOfExpression;
-    typeOfExpression.init(context.thisDocument(), context.snapshot(), context.bindings());
-    if (Symbol *canonicalSymbol = CanonicalSymbol::canonicalSymbol(scope, code, typeOfExpression))
-        return CppTools::CppModelManagerInterface::instance()->references(canonicalSymbol, context);
+    snapshot.insert(doc);
+    typeOfExpression.init(doc, snapshot);
+    if (Symbol *canonicalSymbol = CanonicalSymbol::canonicalSymbol(scope, code, typeOfExpression)) {
+        return CppTools::CppModelManagerInterface::instance()->references(canonicalSymbol, typeOfExpression.context());
+    }
     return QList<int>();
 }
 
@@ -758,12 +760,10 @@ void CPPEditor::markSymbols(const QTextCursor &tc, const SemanticInfo &info)
     CanonicalSymbol cs(this, info);
     QString expression;
     if (Scope *scope = cs.getScopeAndExpression(this, info, tc, &expression)) {
-        LookupContext context(info.doc, info.snapshot);
-
         m_references.cancel();
         m_referencesRevision = info.revision;
         m_referencesCursorPosition = position();
-        m_references = QtConcurrent::run(&lazyFindReferences, scope, expression, context);
+        m_references = QtConcurrent::run(&lazyFindReferences, scope, expression, info.doc, info.snapshot);
         m_referencesWatcher.setFuture(m_references);
     } else {
         const QList<QTextEdit::ExtraSelection> selections = extraSelections(CodeSemanticsSelection);
diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp
index aabe12ca5e5485dbbcc4dbe026832a941921da31..87254f03047719ee0665b9771d1a60465a677701 100644
--- a/src/plugins/cpptools/cppfindreferences.cpp
+++ b/src/plugins/cpptools/cppfindreferences.cpp
@@ -52,6 +52,7 @@
 
 #include <cplusplus/CppDocument.h>
 #include <cplusplus/Overview.h>
+#include <cplusplus/FindUsages.h>
 
 #include <QtCore/QTime>
 #include <QtCore/QTimer>
@@ -108,18 +109,25 @@ public:
                 return usages; // skip this document, it's not using symbolId.
         }
 
-        QByteArray source = snapshot.preprocessedCode(
-                getSource(fileName, workingCopy), fileName);
+        Document::Ptr doc;
+        QByteArray source;
 
-        Document::Ptr doc = snapshot.documentFromSource(source, fileName);
-        doc->tokenize();
+        if (symbolDocument && fileName == symbolDocument->fileName())
+            doc = symbolDocument;
+        else {
+            source = snapshot.preprocessedCode(getSource(fileName, workingCopy), fileName);
+            doc = snapshot.documentFromSource(source, fileName);
+            doc->tokenize();
+        }
 
         Control *control = doc->control();
         if (control->findIdentifier(symbolId->chars(), symbolId->size()) != 0) {
-            doc->check();
+            if (doc != symbolDocument)
+                doc->check();
 
             FindUsages process(doc, snapshot);
             process(symbol);
+
             usages = process.usages();
         }
 
diff --git a/src/shared/cplusplus/Control.cpp b/src/shared/cplusplus/Control.cpp
index 15b2c517871d63d826b4b5175a9a523623cc95e3..c2752220dfe32352d88972f4b22602fb47aabc32 100644
--- a/src/shared/cplusplus/Control.cpp
+++ b/src/shared/cplusplus/Control.cpp
@@ -56,6 +56,7 @@
 #include "TypeMatcher.h"
 #include <map>
 #include <set>
+#include <algorithm>
 
 using namespace CPlusPlus;
 
@@ -770,3 +771,8 @@ const Identifier *Control::objcCopyId() const
 
 const Identifier *Control::objcNonatomicId() const
 { return d->objcNonatomicId; }
+
+bool Control::hasSymbol(Symbol *symbol) const
+{
+    return std::find(d->symbols.begin(), d->symbols.end(), symbol) != d->symbols.end();
+}
diff --git a/src/shared/cplusplus/Control.h b/src/shared/cplusplus/Control.h
index 7cd42e2614506e0302cc8d5d564144b6d5f88faf..bc793da03cf11acf1b94f1ed147a1d9636d87d44 100644
--- a/src/shared/cplusplus/Control.h
+++ b/src/shared/cplusplus/Control.h
@@ -209,6 +209,8 @@ public:
     const NumericLiteral *findOrInsertNumericLiteral(const char *chars, unsigned size);
     const NumericLiteral *findOrInsertNumericLiteral(const char *chars);
 
+    bool hasSymbol(Symbol *symbol) const;
+
 private:
     class Data;
     friend class Data;