diff --git a/src/plugins/cppeditor/cppchecksymbols.cpp b/src/plugins/cppeditor/cppchecksymbols.cpp
index 635ddb6285c5da6971667e7b6f979d6b435a1f54..f33c6bdf4677e8d2cc56cbd941a93b0144780219 100644
--- a/src/plugins/cppeditor/cppchecksymbols.cpp
+++ b/src/plugins/cppeditor/cppchecksymbols.cpp
@@ -28,6 +28,8 @@
 **************************************************************************/
 
 #include "cppchecksymbols.h"
+#include "cpplocalsymbols.h"
+
 #include <cplusplus/Overview.h>
 
 #include <Names.h>
@@ -45,6 +47,7 @@
 #include <qtconcurrent/runextensions.h>
 
 using namespace CPlusPlus;
+using namespace CppEditor::Internal;
 
 namespace {
 
@@ -53,6 +56,7 @@ class CollectTypes: protected SymbolVisitor
     Document::Ptr _doc;
     Snapshot _snapshot;
     QSet<QByteArray> _types;
+    QSet<QByteArray> _members;
     QList<ScopedSymbol *> _scopes;
     QList<NameAST *> _names;
     bool _mainDocument;
@@ -70,6 +74,11 @@ public:
         return _types;
     }
 
+    const QSet<QByteArray> &members() const
+    {
+        return _members;
+    }
+
     const QList<ScopedSymbol *> &scopes() const
     {
         return _scopes;
@@ -126,6 +135,18 @@ protected:
         }
     }
 
+    void addMember(const Name *name)
+    {
+        if (! name) {
+            return;
+
+        } else if (name->isNameId()) {
+            const Identifier *id = name->identifier();
+            _members.insert(QByteArray::fromRawData(id->chars(), id->size()));
+
+        }
+    }
+
     void addScope(ScopedSymbol *symbol)
     {
         if (_mainDocument)
@@ -166,6 +187,8 @@ protected:
     {
         if (symbol->isTypedef())
             addType(symbol->name());
+        else if (! symbol->type()->isFunctionType() && symbol->enclosingSymbol()->isClass())
+            addMember(symbol->name());
 
         return true;
     }
@@ -267,6 +290,7 @@ CheckSymbols::CheckSymbols(Document::Ptr doc, const LookupContext &context)
     _fileName = doc->fileName();
     CollectTypes collectTypes(doc, context.snapshot());
     _potentialTypes = collectTypes.types();
+    _potentialMembers = collectTypes.members();
     _scopes = collectTypes.scopes();
     _flushRequested = false;
     _flushLine = 0;
@@ -351,6 +375,12 @@ bool CheckSymbols::visit(NamedTypeSpecifierAST *)
     return true;
 }
 
+bool CheckSymbols::visit(MemberAccessAST *ast)
+{
+    accept(ast->base_expression);
+    return false;
+}
+
 void CheckSymbols::checkNamespace(NameAST *name)
 {
     if (! name)
@@ -380,6 +410,28 @@ void CheckSymbols::checkName(NameAST *ast)
                 Scope *scope = findScope(ast);
                 const QList<Symbol *> candidates = _context.lookup(ast->name, scope);
                 addTypeUsage(candidates, ast);
+            } else if (_potentialMembers.contains(id)) {
+                Scope *scope = findScope(ast);
+                const QList<Symbol *> candidates = _context.lookup(ast->name, scope);
+                addMemberUsage(candidates, ast);
+            }
+        }
+    }
+}
+
+void CheckSymbols::checkMemberName(NameAST *ast)
+{
+    if (ast && ast->name) {
+        if (const Identifier *ident = ast->name->identifier()) {
+            const QByteArray id = QByteArray::fromRawData(ident->chars(), ident->size());
+            if (_potentialMembers.contains(id)) {
+                Scope *scope = findScope(ast);
+                const QList<Symbol *> candidates = _context.lookup(ast->name, scope);
+                addMemberUsage(candidates, ast);
+            } else if (_potentialMembers.contains(id)) {
+                Scope *scope = findScope(ast);
+                const QList<Symbol *> candidates = _context.lookup(ast->name, scope);
+                addMemberUsage(candidates, ast);
             }
         }
     }
@@ -473,14 +525,35 @@ void CheckSymbols::endVisit(TemplateDeclarationAST *)
     _templateDeclarationStack.takeFirst();
 }
 
+bool CheckSymbols::visit(FunctionDefinitionAST *ast)
+{
+    _functionDefinitionStack.append(ast);
+    const LocalSymbols locals(_doc, ast);
+    QList<SemanticInfo::Use> uses;
+    foreach (uses, locals.uses) {
+        foreach (const SemanticInfo::Use &u, uses)
+            addTypeUsage(u);
+    }
+
+    accept(ast->decl_specifier_list);
+    accept(ast->declarator);
+    accept(ast->ctor_initializer);
+    accept(ast->function_body);
+
+    _functionDefinitionStack.removeLast();
+    return false;
+}
+
 void CheckSymbols::addTypeUsage(const Use &use)
 {
-    if (_typeUsages.size() >= 50) {
-        if (_flushRequested && use.line != _flushLine)
-            flush();
-        else if (! _flushRequested) {
-            _flushRequested = true;
-            _flushLine = use.line;
+    if (_functionDefinitionStack.isEmpty()) {
+        if (_typeUsages.size() >= 50) {
+            if (_flushRequested && use.line != _flushLine)
+                flush();
+            else if (! _flushRequested) {
+                _flushRequested = true;
+                _flushLine = use.line;
+            }
         }
     }
 
@@ -538,6 +611,36 @@ void CheckSymbols::addTypeUsage(const QList<Symbol *> &candidates, NameAST *ast)
     }
 }
 
+void CheckSymbols::addMemberUsage(const QList<Symbol *> &candidates, NameAST *ast)
+{
+    unsigned startToken = ast->firstToken();
+    if (DestructorNameAST *dtor = ast->asDestructorName())
+        startToken = dtor->identifier_token;
+
+    const Token &tok = tokenAt(startToken);
+    if (tok.generated())
+        return;
+
+    unsigned line, column;
+    getTokenStartPosition(startToken, &line, &column);
+    const unsigned length = tok.length();
+
+    foreach (Symbol *c, candidates) {
+        if (! c->isDeclaration())
+            continue;
+        else if (c->isTypedef())
+            continue;
+        else if (c->type()->isFunctionType())
+            continue;
+        else if (! c->enclosingSymbol()->isClass())
+            continue;
+
+        const Use use(line, column, length, Use::Field);
+        addTypeUsage(use);
+        //qDebug() << "added use" << oo(ast->name) << line << column << length;
+    }
+}
+
 unsigned CheckSymbols::startOfTemplateDeclaration(TemplateDeclarationAST *ast) const
 {
     if (ast->declaration) {
diff --git a/src/plugins/cppeditor/cppchecksymbols.h b/src/plugins/cppeditor/cppchecksymbols.h
index 876132ab3f42adb5357b0799269602cdf36ff0d1..bb996fb691d9cc2ee0f7e5347e3a215e865cac7a 100644
--- a/src/plugins/cppeditor/cppchecksymbols.h
+++ b/src/plugins/cppeditor/cppchecksymbols.h
@@ -87,6 +87,9 @@ protected:
     void addTypeUsage(const QList<Symbol *> &candidates, NameAST *ast);
     void addTypeUsage(const Use &use);
 
+    void checkMemberName(NameAST *ast);
+    void addMemberUsage(const QList<Symbol *> &candidates, NameAST *ast);
+
     virtual bool preVisit(AST *);
 
     virtual bool visit(NamespaceAST *);
@@ -105,6 +108,9 @@ protected:
     virtual bool visit(TypenameTypeParameterAST *ast);
     virtual bool visit(TemplateTypeParameterAST *ast);
 
+    virtual bool visit(FunctionDefinitionAST *ast);
+    virtual bool visit(MemberAccessAST *ast);
+
     unsigned startOfTemplateDeclaration(TemplateDeclarationAST *ast) const;
     Scope *findScope(AST *ast) const;
 
@@ -116,8 +122,10 @@ private:
     QString _fileName;
     QList<Document::DiagnosticMessage> _diagnosticMessages;
     QSet<QByteArray> _potentialTypes;
+    QSet<QByteArray> _potentialMembers;
     QList<ScopedSymbol *> _scopes;
     QList<TemplateDeclarationAST *> _templateDeclarationStack;
+    QList<FunctionDefinitionAST *> _functionDefinitionStack;
     QVector<Use> _typeUsages;
     bool _flushRequested;
     unsigned _flushLine;
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index adef080f35ffa6e0f388c33f00abf06010479956..034e17831237f8cac77b40c1d60cab01279b7a0a 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -33,6 +33,7 @@
 #include "cpphighlighter.h"
 #include "cppchecksymbols.h"
 #include "cppquickfix.h"
+#include "cpplocalsymbols.h"
 
 #include <AST.h>
 #include <Control.h>
@@ -172,240 +173,6 @@ private:
     CPlusPlus::OverviewModel *m_sourceModel;
 };
 
-
-class FindLocalUses: protected ASTVisitor
-{
-    Scope *_functionScope;
-    Document::Ptr _doc;
-
-public:
-    FindLocalUses(Document::Ptr doc)
-        : ASTVisitor(doc->translationUnit()), _doc(doc), hasD(false), hasQ(false)
-    { }
-
-    // local and external uses.
-    SemanticInfo::LocalUseMap localUses;
-    bool hasD;
-    bool hasQ;
-
-    void operator()(DeclarationAST *ast)
-    {
-        localUses.clear();
-
-        if (!ast)
-            return;
-
-        if (FunctionDefinitionAST *def = ast->asFunctionDefinition()) {
-            if (def->symbol) {
-                _functionScope = def->symbol->members();
-                accept(ast);
-            }
-        } else if (ObjCMethodDeclarationAST *decl = ast->asObjCMethodDeclaration()) {
-            if (decl->method_prototype->symbol) {
-                _functionScope = decl->method_prototype->symbol->members();
-                accept(ast);
-            }
-        }
-    }
-
-protected:
-    using ASTVisitor::visit;
-
-    bool findMember(Scope *scope, NameAST *ast, unsigned line, unsigned column)
-    {
-        if (! (ast && ast->name))
-            return false;
-
-        const Identifier *id = ast->name->identifier();
-
-        if (scope) {
-            for (Symbol *member = scope->lookat(id); member; member = member->next()) {
-                if (member->identifier() != id)
-                    continue;
-                else if (member->line() < line || (member->line() == line && member->column() <= column)) {
-                    localUses[member].append(SemanticInfo::Use(line, column, id->size()));
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    void searchUsesInTemplateArguments(NameAST *name)
-    {
-        if (! name)
-            return;
-
-        else if (TemplateIdAST *template_id = name->asTemplateId()) {
-            for (TemplateArgumentListAST *it = template_id->template_argument_list; it; it = it->next) {
-                accept(it->value);
-            }
-        }
-    }
-
-    virtual bool visit(SimpleNameAST *ast)
-    { return findMemberForToken(ast->firstToken(), ast); }
-
-    bool findMemberForToken(unsigned tokenIdx, NameAST *ast)
-    {
-        const Token &tok = tokenAt(tokenIdx);
-        if (tok.generated())
-            return false;
-
-        unsigned line, column;
-        getTokenStartPosition(tokenIdx, &line, &column);
-
-        Scope *scope = _doc->scopeAt(line, column);
-
-        while (scope) {
-            if (scope->isFunctionScope()) {
-                Function *fun = scope->owner()->asFunction();
-                if (findMember(fun->members(), ast, line, column))
-                    return false;
-                else if (findMember(fun->arguments(), ast, line, column))
-                    return false;
-            } else if (scope->isObjCMethodScope()) {
-                ObjCMethod *method = scope->owner()->asObjCMethod();
-                if (findMember(method->members(), ast, line, column))
-                    return false;
-                else if (findMember(method->arguments(), ast, line, column))
-                    return false;
-            } else if (scope->isBlockScope()) {
-                if (findMember(scope, ast, line, column))
-                    return false;
-            } else {
-                break;
-            }
-
-            scope = scope->enclosingScope();
-        }
-
-        return false;
-    }
-
-    virtual bool visit(TemplateIdAST *ast)
-    {
-        for (TemplateArgumentListAST *arg = ast->template_argument_list; arg; arg = arg->next)
-            accept(arg->value);
-
-        const Token &tok = tokenAt(ast->identifier_token);
-        if (tok.generated())
-            return false;
-
-        unsigned line, column;
-        getTokenStartPosition(ast->firstToken(), &line, &column);
-
-        Scope *scope = _doc->scopeAt(line, column);
-
-        while (scope) {
-            if (scope->isFunctionScope()) {
-                Function *fun = scope->owner()->asFunction();
-                if (findMember(fun->members(), ast, line, column))
-                    return false;
-                else if (findMember(fun->arguments(), ast, line, column))
-                    return false;
-            } else if (scope->isBlockScope()) {
-                if (findMember(scope, ast, line, column))
-                    return false;
-            } else {
-                break;
-            }
-
-            scope = scope->enclosingScope();
-        }
-
-        return false;
-    }
-
-    virtual bool visit(QualifiedNameAST *ast)
-    {
-        for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next)
-            searchUsesInTemplateArguments(it->value->class_or_namespace_name);
-
-        searchUsesInTemplateArguments(ast->unqualified_name);
-        return false;
-    }
-
-    virtual bool visit(MemberAccessAST *ast)
-    {
-        // accept only the base expression
-        accept(ast->base_expression);
-        // and ignore the member name.
-        return false;
-    }
-
-    virtual bool visit(ElaboratedTypeSpecifierAST *)
-    {
-        // ### template args
-        return false;
-    }
-
-    virtual bool visit(ClassSpecifierAST *)
-    {
-        // ### template args
-        return false;
-    }
-
-    virtual bool visit(EnumSpecifierAST *)
-    {
-        // ### template args
-        return false;
-    }
-
-    virtual bool visit(UsingDirectiveAST *)
-    {
-        return false;
-    }
-
-    virtual bool visit(UsingAST *ast)
-    {
-        accept(ast->name);
-        return false;
-    }
-
-    virtual bool visit(QtMemberDeclarationAST *ast)
-    {
-        if (tokenKind(ast->q_token) == T_Q_D)
-            hasD = true;
-        else
-            hasQ = true;
-
-        return true;
-    }
-
-    virtual bool visit(ExpressionOrDeclarationStatementAST *ast)
-    {
-        accept(ast->declaration);
-        return false;
-    }
-
-    virtual bool visit(FunctionDeclaratorAST *ast)
-    {
-        accept(ast->parameters);
-
-        for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next)
-            accept(it->value);
-
-        accept(ast->exception_specification);
-
-        return false;
-    }
-
-    virtual bool visit(ObjCMethodPrototypeAST *ast)
-    {
-        accept(ast->argument_list);
-        return false;
-    }
-
-    virtual bool visit(ObjCMessageArgumentDeclarationAST *ast)
-    {
-        accept(ast->param_name);
-        return false;
-    }
-};
-
-
 class FunctionDefinitionUnderCursor: protected ASTVisitor
 {
     unsigned _line;
@@ -1131,6 +898,12 @@ void CPPEditor::highlightTypeUsages(int from, int to)
     Q_ASSERT(!chunks.isEmpty());
     QTextBlock b = doc->findBlockByNumber(m_nextHighlightBlockNumber);
 
+    QTextCharFormat localUseFormat;
+    localUseFormat.setForeground(Qt::darkBlue); // ### hardcoded
+
+    QTextCharFormat memberUseFormat;
+    memberUseFormat.setForeground(Qt::darkRed); // ### hardcoded
+
     QMapIterator<int, QVector<SemanticInfo::Use> > it(chunks);
     while (b.isValid() && it.hasNext()) {
         it.next();
@@ -1146,7 +919,24 @@ void CPPEditor::highlightTypeUsages(int from, int to)
         QList<QTextLayout::FormatRange> formats;
         foreach (const SemanticInfo::Use &use, it.value()) {
             QTextLayout::FormatRange formatRange;
-            formatRange.format = m_typeFormat;
+
+            switch (use.kind) {
+            case SemanticInfo::Use::Type:
+                formatRange.format = m_typeFormat;
+                break;
+
+            case SemanticInfo::Use::Field:
+                formatRange.format = memberUseFormat;
+                break;
+
+            case SemanticInfo::Use::Local:
+                formatRange.format = localUseFormat;
+                break;
+
+            default:
+                continue;
+            }
+
             formatRange.start = use.column - 1;
             formatRange.length = use.length;
             formats.append(formatRange);
@@ -2187,8 +1977,7 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source)
     Snapshot snapshot;
     Document::Ptr doc;
     QList<Document::DiagnosticMessage> diagnosticMessages;
-    QList<SemanticInfo::Use> typeUsages, objcKeywords;
-    LookupContext context;
+    QList<SemanticInfo::Use> objcKeywords;
 
     if (! source.force && revision == source.revision) {
         m_mutex.lock();
@@ -2207,13 +1996,7 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source)
         doc->check();
 
 #if 0
-        context = LookupContext(doc, snapshot);
-
         if (TranslationUnit *unit = doc->translationUnit()) {
-            CheckUndefinedSymbols checkUndefinedSymbols(unit, context);
-            diagnosticMessages = checkUndefinedSymbols(unit->ast());
-            typeUsages = checkUndefinedSymbols.typeUsages();
-
             FindObjCKeywords findObjCKeywords(unit); // ### remove me
             objcKeywords = findObjCKeywords();
         }
@@ -2226,14 +2009,13 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source)
     FunctionDefinitionUnderCursor functionDefinitionUnderCursor(translationUnit);
     DeclarationAST *currentFunctionDefinition = functionDefinitionUnderCursor(ast, source.line, source.column);
 
-    FindLocalUses useTable(doc);
-    useTable(currentFunctionDefinition);
+    const LocalSymbols useTable(doc, currentFunctionDefinition);
 
     SemanticInfo semanticInfo;
     semanticInfo.revision = source.revision;
     semanticInfo.snapshot = snapshot;
     semanticInfo.doc = doc;
-    semanticInfo.localUses = useTable.localUses;
+    semanticInfo.localUses = useTable.uses;
     semanticInfo.hasQ = useTable.hasQ;
     semanticInfo.hasD = useTable.hasD;
     semanticInfo.forced = source.force;
diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro
index 4b017f64fee12ef67cab8aca3d73cf7d550932ea..274639f4141756b2bc76a6c263f93b6a736f0079 100644
--- a/src/plugins/cppeditor/cppeditor.pro
+++ b/src/plugins/cppeditor/cppeditor.pro
@@ -20,7 +20,8 @@ HEADERS += cppplugin.h \
     cppchecksymbols.h \
     cppsemanticinfo.h \
     cppoutline.h \
-    cppdeclfromdef.h
+    cppdeclfromdef.h \
+    cpplocalsymbols.h
 
 SOURCES += cppplugin.cpp \
     cppeditor.cpp \
@@ -33,7 +34,8 @@ SOURCES += cppplugin.cpp \
     cppchecksymbols.cpp \
     cppsemanticinfo.cpp \
     cppoutline.cpp \
-    cppdeclfromdef.cpp
+    cppdeclfromdef.cpp \
+    cpplocalsymbols.cpp
 
 RESOURCES += cppeditor.qrc
 
diff --git a/src/plugins/cppeditor/cpplocalsymbols.cpp b/src/plugins/cppeditor/cpplocalsymbols.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1f5e9f4300b2f5ce0716df4208bd6ca93b7fc74d
--- /dev/null
+++ b/src/plugins/cppeditor/cpplocalsymbols.cpp
@@ -0,0 +1,289 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "cpplocalsymbols.h"
+#include "cppsemanticinfo.h"
+
+#include <cplusplus/CppDocument.h>
+#include <ASTVisitor.h>
+#include <AST.h>
+#include <Scope.h>
+#include <Symbols.h>
+#include <CoreTypes.h>
+#include <Names.h>
+#include <Literals.h>
+
+using namespace CPlusPlus;
+using namespace CppEditor::Internal;
+
+namespace {
+
+class FindLocalSymbols: protected ASTVisitor
+{
+    Scope *_functionScope;
+    Document::Ptr _doc;
+
+public:
+    FindLocalSymbols(Document::Ptr doc)
+        : ASTVisitor(doc->translationUnit()), _doc(doc), hasD(false), hasQ(false)
+    { }
+
+    // local and external uses.
+    SemanticInfo::LocalUseMap localUses;
+    bool hasD;
+    bool hasQ;
+
+    void operator()(DeclarationAST *ast)
+    {
+        localUses.clear();
+
+        if (!ast)
+            return;
+
+        if (FunctionDefinitionAST *def = ast->asFunctionDefinition()) {
+            if (def->symbol) {
+                _functionScope = def->symbol->members();
+                accept(ast);
+            }
+        } else if (ObjCMethodDeclarationAST *decl = ast->asObjCMethodDeclaration()) {
+            if (decl->method_prototype->symbol) {
+                _functionScope = decl->method_prototype->symbol->members();
+                accept(ast);
+            }
+        }
+    }
+
+protected:
+    using ASTVisitor::visit;
+
+    bool findMember(Scope *scope, NameAST *ast, unsigned line, unsigned column)
+    {
+        if (! (ast && ast->name))
+            return false;
+
+        const Identifier *id = ast->name->identifier();
+
+        if (scope) {
+            for (Symbol *member = scope->lookat(id); member; member = member->next()) {
+                if (member->identifier() != id)
+                    continue;
+                else if (member->line() < line || (member->line() == line && member->column() <= column)) {
+                    localUses[member].append(SemanticInfo::Use(line, column, id->size(), SemanticInfo::Use::Local));
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    void searchUsesInTemplateArguments(NameAST *name)
+    {
+        if (! name)
+            return;
+
+        else if (TemplateIdAST *template_id = name->asTemplateId()) {
+            for (TemplateArgumentListAST *it = template_id->template_argument_list; it; it = it->next) {
+                accept(it->value);
+            }
+        }
+    }
+
+    virtual bool visit(SimpleNameAST *ast)
+    { return findMemberForToken(ast->firstToken(), ast); }
+
+    bool findMemberForToken(unsigned tokenIdx, NameAST *ast)
+    {
+        const Token &tok = tokenAt(tokenIdx);
+        if (tok.generated())
+            return false;
+
+        unsigned line, column;
+        getTokenStartPosition(tokenIdx, &line, &column);
+
+        Scope *scope = _doc->scopeAt(line, column);
+
+        while (scope) {
+            if (scope->isFunctionScope()) {
+                Function *fun = scope->owner()->asFunction();
+                if (findMember(fun->members(), ast, line, column))
+                    return false;
+                else if (findMember(fun->arguments(), ast, line, column))
+                    return false;
+            } else if (scope->isObjCMethodScope()) {
+                ObjCMethod *method = scope->owner()->asObjCMethod();
+                if (findMember(method->members(), ast, line, column))
+                    return false;
+                else if (findMember(method->arguments(), ast, line, column))
+                    return false;
+            } else if (scope->isBlockScope()) {
+                if (findMember(scope, ast, line, column))
+                    return false;
+            } else {
+                break;
+            }
+
+            scope = scope->enclosingScope();
+        }
+
+        return false;
+    }
+
+    virtual bool visit(TemplateIdAST *ast)
+    {
+        for (TemplateArgumentListAST *arg = ast->template_argument_list; arg; arg = arg->next)
+            accept(arg->value);
+
+        const Token &tok = tokenAt(ast->identifier_token);
+        if (tok.generated())
+            return false;
+
+        unsigned line, column;
+        getTokenStartPosition(ast->firstToken(), &line, &column);
+
+        Scope *scope = _doc->scopeAt(line, column);
+
+        while (scope) {
+            if (scope->isFunctionScope()) {
+                Function *fun = scope->owner()->asFunction();
+                if (findMember(fun->members(), ast, line, column))
+                    return false;
+                else if (findMember(fun->arguments(), ast, line, column))
+                    return false;
+            } else if (scope->isBlockScope()) {
+                if (findMember(scope, ast, line, column))
+                    return false;
+            } else {
+                break;
+            }
+
+            scope = scope->enclosingScope();
+        }
+
+        return false;
+    }
+
+    virtual bool visit(QualifiedNameAST *ast)
+    {
+        for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next)
+            searchUsesInTemplateArguments(it->value->class_or_namespace_name);
+
+        searchUsesInTemplateArguments(ast->unqualified_name);
+        return false;
+    }
+
+    virtual bool visit(MemberAccessAST *ast)
+    {
+        // accept only the base expression
+        accept(ast->base_expression);
+        // and ignore the member name.
+        return false;
+    }
+
+    virtual bool visit(ElaboratedTypeSpecifierAST *)
+    {
+        // ### template args
+        return false;
+    }
+
+    virtual bool visit(ClassSpecifierAST *)
+    {
+        // ### template args
+        return false;
+    }
+
+    virtual bool visit(EnumSpecifierAST *)
+    {
+        // ### template args
+        return false;
+    }
+
+    virtual bool visit(UsingDirectiveAST *)
+    {
+        return false;
+    }
+
+    virtual bool visit(UsingAST *ast)
+    {
+        accept(ast->name);
+        return false;
+    }
+
+    virtual bool visit(QtMemberDeclarationAST *ast)
+    {
+        if (tokenKind(ast->q_token) == T_Q_D)
+            hasD = true;
+        else
+            hasQ = true;
+
+        return true;
+    }
+
+    virtual bool visit(ExpressionOrDeclarationStatementAST *ast)
+    {
+        accept(ast->declaration);
+        return false;
+    }
+
+    virtual bool visit(FunctionDeclaratorAST *ast)
+    {
+        accept(ast->parameters);
+
+        for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next)
+            accept(it->value);
+
+        accept(ast->exception_specification);
+
+        return false;
+    }
+
+    virtual bool visit(ObjCMethodPrototypeAST *ast)
+    {
+        accept(ast->argument_list);
+        return false;
+    }
+
+    virtual bool visit(ObjCMessageArgumentDeclarationAST *ast)
+    {
+        accept(ast->param_name);
+        return false;
+    }
+};
+
+} // end of anonymous namespace
+
+
+LocalSymbols::LocalSymbols(CPlusPlus::Document::Ptr doc, CPlusPlus::DeclarationAST *ast)
+{
+    FindLocalSymbols FindLocalSymbols(doc);
+    FindLocalSymbols(ast);
+    hasD = FindLocalSymbols.hasD;
+    hasQ = FindLocalSymbols.hasQ;
+    uses = FindLocalSymbols.localUses;
+}
diff --git a/src/plugins/cppeditor/cpplocalsymbols.h b/src/plugins/cppeditor/cpplocalsymbols.h
new file mode 100644
index 0000000000000000000000000000000000000000..42f3a2fb0a428d1bc2bfcb5b068d240ed0975b16
--- /dev/null
+++ b/src/plugins/cppeditor/cpplocalsymbols.h
@@ -0,0 +1,56 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef CPPLOCALSYMBOLS_H
+#define CPPLOCALSYMBOLS_H
+
+#include "cppsemanticinfo.h"
+#include <cplusplus/CppDocument.h>
+#include <ASTfwd.h>
+
+namespace CppEditor {
+namespace Internal {
+
+class LocalSymbols
+{
+    Q_DISABLE_COPY(LocalSymbols)
+
+public:
+    LocalSymbols(CPlusPlus::Document::Ptr doc, CPlusPlus::DeclarationAST *ast);
+
+    bool hasD;
+    bool hasQ;
+    SemanticInfo::LocalUseMap uses;
+};
+
+}
+
+}
+
+#endif // CPPLOCALSYMBOLS_H
diff --git a/src/plugins/cppeditor/cppsemanticinfo.h b/src/plugins/cppeditor/cppsemanticinfo.h
index 7f374c8ffd703c3731977cdf787269df36e8829b..3ea662bdbbe3049a054e864bc61aa4729574bf0c 100644
--- a/src/plugins/cppeditor/cppsemanticinfo.h
+++ b/src/plugins/cppeditor/cppsemanticinfo.h
@@ -46,9 +46,16 @@ public:
         unsigned line;
         unsigned column;
         unsigned length;
+        unsigned kind;
 
-        Use(unsigned line = 0, unsigned column = 0, unsigned length = 0)
-            : line(line), column(column), length(length) {}
+        enum {
+            Type = 0,
+            Local,
+            Field
+        };
+
+        Use(unsigned line = 0, unsigned column = 0, unsigned length = 0, unsigned kind = Type)
+            : line(line), column(column), length(length), kind(kind) {}
     };
 
     typedef QHash<CPlusPlus::Symbol *, QList<Use> > LocalUseMap;