diff --git a/src/plugins/cpptools/cppclassesfilter.cpp b/src/plugins/cpptools/cppclassesfilter.cpp
index 1e516084136c15e2d95608c57d684db06c07c167..316edb2898e83246f3fba9e2d18a4a28381f4755 100644
--- a/src/plugins/cpptools/cppclassesfilter.cpp
+++ b/src/plugins/cpptools/cppclassesfilter.cpp
@@ -32,21 +32,24 @@
 using namespace CppTools;
 using namespace CppTools::Internal;
 
-CppClassesFilter::CppClassesFilter(CppModelManager *manager)
-    : CppLocatorFilter(manager)
+CppClassesFilter::CppClassesFilter(CppLocatorData *locatorData)
+    : CppLocatorFilter(locatorData)
 {
     setId("Classes");
     setShortcutString(QLatin1String("c"));
     setIncludedByDefault(false);
     setDisplayName(tr("C++ Classes"));
-
-    search.setSymbolsToSearchFor(SymbolSearcher::Classes);
 }
 
 CppClassesFilter::~CppClassesFilter()
 {
 }
 
+QList<QList<CppTools::ModelItemInfo> > CppClassesFilter::itemsToMatchUserInputAgainst() const
+{
+    return QList<QList<CppTools::ModelItemInfo> >() << m_data->classes();
+}
+
 Locator::FilterEntry CppClassesFilter::filterEntryFromModelItemInfo(const ModelItemInfo &info)
 {
     const QVariant id = qVariantFromValue(info);
diff --git a/src/plugins/cpptools/cppclassesfilter.h b/src/plugins/cpptools/cppclassesfilter.h
index b8d9bc39b330ab7d829689956132a926259a0b54..cb0475dd4863bf1e0d4a04459e511df0005d7e5f 100644
--- a/src/plugins/cpptools/cppclassesfilter.h
+++ b/src/plugins/cpptools/cppclassesfilter.h
@@ -31,6 +31,7 @@
 #define CPPCLASSESFILTER_H
 
 #include "cpptools_global.h"
+#include "cpplocatordata.h"
 #include "cpplocatorfilter.h"
 
 namespace CppTools {
@@ -40,10 +41,11 @@ class CPPTOOLS_EXPORT CppClassesFilter : public Internal::CppLocatorFilter
     Q_OBJECT
 
 public:
-    CppClassesFilter(Internal::CppModelManager *manager);
+    CppClassesFilter(Internal::CppLocatorData *locatorData);
     ~CppClassesFilter();
 
 private:
+    QList<QList<CppTools::ModelItemInfo> > itemsToMatchUserInputAgainst() const;
     Locator::FilterEntry filterEntryFromModelItemInfo(const ModelItemInfo &info);
 };
 
diff --git a/src/plugins/cpptools/cppfunctionsfilter.cpp b/src/plugins/cpptools/cppfunctionsfilter.cpp
index 101b133bcd1f48592b21c3c4bae554a73ac508a5..89052c265f37ee51369162a3e7e07e958af67ef2 100644
--- a/src/plugins/cpptools/cppfunctionsfilter.cpp
+++ b/src/plugins/cpptools/cppfunctionsfilter.cpp
@@ -31,21 +31,24 @@
 
 using namespace CppTools::Internal;
 
-CppFunctionsFilter::CppFunctionsFilter(CppModelManager *manager)
-    : CppLocatorFilter(manager)
+CppFunctionsFilter::CppFunctionsFilter(CppLocatorData *locatorData)
+    : CppLocatorFilter(locatorData)
 {
     setId("Methods");
     setDisplayName(tr("C++ Methods and Functions"));
     setShortcutString(QString(QLatin1Char('m')));
     setIncludedByDefault(false);
-
-    search.setSymbolsToSearchFor(SymbolSearcher::Functions);
 }
 
 CppFunctionsFilter::~CppFunctionsFilter()
 {
 }
 
+QList<QList<CppTools::ModelItemInfo> > CppFunctionsFilter::itemsToMatchUserInputAgainst() const
+{
+    return QList<QList<CppTools::ModelItemInfo> >() << m_data->functions();
+}
+
 Locator::FilterEntry CppFunctionsFilter::filterEntryFromModelItemInfo(const CppTools::ModelItemInfo &info)
 {
     const QVariant id = qVariantFromValue(info);
diff --git a/src/plugins/cpptools/cppfunctionsfilter.h b/src/plugins/cpptools/cppfunctionsfilter.h
index aa4e97d88ff2d38a4fde89f576651ac35599f6d5..1357e6d76d7b9584a5e58ccd416bac201ae33088 100644
--- a/src/plugins/cpptools/cppfunctionsfilter.h
+++ b/src/plugins/cpptools/cppfunctionsfilter.h
@@ -30,6 +30,7 @@
 #ifndef CPPFUNCTIONSFILTER_H
 #define CPPFUNCTIONSFILTER_H
 
+#include "cpplocatordata.h"
 #include "cpplocatorfilter.h"
 
 namespace CppTools {
@@ -40,10 +41,11 @@ class CppFunctionsFilter : public CppLocatorFilter
     Q_OBJECT
 
 public:
-    CppFunctionsFilter(CppModelManager *manager);
+    CppFunctionsFilter(CppLocatorData *locatorData);
     ~CppFunctionsFilter();
 
 private:
+    QList<QList<ModelItemInfo> > itemsToMatchUserInputAgainst() const;
     Locator::FilterEntry filterEntryFromModelItemInfo(const ModelItemInfo &info);
 };
 
diff --git a/src/plugins/cpptools/cpplocatordata.cpp b/src/plugins/cpptools/cpplocatordata.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..14fcd9df2c6d8385b357d518927686aa0d87e497
--- /dev/null
+++ b/src/plugins/cpptools/cpplocatordata.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+
+#include "cpplocatordata.h"
+
+using namespace CppTools;
+using namespace CppTools::Internal;
+
+static const int MaxPendingDocuments = 10;
+
+CppLocatorData::CppLocatorData(CppModelManager *modelManager)
+    : m_modelManager(modelManager)
+    , m_pendingDocumentsMutex(QMutex::Recursive)
+{
+    m_search.setSymbolsToSearchFor(SymbolSearcher::Enums
+                                 | SymbolSearcher::Classes
+                                 | SymbolSearcher::Functions);
+    m_pendingDocuments.reserve(MaxPendingDocuments);
+
+    connect(m_modelManager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)),
+            this, SLOT(onDocumentUpdated(CPlusPlus::Document::Ptr)));
+
+    connect(m_modelManager, SIGNAL(aboutToRemoveFiles(QStringList)),
+            this, SLOT(onAboutToRemoveFiles(QStringList)));
+}
+
+QList<ModelItemInfo> CppLocatorData::enums()
+{
+    flushPendingDocument(true);
+    return allModelItemInfos(m_allEnums);
+}
+
+QList<ModelItemInfo> CppLocatorData::classes()
+{
+    flushPendingDocument(true);
+    return allModelItemInfos(m_allClasses);
+}
+
+QList<ModelItemInfo> CppLocatorData::functions()
+{
+    flushPendingDocument(true);
+    return allModelItemInfos(m_allFunctions);
+}
+
+void CppLocatorData::onDocumentUpdated(const CPlusPlus::Document::Ptr &document)
+{
+    QMutexLocker locker(&m_pendingDocumentsMutex);
+
+    int i = 0, ei = m_pendingDocuments.size();
+    for (; i < ei; ++i) {
+        const CPlusPlus::Document::Ptr &doc = m_pendingDocuments.at(i);
+        if (doc->fileName() == document->fileName()
+                && doc->revision() < document->revision()) {
+            m_pendingDocuments[i] = document;
+            break;
+        }
+    }
+
+    if (i == ei)
+        m_pendingDocuments.append(document);
+
+    flushPendingDocument(false);
+}
+
+void CppLocatorData::onAboutToRemoveFiles(const QStringList &files)
+{
+    QMutexLocker locker(&m_pendingDocumentsMutex);
+
+    for (int i = 0; i < m_pendingDocuments.size(); ) {
+        if (files.contains(m_pendingDocuments.at(i)->fileName()))
+            m_pendingDocuments.remove(i);
+        else
+            ++i;
+    }
+
+    foreach (const QString &file, files) {
+        m_allEnums.remove(file);
+        m_allClasses.remove(file);
+        m_allFunctions.remove(file);
+        removeFilePath(file);
+    }
+}
+
+void CppLocatorData::flushPendingDocument(bool force)
+{
+    QMutexLocker locker(&m_pendingDocumentsMutex);
+    if (!force && m_pendingDocuments.size() < MaxPendingDocuments)
+        return;
+
+    foreach (CPlusPlus::Document::Ptr doc, m_pendingDocuments) {
+        const QString fileName = findOrInsertFilePath(doc->fileName());
+
+        QList<ModelItemInfo> resultsEnums;
+        QList<ModelItemInfo> resultsClasses;
+        QList<ModelItemInfo> resultsFunctions;
+
+        const int sizeHint = m_allEnums[fileName].size() + m_allClasses[fileName].size()
+                + m_allFunctions[fileName].size() + 10;
+        const QList<ModelItemInfo> results = m_search(doc, sizeHint);
+        foreach (const ModelItemInfo &info, results) {
+            switch (info.type) {
+            case ModelItemInfo::Enum:
+                resultsEnums.append(info);
+                break;
+            case ModelItemInfo::Class:
+                resultsClasses.append(info);
+                break;
+            case ModelItemInfo::Method:
+                resultsFunctions.append(info);
+                break;
+            default:
+                break;
+            }
+        }
+
+        m_allEnums[fileName] = resultsEnums;
+        m_allClasses[fileName] = resultsClasses;
+        m_allFunctions[fileName] = resultsFunctions;
+    }
+
+    m_pendingDocuments.clear();
+    m_pendingDocuments.reserve(MaxPendingDocuments);
+}
+
+QList<ModelItemInfo> CppLocatorData::allModelItemInfos(const QHash<QString,
+                                                       QList<ModelItemInfo> > &items) const
+{
+    QList<ModelItemInfo> result;
+    QHashIterator<QString, QList<ModelItemInfo> > it(items);
+    while (it.hasNext()) {
+        it.next();
+        result.append(it.value());
+    }
+    return result;
+}
diff --git a/src/plugins/cpptools/cpplocatordata.h b/src/plugins/cpptools/cpplocatordata.h
new file mode 100644
index 0000000000000000000000000000000000000000..d7a47c4161c89314049d794afd3dc5425b4deed6
--- /dev/null
+++ b/src/plugins/cpptools/cpplocatordata.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+
+#ifndef CPPLOCATORDATA_H
+#define CPPLOCATORDATA_H
+
+#include <QHash>
+#include <QVector>
+
+#include <cplusplus/CppDocument.h>
+
+#include "cppmodelmanager.h"
+#include "searchsymbols.h"
+
+namespace CppTools {
+namespace Internal {
+
+class CppLocatorData : public QObject
+{
+    Q_OBJECT
+public:
+    explicit CppLocatorData(CppModelManager *modelManager);
+
+    QList<ModelItemInfo> enums();
+    QList<ModelItemInfo> classes();
+    QList<ModelItemInfo> functions();
+
+private slots:
+    void onDocumentUpdated(const CPlusPlus::Document::Ptr &document);
+    void onAboutToRemoveFiles(const QStringList &files);
+
+private:
+    void flushPendingDocument(bool force);
+    QList<ModelItemInfo> allModelItemInfos(const QHash<QString,
+                                           QList<ModelItemInfo> > &items) const;
+
+    QString findOrInsertFilePath(const QString &path)
+    { return *m_filePaths.insert(path); }
+
+    void removeFilePath(const QString &path)
+    { m_filePaths.remove(path); }
+
+private:
+    CppModelManager *m_modelManager;
+
+    QSet<QString> m_filePaths; // Used to avoid QString duplication
+
+    SearchSymbols m_search;
+    QHash<QString, QList<ModelItemInfo> > m_allEnums;
+    QHash<QString, QList<ModelItemInfo> > m_allClasses;
+    QHash<QString, QList<ModelItemInfo> > m_allFunctions;
+
+    mutable QMutex m_pendingDocumentsMutex;
+    QVector<CPlusPlus::Document::Ptr> m_pendingDocuments;
+};
+
+} // namespace Internal
+} // namespace CppTools
+
+#endif // CPPLOCATORDATA_H
diff --git a/src/plugins/cpptools/cpplocatorfilter.cpp b/src/plugins/cpptools/cpplocatorfilter.cpp
index 52cb87695c8c02f65e985f936c4b40c1a8e257fa..474000e9fb78a9afde44c3403f70bfdfcfb5da3f 100644
--- a/src/plugins/cpptools/cpplocatorfilter.cpp
+++ b/src/plugins/cpptools/cpplocatorfilter.cpp
@@ -36,76 +36,17 @@ using namespace CppTools::Internal;
 
 static const int MaxPendingDocuments = 10;
 
-CppLocatorFilter::CppLocatorFilter(CppModelManager *manager)
-    : m_manager(manager)
-    , m_pendingDocumentsMutex(QMutex::Recursive)
+CppLocatorFilter::CppLocatorFilter(CppLocatorData *locatorData)
+    : m_data(locatorData)
 {
     setId("Classes and Methods");
     setDisplayName(tr("C++ Classes and Methods"));
     setShortcutString(QString(QLatin1Char(':')));
     setIncludedByDefault(false);
-
-    m_pendingDocuments.reserve(MaxPendingDocuments);
-
-    connect(manager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)),
-            this, SLOT(onDocumentUpdated(CPlusPlus::Document::Ptr)));
-
-    connect(manager, SIGNAL(aboutToRemoveFiles(QStringList)),
-            this, SLOT(onAboutToRemoveFiles(QStringList)));
 }
 
 CppLocatorFilter::~CppLocatorFilter()
-{ }
-
-
-void CppLocatorFilter::flushPendingDocument(bool force)
-{
-    QMutexLocker locker(&m_pendingDocumentsMutex);
-    if (!force && m_pendingDocuments.size() < MaxPendingDocuments)
-        return;
-
-    foreach (CPlusPlus::Document::Ptr doc, m_pendingDocuments) {
-        QList<ModelItemInfo> &results = m_searchList[doc->fileName()];
-        results = search(doc, results.size() + 10);
-    }
-
-    m_pendingDocuments.clear();
-    m_pendingDocuments.reserve(MaxPendingDocuments);
-}
-
-void CppLocatorFilter::onDocumentUpdated(CPlusPlus::Document::Ptr updatedDoc)
-{
-    QMutexLocker locker(&m_pendingDocumentsMutex);
-
-    int i = 0, ei = m_pendingDocuments.size();
-    for (; i < ei; ++i) {
-        const CPlusPlus::Document::Ptr &doc = m_pendingDocuments.at(i);
-        if (doc->fileName() == updatedDoc->fileName()
-                && doc->revision() < updatedDoc->revision()) {
-            m_pendingDocuments[i] = updatedDoc;
-            break;
-        }
-    }
-
-    if (i == ei)
-        m_pendingDocuments.append(updatedDoc);
-
-    flushPendingDocument(false);
-}
-
-void CppLocatorFilter::onAboutToRemoveFiles(const QStringList &files)
 {
-    QMutexLocker locker(&m_pendingDocumentsMutex);
-
-    for (int i = 0; i < m_pendingDocuments.size(); ) {
-        if (files.contains(m_pendingDocuments.at(i)->fileName()))
-            m_pendingDocuments.remove(i);
-        else
-            ++i;
-    }
-
-    foreach (const QString &file, files)
-        m_searchList.remove(file);
 }
 
 Locator::FilterEntry CppLocatorFilter::filterEntryFromModelItemInfo(const CppTools::ModelItemInfo &info)
@@ -124,6 +65,14 @@ void CppLocatorFilter::refresh(QFutureInterface<void> &future)
     Q_UNUSED(future)
 }
 
+QList<QList<CppTools::ModelItemInfo> > CppLocatorFilter::itemsToMatchUserInputAgainst() const
+{
+    return QList<QList<CppTools::ModelItemInfo> >()
+        << m_data->classes()
+        << m_data->functions()
+        << m_data->enums();
+}
+
 static bool compareLexigraphically(const Locator::FilterEntry &a,
                                    const Locator::FilterEntry &b)
 {
@@ -132,8 +81,6 @@ static bool compareLexigraphically(const Locator::FilterEntry &a,
 
 QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &origEntry)
 {
-    flushPendingDocument(true);
-
     QString entry = trimWildcards(origEntry);
     QList<Locator::FilterEntry> goodEntries;
     QList<Locator::FilterEntry> betterEntries;
@@ -146,18 +93,14 @@ QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(QFutureInterface<Locato
     bool hasColonColon = entry.contains(QLatin1String("::"));
     const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry);
 
-    QHashIterator<QString, QList<ModelItemInfo> > it(m_searchList);
-    while (it.hasNext()) {
-        if (future.isCanceled())
-            break;
-
-        it.next();
-
-        const QList<ModelItemInfo> items = it.value();
+    const QList<QList<CppTools::ModelItemInfo> > itemLists = itemsToMatchUserInputAgainst();
+    foreach (const QList<CppTools::ModelItemInfo> &items, itemLists) {
         foreach (const ModelItemInfo &info, items) {
+            if (future.isCanceled())
+                break;
             const QString matchString = hasColonColon ? info.scopedSymbolName() : info.symbolName;
             if ((hasWildcard && regexp.exactMatch(matchString))
-                    || (!hasWildcard && matcher.indexIn(matchString) != -1)) {
+                || (!hasWildcard && matcher.indexIn(matchString) != -1)) {
                 const Locator::FilterEntry filterEntry = filterEntryFromModelItemInfo(info);
                 if (matchString.startsWith(entry, caseSensitivityForPrefix))
                     betterEntries.append(filterEntry);
@@ -168,9 +111,9 @@ QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(QFutureInterface<Locato
     }
 
     if (goodEntries.size() < 1000)
-        qSort(goodEntries.begin(), goodEntries.end(), compareLexigraphically);
+        qStableSort(goodEntries.begin(), goodEntries.end(), compareLexigraphically);
     if (betterEntries.size() < 1000)
-        qSort(betterEntries.begin(), betterEntries.end(), compareLexigraphically);
+        qStableSort(betterEntries.begin(), betterEntries.end(), compareLexigraphically);
 
     betterEntries += goodEntries;
     return betterEntries;
@@ -181,9 +124,3 @@ void CppLocatorFilter::accept(Locator::FilterEntry selection) const
     ModelItemInfo info = qvariant_cast<CppTools::ModelItemInfo>(selection.internalData);
     Core::EditorManager::openEditorAt(info.fileName, info.line, info.column);
 }
-
-void CppLocatorFilter::reset()
-{
-    m_searchList.clear();
-    m_previousEntry.clear();
-}
diff --git a/src/plugins/cpptools/cpplocatorfilter.h b/src/plugins/cpptools/cpplocatorfilter.h
index 866327cdd777ce2fd7b401c96c8454f4a40316c4..583cdbb57f47929e7f2e7a8e851ea39f32ddae95 100644
--- a/src/plugins/cpptools/cpplocatorfilter.h
+++ b/src/plugins/cpptools/cpplocatorfilter.h
@@ -30,6 +30,7 @@
 #ifndef CPPLOCATORFILTER_H
 #define CPPLOCATORFILTER_H
 
+#include "cpplocatordata.h"
 #include "searchsymbols.h"
 
 #include <locator/ilocatorfilter.h>
@@ -44,35 +45,19 @@ class CppLocatorFilter : public Locator::ILocatorFilter
     Q_OBJECT
 
 public:
-    CppLocatorFilter(CppModelManager *manager);
+    CppLocatorFilter(CppLocatorData *locatorData);
     ~CppLocatorFilter();
 
     QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
     void accept(Locator::FilterEntry selection) const;
     void refresh(QFutureInterface<void> &future);
 
-    void reset();
-
-protected:
-    SearchSymbols search;
-
-    void flushPendingDocument(bool force);
-
-private slots:
-    void onDocumentUpdated(CPlusPlus::Document::Ptr updatedDoc);
-    void onAboutToRemoveFiles(const QStringList &files);
-
 private:
+    virtual QList<QList<ModelItemInfo> > itemsToMatchUserInputAgainst() const;
     virtual Locator::FilterEntry filterEntryFromModelItemInfo(const ModelItemInfo &info);
 
-private:
-    CppModelManager *m_manager;
-
-    QHash<QString, QList<ModelItemInfo> > m_searchList;
-    QString m_previousEntry;
-
-    mutable QMutex m_pendingDocumentsMutex;
-    QVector<CPlusPlus::Document::Ptr> m_pendingDocuments;
+protected:
+    CppLocatorData *m_data;
 };
 
 } // namespace Internal
diff --git a/src/plugins/cpptools/cpplocatorfilter_test.cpp b/src/plugins/cpptools/cpplocatorfilter_test.cpp
index 14803411a513cad0740f2bc4ffb909c08463ee9a..7be5c794f8dac13b3cb24a7acbd31da267d28ed2 100644
--- a/src/plugins/cpptools/cpplocatorfilter_test.cpp
+++ b/src/plugins/cpptools/cpplocatorfilter_test.cpp
@@ -213,12 +213,12 @@ void CppToolsPlugin::test_cpplocatorfilters_CppLocatorFilter_data()
         << cppLocatorFilter
         << _("my")
         << (QList<ResultData>()
+            << ResultData(_("MyClass"), testFileShort)
+            << ResultData(_("MyClass"), testFileShort)
             << ResultData(_("MyClass"), testFileShort)
             << ResultData(_("MyClass"), _("()"))
             << ResultData(_("MyClass"), _("()"))
-            << ResultData(_("MyClass"), testFileShort)
             << ResultData(_("MyClass"), _("()"))
-            << ResultData(_("MyClass"), testFileShort)
             << ResultData(_("MyEnum"), testFileShort)
             << ResultData(_("MyEnum"), testFileShort)
             << ResultData(_("MyEnum"), testFileShort)
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index a8a1d3993818fdb0a4473af05f12c20f6fcb3cfb..984c6f127b2201a64aec772e9d4af3a2ba9cac36 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -45,7 +45,8 @@ HEADERS += completionsettingspage.h \
     cpppointerdeclarationformatter.h \
     cppprojectfile.h \
     cpppreprocessor.h \
-    includeutils.h
+    includeutils.h \
+    cpplocatordata.h
 
 SOURCES += completionsettingspage.cpp \
     cppclassesfilter.cpp \
@@ -89,7 +90,8 @@ SOURCES += completionsettingspage.cpp \
     cpppointerdeclarationformatter.cpp \
     cppprojectfile.cpp \
     cpppreprocessor.cpp \
-    includeutils.cpp
+    includeutils.cpp \
+    cpplocatordata.cpp
 
 FORMS += completionsettingspage.ui \
     cppfilesettingspage.ui \
diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs
index a8b29fc06fa8198ca4dab61e85963a7042234a65..36da8f0ea5d45fff8b38121cb8cbc36e70cacab9 100644
--- a/src/plugins/cpptools/cpptools.qbs
+++ b/src/plugins/cpptools/cpptools.qbs
@@ -64,6 +64,8 @@ QtcPlugin {
         "cppindexingsupport.h",
         "cpplocalsymbols.cpp",
         "cpplocalsymbols.h",
+        "cpplocatordata.cpp",
+        "cpplocatordata.h",
         "cpplocatorfilter.cpp",
         "cpplocatorfilter.h",
         "cppmodelmanager.cpp",
diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp
index be08a9afffffbb39f6675a8cbffbb187caa71c90..f73b0444ca4a9e6765568e5cad0cc1482d97d06e 100644
--- a/src/plugins/cpptools/cpptoolsplugin.cpp
+++ b/src/plugins/cpptools/cpptoolsplugin.cpp
@@ -40,6 +40,7 @@
 #include "cpptoolssettings.h"
 #include "cpptoolsreuse.h"
 #include "cppprojectfile.h"
+#include "cpplocatordata.h"
 
 #include <coreplugin/actionmanager/actioncontainer.h>
 #include <coreplugin/actionmanager/actionmanager.h>
@@ -101,9 +102,11 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
     connect(Core::DocumentManager::instance(), SIGNAL(filesChangedInternally(QStringList)),
             modelManager, SLOT(updateSourceFiles(QStringList)));
 
-    addAutoReleasedObject(new CppLocatorFilter(modelManager));
-    addAutoReleasedObject(new CppClassesFilter(modelManager));
-    addAutoReleasedObject(new CppFunctionsFilter(modelManager));
+    CppLocatorData *locatorData = new CppLocatorData(modelManager);
+    addAutoReleasedObject(locatorData);
+    addAutoReleasedObject(new CppLocatorFilter(locatorData));
+    addAutoReleasedObject(new CppClassesFilter(locatorData));
+    addAutoReleasedObject(new CppFunctionsFilter(locatorData));
     addAutoReleasedObject(new CppCurrentDocumentFilter(modelManager));
     addAutoReleasedObject(new CppFileSettingsPage(m_fileSettings));
     addAutoReleasedObject(new SymbolsFindFilter(modelManager));
diff --git a/src/plugins/locator/locatorfiltertest.cpp b/src/plugins/locator/locatorfiltertest.cpp
index cbc2661b8ee32296c42e23fcf43326e441cf77ab..692d213ef93c178217e16820bdafc4b64409132d 100644
--- a/src/plugins/locator/locatorfiltertest.cpp
+++ b/src/plugins/locator/locatorfiltertest.cpp
@@ -57,18 +57,6 @@ QList<FilterEntry> BasicLocatorFilterTest::matchesFor(const QString &searchText)
     return locatorSearch.results();
 }
 
-QT_BEGIN_NAMESPACE
-namespace QTest {
-
-template<> char *toString(const Locator::Internal::Tests::ResultData &data)
-{
-    QByteArray ba = "\"" + data.textColumn1.toUtf8() + "\", \"" + data.textColumn2.toUtf8() + "\"";
-    return qstrdup(ba.data());
-}
-
-} // namespace QTest
-QT_END_NAMESPACE
-
 ResultData::ResultData()
 {
 }
diff --git a/src/plugins/locator/locatorfiltertest.h b/src/plugins/locator/locatorfiltertest.h
index 950d94d6d11726a552b448eedcb96110ebc7355b..df520adfdf8bc40a7938ac94db1c86e1b1c9125a 100644
--- a/src/plugins/locator/locatorfiltertest.h
+++ b/src/plugins/locator/locatorfiltertest.h
@@ -83,4 +83,16 @@ typedef ResultData::ResultDataList ResultDataList;
 Q_DECLARE_METATYPE(Locator::Internal::Tests::ResultData)
 Q_DECLARE_METATYPE(Locator::Internal::Tests::ResultDataList)
 
+QT_BEGIN_NAMESPACE
+namespace QTest {
+
+template<> inline char *toString(const Locator::Internal::Tests::ResultData &data)
+{
+    QByteArray ba = "\"" + data.textColumn1.toUtf8() + "\", \"" + data.textColumn2.toUtf8() + "\"";
+    return qstrdup(ba.data());
+}
+
+} // namespace QTest
+QT_END_NAMESPACE
+
 #endif // LOCATORFILTERTEST_H