diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index cf4dd079401733660de30435c8e87c07a46d5ae0..2abaf72ef21ac7b02cf6c1339e5217d1f12132b0 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -57,6 +57,91 @@ using namespace CPlusPlus;
 
 namespace {
 
+class FindScopeAt: protected SymbolVisitor
+{
+    TranslationUnit *_unit;
+    unsigned _line;
+    unsigned _column;
+    Scope *_scope;
+
+public:
+    FindScopeAt(TranslationUnit *unit, unsigned line, unsigned column)
+        : _unit(unit), _line(line), _column(column), _scope(0) {}
+
+    Scope *operator()(Symbol *symbol)
+    {
+        accept(symbol);
+        return _scope;
+    }
+
+protected:
+    bool process(ScopedSymbol *symbol)
+    {
+        if (! _scope) {
+            Scope *scope = symbol->members();
+
+            for (unsigned i = 0; i < scope->symbolCount(); ++i) {
+                accept(scope->symbolAt(i));
+
+                if (_scope)
+                    return false;
+            }
+
+            unsigned startLine, startColumn;
+            _unit->getPosition(symbol->startOffset(), &startLine, &startColumn);
+
+            if (_line > startLine || (_line == startLine && _column >= startColumn)) {
+                unsigned endLine, endColumn;
+                _unit->getPosition(symbol->endOffset(), &endLine, &endColumn);
+
+                if (_line < endLine || (_line == endLine && _column < endColumn))
+                    _scope = scope;
+            }
+        }
+
+        return false;
+    }
+
+    using SymbolVisitor::visit;
+
+    virtual bool preVisit(Symbol *)
+    { return ! _scope; }
+
+    virtual bool visit(UsingNamespaceDirective *) { return false; }
+    virtual bool visit(UsingDeclaration *) { return false; }
+    virtual bool visit(NamespaceAlias *) { return false; }
+    virtual bool visit(Declaration *) { return false; }
+    virtual bool visit(Argument *) { return false; }
+    virtual bool visit(TypenameArgument *) { return false; }
+    virtual bool visit(BaseClass *) { return false; }
+    virtual bool visit(ForwardClassDeclaration *) { return false; }
+
+    virtual bool visit(Enum *symbol)
+    { return process(symbol); }
+
+    virtual bool visit(Function *symbol)
+    { return process(symbol); }
+
+    virtual bool visit(Namespace *symbol)
+    { return process(symbol); }
+
+    virtual bool visit(Class *symbol)
+    { return process(symbol); }
+
+    virtual bool visit(Block *symbol)
+    { return process(symbol); }
+
+    // Objective-C
+    virtual bool visit(ObjCBaseClass *) { return false; }
+    virtual bool visit(ObjCBaseProtocol *) { return false; }
+    virtual bool visit(ObjCClass *) { return false; }
+    virtual bool visit(ObjCForwardClassDeclaration *) { return false; }
+    virtual bool visit(ObjCProtocol *) { return false; }
+    virtual bool visit(ObjCForwardProtocolDeclaration *) { return false; }
+    virtual bool visit(ObjCMethod *) { return false; }
+    virtual bool visit(ObjCPropertyDeclaration *) { return false; }
+};
+
 class DocumentDiagnosticClient : public DiagnosticClient
 {
     enum { MAX_MESSAGE_COUNT = 10 };
@@ -313,6 +398,12 @@ void Document::setGlobalNamespace(Namespace *globalNamespace)
     _globalNamespace = globalNamespace;
 }
 
+Scope *Document::scopeAt(unsigned line, unsigned column)
+{
+    FindScopeAt findScopeAt(_translationUnit, line, column);
+    return findScopeAt(_globalNamespace);
+}
+
 Symbol *Document::findSymbolAt(unsigned line, unsigned column) const
 {
     return findSymbolAt(line, column, globalSymbols());
@@ -616,7 +707,7 @@ Symbol *Snapshot::findMatchingDefinition(Symbol *symbol) const
     }
 
     LookupContext thisContext(thisDocument, *this);
-    const QList<Symbol *> declarationCandidates = thisContext.lookup(symbol->name(), symbol);
+    const QList<Symbol *> declarationCandidates = thisContext.lookup(symbol->name(), symbol->scope());
     if (declarationCandidates.isEmpty()) {
         qWarning() << "unresolved declaration:" << symbol->fileName() << symbol->line() << symbol->column();
         return 0;
@@ -644,7 +735,7 @@ Symbol *Snapshot::findMatchingDefinition(Symbol *symbol) const
             QList<Function *> viableFunctions;
 
             foreach (Function *fun, result) {
-                const QList<Symbol *> declarations = context.lookup(fun->name(), fun);
+                const QList<Symbol *> declarations = context.lookup(fun->name(), fun->scope());
 
                 if (declarations.contains(declaration))
                     viableFunctions.append(fun);
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index 854da42a0ce1dd811f9a152933dc0c20918e27c6..a2cfcbb113c70b8d7e6059fd257e3b8615ff3db7 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -92,7 +92,8 @@ public:
     QList<Macro> definedMacros() const
     { return _definedMacros; }
 
-    Symbol *findSymbolAt(unsigned line, unsigned column) const;
+    Q_DECL_DEPRECATED Symbol *findSymbolAt(unsigned line, unsigned column) const;
+    Scope *scopeAt(unsigned line, unsigned column);
 
     QByteArray source() const;
     void setSource(const QByteArray &source);
diff --git a/src/libs/cplusplus/DeprecatedLookupContext.cpp b/src/libs/cplusplus/DeprecatedLookupContext.cpp
index 0368c490295765f6691aef7b541c9b77dbd8d886..75c71c30a1e4aeef09d4ce4341fab57867f9aac1 100644
--- a/src/libs/cplusplus/DeprecatedLookupContext.cpp
+++ b/src/libs/cplusplus/DeprecatedLookupContext.cpp
@@ -349,7 +349,7 @@ QList<Scope *> DeprecatedLookupContext::buildVisibleScopes()
 }
 
 QList<Scope *> DeprecatedLookupContext::visibleScopes(const LookupItem &result) const
-{ return visibleScopes(result.lastVisibleSymbol()); }
+{ return visibleScopes(result.declaration()); }
 
 QList<Scope *> DeprecatedLookupContext::visibleScopes(Symbol *symbol) const
 {
@@ -710,7 +710,7 @@ Symbol *DeprecatedLookupContext::canonicalSymbol(const QList<LookupItem> &result
     QList<Symbol *> candidates;
 
     foreach (const LookupItem &result, results)
-        candidates.append(result.lastVisibleSymbol()); // ### not exactly.
+        candidates.append(result.declaration()); // ### not exactly.
 
     return canonicalSymbol(candidates, globalNamespaceBinding);
 }
diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp
index 9c367d1ab7c26fec021ca52c7e31502e6cc651b5..3d10e71346da43100a951b538fd038101fd26ba1 100644
--- a/src/libs/cplusplus/FindUsages.cpp
+++ b/src/libs/cplusplus/FindUsages.cpp
@@ -29,6 +29,7 @@
 
 #include "FindUsages.h"
 #include "TypeOfExpression.h"
+#include "DeprecatedLookupContext.h"
 
 #include <Control.h>
 #include <Literals.h>
@@ -46,6 +47,7 @@ FindUsages::FindUsages(Document::Ptr doc, const Snapshot &snapshot)
     : ASTVisitor(doc->translationUnit()),
       _doc(doc),
       _snapshot(snapshot),
+      _context(doc, snapshot),
       _source(_doc->source()),
       _sem(doc->translationUnit()),
       _inSimpleDeclaration(0),
@@ -105,6 +107,14 @@ QString FindUsages::matchingLine(const Token &tk) const
     return matchingLine;
 }
 
+Scope *FindUsages::scopeAt(unsigned tokenIndex) const
+{
+    TranslationUnit *unit = _doc->translationUnit();
+    unsigned line, column;
+    unit->getTokenPosition(tokenIndex, &line, &column);
+    return _doc->scopeAt(line, column);
+}
+
 void FindUsages::reportResult(unsigned tokenIndex, const QList<Symbol *> &candidates)
 {
     if (_processed.contains(tokenIndex))
@@ -201,27 +211,6 @@ bool FindUsages::checkSymbol(Symbol *symbol) const
     return false;
 }
 
-DeprecatedLookupContext FindUsages::currentContext(AST *ast)
-{
-    unsigned line, column;
-    getTokenStartPosition(ast->firstToken(), &line, &column);
-    Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column);
-
-    if (_inQProperty && lastVisibleSymbol->isClass()) {
-        Scope *memberScope = lastVisibleSymbol->asClass()->members();
-
-        if (unsigned count = memberScope->symbolCount())
-            lastVisibleSymbol = memberScope->symbolAt(count - 1);
-    }
-
-    if (lastVisibleSymbol && lastVisibleSymbol == _previousContext.symbol())
-        return _previousContext;
-
-    DeprecatedLookupContext ctx(lastVisibleSymbol, _exprDoc, _doc, _snapshot);
-    _previousContext = ctx;
-    return _previousContext;
-}
-
 void FindUsages::ensureNameIsValid(NameAST *ast)
 {
     if (ast && ! ast->name)
@@ -235,8 +224,7 @@ bool FindUsages::visit(MemInitializerAST *ast)
 
         SimpleNameAST *simple = ast->name->asSimpleName();
         if (identifier(simple->identifier_token) == _id) {
-            DeprecatedLookupContext context = currentContext(ast);
-            const QList<Symbol *> candidates = context.resolve(simple->name);
+            const QList<Symbol *> candidates = _context.lookup(simple->name, scopeAt(simple->identifier_token));
             reportResult(simple->identifier_token, candidates);
         }
     }
@@ -286,15 +274,15 @@ void FindUsages::checkExpression(unsigned startToken, unsigned endToken)
 
     unsigned line, column;
     getTokenStartPosition(startToken, &line, &column);
-    Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column);
+    Scope *scope = _doc->scopeAt(line, column);
 
-    const QList<LookupItem> results = typeofExpression(expression, lastVisibleSymbol,
+    const QList<LookupItem> results = typeofExpression(expression, scope,
                                                        TypeOfExpression::Preprocess);
 
     QList<Symbol *> candidates;
 
     foreach (const LookupItem &r, results) {
-        Symbol *lastVisibleSymbol = r.lastVisibleSymbol();
+        Symbol *lastVisibleSymbol = r.declaration();
         candidates.append(lastVisibleSymbol);
     }
 
@@ -365,8 +353,7 @@ bool FindUsages::visit(EnumeratorAST *ast)
 {
     const Identifier *id = identifier(ast->identifier_token);
     if (id == _id) {
-        DeprecatedLookupContext context = currentContext(ast);
-        const QList<Symbol *> candidates = context.resolve(control()->nameId(id));
+        const QList<Symbol *> candidates = _context.lookup(control()->nameId(id), scopeAt(ast->identifier_token));
         reportResult(ast->identifier_token, candidates);
     }
 
@@ -379,8 +366,7 @@ bool FindUsages::visit(SimpleNameAST *ast)
 {
     const Identifier *id = identifier(ast->identifier_token);
     if (id == _id) {
-        DeprecatedLookupContext context = currentContext(ast);
-        const QList<Symbol *> candidates = context.resolve(ast->name);
+        const QList<Symbol *> candidates = _context.lookup(ast->name, scopeAt(ast->identifier_token));
         reportResult(ast->identifier_token, candidates);
     }
 
@@ -391,8 +377,7 @@ bool FindUsages::visit(DestructorNameAST *ast)
 {
     const Identifier *id = identifier(ast->identifier_token);
     if (id == _id) {
-        DeprecatedLookupContext context = currentContext(ast);
-        const QList<Symbol *> candidates = context.resolve(ast->name);
+        const QList<Symbol *> candidates = _context.lookup(ast->name, scopeAt(ast->identifier_token));
         reportResult(ast->identifier_token, candidates);
     }
 
@@ -402,8 +387,7 @@ bool FindUsages::visit(DestructorNameAST *ast)
 bool FindUsages::visit(TemplateIdAST *ast)
 {
     if (_id == identifier(ast->identifier_token)) {
-        DeprecatedLookupContext context = currentContext(ast);
-        const QList<Symbol *> candidates = context.resolve(ast->name);
+        const QList<Symbol *> candidates = _context.lookup(ast->name, scopeAt(ast->identifier_token));
         reportResult(ast->identifier_token, candidates);
     }
 
@@ -478,8 +462,7 @@ bool FindUsages::visit(ObjCSelectorAST *ast)
     if (ast->name) {
         const Identifier *id = ast->name->identifier();
         if (id == _id) {
-            DeprecatedLookupContext context = currentContext(ast);
-            const QList<Symbol *> candidates = context.resolve(ast->name);
+            const QList<Symbol *> candidates = _context.lookup(ast->name, scopeAt(ast->firstToken()));
             reportResult(ast->firstToken(), candidates);
         }
     }
diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h
index 8b5cf173c5a2b8f8541185490ec108b8c4ffc59a..f945ea1c41f772b40b8f987b19fc7af692167101 100644
--- a/src/libs/cplusplus/FindUsages.h
+++ b/src/libs/cplusplus/FindUsages.h
@@ -30,7 +30,7 @@
 #ifndef FINDUSAGES_H
 #define FINDUSAGES_H
 
-#include "DeprecatedLookupContext.h"
+#include "LookupContext.h"
 #include "CppDocument.h"
 #include "CppBindings.h"
 #include "Semantic.h"
@@ -73,6 +73,7 @@ protected:
     using ASTVisitor::endVisit;
 
     QString matchingLine(const Token &tk) const;
+    Scope *scopeAt(unsigned tokenIndex) const;
 
     void reportResult(unsigned tokenIndex, const QList<Symbol *> &candidates);
     void reportResult(unsigned tokenIndex);
@@ -82,8 +83,6 @@ protected:
     bool checkScope(Symbol *symbol, Symbol *otherSymbol) const;
     void checkExpression(unsigned startToken, unsigned endToken);
 
-    DeprecatedLookupContext currentContext(AST *ast);
-
     void ensureNameIsValid(NameAST *ast);
 
     virtual bool visit(MemInitializerAST *ast);
@@ -108,6 +107,7 @@ private:
     Symbol *_declSymbol;
     Document::Ptr _doc;
     Snapshot _snapshot;
+    LookupContext _context;
     QByteArray _source;
     Document::Ptr _exprDoc;
     Semantic _sem;
@@ -116,7 +116,6 @@ private:
     QList<QualifiedNameAST *> _qualifiedNameStack;
     QList<int> _references;
     QList<Usage> _usages;
-    DeprecatedLookupContext _previousContext;
     int _inSimpleDeclaration;
     bool _inQProperty;
     QSet<unsigned> _processed;
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index c1add876e4f06da3c46707fa0a488b530fb2614a..155554052153ca700e380f75ae0a195a6bb178c1 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -185,16 +185,6 @@ ClassOrNamespace *LookupContext::classOrNamespace(const Name *name, Symbol *last
     return classOrNamespace(name, scope);
 }
 
-QList<Symbol *> LookupContext::lookup(const Name *name, Symbol *lastVisibleSymbol) const
-{
-    Scope *scope = _thisDocument->globalSymbols();
-
-    if (lastVisibleSymbol && lastVisibleSymbol->scope())
-        scope = lastVisibleSymbol->scope();
-
-    return lookup(name, scope);
-}
-
 QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const
 {
     QList<Symbol *> candidates;
diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h
index 04a74440469a9f6a0e68b62e314398c46cfba314..489eb691b98f7b55204f13f37ca27c525b4e121b 100644
--- a/src/libs/cplusplus/LookupContext.h
+++ b/src/libs/cplusplus/LookupContext.h
@@ -214,12 +214,10 @@ public:
     Document::Ptr document(const QString &fileName) const;
     Snapshot snapshot() const;
 
-    QList<Symbol *> lookup(const Name *name, Symbol *lastVisibleSymbol) const;
     QList<Symbol *> lookup(const Name *name, Scope *scope) const;
 
     ClassOrNamespace *globalNamespace() const;
 
-    ClassOrNamespace *classOrNamespace(const Name *name, Symbol *lastVisibleSymbol) const;
     ClassOrNamespace *classOrNamespace(const Name *name, Scope *scope) const;
     ClassOrNamespace *classOrNamespace(Symbol *symbol) const;
 
@@ -233,6 +231,8 @@ public:
 
     static QList<const Name *> fullyQualifiedName(Symbol *symbol);
 
+    Q_DECL_DEPRECATED ClassOrNamespace *classOrNamespace(const Name *name, Symbol *lastVisibleSymbol) const;
+
 private:
     Control *_control;
 
diff --git a/src/libs/cplusplus/LookupItem.cpp b/src/libs/cplusplus/LookupItem.cpp
index a4ddfa77b7cec2046c1041abcd592a437eca1845..2502c02790b6f5617136d0314b2be6676d08fb21 100644
--- a/src/libs/cplusplus/LookupItem.cpp
+++ b/src/libs/cplusplus/LookupItem.cpp
@@ -39,16 +39,12 @@ using namespace CPlusPlus;
 uint CPlusPlus::qHash(const CPlusPlus::LookupItem &key)
 {
     const uint h1 = QT_PREPEND_NAMESPACE(qHash)(key.type().type());
-    const uint h2 = QT_PREPEND_NAMESPACE(qHash)(key.lastVisibleSymbol());
+    const uint h2 = QT_PREPEND_NAMESPACE(qHash)(key.scope());
     return ((h1 << 16) | (h1 >> 16)) ^ h2;
 }
 
 LookupItem::LookupItem()
-    : _lastVisibleSymbol(0), _declaration(0)
-{ }
-
-LookupItem::LookupItem(const FullySpecifiedType &type, Symbol *lastVisibleSymbol, Symbol *declaration)
-    : _type(type), _lastVisibleSymbol(lastVisibleSymbol), _declaration(declaration)
+    : _scope(0), _declaration(0)
 { }
 
 FullySpecifiedType LookupItem::type() const
@@ -63,15 +59,20 @@ Symbol *LookupItem::declaration() const
 void LookupItem::setDeclaration(Symbol *declaration)
 { _declaration = declaration; }
 
-Symbol *LookupItem::lastVisibleSymbol() const
-{ return _lastVisibleSymbol; }
+Scope *LookupItem::scope() const
+{
+    if (! _scope && _declaration)
+        return _declaration->scope();
+
+    return _scope;
+}
 
-void LookupItem::setLastVisibleSymbol(Symbol *symbol)
-{ _lastVisibleSymbol = symbol; }
+void LookupItem::setScope(Scope *scope)
+{ _scope = scope; }
 
 bool LookupItem::operator == (const LookupItem &other) const
 {
-    if (_type == other._type && _declaration == other._declaration && _lastVisibleSymbol == other._lastVisibleSymbol)
+    if (_type == other._type && _declaration == other._declaration && _scope == other._scope)
         return true;
 
     return false;
diff --git a/src/libs/cplusplus/LookupItem.h b/src/libs/cplusplus/LookupItem.h
index 6254fbf82bcef49e22205cd7d69fec47fd612be7..14ba99c5734ff1cdeaac98e79f3f15edc4a5bed4 100644
--- a/src/libs/cplusplus/LookupItem.h
+++ b/src/libs/cplusplus/LookupItem.h
@@ -41,9 +41,6 @@ public:
     /// Constructs an null LookupItem.
     LookupItem();
 
-    /// Contructs a LookupItem with the given \a type, \a lastVisibleSymbol and \a declaration.
-    LookupItem(const FullySpecifiedType &type, Symbol *lastVisibleSymbol, Symbol *declaration = 0);
-
     /// Returns this item's type.
     FullySpecifiedType type() const;
 
@@ -51,23 +48,23 @@ public:
     void setType(const FullySpecifiedType &type);
 
     /// Returns the last visible symbol.
-    Symbol *lastVisibleSymbol() const;
+    Symbol *declaration() const;
 
     /// Sets the last visible symbol.
-    void setLastVisibleSymbol(Symbol *symbol);
+    void setDeclaration(Symbol *declaration);
 
-    /// Returns this item's declaration.
-    Symbol *declaration() const;
+    /// Returns this item's scope.
+    Scope *scope() const;
 
-    /// Sets this item's declaration.
-    void setDeclaration(Symbol *declaration);
+    /// Sets this item's scope.
+    void setScope(Scope *scope);
 
     bool operator == (const LookupItem &other) const;
     bool operator != (const LookupItem &other) const;
 
 private:
     FullySpecifiedType _type;
-    Symbol *_lastVisibleSymbol;
+    Scope *_scope;
     Symbol *_declaration;
 };
 
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index c4a3b16a76c5f9a1e107d896a58bc32776d13678..ed0253b6a7b59d47c74634d6e385f58305c7aba2 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -70,21 +70,9 @@ static QList<_Tp> removeDuplicates(const QList<_Tp> &results)
 /////////////////////////////////////////////////////////////////////
 // ResolveExpression
 /////////////////////////////////////////////////////////////////////
-ResolveExpression::ResolveExpression(Symbol *lastVisibleSymbol, const LookupContext &context)
+ResolveExpression::ResolveExpression(const LookupContext &context)
     : ASTVisitor(context.expressionDocument()->translationUnit()),
-      _lastVisibleSymbol(lastVisibleSymbol),
-      _context(context),
-      sem(context.expressionDocument()->translationUnit())
-{
-    if (! lastVisibleSymbol)
-        lastVisibleSymbol = context.thisDocument()->globalNamespace();
-    _scope = lastVisibleSymbol->scope();
-}
-
-ResolveExpression::ResolveExpression(Scope *scope, const LookupContext &context)
-    : ASTVisitor(context.expressionDocument()->translationUnit()),
-      _lastVisibleSymbol(0),
-      _scope(scope),
+      _scope(0),
       _context(context),
       sem(context.expressionDocument()->translationUnit())
 { }
@@ -92,15 +80,28 @@ ResolveExpression::ResolveExpression(Scope *scope, const LookupContext &context)
 ResolveExpression::~ResolveExpression()
 { }
 
-QList<LookupItem> ResolveExpression::operator()(ExpressionAST *ast)
+QList<LookupItem> ResolveExpression::operator()(ExpressionAST *ast, Scope *scope)
+{ return resolve(ast, scope); }
+
+QList<LookupItem> ResolveExpression::resolve(ExpressionAST *ast, Scope *scope)
+{
+    Q_ASSERT(scope != 0);
+
+    Scope *previousVisibleSymbol = _scope;
+    _scope = scope;
+    const QList<LookupItem> result = resolve(ast);
+    _scope = previousVisibleSymbol;
+    return result;
+}
+
+QList<LookupItem> ResolveExpression::resolve(ExpressionAST *ast)
 {
     const QList<LookupItem> previousResults = switchResults(QList<LookupItem>());
     accept(ast);
     return removeDuplicates(switchResults(previousResults));
 }
 
-QList<LookupItem>
-ResolveExpression::switchResults(const QList<LookupItem> &results)
+QList<LookupItem> ResolveExpression::switchResults(const QList<LookupItem> &results)
 {
     const QList<LookupItem> previousResults = _results;
     _results = results;
@@ -109,23 +110,25 @@ ResolveExpression::switchResults(const QList<LookupItem> &results)
 
 void ResolveExpression::addResults(const QList<Symbol *> &symbols)
 {
-    foreach (Symbol *s, symbols) {
-        LookupItem item(s->type(), s, s);
+    foreach (Symbol *symbol, symbols) {
+        LookupItem item;
+        item.setType(symbol->type());
+        item.setScope(symbol->scope());
+        item.setDeclaration(symbol);
         _results.append(item);
     }
 }
 
-void ResolveExpression::addResult(const FullySpecifiedType &ty, Symbol *symbol)
+void ResolveExpression::addResult(const FullySpecifiedType &ty, Scope *scope)
 {
-    if (! symbol) {
-        if (_scope)
-            symbol = _scope->owner();
+    Q_ASSERT(scope != 0);
+#warning fix the signature of addResult.
 
-        else
-            symbol = _context.thisDocument()->globalNamespace();
-    }
+    LookupItem item;
+    item.setType(ty);
+    item.setScope(scope);
 
-    _results.append(LookupItem(ty, symbol));
+    _results.append(item);
 }
 
 bool ResolveExpression::visit(BinaryExpressionAST *ast)
@@ -155,7 +158,9 @@ bool ResolveExpression::visit(BinaryExpressionAST *ast)
 
 bool ResolveExpression::visit(CastExpressionAST *ast)
 {
-    addResult(sem.check(ast->type_id, _context.expressionDocument()->globalSymbols()));
+    Scope *dummyScope = _context.expressionDocument()->globalSymbols();
+    FullySpecifiedType ty = sem.check(ast->type_id, dummyScope);
+    addResult(ty, _scope);
     return false;
 }
 
@@ -178,14 +183,16 @@ bool ResolveExpression::visit(ConditionalExpressionAST *ast)
 
 bool ResolveExpression::visit(CppCastExpressionAST *ast)
 {
-    addResult(sem.check(ast->type_id, _context.expressionDocument()->globalSymbols()));
+    Scope *dummyScope = _context.expressionDocument()->globalSymbols();
+    FullySpecifiedType ty = sem.check(ast->type_id, dummyScope);
+    addResult(ty, _scope);
     return false;
 }
 
 bool ResolveExpression::visit(DeleteExpressionAST *)
 {
     FullySpecifiedType ty(control()->voidType());
-    addResult(ty);
+    addResult(ty, _scope);
     return false;
 }
 
@@ -198,11 +205,11 @@ bool ResolveExpression::visit(ArrayInitializerAST *)
 bool ResolveExpression::visit(NewExpressionAST *ast)
 {
     if (ast->new_type_id) {
-        Scope *scope = _context.expressionDocument()->globalSymbols();
-        FullySpecifiedType ty = sem.check(ast->new_type_id->type_specifier_list, scope);
-        ty = sem.check(ast->new_type_id->ptr_operator_list, ty, scope);
+        Scope *dummyScope = _context.expressionDocument()->globalSymbols();
+        FullySpecifiedType ty = sem.check(ast->new_type_id->type_specifier_list, dummyScope);
+        ty = sem.check(ast->new_type_id->ptr_operator_list, ty, dummyScope);
         FullySpecifiedType ptrTy(control()->pointerType(ty));
-        addResult(ptrTy);
+        addResult(ptrTy, _scope);
     }
     // nothing to do.
     return false;
@@ -216,7 +223,7 @@ bool ResolveExpression::visit(TypeidExpressionAST *)
 
     const Name *q = control()->qualifiedNameId(std_type_info, 2, /*global=*/ true);
     FullySpecifiedType ty(control()->namedType(q));
-    addResult(ty);
+    addResult(ty, _scope);
 
     return false;
 }
@@ -248,7 +255,7 @@ bool ResolveExpression::visit(SizeofExpressionAST *)
 {
     FullySpecifiedType ty(control()->integerType(IntegerType::Int));
     ty.setUnsigned(true);
-    addResult(ty);
+    addResult(ty, _scope);
     return false;
 }
 
@@ -280,14 +287,14 @@ bool ResolveExpression::visit(NumericLiteralAST *ast)
     if (literal->isUnsigned())
         ty.setUnsigned(true);
 
-    addResult(ty);
+    addResult(ty, _scope);
     return false;
 }
 
 bool ResolveExpression::visit(BoolLiteralAST *)
 {
     FullySpecifiedType ty(control()->integerType(IntegerType::Bool));
-    addResult(ty);
+    addResult(ty, _scope);
     return false;
 }
 
@@ -307,7 +314,7 @@ void ResolveExpression::thisObject()
                 Class *klass = cscope->owner()->asClass();
                 FullySpecifiedType classTy(control()->namedType(klass->name()));
                 FullySpecifiedType ptrTy(control()->pointerType(classTy));
-                addResult(ptrTy, fun);
+                addResult(ptrTy, fun->scope());
                 break;
             } else if (const QualifiedNameId *q = fun->name()->asQualifiedNameId()) {
                 const Name *nestedNameSpecifier = 0;
@@ -317,7 +324,7 @@ void ResolveExpression::thisObject()
                     nestedNameSpecifier = control()->qualifiedNameId(q->names(), q->nameCount() - 1);
                 FullySpecifiedType classTy(control()->namedType(nestedNameSpecifier));
                 FullySpecifiedType ptrTy(control()->pointerType(classTy));
-                addResult(ptrTy, fun);
+                addResult(ptrTy, fun->scope());
                 break;
             }
         }
@@ -344,7 +351,7 @@ bool ResolveExpression::visit(StringLiteralAST *)
     FullySpecifiedType charTy = control()->integerType(IntegerType::Char);
     charTy.setConst(true);
     FullySpecifiedType ty(control()->pointerType(charTy));
-    addResult(ty);
+    addResult(ty, _scope);
     return false;
 }
 
@@ -419,7 +426,7 @@ bool ResolveExpression::visit(TemplateIdAST *ast)
 bool ResolveExpression::visit(DestructorNameAST *)
 {
     FullySpecifiedType ty(control()->voidType());
-    addResult(ty);
+    addResult(ty, _scope);
     return false;
 }
 
@@ -466,7 +473,7 @@ bool ResolveExpression::visit(CallAST *ast)
 
     //QList< QList<Result> > arguments;
     for (ExpressionListAST *exprIt = ast->expression_list; exprIt; exprIt = exprIt->next) {
-        //arguments.append(operator()(exprIt->expression));
+        //arguments.append(resolve(exprIt->expression));
         ++actualArgumentCount;
     }
 
@@ -474,15 +481,15 @@ bool ResolveExpression::visit(CallAST *ast)
 
     foreach (const LookupItem &result, baseResults) {
         FullySpecifiedType ty = result.type().simplified();
-        Symbol *lastVisibleSymbol = result.lastVisibleSymbol();
+        Scope *scope = result.scope();
 
         if (NamedType *namedTy = ty->asNamedType()) {
-            if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), lastVisibleSymbol)) {
+            if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), scope)) {
                 foreach (Symbol *overload, b->find(functionCallOp)) {
                     if (Function *funTy = overload->type()->asFunctionType()) {
                         if (maybeValidPrototype(funTy, actualArgumentCount)) {
                             Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType();
-                            addResult(proto->returnType().simplified(), lastVisibleSymbol);
+                            addResult(proto->returnType().simplified(), scope);
                         }
                     }
                 }
@@ -490,12 +497,12 @@ bool ResolveExpression::visit(CallAST *ast)
 
         } else if (Function *funTy = ty->asFunctionType()) {
             if (maybeValidPrototype(funTy, actualArgumentCount))
-                addResult(funTy->returnType().simplified(), lastVisibleSymbol);
+                addResult(funTy->returnType().simplified(), scope);
 
         } else if (Class *classTy = ty->asClassType()) {
             // Constructor call
             FullySpecifiedType ctorTy = control()->namedType(classTy->name());
-            addResult(ctorTy, lastVisibleSymbol);
+            addResult(ctorTy, scope);
         }
     }
 
@@ -507,27 +514,27 @@ bool ResolveExpression::visit(ArrayAccessAST *ast)
     const QList<LookupItem> baseResults = _results;
     _results.clear();
 
-    const QList<LookupItem> indexResults = operator()(ast->expression);
+    const QList<LookupItem> indexResults = resolve(ast->expression);
 
     const Name *arrayAccessOp = control()->operatorNameId(OperatorNameId::ArrayAccessOp);
 
     foreach (const LookupItem &result, baseResults) {
         FullySpecifiedType ty = result.type().simplified();
-        Symbol *lastVisibleSymbol = result.lastVisibleSymbol();
+        Scope *scope = result.scope();
 
         if (PointerType *ptrTy = ty->asPointerType()) {
-            addResult(ptrTy->elementType().simplified(), lastVisibleSymbol);
+            addResult(ptrTy->elementType().simplified(), scope);
 
         } else if (ArrayType *arrTy = ty->asArrayType()) {
-            addResult(arrTy->elementType().simplified(), lastVisibleSymbol);
+            addResult(arrTy->elementType().simplified(), scope);
 
         } else if (NamedType *namedTy = ty->asNamedType()) {
-            if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), lastVisibleSymbol)) {
+            if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), scope)) {
                 foreach (Symbol *overload, b->find(arrayAccessOp)) {
                     if (Function *funTy = overload->type()->asFunctionType()) {
                         Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType();
                         // ### TODO: check the actual arguments
-                        addResult(proto->returnType().simplified(), lastVisibleSymbol);
+                        addResult(proto->returnType().simplified(), scope);
                     }
                 }
 
@@ -567,7 +574,7 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i
 
     LookupItem result = baseResults.first();
     FullySpecifiedType ty = result.type().simplified();
-    Symbol *lastVisibleSymbol = result.lastVisibleSymbol();
+    Scope *scope = result.scope();
 
     if (Function *funTy = ty->asFunctionType()) {
         if (funTy->isAmbiguous())
@@ -578,26 +585,36 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i
         if (NamedType *namedTy = ty->asNamedType()) {
             const Name *arrowAccessOp = control()->operatorNameId(OperatorNameId::ArrowOp);
 
-            foreach (Symbol *s, _context.lookup(namedTy->name(), result.lastVisibleSymbol())) {
-                if (PointerType *ptrTy = s->type()->asPointerType()) {
+            foreach (Symbol *declaration, _context.lookup(namedTy->name(), result.scope())) {
+                if (PointerType *ptrTy = declaration->type()->asPointerType()) {
                     FullySpecifiedType elementTy = ptrTy->elementType().simplified();
 
-                    if (elementTy->isNamedType() || elementTy->isClassType())
-                        results.append(LookupItem(elementTy, lastVisibleSymbol));
+                    if (elementTy->isNamedType() || elementTy->isClassType()) {
+                        LookupItem item;
+                        item.setType(elementTy);
+                        item.setDeclaration(declaration);
+                        results.append(item);
+                    }
 
-                } else if (const NamedType *nt = s->type()->asNamedType()) {
-                    Symbol *l = _context.lookup(nt->name(), result.lastVisibleSymbol()).first();
+                } else if (const NamedType *nt = declaration->type()->asNamedType()) {
+#warning fix this code
+                    qWarning() << Q_FUNC_INFO << __LINE__;
+                    Symbol *declaration = _context.lookup(nt->name(), result.scope()).first();
 
-                    if (PointerType *ptrTy = l->type()->asPointerType()) {
+                    if (PointerType *ptrTy = declaration->type()->asPointerType()) {
                         FullySpecifiedType elementTy = ptrTy->elementType().simplified();
 
-                        if (elementTy->isNamedType() || elementTy->isClassType())
-                            results.append(LookupItem(elementTy, lastVisibleSymbol));
+                        if (elementTy->isNamedType() || elementTy->isClassType()) {
+                            LookupItem item;
+                            item.setType(elementTy);
+                            item.setDeclaration(declaration);
+                            results.append(item);
+                        }
                     }
                 }
             }
 
-            if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), result.lastVisibleSymbol())) {
+            if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), result.scope())) {
                 foreach (Symbol *overload, b->find(arrowAccessOp)) {
                     if (Function *funTy = overload->type()->asFunctionType()) {
                         FullySpecifiedType f = instantiate(namedTy->name(), funTy);
@@ -605,7 +622,11 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i
 
                         if (PointerType *ptrTy = retTy->asPointerType()) {
                             FullySpecifiedType elementTy = ptrTy->elementType().simplified();
-                            results.append(LookupItem(elementTy, overload));
+
+                            LookupItem item;
+                            item.setType(elementTy);
+                            item.setDeclaration(overload);
+                            results.append(item);
                         }
                     }
                 }
@@ -614,8 +635,12 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i
         } else if (PointerType *ptrTy = ty->asPointerType()) {
             FullySpecifiedType elementTy = ptrTy->elementType().simplified();
 
-            if (elementTy->isNamedType() || elementTy->isClassType())
-                results.append(LookupItem(elementTy, lastVisibleSymbol));
+            if (elementTy->isNamedType() || elementTy->isClassType()) {
+                LookupItem item;
+                item.setType(elementTy);
+                item.setScope(scope);
+                results.append(item);
+            }
         }
     } else if (accessOp == T_DOT) {
         if (replacedDotOperator) {
@@ -629,27 +654,24 @@ ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, i
         }
 
         if (NamedType *namedTy = ty->asNamedType()) {
-            const QList<Symbol *> candidates = _context.lookup(namedTy->name(), result.lastVisibleSymbol());
-            foreach (Symbol *candidate, candidates) {
-                if (candidate->isTypedef() && candidate->type()->isNamedType()) {
-                    ty = candidate->type();
-                    lastVisibleSymbol = candidate;
-                    break;
-                } else if (TypenameArgument *arg = candidate->asTypenameArgument()) {
-                    ty = arg->type();
-                    lastVisibleSymbol = candidate;
-                    break;
+            if (ClassOrNamespace *binding = _context.classOrNamespace(namedTy->name(), result.scope())) {
+                foreach (Symbol *s, binding->symbols()) {
+                    LookupItem item;
+                    item.setType(s->type());
+                    item.setDeclaration(s);
+                    results.append(item);
                 }
             }
 
-            results.append(LookupItem(ty, lastVisibleSymbol));
-
         } else if (Function *fun = ty->asFunctionType()) {
             Scope *funScope = fun->scope();
 
             if (funScope && (funScope->isBlockScope() || funScope->isNamespaceScope())) {
                 FullySpecifiedType retTy = fun->returnType().simplified();
-                results.append(LookupItem(retTy, lastVisibleSymbol));
+                LookupItem item;
+                item.setType(retTy);
+                item.setDeclaration(fun);
+                results.append(item);
             }
         }
     }
@@ -674,9 +696,13 @@ ResolveExpression::resolveMemberExpression(const QList<LookupItem> &baseResults,
             results += resolveMember(memberName, klass);
 
         else if (NamedType *namedTy = ty->asNamedType()) {
-            if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), r.lastVisibleSymbol())) {
-                foreach (Symbol *c, b->find(memberName))
-                    results.append(LookupItem(instantiate(namedTy->name(), c), c));
+            if (ClassOrNamespace *b = _context.classOrNamespace(namedTy->name(), r.scope())) {
+                foreach (Symbol *overload, b->find(memberName)) {
+                    LookupItem item;
+                    item.setType(instantiate(namedTy->name(), overload));
+                    item.setDeclaration(overload);
+                    results.append(item);
+                }
             }
         }
     }
@@ -689,9 +715,8 @@ FullySpecifiedType ResolveExpression::instantiate(const Name *className, Symbol
     return GenTemplateInstance::instantiate(className, candidate, _context.control());
 }
 
-QList<LookupItem>
-ResolveExpression::resolveMember(const Name *memberName, Class *klass,
-                                 const Name *className) const
+QList<LookupItem> ResolveExpression::resolveMember(const Name *memberName, Class *klass,
+                                                   const Name *className) const
 {
     QList<LookupItem> results;
 
@@ -716,15 +741,17 @@ ResolveExpression::resolveMember(const Name *memberName, Class *klass,
         if (const TemplateNameId *templId = unqualifiedNameId->asTemplateNameId())
             ty = GenTemplateInstance::instantiate(templId, candidate, _context.control());
 
-        results.append(LookupItem(ty, candidate));
+        LookupItem item;
+        item.setType(ty);
+        item.setDeclaration(candidate);
+        results.append(item);
     }
 
     return removeDuplicates(results);
 }
 
 
-QList<LookupItem>
-ResolveExpression::resolveMember(const Name *memberName, ObjCClass *klass) const
+QList<LookupItem> ResolveExpression::resolveMember(const Name *memberName, ObjCClass *klass) const
 {
     QList<LookupItem> results;
     if (!memberName || !klass)
@@ -734,8 +761,10 @@ ResolveExpression::resolveMember(const Name *memberName, ObjCClass *klass) const
 
     foreach (Symbol *candidate, candidates) {
         FullySpecifiedType ty = candidate->type();
-
-        results.append(LookupItem(ty, candidate));
+        LookupItem item;
+        item.setType(ty);
+        item.setDeclaration(candidate);
+        results.append(item);
     }
 
     return removeDuplicates(results);
@@ -748,7 +777,7 @@ bool ResolveExpression::visit(PostIncrDecrAST *)
 
 bool ResolveExpression::visit(ObjCMessageExpressionAST *ast)
 {
-    QList<LookupItem> receiverResults = operator()(ast->receiver_expression);
+    const QList<LookupItem> receiverResults = resolve(ast->receiver_expression);
 
     if (!receiverResults.isEmpty()) {
         LookupItem result = receiverResults.first();
@@ -769,7 +798,7 @@ bool ResolveExpression::visit(ObjCMessageExpressionAST *ast)
         }
 
         if (klassName&&ast->selector && ast->selector->name) {
-            const QList<Symbol *> resolvedSymbols = _context.lookup(klassName, result.lastVisibleSymbol());
+            const QList<Symbol *> resolvedSymbols = _context.lookup(klassName, result.scope());
             foreach (Symbol *resolvedSymbol, resolvedSymbols)
                 if (ObjCClass *klass = resolvedSymbol->asObjCClass())
                     _results.append(resolveMember(ast->selector->name, klass));
diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h
index 997cf030acf233d8c3cf727f5be13a3529e5e101..95538ceba6f3a7bad5c2d9fa372232c834e354fa 100644
--- a/src/libs/cplusplus/ResolveExpression.h
+++ b/src/libs/cplusplus/ResolveExpression.h
@@ -41,12 +41,11 @@ namespace CPlusPlus {
 class CPLUSPLUS_EXPORT ResolveExpression: protected ASTVisitor
 {
 public:
-    ResolveExpression(Symbol *lastVisibleSymbol, const LookupContext &context);
-    ResolveExpression(Scope *scope, const LookupContext &context);
-
+    ResolveExpression(const LookupContext &context);
     virtual ~ResolveExpression();
 
-    QList<LookupItem> operator()(ExpressionAST *ast);
+    QList<LookupItem> operator()(ExpressionAST *ast, Scope *scope);
+    QList<LookupItem> resolve(ExpressionAST *ast, Scope *scope);
 
     QList<LookupItem> resolveMemberExpression(const QList<LookupItem> &baseResults,
                                               unsigned accessOp,
@@ -57,19 +56,20 @@ public:
                                             int accessOp,
                                             bool *replacedDotOperator = 0) const;
 
+protected:
+    QList<LookupItem> resolve(ExpressionAST *ast);
+
     Q_DECL_DEPRECATED QList<LookupItem> resolveMember(const Name *memberName, Class *klass,
                                                       const Name *className = 0) const;
 
     Q_DECL_DEPRECATED QList<LookupItem> resolveMember(const Name *memberName, ObjCClass *klass) const;
 
-protected:
     QList<LookupItem> switchResults(const QList<LookupItem> &symbols);
     FullySpecifiedType instantiate(const Name *className, Symbol *candidate) const;
 
     void thisObject();
 
-    void addResult(const FullySpecifiedType &ty, Symbol *symbol = 0);
-
+    void addResult(const FullySpecifiedType &ty, Scope *scope);
     void addResults(const QList<Symbol *> &symbols);
 
     bool maybeValidPrototype(Function *funTy, unsigned actualArgumentCount) const;
@@ -118,7 +118,6 @@ protected:
     virtual bool visit(ObjCMessageExpressionAST *ast);
 
 private:
-    Symbol *_lastVisibleSymbol;
     Scope *_scope;
     LookupContext _context;
     Semantic sem;
diff --git a/src/libs/cplusplus/TypeOfExpression.cpp b/src/libs/cplusplus/TypeOfExpression.cpp
index cfe8ac74e990067e4ea3a93ac641884f6a52e185..0eb8b676b0398c1e46d315fc00543ee2c32c37d9 100644
--- a/src/libs/cplusplus/TypeOfExpression.cpp
+++ b/src/libs/cplusplus/TypeOfExpression.cpp
@@ -34,13 +34,14 @@
 #include "pp.h"
 
 #include <AST.h>
+#include <Symbol.h>
 #include <QSet>
 
 using namespace CPlusPlus;
 
 TypeOfExpression::TypeOfExpression():
     m_ast(0),
-    m_lastVisibleSymbol(0)
+    m_scope(0)
 {
 }
 
@@ -49,7 +50,7 @@ void TypeOfExpression::reset()
     m_thisDocument.clear();
     m_snapshot = Snapshot();
     m_ast = 0;
-    m_lastVisibleSymbol = 0;
+    m_scope = 0;
     m_lookupContext = LookupContext();
     m_bindings.clear();
     m_environment.clear();
@@ -61,14 +62,14 @@ void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot
     m_thisDocument = thisDocument;
     m_snapshot = snapshot;
     m_ast = 0;
-    m_lastVisibleSymbol = 0;
+    m_scope = 0;
     m_lookupContext = LookupContext();
     m_bindings = bindings;
     m_environment.clear();
 }
 
 QList<LookupItem> TypeOfExpression::operator()(const QString &expression,
-                                               Symbol *lastVisibleSymbol,
+                                               Scope *scope,
                                                PreprocessMode mode)
 {
     QString code = expression;
@@ -80,13 +81,14 @@ QList<LookupItem> TypeOfExpression::operator()(const QString &expression,
     expressionDoc->check();
     m_ast = extractExpressionAST(expressionDoc);
 
-    m_lastVisibleSymbol = lastVisibleSymbol;
+    m_scope = scope;
 
     m_lookupContext = LookupContext(expressionDoc, m_thisDocument, m_snapshot);
     m_lookupContext.setBindings(m_bindings);
 
-    ResolveExpression resolveExpression(lastVisibleSymbol, m_lookupContext);
-    return resolveExpression(m_ast);
+    ResolveExpression resolve(m_lookupContext);
+#warning fix the signature of operator()
+    return resolve(m_ast, scope);
 }
 
 QString TypeOfExpression::preprocess(const QString &expression) const
@@ -99,9 +101,9 @@ ExpressionAST *TypeOfExpression::ast() const
     return m_ast;
 }
 
-Symbol *TypeOfExpression::lastVisibleSymbol() const
+Scope *TypeOfExpression::scope() const
 {
-    return m_lastVisibleSymbol;
+    return m_scope;
 }
 
 const LookupContext &TypeOfExpression::lookupContext() const
diff --git a/src/libs/cplusplus/TypeOfExpression.h b/src/libs/cplusplus/TypeOfExpression.h
index b2c181a419bcf3f8006e05b8c8138c9f60c3b88e..28bd1db08f37ffe1e1f36198c19d344647d0c692 100644
--- a/src/libs/cplusplus/TypeOfExpression.h
+++ b/src/libs/cplusplus/TypeOfExpression.h
@@ -76,10 +76,10 @@ public:
      * has been made!
      *
      * @param expression        The expression to evaluate.
-     * @param lastVisibleSymbol The last visible symbol in the document.
+     * @param scope             The scope enclosing the expression.
      */
     QList<LookupItem> operator()(const QString &expression,
-                                 Symbol *lastVisibleSymbol,
+                                 Scope *scope,
                                  PreprocessMode mode = NoPreprocess);
 
     QString preprocess(const QString &expression) const;
@@ -93,7 +93,7 @@ public:
      * Returns the lookup context of the last evaluated expression.
      */
     const LookupContext &lookupContext() const;
-    Symbol *lastVisibleSymbol() const;
+    Scope *scope() const;
 
     ExpressionAST *expressionAST() const;
 
@@ -111,7 +111,7 @@ private:
     Snapshot m_snapshot;
     QSharedPointer<CreateBindings> m_bindings;
     ExpressionAST *m_ast;
-    Symbol *m_lastVisibleSymbol;
+    Scope *m_scope;
     LookupContext m_lookupContext;
     mutable QSharedPointer<Environment> m_environment;
 };
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 2d1a06d21d88993cac114becc88068b8df9fc2dd..4fd03c3cd5ae146a8b7d5713b1c1dd75f8a0171b 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -871,9 +871,7 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor,
     TypeOfExpression typeOfExpression;
     typeOfExpression.init(doc, snapshot);
 
-    Symbol *lastVisibleSymbol = doc->findSymbolAt(line, col);
-
-    const QList<LookupItem> results = typeOfExpression(code, lastVisibleSymbol,
+    const QList<LookupItem> results = typeOfExpression(code, doc->scopeAt(line, col),
                                                        TypeOfExpression::Preprocess);
 
     NamespaceBindingPtr glo = bind(doc, snapshot);
@@ -1235,6 +1233,10 @@ void CPPEditor::switchDeclarationDefinition()
     if (!m_modelManager)
         return;
 
+#warning implement CPPEditor::switchDeclarationDefinition
+    qWarning() << Q_FUNC_INFO << __LINE__;
+
+#if 0
     const Snapshot snapshot = m_modelManager->snapshot();
 
     Document::Ptr doc = snapshot.document(file()->fileName());
@@ -1274,6 +1276,7 @@ void CPPEditor::switchDeclarationDefinition()
         if (Symbol *def = findDefinition(lastSymbol, snapshot))
             openCppEditorAt(linkToSymbol(def));
     }
+#endif
 }
 
 static inline LookupItem skipForwardDeclarations(const QList<LookupItem> &resolvedSymbols)
@@ -1425,8 +1428,8 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
     }
 
     // Find the last symbol up to the cursor position
-    Symbol *lastSymbol = doc->findSymbolAt(line, column);
-    if (!lastSymbol)
+    Scope *scope = doc->scopeAt(line, column);
+    if (!scope)
         return link;
 
     // Evaluate the type of the expression under the cursor
@@ -1435,16 +1438,20 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
 
     TypeOfExpression typeOfExpression;
     typeOfExpression.init(doc, snapshot);
-    QList<LookupItem> resolvedSymbols =
-            typeOfExpression(expression, lastSymbol);
+    QList<LookupItem> resolvedSymbols = typeOfExpression(expression, scope, TypeOfExpression::Preprocess);
 
     if (!resolvedSymbols.isEmpty()) {
-        LookupItem result = skipForwardDeclarations(resolvedSymbols);
+        const LookupItem result = skipForwardDeclarations(resolvedSymbols);
 
-        if (Symbol *symbol = result.lastVisibleSymbol()) {
+        if (Symbol *symbol = result.declaration()) {
             Symbol *def = 0;
+
+            qWarning() << "find definition?";
+#warning port me
+#if 0
             if (resolveTarget && !lastSymbol->isFunction())
                 def = findDefinition(symbol, snapshot);
+#endif
 
             link = linkToSymbol(def ? def : symbol);
             link.begin = beginOfToken;
diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp
index f38179e09edaffc684537edf0ca44100339c0318..04545161ad26a8284362a5ae5955f7b00f9aecb4 100644
--- a/src/plugins/cppeditor/cpphoverhandler.cpp
+++ b/src/plugins/cppeditor/cpphoverhandler.cpp
@@ -178,6 +178,9 @@ static QString buildHelpId(Symbol *symbol, const Name *name)
     return qualifiedNames.join(QLatin1String("::"));
 }
 
+#warning implement static FullySpecifiedType resolve()
+
+#if 0
 // ### move me
 static FullySpecifiedType resolve(const FullySpecifiedType &ty,
                                   const LookupContext &context,
@@ -257,6 +260,7 @@ static FullySpecifiedType resolve(const FullySpecifiedType &ty,
 
     return ty;
 }
+#endif
 
 void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos)
 {
@@ -270,6 +274,8 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
     if (!edit)
         return;
 
+#warning void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos)
+#if 0
     const Snapshot documents = m_modelManager->snapshot();
     const QString fileName = editor->file()->fileName();
     Document::Ptr doc = documents.document(fileName);
@@ -285,7 +291,7 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
     // Find the last symbol up to the cursor position
     int line = 0, column = 0;
     editor->convertPosition(tc.position(), &line, &column);
-    Symbol *lastSymbol = doc->findSymbolAt(line, column);
+    Scope *scope = doc->scopeAt(line, column);
 
     TypeOfExpression typeOfExpression;
     typeOfExpression.init(doc, documents);
@@ -336,18 +342,18 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
         ExpressionUnderCursor expressionUnderCursor;
         const QString expression = expressionUnderCursor(tc);
 
-        const QList<LookupItem> types = typeOfExpression(expression, lastSymbol);
+        const QList<LookupItem> types = typeOfExpression(expression, scope);
 
         if (!types.isEmpty()) {
             const LookupItem result = types.first();
 
             FullySpecifiedType firstType = result.type(); // result of `type of expression'.
-            Symbol *lookupSymbol = result.lastVisibleSymbol(); // lookup symbol
+            Symbol *lookupSymbol = result.declaration(); // lookup symbol
 
             Symbol *resolvedSymbol = lookupSymbol;
             const Name *resolvedName = lookupSymbol ? lookupSymbol->name() : 0;
             firstType = resolve(firstType, typeOfExpression.lookupContext(),
-                                lastSymbol,
+                                scope,
                                 &resolvedSymbol, &resolvedName);
 
             if (resolvedSymbol && resolvedSymbol->scope()
@@ -362,7 +368,7 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
             m_helpId = buildHelpId(resolvedSymbol, resolvedName);
 
             if (m_toolTip.isEmpty()) {
-                Symbol *symbol = result.lastVisibleSymbol();
+                Symbol *symbol = result.declaration();
                 if (resolvedSymbol)
                     symbol = resolvedSymbol;
 
@@ -431,4 +437,5 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
     } else if (!m_toolTip.isEmpty() && Qt::mightBeRichText(m_toolTip)) {
         m_toolTip = QString(QLatin1String("<nobr>%1")).arg(Qt::escape(m_toolTip));
     }
+#endif
 }
diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp
index 977fb4001a3c9fb3e75b6d6aa2d1090e0b60d986..bd2c4f87a1eafbedd468430dd20fadfcaeed6e04 100644
--- a/src/plugins/cpptools/cppcodecompletion.cpp
+++ b/src/plugins/cpptools/cppcodecompletion.cpp
@@ -754,15 +754,17 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
         }
     }
 
+    Scope *scope = thisDocument->scopeAt(line, column);
+    Q_ASSERT(scope != 0);
 
-    QList<LookupItem> results = typeOfExpression(expression, lastVisibleSymbol, TypeOfExpression::Preprocess);
+    QList<LookupItem> results = typeOfExpression(expression, scope, TypeOfExpression::Preprocess);
     LookupContext context = typeOfExpression.lookupContext();
 
     if (results.isEmpty()) {
         if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) {
             if (! (expression.isEmpty() || expression == QLatin1String("this"))) {
                 expression = QLatin1String("this");
-                results = typeOfExpression(expression, lastVisibleSymbol);
+                results = typeOfExpression(expression, scope);
             }
 
             if (results.isEmpty())
@@ -785,7 +787,7 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
 
             // Resolve the type of this expression
             const QList<LookupItem> results =
-                    typeOfExpression(baseExpression, lastVisibleSymbol,
+                    typeOfExpression(baseExpression, scope,
                                      TypeOfExpression::Preprocess);
 
             // If it's a class, add completions for the constructors
@@ -930,10 +932,10 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r
 
         foreach (const LookupItem &result, results) {
             FullySpecifiedType ty = result.type().simplified();
-            Symbol *lastVisibleSymbol = result.lastVisibleSymbol();
+            Scope *scope = result.scope();
 
             if (NamedType *namedTy = ty->asNamedType()) {
-                if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), lastVisibleSymbol)) {
+                if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), scope)) {
                     foreach (Symbol *overload, b->lookup(functionCallOp)) {
                         FullySpecifiedType overloadTy = overload->type().simplified();
 
@@ -966,8 +968,8 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r
         // find a scope that encloses the current location, starting from the lastVisibileSymbol
         // and moving outwards
         Scope *sc = 0;
-        if (typeOfExpression.lastVisibleSymbol())
-            sc = typeOfExpression.lastVisibleSymbol()->scope();
+        if (typeOfExpression.scope())
+            sc = typeOfExpression.scope();
         else if (context.thisDocument())
             sc = context.thisDocument()->globalSymbols();
 
@@ -1054,7 +1056,7 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults,
     if (baseResults.isEmpty())
         return false;
 
-    ResolveExpression resolveExpression(typeOfExpression.lastVisibleSymbol(), context);
+    ResolveExpression resolveExpression(context);
 
     bool replacedDotOperator = false;
     const QList<LookupItem> classObjectResults =
@@ -1064,21 +1066,22 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults,
 
     ClassOrNamespace *classOrNamespace = 0;
 
-    QList<Symbol *> classObjectCandidates;
     foreach (const LookupItem &r, classObjectResults) {
         FullySpecifiedType ty = r.type().simplified();
 
-        if (Class *klass = ty->asClassType())
-            classObjectCandidates.append(klass);
+        if (Class *klass = ty->asClassType()) {
+            if (ClassOrNamespace *b = context.classOrNamespace(klass)) {
+                classOrNamespace = b;
+                break;
+            }
+        }
 
         else if (NamedType *namedTy = ty->asNamedType()) {
-            if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), r.lastVisibleSymbol())) {
+            if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), r.scope())) {
                 classOrNamespace = b;
                 break;
-
             }  else {
                 Overview oo;
-
                 qDebug() << "*** no class for" << oo(namedTy->name());
             }
         }
@@ -1109,10 +1112,10 @@ bool CppCodeCompletion::completeScope(const QList<LookupItem> &results,
 
     foreach (const LookupItem &result, results) {
         FullySpecifiedType ty = result.type();
-        Symbol *lastVisibleSymbol = result.lastVisibleSymbol();
+        Scope *scope = result.scope();
 
         if (NamedType *namedTy = ty->asNamedType()) {
-            if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), lastVisibleSymbol)) {
+            if (ClassOrNamespace *b = context.classOrNamespace(namedTy->name(), scope)) {
                 completeClass(b, context);
                 break;
             }
@@ -1353,7 +1356,7 @@ bool CppCodeCompletion::completeQtMethod(const QList<LookupItem> &results,
     if (results.isEmpty())
         return false;
 
-    DeprecatedLookupContext context(typeOfExpression.lastVisibleSymbol(),
+    DeprecatedLookupContext context(typeOfExpression.scope()->owner(),
                                     newContext.expressionDocument(),
                                     newContext.thisDocument(),
                                     newContext.snapshot());
@@ -1377,7 +1380,7 @@ bool CppCodeCompletion::completeQtMethod(const QList<LookupItem> &results,
         if (! namedTy) // not a class name.
             continue;
 
-        ClassOrNamespace *b = newContext.classOrNamespace(namedTy->name(), p.lastVisibleSymbol());
+        ClassOrNamespace *b = newContext.classOrNamespace(namedTy->name(), p.scope());
         if (! b)
             continue;