diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index e9d25f2e2380c5956d16d64817b324cc07d0d0b5..07529dfe836d786603ed93e8779954f469b0e162 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -420,7 +420,7 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent)
     , m_firstRenameChange(false)
     , m_objcEnabled(false)
     , m_commentsSettings(CppTools::CppToolsSettings::instance()->commentsSettings())
-    , m_symbolFinder(new CppTools::SymbolFinder(QString()))
+    , m_symbolFinder(new CppTools::SymbolFinder)
 {
     m_initialized = false;
     qRegisterMetaType<CppEditor::Internal::SemanticInfo>("CppEditor::Internal::SemanticInfo");
@@ -864,9 +864,7 @@ void CPPEditorWidget::onContentsChanged(int position, int charsRemoved, int char
 }
 
 void CPPEditorWidget::updateFileName()
-{
-    m_symbolFinder.reset(new CppTools::SymbolFinder(file()->fileName()));
-}
+{}
 
 void CPPEditorWidget::jumpToOutlineElement(int)
 {
@@ -2258,9 +2256,9 @@ void CPPEditorWidget::applyDeclDefLinkChanges(bool jumpToMatch)
     updateFunctionDeclDefLink();
 }
 
-CppTools::SymbolFinder *CPPEditorWidget::symbolFinder() const
+QSharedPointer<CppTools::SymbolFinder> CPPEditorWidget::symbolFinder() const
 {
-    return m_symbolFinder.data();
+    return m_symbolFinder;
 }
 
 void CPPEditorWidget::abortDeclDefLink()
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index eb55422bcbf4ab18e87825c2c2185d1acc2eeb3b..0104406002e9df4550f769399b6f8459e66e74dd 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -50,7 +50,6 @@
 #include <QtCore/QFutureWatcher>
 #include <QtCore/QModelIndex>
 #include <QtCore/QVector>
-#include <QtCore/QScopedPointer>
 
 QT_BEGIN_NAMESPACE
 class QComboBox;
@@ -202,7 +201,7 @@ public:
     QSharedPointer<FunctionDeclDefLink> declDefLink() const;
     void applyDeclDefLinkChanges(bool jumpToMatch);
 
-    CppTools::SymbolFinder *symbolFinder() const;
+    QSharedPointer<CppTools::SymbolFinder> symbolFinder() const;
 
 Q_SIGNALS:
     void outlineModelIndexChanged(const QModelIndex &index);
@@ -337,7 +336,7 @@ private:
     QSharedPointer<FunctionDeclDefLink> m_declDefLink;
 
     CppTools::CommentsSettings m_commentsSettings;
-    QScopedPointer<CppTools::SymbolFinder> m_symbolFinder;
+    QSharedPointer<CppTools::SymbolFinder> m_symbolFinder;
 };
 
 
diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
index ee9bcb1fffdc5b3e29ce1c132e01606c7b77818c..a71cbe888e9be779322a19828c2c082a5b13c6fa 100644
--- a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
+++ b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp
@@ -164,17 +164,15 @@ static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<Functio
 
     // find the matching decl/def symbol
     Symbol *target = 0;
+    CppTools::SymbolFinder finder;
     if (FunctionDefinitionAST *funcDef = link->sourceDeclaration->asFunctionDefinition()) {
         QList<Declaration *> nameMatch, argumentCountMatch, typeMatch;
-        CppTools::SymbolFinder finder(funcDef->symbol->fileName(), funcDef->symbol->fileNameLength());
         finder.findMatchingDeclaration(LookupContext(link->sourceDocument, snapshot),
                                        funcDef->symbol,
                                        &typeMatch, &argumentCountMatch, &nameMatch);
         if (!typeMatch.isEmpty())
             target = typeMatch.first();
     } else if (link->sourceDeclaration->asSimpleDeclaration()) {
-        CppTools::SymbolFinder finder(link->sourceFunctionDeclarator->symbol->fileName(),
-                                      link->sourceFunctionDeclarator->symbol->fileNameLength());
         target = finder.findMatchingDefinition(link->sourceFunctionDeclarator->symbol, snapshot, true);
     }
     if (!target) {
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index 113583e52253228654574fc30ab1d1a32aa0bd0f..a75ef11f16ae33c5a323c513b0917bfb47188dfc 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -1553,7 +1553,7 @@ private:
         {
             Q_ASSERT(fwdClass != 0);
 
-            CppTools::SymbolFinder symbolFinder(fwdClass->fileName(), fwdClass->fileNameLength());
+            CppTools::SymbolFinder symbolFinder;
             if (Class *k =
                     symbolFinder.findMatchingClassDeclaration(fwdClass,
                                                               assistInterface()->snapshot())) {
diff --git a/src/plugins/cpptools/insertionpointlocator.cpp b/src/plugins/cpptools/insertionpointlocator.cpp
index baecd498c1f03fdb10087866b589a0036ac1cfe7..64ccb8ed4c6f77416bd01d96f2208b49a16775b4 100644
--- a/src/plugins/cpptools/insertionpointlocator.cpp
+++ b/src/plugins/cpptools/insertionpointlocator.cpp
@@ -517,8 +517,7 @@ static InsertionLocation nextToSurroundingDefinitions(Declaration *declaration,
     }
 
     // find the declaration's definition
-    CppTools::SymbolFinder symbolFinder(surroundingFunctionDecl->fileName(),
-                                        surroundingFunctionDecl->fileNameLength());
+    CppTools::SymbolFinder symbolFinder;
     Symbol *definition = symbolFinder.findMatchingDefinition(surroundingFunctionDecl,
                                                              changes.snapshot());
     if (!definition)
@@ -559,7 +558,7 @@ QList<InsertionLocation> InsertionPointLocator::methodDefinition(
     if (!declaration)
         return result;
 
-    CppTools::SymbolFinder symbolFinder(declaration->fileName(), declaration->fileNameLength());
+    CppTools::SymbolFinder symbolFinder;
     if (Symbol *s = symbolFinder.findMatchingDefinition(declaration,
                                                         m_refactoringChanges.snapshot(),
                                                         true)) {
diff --git a/src/plugins/cpptools/symbolfinder.cpp b/src/plugins/cpptools/symbolfinder.cpp
index bb7a795817204813e5ce08ed42215a13013d27e8..2f1751f52be62d3c2ce4b08211bddc7a04886bdf 100644
--- a/src/plugins/cpptools/symbolfinder.cpp
+++ b/src/plugins/cpptools/symbolfinder.cpp
@@ -63,13 +63,9 @@ public:
 
 } // end of anonymous namespace
 
+static const int kMaxSize = 2;
 
-SymbolFinder::SymbolFinder(const QString &referenceFileName)
-    : m_referenceFile(referenceFileName)
-{}
-
-SymbolFinder::SymbolFinder(const char *referenceFileName, unsigned referenceFileLength)
-    : m_referenceFile(QString::fromUtf8(referenceFileName, referenceFileLength))
+SymbolFinder::SymbolFinder()
 {}
 
 // strict means the returned symbol has to match exactly,
@@ -82,7 +78,6 @@ Symbol *SymbolFinder::findMatchingDefinition(Symbol *declaration,
         return 0;
 
     QString declFile = QString::fromUtf8(declaration->fileName(), declaration->fileNameLength());
-    Q_ASSERT(declFile == m_referenceFile);
 
     Document::Ptr thisDocument = snapshot.document(declFile);
     if (! thisDocument) {
@@ -97,10 +92,10 @@ Symbol *SymbolFinder::findMatchingDefinition(Symbol *declaration,
         return 0;
     }
 
-    foreach (const QString &fileName, fileIterationOrder(snapshot)) {
+    foreach (const QString &fileName, fileIterationOrder(declFile, snapshot)) {
         Document::Ptr doc = snapshot.document(fileName);
         if (!doc) {
-            clear(fileName);
+            clearCache(declFile, fileName);
             continue;
         }
 
@@ -187,12 +182,11 @@ Class *SymbolFinder::findMatchingClassDeclaration(Symbol *declaration, const Sna
         return 0;
 
     QString declFile = QString::fromUtf8(declaration->fileName(), declaration->fileNameLength());
-    Q_ASSERT(declFile == m_referenceFile);
 
-    foreach (const QString &file, fileIterationOrder(snapshot)) {
+    foreach (const QString &file, fileIterationOrder(declFile, snapshot)) {
         Document::Ptr doc = snapshot.document(file);
         if (!doc) {
-            clear(file);
+            clearCache(declFile, file);
             continue;
         }
 
@@ -289,41 +283,63 @@ QList<Declaration *> SymbolFinder::findMatchingDeclaration(const LookupContext &
     return result;
 }
 
-#include <QtCore/QThread>
-QStringList SymbolFinder::fileIterationOrder(const Snapshot &snapshot)
+QStringList SymbolFinder::fileIterationOrder(const QString &referenceFile, const Snapshot &snapshot)
 {
-    if (m_filePriorityCache.isEmpty()) {
-        foreach (const Document::Ptr &doc, snapshot)
-            insert(doc->fileName());
+    if (m_filePriorityCache.contains(referenceFile)) {
+        checkCacheConsistency(referenceFile, snapshot);
     } else {
-        checkCacheConsistency(snapshot);
+        foreach (Document::Ptr doc, snapshot)
+            insertCache(referenceFile, doc->fileName());
     }
 
-    return m_filePriorityCache.values();
+    trackCacheUse(referenceFile);
+
+    return m_filePriorityCache.value(referenceFile).values();
 }
 
-void SymbolFinder::checkCacheConsistency(const Snapshot &snapshot)
+void SymbolFinder::checkCacheConsistency(const QString &referenceFile, const Snapshot &snapshot)
 {
     // We only check for "new" files, which which are in the snapshot but not in the cache.
     // The counterpart validation for "old" files is done when one tries to access the
     // corresponding document and notices it's now null.
+    const QSet<QString> &meta = m_fileMetaCache.value(referenceFile);
     foreach (const Document::Ptr &doc, snapshot) {
-        if (!m_fileMetaCache.contains(doc->fileName()))
-            insert(doc->fileName());
+        if (!meta.contains(doc->fileName()))
+            insertCache(referenceFile, doc->fileName());
     }
 }
 
-void SymbolFinder::clear(const QString &comparingFile)
+void SymbolFinder::clearCache(const QString &referenceFile, const QString &comparingFile)
 {
-    m_filePriorityCache.remove(computeKey(m_referenceFile, comparingFile), comparingFile);
-    m_fileMetaCache.remove(comparingFile);
+    m_filePriorityCache[referenceFile].remove(computeKey(referenceFile, comparingFile),
+                                              comparingFile);
+    m_fileMetaCache[referenceFile].remove(comparingFile);
 }
 
-void SymbolFinder::insert(const QString &comparingFile)
+void SymbolFinder::insertCache(const QString &referenceFile, const QString &comparingFile)
 {
     // We want an ordering such that the documents with the most common path appear first.
-    m_filePriorityCache.insert(computeKey(m_referenceFile, comparingFile), comparingFile);
-    m_fileMetaCache.insert(comparingFile);
+    m_filePriorityCache[referenceFile].insert(computeKey(referenceFile, comparingFile),
+                                              comparingFile);
+    m_fileMetaCache[referenceFile].insert(comparingFile);
+}
+
+void SymbolFinder::trackCacheUse(const QString &referenceFile)
+{
+    if (!m_recent.isEmpty()) {
+        if (m_recent.last() == referenceFile)
+            return;
+        m_recent.removeOne(referenceFile);
+    }
+
+    m_recent.append(referenceFile);
+
+    // We don't want this to grow too much.
+    if (m_recent.size() > kMaxSize) {
+        const QString &oldest = m_recent.front();
+        m_filePriorityCache.remove(oldest);
+        m_fileMetaCache.remove(oldest);
+    }
 }
 
 int SymbolFinder::computeKey(const QString &referenceFile, const QString &comparingFile)
diff --git a/src/plugins/cpptools/symbolfinder.h b/src/plugins/cpptools/symbolfinder.h
index dae042920783a0afeadc1d934de6b9d532f92dac..23310c399b1c156dcf53157b73338b5c3a3e7b21 100644
--- a/src/plugins/cpptools/symbolfinder.h
+++ b/src/plugins/cpptools/symbolfinder.h
@@ -8,7 +8,6 @@
 
 #include <QtCore/QHash>
 #include <QtCore/QStringList>
-#include <QtCore/QQueue>
 #include <QtCore/QMultiMap>
 #include <QtCore/QSet>
 
@@ -17,8 +16,7 @@ namespace CppTools {
 class CPPTOOLS_EXPORT SymbolFinder
 {
 public:
-    SymbolFinder(const QString &referenceFileName);
-    SymbolFinder(const char *referenceFileName, unsigned referenceFileLength);
+    SymbolFinder();
 
     CPlusPlus::Symbol *findMatchingDefinition(CPlusPlus::Symbol *symbol,
                                               const CPlusPlus::Snapshot &snapshot,
@@ -37,17 +35,20 @@ public:
                                                             CPlusPlus::Function *functionType);
 
 private:
-    QStringList fileIterationOrder(const CPlusPlus::Snapshot &snapshot);
+    QStringList fileIterationOrder(const QString &referenceFile,
+                                   const CPlusPlus::Snapshot &snapshot);
 
-    void checkCacheConsistency(const CPlusPlus::Snapshot &snapshot);
-    void clear(const QString &comparingFile);
-    void insert(const QString &comparingFile);
+    void checkCacheConsistency(const QString &referenceFile, const CPlusPlus::Snapshot &snapshot);
+    void clearCache(const QString &referenceFile, const QString &comparingFile);
+    void insertCache(const QString &referenceFile, const QString &comparingFile);
+
+    void trackCacheUse(const QString &referenceFile);
 
     static int computeKey(const QString &referenceFile, const QString &comparingFile);
 
-    QMultiMap<int, QString> m_filePriorityCache;
-    QSet<QString> m_fileMetaCache;
-    QString m_referenceFile;
+    QHash<QString, QMultiMap<int, QString> > m_filePriorityCache;
+    QHash<QString, QSet<QString> > m_fileMetaCache;
+    QStringList m_recent;
 };
 
 } // namespace CppTools
diff --git a/src/plugins/designer/qtcreatorintegration.cpp b/src/plugins/designer/qtcreatorintegration.cpp
index c5c34c014b6aabcfb6c8f0b2d455e5f09836ef95..fd426bd48cbb6ba6ca867cf05acdfb05a2981539 100644
--- a/src/plugins/designer/qtcreatorintegration.cpp
+++ b/src/plugins/designer/qtcreatorintegration.cpp
@@ -274,8 +274,7 @@ static Document::Ptr findDefinition(Function *functionDeclaration, int *line)
 {
     if (CppModelManagerInterface *cppModelManager = CppModelManagerInterface::instance()) {
         const Snapshot snapshot = cppModelManager->snapshot();
-        CppTools::SymbolFinder symbolFinder(functionDeclaration->fileName(),
-                                            functionDeclaration->fileNameLength());
+        CppTools::SymbolFinder symbolFinder;
         if (Symbol *def = symbolFinder.findMatchingDefinition(functionDeclaration, snapshot)) {
             if (line)
                 *line = def->line();