diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index c13b3da5f1bd27798050fb4335ed1f84a8d6b82a..40294cde5ea5ebc42cdd8af1fe3822c796d8fefc 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -375,6 +375,9 @@ struct CanonicalSymbol
 
 };
 
+
+int numberOfClosedEditors = 0;
+
 } // end of anonymous namespace
 
 CPPEditorEditable::CPPEditorEditable(CPPEditor *editor)
@@ -428,6 +431,12 @@ CPPEditor::~CPPEditor()
 
     m_semanticHighlighter->abort();
     m_semanticHighlighter->wait();
+
+    ++numberOfClosedEditors;
+    if (numberOfClosedEditors == 5) {
+        m_modelManager->GC();
+        numberOfClosedEditors = 0;
+    }
 }
 
 TextEditor::BaseTextEditorEditable *CPPEditor::createEditableInterface()
diff --git a/src/plugins/cpptools/cpplocatorfilter.cpp b/src/plugins/cpptools/cpplocatorfilter.cpp
index 34c696a15d8aa621b9da6d09e546e65dafdf5857..2b10afdce60f1518f0f4bab24cc39b95526f44b1 100644
--- a/src/plugins/cpptools/cpplocatorfilter.cpp
+++ b/src/plugins/cpptools/cpplocatorfilter.cpp
@@ -56,7 +56,7 @@ CppLocatorFilter::~CppLocatorFilter()
 
 void CppLocatorFilter::onDocumentUpdated(CPlusPlus::Document::Ptr doc)
 {
-    m_searchList[doc->fileName()] = Info(doc);
+    m_searchList[doc->fileName()] = search(doc);
 }
 
 void CppLocatorFilter::onAboutToRemoveFiles(const QStringList &files)
@@ -88,20 +88,12 @@ QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(const QString &origEntr
         return goodEntries;
     bool hasWildcard = (entry.contains(asterisk) || entry.contains('?'));
 
-    QMutableMapIterator<QString, Info> it(m_searchList);
+    QHashIterator<QString, QList<ModelItemInfo> > it(m_searchList);
     while (it.hasNext()) {
         it.next();
 
-        Info info = it.value();
-        if (info.dirty) {
-            info.dirty = false;
-            info.items = search(info.doc);
-            it.setValue(info);
-        }
-
-        QList<ModelItemInfo> items = info.items;
-
-        foreach (ModelItemInfo info, items) {
+        const QList<ModelItemInfo> items = it.value();
+        foreach (const ModelItemInfo &info, items) {
             if ((hasWildcard && regexp.exactMatch(info.symbolName))
                     || (!hasWildcard && matcher.indexIn(info.symbolName) != -1)) {
 
diff --git a/src/plugins/cpptools/cpplocatorfilter.h b/src/plugins/cpptools/cpplocatorfilter.h
index 4c4df83a236f5ad17f990e3eaf69d095b8f06ced..7b13adc6c7fa83b66cf4cd47b4b63910be89678e 100644
--- a/src/plugins/cpptools/cpplocatorfilter.h
+++ b/src/plugins/cpptools/cpplocatorfilter.h
@@ -31,7 +31,6 @@
 #define CPPLOCATORFILTER_H
 
 #include "searchsymbols.h"
-
 #include <locator/ilocatorfilter.h>
 
 namespace CppTools {
@@ -63,16 +62,7 @@ private slots:
 private:
     CppModelManager *m_manager;
 
-    struct Info {
-        Info(): dirty(true) {}
-        Info(CPlusPlus::Document::Ptr doc): doc(doc), dirty(true) {}
-
-        CPlusPlus::Document::Ptr doc;
-        QList<ModelItemInfo> items;
-        bool dirty;
-    };
-
-    QMap<QString, Info> m_searchList;
+    QHash<QString, QList<ModelItemInfo> > m_searchList;
     QList<ModelItemInfo> m_previousResults;
     bool m_forceNewSearchList;
     QString m_previousEntry;
diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp
index 828f0ce2efb9378968e43f19826f7105bae784c8..01aecaa236ddec4cac2eb28670fdd9d0da56a634 100644
--- a/src/plugins/cpptools/searchsymbols.cpp
+++ b/src/plugins/cpptools/searchsymbols.cpp
@@ -67,6 +67,7 @@ QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, const QString
         accept(doc->globalSymbolAt(i));
     }
     (void) switchScope(previousScope);
+    strings.clear();
     return items;
 }
 
@@ -216,10 +217,17 @@ void SearchSymbols::appendItem(const QString &name,
     QStringList fullyQualifiedName;
     foreach (const Name *name, LookupContext::fullyQualifiedName(symbol))
         fullyQualifiedName.append(overview.prettyName(name));
+
+    QString path = m_paths.value(symbol->fileId(), QString());
+    if (path.isEmpty()) {
+        path = QString::fromUtf8(symbol->fileName(), symbol->fileNameLength());
+        m_paths.insert(symbol->fileId(), path);
+    }
+
     const QIcon icon = icons.iconForSymbol(symbol);
     items.append(ModelItemInfo(name, info, type,
                                fullyQualifiedName,
-                               QString::fromUtf8(symbol->fileName(), symbol->fileNameLength()),
+                               path,
                                symbol->line(),
                                symbol->column() - 1, // 1-based vs 0-based column
                                icon));
diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h
index 9a08b4dced29deed3704d8fbf81ae8d9cc113129..5b61fe783ba429d774a02642a22f8717491de675 100644
--- a/src/plugins/cpptools/searchsymbols.h
+++ b/src/plugins/cpptools/searchsymbols.h
@@ -40,6 +40,7 @@
 #include <QMetaType>
 #include <QString>
 #include <QSet>
+#include <QHash>
 
 #include <functional>
 
@@ -66,33 +67,33 @@ struct ModelItemInfo
                   const QIcon &icon)
         : symbolName(symbolName),
           symbolType(symbolType),
-          type(type),
           fullyQualifiedName(fullyQualifiedName),
           fileName(fileName),
+          icon(icon),
+          type(type),
           line(line),
-          column(column),
-          icon(icon)
+          column(column)
     { }
 
     ModelItemInfo(const ModelItemInfo &otherInfo)
         : symbolName(otherInfo.symbolName),
           symbolType(otherInfo.symbolType),
-          type(otherInfo.type),
           fullyQualifiedName(otherInfo.fullyQualifiedName),
           fileName(otherInfo.fileName),
+          icon(otherInfo.icon),
+          type(otherInfo.type),
           line(otherInfo.line),
-          column(otherInfo.column),
-          icon(otherInfo.icon)
+          column(otherInfo.column)
     {  }
 
     QString symbolName;
     QString symbolType;
-    ItemType type;
     QStringList fullyQualifiedName;
     QString fileName;
+    QIcon icon;
+    ItemType type;
     int line;
     int column;
-    QIcon icon;
 };
 
 class SearchSymbols: public std::unary_function<CPlusPlus::Document::Ptr, QList<ModelItemInfo> >,
@@ -152,6 +153,7 @@ private:
     CPlusPlus::Icons icons;
     QList<ModelItemInfo> items;
     SymbolTypes symbolsToSearchFor;
+    QHash<const CPlusPlus::StringLiteral *, QString> m_paths;
     bool separateScope;
 };
 
diff --git a/src/plugins/locator/locatorwidget.cpp b/src/plugins/locator/locatorwidget.cpp
index 8f29bbba7a19b94c1645c5ce6a6a13eae3924325..0ee99048ea07d7ef59c0aba86b14fda438a6fa22 100644
--- a/src/plugins/locator/locatorwidget.cpp
+++ b/src/plugins/locator/locatorwidget.cpp
@@ -439,7 +439,6 @@ static void filter_helper(QFutureInterface<FilterEntry> &entries, QList<ILocator
         foreach (const FilterEntry &entry, filter->matchesFor(searchText)) {
             if (checkDuplicates && alreadyAdded.contains(entry))
                 continue;
-            //entries.append(entry);
             entries.reportResult(entry);
             if (checkDuplicates)
                 alreadyAdded.insert(entry);
@@ -457,7 +456,6 @@ void LocatorWidget::updateCompletionList(const QString &text)
 
     QFuture<FilterEntry> future = QtConcurrent::run(filter_helper, filters, searchText);
     m_entriesWatcher->setFuture(future);
-    future.waitForFinished();
 }
 
 void LocatorWidget::updateEntries()