diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 75f64fea5da9db750abf37ff1de1652a31e7c13e..c7e1d3fc5da50ab54e12e6f32dd07dc9e73b4f0a 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -120,6 +120,9 @@ public:
     void run(QString &fileName);
     void operator()(QString &fileName);
 
+public: // attributes
+    Snapshot snapshot;
+
 protected:
     CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc);
 
@@ -141,7 +144,6 @@ protected:
 
 private:
     QPointer<CppModelManager> m_modelManager;
-    Snapshot m_snapshot;
     Environment env;
     Preprocessor m_proc;
     QStringList m_includePaths;
@@ -157,9 +159,9 @@ private:
 } // namespace CppTools
 
 CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager)
-    : m_modelManager(modelManager),
-    m_snapshot(modelManager->snapshot()),
-    m_proc(this, env)
+    : snapshot(modelManager->snapshot()),
+      m_modelManager(modelManager),
+      m_proc(this, env)
 { }
 
 void CppPreprocessor::setWorkingCopy(const QMap<QString, QByteArray> &workingCopy)
@@ -337,8 +339,13 @@ void CppPreprocessor::mergeEnvironment(Document::Ptr doc, QSet<QString> *process
 
     processed->insert(fn);
 
-    foreach (QString includedFile, doc->includedFiles()) {
-        mergeEnvironment(m_snapshot.value(includedFile), processed);
+    foreach (Document::Include incl, doc->includes()) {
+        QString includedFile = incl.fileName();
+
+        if (Document::Ptr includedDoc = snapshot.value(includedFile))
+            mergeEnvironment(includedDoc, processed);
+        else
+            run(includedFile);
     }
 
     foreach (const Macro macro, doc->definedMacros()) {
@@ -384,7 +391,7 @@ void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type,
     }
 
     if (! contents.isEmpty()) {
-        Document::Ptr cachedDoc = m_snapshot.value(fileName);
+        Document::Ptr cachedDoc = snapshot.value(fileName);
         if (cachedDoc && m_currentDoc) {
             mergeEnvironment(cachedDoc);
         } else {
@@ -393,8 +400,8 @@ void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type,
             const QByteArray previousFile = env.currentFile;
             const unsigned previousLine = env.currentLine;
 
-            env.currentFile = QByteArray(m_currentDoc->translationUnit()->fileName(),
-                                         m_currentDoc->translationUnit()->fileNameLength());
+            TranslationUnit *unit = m_currentDoc->translationUnit();
+            env.currentFile = QByteArray(unit->fileName(), unit->fileNameLength());
 
             QByteArray preprocessedCode;
             m_proc(contents, &preprocessedCode);
@@ -775,7 +782,12 @@ void CppModelManager::parse(QFutureInterface<void> &future,
                             CppPreprocessor *preproc,
                             QStringList files)
 {
-    QTC_ASSERT(!files.isEmpty(), return);
+    if (files.isEmpty())
+        return;
+
+    foreach (QString file, files) {
+        preproc->snapshot.remove(file);
+    }
 
     // Change the priority of the background parser thread to idle.
     QThread::currentThread()->setPriority(QThread::IdlePriority);
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index f5e3ac42fc57463e533e6a4aa54d57792cc895b8..d29342b30a69ee629ecadc08da930376e65bd83d 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -60,6 +60,20 @@
 CPLUSPLUS_BEGIN_HEADER
 CPLUSPLUS_BEGIN_NAMESPACE
 
+template <typename _Tp>
+class List: public Managed
+{
+    List(const List &other);
+    void operator =(const List &other);
+
+public:
+    List()
+    { }
+
+    _Tp value;
+    List *next;
+};
+
 class CPLUSPLUS_EXPORT AST: public Managed
 {
     AST(const AST &other);
@@ -351,6 +365,9 @@ public:
     DeclaratorListAST *declarators;
     unsigned semicolon_token;
 
+public:
+    List<Declaration *> *symbols;
+
 public:
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
@@ -422,6 +439,9 @@ public:
     NameAST *name;
     BaseSpecifierAST *next;
 
+public: // annotations
+    BaseClass *symbol;
+
 public:
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
@@ -516,7 +536,7 @@ public:
     unsigned rbrace_token;
 
 public: // annotations
-    Class *class_symbol;
+    Class *symbol;
 
 public:
     virtual unsigned firstToken() const;
@@ -691,6 +711,9 @@ public:
     SpecifierAST *cv_qualifier_seq;
     ExceptionSpecificationAST *exception_specification;
 
+public: // annotations
+    Function *symbol;
+
 public:
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
@@ -918,6 +941,9 @@ public:
     CtorInitializerAST *ctor_initializer;
     StatementAST *function_body;
 
+public: // annotations
+    Function *symbol;
+
 public:
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
@@ -1060,6 +1086,9 @@ protected:
 
 class CPLUSPLUS_EXPORT NameAST: public ExpressionAST
 {
+public: // annotations
+    Name *name;
+
 public:
     virtual NameAST *clone(MemoryPool *pool) const = 0;
 };
@@ -1188,6 +1217,9 @@ public:
     SpecifierAST *attributes;
     DeclarationAST *linkage_body;
 
+public: // annotations
+    Namespace *symbol;
+
 public:
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
@@ -1312,6 +1344,9 @@ public:
     unsigned equal_token;
     ExpressionAST *expression;
 
+public: // annotations
+    Argument *symbol;
+
 public:
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
@@ -1849,6 +1884,9 @@ public:
     unsigned equal_token;
     ExpressionAST *type_id;
 
+public: // annotations
+    Argument *symbol;
+
 public:
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
@@ -1871,6 +1909,9 @@ public:
     unsigned equal_token;
     ExpressionAST *type_id;
 
+public:
+    Argument *symbol;
+
 public:
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
@@ -1905,6 +1946,9 @@ public:
     NameAST *name;
     unsigned semicolon_token;
 
+public: // annotations
+    UsingDeclaration *symbol;
+
 public:
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
@@ -1923,6 +1967,9 @@ public:
     NameAST *name;
     unsigned semicolon_token;
 
+public:
+    UsingNamespaceDirective *symbol;
+
 public:
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index 610d57626f43849816ee078788eb0c0dcc58d2f2..179dd069879c76ab6e63a6a3bc547d08d20a7435 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -136,6 +136,7 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
         }
     }
 
+    List<Declaration *> **decl_it = &ast->symbols;
     for (DeclaratorListAST *it = ast->declarators; it; it = it->next) {
         Name *name = 0;
         FullySpecifiedType declTy = semantic()->check(it->declarator, qualTy,
@@ -179,6 +180,10 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
         else if (ty.isTypedef())
             symbol->setStorage(Symbol::Typedef);
 
+        *decl_it = new (translationUnit()->memoryPool()) List<Declaration *>();
+        (*decl_it)->value = symbol;
+        decl_it = &(*decl_it)->next;
+
         _scope->enterSymbol(symbol);
     }
     return false;
@@ -234,6 +239,7 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast)
 
     checkFunctionArguments(fun);
 
+    ast->symbol = fun;
     _scope->enterSymbol(fun);
 
     if (ast->ctor_initializer) {
@@ -286,6 +292,7 @@ bool CheckDeclaration::visit(NamespaceAST *ast)
     Identifier *id = identifier(ast->identifier_token);
     Name *namespaceName = control()->nameId(id);
     Namespace *ns = control()->newNamespace(ast->firstToken(), namespaceName);
+    ast->symbol = ns;
     _scope->enterSymbol(ns);
     semantic()->check(ast->linkage_body, ns->members()); // ### we'll do the merge later.
 
@@ -310,6 +317,7 @@ bool CheckDeclaration::visit(ParameterDeclarationAST *ast)
                                                  _scope, &argName);
     FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
     Argument *arg = control()->newArgument(ast->firstToken(), argName);
+    ast->symbol = arg;
     if (ast->expression)
         arg->setInitializer(true);
     arg->setType(argTy);
@@ -319,15 +327,6 @@ bool CheckDeclaration::visit(ParameterDeclarationAST *ast)
 
 bool CheckDeclaration::visit(TemplateDeclarationAST *ast)
 {
-/*
-    Template *templ = control()->newTemplate(ast->firstToken());
-
-    for (DeclarationAST *param = ast->template_parameters; param;
-            param = param->next) {
-       semantic()->check(param, templ->members());
-    }
-*/
-
     Scope *previousScope = switchScope(new Scope(_scope->owner()));
     for (DeclarationAST *param = ast->template_parameters; param;
             param = param->next) {
@@ -343,6 +342,7 @@ bool CheckDeclaration::visit(TypenameTypeParameterAST *ast)
 {
     Name *name = semantic()->check(ast->name, _scope);
     Argument *arg = control()->newArgument(ast->firstToken(), name); // ### new template type
+    ast->symbol = arg;
     _scope->enterSymbol(arg);
     return false;
 }
@@ -351,6 +351,7 @@ bool CheckDeclaration::visit(TemplateTypeParameterAST *ast)
 {
     Name *name = semantic()->check(ast->name, _scope);
     Argument *arg = control()->newArgument(ast->firstToken(), name); // ### new template type
+    ast->symbol = arg;
     _scope->enterSymbol(arg);
     return false;
 }
@@ -359,6 +360,7 @@ bool CheckDeclaration::visit(UsingAST *ast)
 {
     Name *name = semantic()->check(ast->name, _scope);
     UsingDeclaration *u = control()->newUsingDeclaration(ast->firstToken(), name);
+    ast->symbol = u;
     _scope->enterSymbol(u);
     return false;
 }
@@ -367,6 +369,7 @@ bool CheckDeclaration::visit(UsingDirectiveAST *ast)
 {
     Name *name = semantic()->check(ast->name, _scope);
     UsingNamespaceDirective *u = control()->newUsingNamespaceDirective(ast->firstToken(), name);
+    ast->symbol = u;
     _scope->enterSymbol(u);
     return false;
 }
diff --git a/src/shared/cplusplus/CheckDeclarator.cpp b/src/shared/cplusplus/CheckDeclarator.cpp
index 13120fec589265f83e4989b174a00f10c72e9779..beb2ed0bca769f0f556ec2a6076a4a2d73926cf3 100644
--- a/src/shared/cplusplus/CheckDeclarator.cpp
+++ b/src/shared/cplusplus/CheckDeclarator.cpp
@@ -158,6 +158,7 @@ bool CheckDeclarator::visit(NestedDeclaratorAST *ast)
 bool CheckDeclarator::visit(FunctionDeclaratorAST *ast)
 {
     Function *fun = control()->newFunction(ast->firstToken());
+    ast->symbol = fun;
     fun->setReturnType(_fullySpecifiedType);
 
     if (ast->parameters) {
diff --git a/src/shared/cplusplus/CheckName.cpp b/src/shared/cplusplus/CheckName.cpp
index 09b90f3cb804f4c777eaa4b29ee96a16e52a7d8d..dfd8158464052704ce5f9ce60ebddc07a8aa1eca 100644
--- a/src/shared/cplusplus/CheckName.cpp
+++ b/src/shared/cplusplus/CheckName.cpp
@@ -121,6 +121,8 @@ bool CheckName::visit(QualifiedNameAST *ast)
     names.push_back(semantic()->check(ast->unqualified_name, _scope));
     _name = control()->qualifiedNameId(&names[0], names.size(),
                                           ast->global_scope_token != 0);
+
+    ast->name = _name;
     return false;
 }
 
@@ -302,6 +304,7 @@ bool CheckName::visit(OperatorFunctionIdAST *ast)
     } // switch
 
     _name = control()->operatorNameId(kind);
+    ast->name = _name;
     return false;
 }
 
@@ -317,6 +320,7 @@ bool CheckName::visit(SimpleNameAST *ast)
 {
     Identifier *id = identifier(ast->identifier_token);
     _name = control()->nameId(id);
+    ast->name = _name;
     return false;
 }
 
@@ -324,6 +328,7 @@ bool CheckName::visit(DestructorNameAST *ast)
 {
     Identifier *id = identifier(ast->identifier_token);
     _name = control()->destructorNameId(id);
+    ast->name = _name;
     return false;
 }
 
@@ -342,6 +347,7 @@ bool CheckName::visit(TemplateIdAST *ast)
     else
         _name = control()->templateNameId(id, &templateArguments[0],
                                           templateArguments.size());
+    ast->name = _name;
     return false;
 }
 
diff --git a/src/shared/cplusplus/CheckSpecifier.cpp b/src/shared/cplusplus/CheckSpecifier.cpp
index cb929b868caac1c68d314fc79ed7fa951983bf31..20a3662e7b8c8b770de4fe8d0fcef3f54a6356f6 100644
--- a/src/shared/cplusplus/CheckSpecifier.cpp
+++ b/src/shared/cplusplus/CheckSpecifier.cpp
@@ -300,7 +300,7 @@ bool CheckSpecifier::visit(ClassSpecifierAST *ast)
 {
     Name *className = semantic()->check(ast->name, _scope);
     Class *klass = control()->newClass(ast->firstToken(), className);
-    ast->class_symbol = klass;
+    ast->symbol = klass;
     unsigned classKey = tokenKind(ast->classkey_token);
     if (classKey == T_CLASS)
         klass->setClassKey(Class::ClassKey);
@@ -315,6 +315,7 @@ bool CheckSpecifier::visit(ClassSpecifierAST *ast)
     for (BaseSpecifierAST *base = ast->base_clause; base; base = base->next) {
         Name *baseClassName = semantic()->check(base->name, _scope);
         BaseClass *baseClass = control()->newBaseClass(ast->firstToken(), baseClassName);
+        base->symbol = baseClass;
         if (base->token_virtual)
             baseClass->setVirtual(true);
         if (base->token_access_specifier) {
diff --git a/src/shared/cplusplus/Control.cpp b/src/shared/cplusplus/Control.cpp
index e44d84a1aee801bf7daf22bf3348ae8bcb876af3..4d708f4340c5553206984ba155ea2222bd53c500 100644
--- a/src/shared/cplusplus/Control.cpp
+++ b/src/shared/cplusplus/Control.cpp
@@ -51,7 +51,6 @@
 // THE SOFTWARE.
 
 #include "Control.h"
-#include "MemoryPool.h"
 #include "Literals.h"
 #include "LiteralTable.h"
 #include "TranslationUnit.h"
diff --git a/tests/auto/cplusplus/lookup/tst_lookup.cpp b/tests/auto/cplusplus/lookup/tst_lookup.cpp
index ecf3ae71fefe6164e1eab56cfc6d72b8fdc39481..f3e6a570d5a81ac02eadfc4091a55e605abaf633 100644
--- a/tests/auto/cplusplus/lookup/tst_lookup.cpp
+++ b/tests/auto/cplusplus/lookup/tst_lookup.cpp
@@ -12,6 +12,17 @@
 
 CPLUSPLUS_USE_NAMESPACE
 
+template <template <typename, typename> class _Map, typename _T1, typename _T2>
+_Map<_T2, _T1> invert(const _Map<_T1, _T2> &m)
+{
+    _Map<_T2, _T1> i;
+    typename _Map<_T1, _T2>::const_iterator it = m.constBegin();
+    for (; it != m.constEnd(); ++it) {
+        i.insertMulti(it.value(), it.key());
+    }
+    return i;
+}
+
 class ClassSymbols: protected ASTVisitor,
     public QMap<ClassSpecifierAST *, Class *>
 {
@@ -20,13 +31,16 @@ public:
         : ASTVisitor(control)
     { }
 
+    QMap<ClassSpecifierAST *, Class *> asMap() const
+    { return *this; }
+
     void operator()(AST *ast)
     { accept(ast); }
 
 protected:
     virtual bool visit(ClassSpecifierAST *ast)
     {
-        Class *classSymbol = ast->class_symbol;
+        Class *classSymbol = ast->symbol;
         Q_ASSERT(classSymbol != 0);
 
         insert(ast, classSymbol);
@@ -62,7 +76,7 @@ void tst_Lookup::base_class_defined_1()
     Snapshot snapshot;
     snapshot.insert(doc->fileName(), doc);
 
-    Document::Ptr emptyDoc = Document::create("empty");
+    Document::Ptr emptyDoc = Document::create("<empty>");
 
     Class *baseClass = doc->globalSymbolAt(0)->asClass();
     QVERIFY(baseClass);
@@ -88,6 +102,12 @@ void tst_Lookup::base_class_defined_1()
     classSymbols(ast);
 
     QCOMPARE(classSymbols.size(), 2);
+
+    const QMap<Class *, ClassSpecifierAST *> classToAST =
+            invert(classSymbols.asMap());
+
+    QVERIFY(classToAST.value(baseClass) != 0);
+    QVERIFY(classToAST.value(derivedClass) != 0);
 }
 
 QTEST_APPLESS_MAIN(tst_Lookup)