diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index b370faea1bb626a110c666102dbe4e4b7db9eda8..ab38af3772bcf99e78aa923f553987604f07aa88 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -45,6 +45,7 @@
 #include <CoreTypes.h>
 #include <Literals.h>
 #include <Semantic.h>
+#include <SymbolVisitor.h>
 #include <cplusplus/ExpressionUnderCursor.h>
 #include <cplusplus/LookupContext.h>
 #include <cplusplus/Overview.h>
@@ -100,6 +101,44 @@ public:
     }
 };
 
+class FindFunctionDefinitions: protected SymbolVisitor
+{
+    Name *_declarationName;
+    QList<Function *> *_functions;
+
+public:
+    FindFunctionDefinitions()
+        : _declarationName(0),
+          _functions(0)
+    { }
+
+    void operator()(Name *declarationName, Scope *globals,
+                    QList<Function *> *functions)
+    {
+        _declarationName = declarationName;
+        _functions = functions;
+
+        for (unsigned i = 0; i < globals->symbolCount(); ++i) {
+            accept(globals->symbolAt(i));
+        }
+    }
+
+protected:
+    using SymbolVisitor::visit;
+
+    virtual bool visit(Function *function)
+    {
+        Name *name = function->name();
+        if (QualifiedNameId *q = name->asQualifiedNameId())
+            name = q->unqualifiedNameId();
+
+        if (_declarationName->isEqualTo(name))
+            _functions->append(function);
+
+        return false;
+    }
+};
+
 } // end of anonymous namespace
 
 QualifiedNameId *qualifiedNameIdForSymbol(Symbol *s, const LookupContext &context)
@@ -550,58 +589,60 @@ void CPPEditor::jumpToDefinition()
     }
 }
 
-Symbol *CPPEditor::findDefinition(Symbol *lastSymbol)
+Symbol *CPPEditor::findDefinition(Symbol *symbol)
 {
-    // Currently only functions are supported
-    if (!lastSymbol->type()->isFunction())
-        return 0;
+    if (symbol->isFunction())
+        return 0; // symbol is a function definition.
 
-    QVector<Name *> qualifiedName;
-    Scope *scope = lastSymbol->scope();
-    for (; scope; scope = scope->enclosingScope()) {
-        if (scope->isClassScope() || scope->isNamespaceScope()) {
-            if (scope->owner() && scope->owner()->name()) {
-                Name *scopeOwnerName = scope->owner()->name();
-                if (QualifiedNameId *q = scopeOwnerName->asQualifiedNameId()) {
-                    for (unsigned i = 0; i < q->nameCount(); ++i) {
-                        qualifiedName.prepend(q->nameAt(i));
-                    }
-                } else {
-                    qualifiedName.prepend(scopeOwnerName);
-                }
-            }
+    Function *funTy = symbol->type()->asFunction();
+    if (! funTy)
+        return 0; // symbol does not have function type.
+
+    Name *name = symbol->name();
+    if (! name)
+        return 0; // skip anonymous functions!
+
+    if (QualifiedNameId *q = name->asQualifiedNameId())
+        name = q->unqualifiedNameId();
+
+    // map from file names to function definitions.
+    QMap<QString, QList<Function *> > functionDefinitions;
+
+    // find function definitions.
+    FindFunctionDefinitions findFunctionDefinitions;
+
+    // save the current snapshot
+    const Snapshot snapshot = m_modelManager->snapshot();
+
+    foreach (Document::Ptr doc, snapshot) {
+        if (Scope *globals = doc->globalSymbols()) {
+            QList<Function *> *localFunctionDefinitions =
+                    &functionDefinitions[doc->fileName()];
+
+            findFunctionDefinitions(name, globals,
+                                    localFunctionDefinitions);
         }
     }
 
-    qualifiedName.append(lastSymbol->name());
-
-    Control control;
-    QualifiedNameId *q = control.qualifiedNameId(&qualifiedName[0], qualifiedName.size());
-    LookupContext context(&control);
-
-    const Snapshot documents = m_modelManager->snapshot();
-    foreach (Document::Ptr doc, documents) {
-        QList<Scope *> visibleScopes;
-        visibleScopes.append(doc->globalSymbols());
-        visibleScopes = context.expand(visibleScopes);
-        //qDebug() << "** doc:" << doc->fileName() << "visible scopes:" << visibleScopes.count();
-        foreach (Scope *visibleScope, visibleScopes) {
-            Symbol *symbol = 0;
-            if (NameId *nameId = q->unqualifiedNameId()->asNameId())
-                symbol = visibleScope->lookat(nameId->identifier());
-            else if (DestructorNameId *dtorId = q->unqualifiedNameId()->asDestructorNameId())
-                symbol = visibleScope->lookat(dtorId->identifier());
-            else if (TemplateNameId *templNameId = q->unqualifiedNameId()->asTemplateNameId())
-                symbol = visibleScope->lookat(templNameId->identifier());
-            else if (OperatorNameId *opId = q->unqualifiedNameId()->asOperatorNameId())
-                symbol = visibleScope->lookat(opId->kind());
-            // ### cast operators
-            for (; symbol; symbol = symbol->next()) {
-                if (! symbol->isFunction())
-                    continue;
-                else if (! isCompatible(symbol->asFunction(), lastSymbol, q))
-                    continue;
-                return symbol;
+    // a dummy document.
+    Document::Ptr expressionDocument = Document::create("<empty>");
+
+    QMapIterator<QString, QList<Function *> > it(functionDefinitions);
+    while (it.hasNext()) {
+        it.next();
+
+        // get the instance of the document.
+        Document::Ptr thisDocument = snapshot.value(it.key());
+
+        foreach (Function *f, it.value()) {
+            // create a lookup context
+            const LookupContext context(f, expressionDocument,
+                                        thisDocument, snapshot);
+
+            // search the matching definition for the function declaration `symbol'.
+            foreach (Symbol *s, context.resolve(f->name())) {
+                if (s == symbol)
+                    return f;
             }
         }
     }