diff --git a/src/libs/clangsupport/clangrefactoringservermessages.h b/src/libs/clangsupport/clangrefactoringservermessages.h
index 797b3d58ef763e60dbed953e08e9ab8a88b2ca7b..2be6f0d54d0be5c77342c0fd710f2cf7b76d5c5e 100644
--- a/src/libs/clangsupport/clangrefactoringservermessages.h
+++ b/src/libs/clangsupport/clangrefactoringservermessages.h
@@ -30,3 +30,5 @@
 #include "requestsourcelocationforrenamingmessage.h"
 #include "requestsourcerangesanddiagnosticsforquerymessage.h"
 #include "requestsourcerangesforquerymessage.h"
+#include "updatepchprojectpartsmessage.h"
+#include "removepchprojectpartsmessage.h"
diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri
index c6584b24b081496ace1a5e25dab0ecef818907b1..f7bd2674aec5dd941b2ced664d1f45323f7efaf8 100644
--- a/src/libs/clangsupport/clangsupport-lib.pri
+++ b/src/libs/clangsupport/clangsupport-lib.pri
@@ -174,6 +174,7 @@ HEADERS += \
     $$PWD/ipcclientprovider.h \
     $$PWD/requestsourcerangesforquerymessage.h \
     $$PWD/stringcachefwd.h \
-    $$PWD/stringcachealgorithms.h
+    $$PWD/stringcachealgorithms.h \
+    $$PWD/projectmanagementserverinterface.h
 
 contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
diff --git a/src/libs/clangsupport/pchmanagerserverinterface.h b/src/libs/clangsupport/pchmanagerserverinterface.h
index 58ce6499971f44f8b9ea4c444511f63dd0497450..6af04c91fedcf059234a4af25d04af540e59c92a 100644
--- a/src/libs/clangsupport/pchmanagerserverinterface.h
+++ b/src/libs/clangsupport/pchmanagerserverinterface.h
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "ipcserverinterface.h"
+#include "projectmanagementserverinterface.h"
 
 #include <memory>
 
@@ -35,15 +35,12 @@ class PchManagerClientInterface;
 class RemovePchProjectPartsMessage;
 class UpdatePchProjectPartsMessage;
 
-
-class CMBIPC_EXPORT PchManagerServerInterface : public IpcServerInterface
+class CMBIPC_EXPORT PchManagerServerInterface : public ProjectManagementServerInterface
 {
 public:
     void dispatch(const MessageEnvelop &messageEnvelop) override;
 
     virtual void end() = 0;
-    virtual void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) = 0;
-    virtual void removePchProjectParts(RemovePchProjectPartsMessage &&message) = 0;
 };
 
 } // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/projectmanagementserverinterface.h b/src/libs/clangsupport/projectmanagementserverinterface.h
new file mode 100644
index 0000000000000000000000000000000000000000..5704db417c028f467f924f9c5cd038e7d64784fd
--- /dev/null
+++ b/src/libs/clangsupport/projectmanagementserverinterface.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "ipcserverinterface.h"
+
+namespace ClangBackEnd {
+
+class RemovePchProjectPartsMessage;
+class UpdatePchProjectPartsMessage;
+
+class CMBIPC_EXPORT ProjectManagementServerInterface : public IpcInterface
+{
+public:
+    virtual void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) = 0;
+    virtual void removePchProjectParts(RemovePchProjectPartsMessage &&message) = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/refactoringserverinterface.cpp b/src/libs/clangsupport/refactoringserverinterface.cpp
index d6b0f6815b7ae7748037e9baf0fd4f2c83aa2023..52ab7834b064c9e27a7e1b0127392d905fb3b48f 100644
--- a/src/libs/clangsupport/refactoringserverinterface.cpp
+++ b/src/libs/clangsupport/refactoringserverinterface.cpp
@@ -47,6 +47,12 @@ void RefactoringServerInterface::dispatch(const MessageEnvelop &messageEnvelop)
         case MessageType::RequestSourceRangesForQueryMessage:
             requestSourceRangesForQueryMessage(messageEnvelop.message<RequestSourceRangesForQueryMessage>());
             break;
+        case MessageType::UpdatePchProjectPartsMessage:
+            updatePchProjectParts(messageEnvelop.message<UpdatePchProjectPartsMessage>());
+            break;
+        case MessageType::RemovePchProjectPartsMessage:
+            removePchProjectParts(messageEnvelop.message<RemovePchProjectPartsMessage>());
+            break;
         case MessageType::CancelMessage:
             cancel();
             break;
diff --git a/src/libs/clangsupport/refactoringserverinterface.h b/src/libs/clangsupport/refactoringserverinterface.h
index 8c36a7351ef68edcdb2c6685d50e20cc17b3fc7a..a4a3b1e6f4ac0355b3fd8765d2677cba34e86e7a 100644
--- a/src/libs/clangsupport/refactoringserverinterface.h
+++ b/src/libs/clangsupport/refactoringserverinterface.h
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "ipcserverinterface.h"
+#include "projectmanagementserverinterface.h"
 
 #include <memory>
 
@@ -36,8 +36,10 @@ class RequestSourceLocationsForRenamingMessage;
 class RequestSourceRangesAndDiagnosticsForQueryMessage;
 class RequestSourceRangesForQueryMessage;
 class CancelMessage;
+class UpdatePchProjectPartsMessage;
+class RemovePchProjectPartsMessage;
 
-class CMBIPC_EXPORT RefactoringServerInterface : public IpcServerInterface
+class CMBIPC_EXPORT RefactoringServerInterface : public ProjectManagementServerInterface
 
 {
 public:
diff --git a/src/libs/clangsupport/refactoringserverproxy.cpp b/src/libs/clangsupport/refactoringserverproxy.cpp
index 0cf4473f0755733484340ed51a64ee9ccb79afaf..cc6741b118cd68db9761d937cbeb1d41d1ced884 100644
--- a/src/libs/clangsupport/refactoringserverproxy.cpp
+++ b/src/libs/clangsupport/refactoringserverproxy.cpp
@@ -62,6 +62,16 @@ void RefactoringServerProxy::requestSourceRangesForQueryMessage(RequestSourceRan
     writeMessageBlock.write(message);
 }
 
+void RefactoringServerProxy::updatePchProjectParts(UpdatePchProjectPartsMessage &&message)
+{
+    writeMessageBlock.write(message);
+}
+
+void RefactoringServerProxy::removePchProjectParts(RemovePchProjectPartsMessage &&message)
+{
+    writeMessageBlock.write(message);
+}
+
 void RefactoringServerProxy::cancel()
 {
     writeMessageBlock.write(CancelMessage());
diff --git a/src/libs/clangsupport/refactoringserverproxy.h b/src/libs/clangsupport/refactoringserverproxy.h
index 9b10e375298b2ae65f99a02a102e75a04983b422..611155b5110fa777716c06895b3980f39d0a97d2 100644
--- a/src/libs/clangsupport/refactoringserverproxy.h
+++ b/src/libs/clangsupport/refactoringserverproxy.h
@@ -53,6 +53,8 @@ public:
     void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override;
     void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override;
     void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override;
+    void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) override;
+    void removePchProjectParts(RemovePchProjectPartsMessage &&message) override;
     void cancel() override;
 
     void readMessages();
diff --git a/src/libs/clangsupport/stringcache.h b/src/libs/clangsupport/stringcache.h
index e38649488cac06615e96c5112f29b7ab0890fe15..6d5f4e986b2192eb697ff64ffee545727d6943a5 100644
--- a/src/libs/clangsupport/stringcache.h
+++ b/src/libs/clangsupport/stringcache.h
@@ -125,12 +125,7 @@ public:
     {
         std::lock_guard<Mutex> lock(m_mutex);
 
-        Found found = find(stringView);
-
-        if (!found.wasFound)
-            return insertString(found.iterator, stringView);
-
-        return found.iterator->id;
+        return ungardedStringId(stringView);
     }
 
     template <typename Container>
@@ -144,7 +139,7 @@ public:
         std::transform(strings.begin(),
                        strings.end(),
                        std::back_inserter(ids),
-                       [&] (const auto &string) { return this->stringId(string); });
+                       [&] (const auto &string) { return this->ungardedStringId(string); });
 
         return ids;
     }
@@ -182,6 +177,16 @@ public:
     }
 
 private:
+    IndexType ungardedStringId(Utils::SmallStringView stringView)
+    {
+        Found found = find(stringView);
+
+        if (!found.wasFound)
+            return insertString(found.iterator, stringView);
+
+        return found.iterator->id;
+    }
+
     Found find(Utils::SmallStringView stringView)
     {
         return findInSorted(m_strings.cbegin(), m_strings.cend(), stringView, compare);
diff --git a/src/libs/sqlite/sqlite-lib.pri b/src/libs/sqlite/sqlite-lib.pri
index a953a70e0a5772230efd6f4ce8ff3642fe1aedda..67c8c6b937254958c9fe44cb4f7d79288c032b04 100644
--- a/src/libs/sqlite/sqlite-lib.pri
+++ b/src/libs/sqlite/sqlite-lib.pri
@@ -43,7 +43,8 @@ HEADERS += \
     $$PWD/utf8stringvector.h \
     $$PWD/sqlitedatabase.h \
     $$PWD/sqlitetable.h \
-    $$PWD/sqlitecolumn.h
+    $$PWD/sqlitecolumn.h \
+    $$PWD/sqliteindex.h
 
 DEFINES += SQLITE_THREADSAFE=2 SQLITE_ENABLE_FTS4 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_UNLOCK_NOTIFY SQLITE_ENABLE_COLUMN_METADATA
 
diff --git a/src/libs/sqlite/sqlitecolumn.h b/src/libs/sqlite/sqlitecolumn.h
index e25ee68b2d7d4e9996e80c793d121415063df537..a253aee488e00e89884c1a16d50593883d62f540 100644
--- a/src/libs/sqlite/sqlitecolumn.h
+++ b/src/libs/sqlite/sqlitecolumn.h
@@ -29,6 +29,8 @@
 
 #include <utils/smallstring.h>
 
+#include <functional>
+
 namespace Sqlite {
 
 class SqliteColumn
@@ -108,5 +110,7 @@ private:
 };
 
 using SqliteColumns = std::vector<SqliteColumn>;
+using SqliteColumnConstReference = std::reference_wrapper<const SqliteColumn>;
+using SqliteColumnConstReferences = std::vector<SqliteColumnConstReference>;
 
 } // namespace Sqlite
diff --git a/src/libs/sqlite/sqliteindex.h b/src/libs/sqlite/sqliteindex.h
new file mode 100644
index 0000000000000000000000000000000000000000..a6d92432d3ae9bef14a111c5693742cded890122
--- /dev/null
+++ b/src/libs/sqlite/sqliteindex.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+
+#include "sqliteglobal.h"
+
+#include "sqliteexception.h"
+
+#include <utils/smallstringvector.h>
+
+namespace Sqlite {
+
+class SqliteIndex
+{
+public:
+    SqliteIndex(Utils::SmallString &&tableName, Utils::SmallStringVector &&columnNames)
+        : m_tableName(std::move(tableName)),
+          m_columnNames(std::move(columnNames))
+    {
+    }
+
+    Utils::SmallString sqlStatement() const
+    {
+        checkTableName();
+        checkColumns();
+
+        return {"CREATE INDEX IF NOT EXISTS index_",
+                m_tableName,
+                "_",
+                m_columnNames.join("_"),
+                " ON ",
+                m_tableName,
+                "(",
+                m_columnNames.join(", "),
+                ")"
+        };
+    }
+
+    void checkTableName() const
+    {
+        if (m_tableName.isEmpty())
+            throw SqliteException("SqliteIndex has not table name!");
+    }
+
+    void checkColumns() const
+    {
+        if (m_columnNames.empty())
+            throw SqliteException("SqliteIndex has no columns!");
+    }
+
+private:
+    Utils::SmallString m_tableName;
+    Utils::SmallStringVector m_columnNames;
+};
+
+using SqliteIndices = std::vector<SqliteIndex>;
+
+} //
diff --git a/src/libs/sqlite/sqlitetable.h b/src/libs/sqlite/sqlitetable.h
index d9e7d5cd1600d6bb04f79e8cefaaae8ac79cd799..be63e5ae5e837f67f9166f954492f57e1aed8e6c 100644
--- a/src/libs/sqlite/sqlitetable.h
+++ b/src/libs/sqlite/sqlitetable.h
@@ -28,6 +28,7 @@
 #include "createtablesqlstatementbuilder.h"
 #include "sqliteglobal.h"
 #include "sqlitecolumn.h"
+#include "sqliteindex.h"
 #include "sqliteexception.h"
 
 namespace Sqlite {
@@ -37,6 +38,12 @@ class SqliteDatabase;
 class SqliteTable
 {
 public:
+    SqliteTable(std::size_t reserve = 10)
+    {
+        m_sqliteColumns.reserve(reserve);
+        m_sqliteIndices.reserve(reserve);
+    }
+
     void setName(Utils::SmallString &&name)
     {
         m_tableName = std::move(name);
@@ -76,6 +83,13 @@ public:
         return m_sqliteColumns.back();
     }
 
+    SqliteIndex &addIndex(const SqliteColumnConstReferences &columns)
+    {
+        m_sqliteIndices.emplace_back(m_tableName.clone(), sqliteColumnNames(columns));
+
+        return m_sqliteIndices.back();
+    }
+
     const SqliteColumns &columns() const
     {
         return m_sqliteColumns;
@@ -89,22 +103,25 @@ public:
     template <typename Database>
     void initialize(Database &database)
     {
-        try {
-            CreateTableSqlStatementBuilder builder;
+        CreateTableSqlStatementBuilder builder;
 
-            builder.setTableName(m_tableName.clone());
-            builder.setUseWithoutRowId(m_withoutRowId);
-            builder.setUseIfNotExists(m_useIfNotExists);
-            builder.setUseTemporaryTable(m_useTemporaryTable);
-            builder.setColumns(m_sqliteColumns);
+        builder.setTableName(m_tableName.clone());
+        builder.setUseWithoutRowId(m_withoutRowId);
+        builder.setUseIfNotExists(m_useIfNotExists);
+        builder.setUseTemporaryTable(m_useTemporaryTable);
+        builder.setColumns(m_sqliteColumns);
 
-            database.execute(builder.sqlStatement());
+        database.execute(builder.sqlStatement());
 
-            m_isReady = true;
+        initializeIndices(database);
 
-        } catch (const SqliteException &exception) {
-            exception.printWarning();
-        }
+        m_isReady = true;
+    }
+    template <typename Database>
+    void initializeIndices(Database &database)
+    {
+        for (const SqliteIndex &index : m_sqliteIndices)
+            database.execute(index.sqlStatement());
     }
 
     friend bool operator==(const SqliteTable &first, const SqliteTable &second)
@@ -116,9 +133,21 @@ public:
             && first.m_sqliteColumns == second.m_sqliteColumns;
     }
 
+private:
+    Utils::SmallStringVector sqliteColumnNames(const SqliteColumnConstReferences &columns)
+    {
+        Utils::SmallStringVector columnNames;
+
+        for (const SqliteColumn &column : columns)
+            columnNames.push_back(column.name());
+
+        return columnNames;
+    }
+
 private:
     Utils::SmallString m_tableName;
     SqliteColumns m_sqliteColumns;
+    SqliteIndices m_sqliteIndices;
     bool m_withoutRowId = false;
     bool m_useIfNotExists = false;
     bool m_useTemporaryTable = false;
diff --git a/src/libs/sqlite/sqlitetransaction.h b/src/libs/sqlite/sqlitetransaction.h
index 373b33fd8a928de6044f773c634549fa771fc32a..2b817123f12e6464f6512f86560571b646549340 100644
--- a/src/libs/sqlite/sqlitetransaction.h
+++ b/src/libs/sqlite/sqlitetransaction.h
@@ -36,7 +36,7 @@ template <typename Database>
 class SqliteAbstractTransaction
 {
 public:
-    virtual ~SqliteAbstractTransaction()
+    ~SqliteAbstractTransaction()
     {
         if (!m_isAlreadyCommited)
             m_database.execute("ROLLBACK");
@@ -68,7 +68,6 @@ public:
     {
         database.execute("BEGIN");
     }
-
 };
 
 template <typename Database>
@@ -80,7 +79,6 @@ public:
     {
         database.execute("BEGIN IMMEDIATE");
     }
-
 };
 
 template <typename Database>
@@ -92,7 +90,6 @@ public:
     {
         database.execute("BEGIN EXCLUSIVE");
     }
-
 };
 
 } // namespace Sqlite
diff --git a/src/plugins/clangpchmanager/clangpchmanager-source.pri b/src/plugins/clangpchmanager/clangpchmanager-source.pri
index fd5b61a24d4b46728e4abab80e9e1607ea332be9..25d8d637305b9d2eb08449bd1d18ecac66469b6b 100644
--- a/src/plugins/clangpchmanager/clangpchmanager-source.pri
+++ b/src/plugins/clangpchmanager/clangpchmanager-source.pri
@@ -11,12 +11,14 @@ HEADERS += \
     $$PWD/pchmanagernotifierinterface.h \
     $$PWD/pchmanagerconnectionclient.h \
     $$PWD/clangpchmanager_global.h \
-    $$PWD/projectupdater.h
+    $$PWD/projectupdater.h \
+    $$PWD/pchmanagerprojectupdater.h
 
 
 SOURCES += \
     $$PWD/pchmanagerclient.cpp \
     $$PWD/pchmanagernotifierinterface.cpp \
     $$PWD/pchmanagerconnectionclient.cpp \
-    $$PWD/projectupdater.cpp
+    $$PWD/projectupdater.cpp \
+    $$PWD/pchmanagerprojectupdater.cpp
 
diff --git a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
index 4c536968075db1cc0dbc64f05b6c0c473a203dad..086b2fce8eff77f726a86e1c72844c5b33828348 100644
--- a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
+++ b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
@@ -52,7 +52,7 @@ class ClangPchManagerPluginData
 public:
     PchManagerClient pchManagerClient;
     PchManagerConnectionClient connectionClient{&pchManagerClient};
-    QtCreatorProjectUpdater projectUpdate{connectionClient.serverProxy(), pchManagerClient};
+    QtCreatorProjectUpdater<PchManagerProjectUpdater> projectUpdate{connectionClient.serverProxy(), pchManagerClient};
 };
 
 std::unique_ptr<ClangPchManagerPluginData> ClangPchManagerPlugin::d;
diff --git a/src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp b/src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d74ea2a7b069480d7fc4e4882e8e5a05833e17d4
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagerprojectupdater.cpp
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "pchmanagerprojectupdater.h"
+
+#include "pchmanagerclient.h"
+
+namespace ClangPchManager {
+
+PchManagerProjectUpdater::PchManagerProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
+                                                   PchManagerClient &client)
+    : ProjectUpdater(server),
+      m_client(client)
+{
+}
+
+void PchManagerProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
+{
+    ProjectUpdater::removeProjectParts(projectPartIds);
+
+    for (const QString &projectPartiId : projectPartIds)
+        m_client.precompiledHeaderRemoved(projectPartiId);
+}
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/pchmanagerprojectupdater.h b/src/plugins/clangpchmanager/pchmanagerprojectupdater.h
new file mode 100644
index 0000000000000000000000000000000000000000..0849554751e25fae90bc8ee58b73b3293ca43778
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagerprojectupdater.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "projectupdater.h"
+
+namespace ClangPchManager {
+
+class PchManagerProjectUpdater : public ProjectUpdater
+{
+public:
+    PchManagerProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
+                             PchManagerClient &client);
+
+    void removeProjectParts(const QStringList &projectPartIds);
+
+private:
+    PchManagerClient &m_client;
+};
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/projectupdater.cpp b/src/plugins/clangpchmanager/projectupdater.cpp
index 9d5d7c75773a831ae55d59ae422237e25af41ce6..046c5f769fce4063fcecb95277051d1fadfe34e9 100644
--- a/src/plugins/clangpchmanager/projectupdater.cpp
+++ b/src/plugins/clangpchmanager/projectupdater.cpp
@@ -52,10 +52,8 @@ public:
     Utils::PathStringVector sources;
 };
 
-ProjectUpdater::ProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
-                               PchManagerClient &client)
-    : m_server(server),
-      m_client(client)
+ProjectUpdater::ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server)
+    : m_server(server)
 {
 }
 
@@ -75,9 +73,6 @@ void ProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
     ClangBackEnd::RemovePchProjectPartsMessage message{Utils::SmallStringVector(projectPartIds)};
 
     m_server.removePchProjectParts(std::move(message));
-
-    for (const QString &projectPartiId : projectPartIds)
-        m_client.precompiledHeaderRemoved(projectPartiId);
 }
 
 void ProjectUpdater::setExcludedPaths(Utils::PathStringVector &&excludedPaths)
diff --git a/src/plugins/clangpchmanager/projectupdater.h b/src/plugins/clangpchmanager/projectupdater.h
index 60fd636408e31528aeff86b0dec2a5baa1c6f88f..e207a88971fdc93e1528d02ad51067650c80fc3f 100644
--- a/src/plugins/clangpchmanager/projectupdater.h
+++ b/src/plugins/clangpchmanager/projectupdater.h
@@ -35,7 +35,7 @@ class ProjectFile;
 }
 
 namespace ClangBackEnd {
-class PchManagerServerInterface;
+class ProjectManagementServerInterface;
 
 namespace V2 {
 class ProjectPartContainer;
@@ -51,11 +51,10 @@ namespace ClangPchManager {
 class HeaderAndSources;
 class PchManagerClient;
 
-class ProjectUpdater
+class CLANGPCHMANAGER_EXPORT ProjectUpdater
 {
 public:
-    ProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
-                   PchManagerClient &client);
+    ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server);
 
     void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
                             ClangBackEnd::V2::FileContainers &&generatedFiles);
@@ -77,8 +76,7 @@ unittest_public:
 
 private:
     Utils::PathStringVector m_excludedPaths;
-    ClangBackEnd::PchManagerServerInterface &m_server;
-    PchManagerClient &m_client;
+    ClangBackEnd::ProjectManagementServerInterface &m_server;
 };
 
 } // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp b/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
index 6ac93c747a7628be72c51a03e0a7aecc4992ceac..53b37ee2b5fa151246825c45b24090bcf443cb46 100644
--- a/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
+++ b/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
@@ -26,26 +26,18 @@
 #include "qtcreatorprojectupdater.h"
 
 #include <cpptools/abstracteditorsupport.h>
-#include <cpptools/cppmodelmanager.h>
 
 #include <projectexplorer/project.h>
 
 namespace ClangPchManager {
 
-static CppTools::CppModelManager *cppModelManager()
-{
-    return CppTools::CppModelManager::instance();
-}
+namespace Internal {
 
-QtCreatorProjectUpdater::QtCreatorProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
-                                                 PchManagerClient &client)
-    : ProjectUpdater(server, client)
+CppTools::CppModelManager *cppModelManager()
 {
-    connectToCppModelManager();
+    return CppTools::CppModelManager::instance();
 }
 
-namespace {
-
 std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles()
 {
     auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports();
@@ -85,30 +77,7 @@ std::vector<CppTools::ProjectPart*> createProjectParts(ProjectExplorer::Project
                    convertToRawPointer);
 
     return projectParts;
-}
-
-}
 
-void QtCreatorProjectUpdater::projectPartsUpdated(ProjectExplorer::Project *project)
-{
-    updateProjectParts(createProjectParts(project), createGeneratedFiles());
-}
-
-void QtCreatorProjectUpdater::projectPartsRemoved(const QStringList &projectPartIds)
-{
-    removeProjectParts(projectPartIds);
 }
-
-void QtCreatorProjectUpdater::connectToCppModelManager()
-{
-    connect(cppModelManager(),
-            &CppTools::CppModelManager::projectPartsUpdated,
-            this,
-            &QtCreatorProjectUpdater::projectPartsUpdated);
-    connect(cppModelManager(),
-            &CppTools::CppModelManager::projectPartsRemoved,
-            this,
-            &QtCreatorProjectUpdater::projectPartsRemoved);
-}
-
+} // namespace Internal
 } // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/qtcreatorprojectupdater.h b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
index ec99eab50e550ec611be60504d298c92c27a7163..44858ef93677a0a52a2df44253e377d2568c4369 100644
--- a/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
+++ b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
@@ -25,7 +25,11 @@
 
 #pragma once
 
-#include "projectupdater.h"
+#include "pchmanagerprojectupdater.h"
+
+#include <cpptools/cppmodelmanager.h>
+
+#include <filecontainerv2.h>
 
 #include <QObject>
 
@@ -33,19 +37,57 @@ namespace ProjectExplorer {
 class Project;
 }
 
+namespace CppTools {
+class CppModelManager;
+}
+
 namespace ClangPchManager {
 
-class QtCreatorProjectUpdater : public QObject, public ProjectUpdater
+namespace Internal {
+CLANGPCHMANAGER_EXPORT CppTools::CppModelManager *cppModelManager();
+CLANGPCHMANAGER_EXPORT std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles();
+CLANGPCHMANAGER_EXPORT std::vector<CppTools::ProjectPart*> createProjectParts(ProjectExplorer::Project *project);
+}
+
+template <typename ProjectUpdaterType>
+class QtCreatorProjectUpdater : public ProjectUpdaterType
 {
 public:
-    QtCreatorProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
-                            PchManagerClient &client);
+    template <typename ClientType>
+    QtCreatorProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
+                            ClientType &client)
+        : ProjectUpdaterType(server, client)
+    {
+        connectToCppModelManager();
+    }
+
+    QtCreatorProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server)
+        : ProjectUpdaterType(server)
+    {
+        connectToCppModelManager();
+    }
+
+    void projectPartsUpdated(ProjectExplorer::Project *project)
+    {
+        ProjectUpdaterType::updateProjectParts(Internal::createProjectParts(project),
+                                               Internal::createGeneratedFiles());
+    }
 
-    void projectPartsUpdated(ProjectExplorer::Project *project);
-    void projectPartsRemoved(const QStringList &projectPartIds);
+    void projectPartsRemoved(const QStringList &projectPartIds)
+    {
+        ProjectUpdaterType::removeProjectParts(projectPartIds);
+    }
 
 private:
-    void connectToCppModelManager();
+    void connectToCppModelManager()
+    {
+        QObject::connect(Internal::cppModelManager(),
+                         &CppTools::CppModelManager::projectPartsUpdated,
+                         [&] (ProjectExplorer::Project *project) { projectPartsUpdated(project); });
+        QObject::connect(Internal::cppModelManager(),
+                         &CppTools::CppModelManager::projectPartsRemoved,
+                         [&] (const QStringList &projectPartIds) { projectPartsRemoved(projectPartIds); });
+    }
 };
 
 } // namespace ClangPchManager
diff --git a/src/plugins/clangrefactoring/clangrefactoring-source.pri b/src/plugins/clangrefactoring/clangrefactoring-source.pri
index 24102dfd99d52e8055c4917280f3f473e9347f6c..b08d292190c760d94f61ee8fa00ed68dbf2534d9 100644
--- a/src/plugins/clangrefactoring/clangrefactoring-source.pri
+++ b/src/plugins/clangrefactoring/clangrefactoring-source.pri
@@ -11,7 +11,8 @@ HEADERS += \
     $$PWD/clangqueryexamplehighlightmarker.h \
     $$PWD/clangqueryhighlightmarker.h \
     $$PWD/clangqueryexamplehighlighter.h \
-    $$PWD/clangqueryhighlighter.h
+    $$PWD/clangqueryhighlighter.h \
+    $$PWD/refactoringprojectupdater.h
 
 SOURCES += \
     $$PWD/refactoringengine.cpp \
@@ -22,4 +23,5 @@ SOURCES += \
     $$PWD/projectpartutilities.cpp \
     $$PWD/clangqueryprojectsfindfilter.cpp \
     $$PWD/clangqueryexamplehighlighter.cpp \
-    $$PWD/clangqueryhighlighter.cpp
+    $$PWD/clangqueryhighlighter.cpp \
+    $$PWD/refactoringprojectupdater.cpp
diff --git a/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri b/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
index ed775ae4fcad40e658bc194608739d144740dbfd..8a08236177098123bfaadcc08fe3989e9de79129 100644
--- a/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
+++ b/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
@@ -5,4 +5,5 @@ QTC_LIB_DEPENDS += \
 QTC_PLUGIN_DEPENDS += \
     coreplugin \
     cpptools \
-    texteditor
+    texteditor \
+    clangpchmanager
diff --git a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
index 921cc240053a7cae342ad72eb951675b897a890d..ea17409faca7b877f79e0c2e2b74ad683e4edb5a 100644
--- a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
+++ b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp
@@ -25,6 +25,8 @@
 
 #include "clangrefactoringplugin.h"
 
+#include <clangpchmanager/qtcreatorprojectupdater.h>
+
 #include <cpptools/cppmodelmanager.h>
 
 #include <coreplugin/icore.h>
@@ -50,6 +52,7 @@ std::unique_ptr<ClangRefactoringPluginData> ClangRefactoringPlugin::d;
 
 class ClangRefactoringPluginData
 {
+    using ProjectUpdater = ClangPchManager::QtCreatorProjectUpdater<ClangPchManager::ProjectUpdater>;
 public:
     RefactoringClient refactoringClient;
     ClangBackEnd::RefactoringConnectionClient connectionClient{&refactoringClient};
@@ -58,6 +61,9 @@ public:
     QtCreatorClangQueryFindFilter qtCreatorfindFilter{connectionClient.serverProxy(),
                                                       qtCreatorSearch,
                                                       refactoringClient};
+    ProjectUpdater projectUpdate{connectionClient.serverProxy()};
+
+
 };
 
 ClangRefactoringPlugin::ClangRefactoringPlugin()
diff --git a/src/plugins/clangrefactoring/refactoringprojectupdater.cpp b/src/plugins/clangrefactoring/refactoringprojectupdater.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..07a9e97163f431912efc8ba43b465e7c1fb17940
--- /dev/null
+++ b/src/plugins/clangrefactoring/refactoringprojectupdater.cpp
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "refactoringprojectupdater.h"
+
+namespace ClangRefactoring {
+
+RefactoringProjectUpdater::RefactoringProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
+                                                     RefactoringClient &)
+    : ClangPchManager::ProjectUpdater(server)
+{
+
+}
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/refactoringprojectupdater.h b/src/plugins/clangrefactoring/refactoringprojectupdater.h
new file mode 100644
index 0000000000000000000000000000000000000000..3debed0c4dcbd6d3e4888921c8533688c0d89ddf
--- /dev/null
+++ b/src/plugins/clangrefactoring/refactoringprojectupdater.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <clangpchmanager/projectupdater.h>
+
+namespace ClangRefactoring {
+
+class RefactoringClient;
+
+class RefactoringProjectUpdater : public ClangPchManager::ProjectUpdater
+{
+public:
+    RefactoringProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
+                              RefactoringClient &client);
+};
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangrefactoring/sourcelocations.h b/src/plugins/clangrefactoring/sourcelocations.h
index e4cb1df45036d608ec00006c8a7c600fc2da9795..fe2d3dace94461edbe6ff6a9bada9989f1f7a1ef 100644
--- a/src/plugins/clangrefactoring/sourcelocations.h
+++ b/src/plugins/clangrefactoring/sourcelocations.h
@@ -50,6 +50,13 @@ public:
         Utils::PathString sourcePath;
     };
 
+    enum LocationGetter
+    {
+        SourceId = 0,
+        Line,
+        Column
+    };
+
     std::vector<Location> locations;
     std::unordered_map<qint64, Utils::PathString> sources;
 };
diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
index fca9a0c9fcf91a016eab89a524193d4c7064c6e4..fcf6f12f1fad117d7168fadec496915019a6eba0 100644
--- a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
+++ b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp
@@ -26,14 +26,19 @@
 #include <QCommandLineParser>
 #include <QCoreApplication>
 #include <QLoggingCategory>
+#include <QDir>
 
 #include <connectionserver.h>
+#include <stringcache.h>
 #include <refactoringserver.h>
 #include <refactoringclientproxy.h>
+#include <symbolindexing.h>
 
+using ClangBackEnd::FilePathCache;
 using ClangBackEnd::RefactoringClientProxy;
 using ClangBackEnd::RefactoringServer;
 using ClangBackEnd::ConnectionServer;
+using ClangBackEnd::SymbolIndexing;
 
 QString processArguments(QCoreApplication &application)
 {
@@ -52,7 +57,7 @@ QString processArguments(QCoreApplication &application)
 }
 
 int main(int argc, char *argv[])
-{
+try {
     //QLoggingCategory::setFilterRules(QStringLiteral("*.debug=false"));
 
     QCoreApplication::setOrganizationName(QStringLiteral("QtProject"));
@@ -64,13 +69,17 @@ int main(int argc, char *argv[])
 
     const QString connection =  processArguments(application);
 
-    RefactoringServer clangCodeModelServer;
+    FilePathCache<std::mutex> filePathCache;
+    SymbolIndexing symbolIndexing{filePathCache, Utils::PathString{QDir::tempPath() + "/symbol.db"}};
+    RefactoringServer clangCodeModelServer{symbolIndexing, filePathCache};
     ConnectionServer<RefactoringServer, RefactoringClientProxy> connectionServer(connection);
     connectionServer.start();
     connectionServer.setServer(&clangCodeModelServer);
 
 
     return application.exec();
+} catch (const Sqlite::SqliteException &exception) {
+    exception.printWarning();
 }
 
 
diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
index 21748bb071a36ed780496b00419bcde95c9a4220..8ed0c6803c07aa7e28e3e39ff1273fdb6c61374b 100644
--- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
+++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
@@ -9,7 +9,9 @@ HEADERS += \
     $$PWD/symbolscollectorinterface.h \
     $$PWD/symbolstorageinterface.h \
     $$PWD/symbolstorage.h \
-    $$PWD/storagesqlitestatementfactory.h
+    $$PWD/storagesqlitestatementfactory.h \
+    $$PWD/symbolindexing.h \
+    $$PWD/symbolindexinginterface.h
 
 !isEmpty(LIBTOOLING_LIBS) {
 SOURCES += \
@@ -55,4 +57,5 @@ SOURCES += \
     $$PWD/symbolindexer.cpp \
     $$PWD/symbolentry.cpp \
     $$PWD/sourcelocationentry.cpp \
-    $$PWD/symbolstorage.cpp
+    $$PWD/symbolstorage.cpp \
+    $$PWD/symbolindexing.cpp
diff --git a/src/tools/clangrefactoringbackend/source/clangtool.h b/src/tools/clangrefactoringbackend/source/clangtool.h
index 7957bb70448132193c18afb1a4d9195c8676f10a..0f436a0e37dda9d754517ef120644ea0f2cf0f74 100644
--- a/src/tools/clangrefactoringbackend/source/clangtool.h
+++ b/src/tools/clangrefactoringbackend/source/clangtool.h
@@ -110,4 +110,11 @@ private:
     std::vector<UnsavedFileContent> m_unsavedFileContents;
 };
 
+extern template
+void ClangTool::addFiles<Utils::SmallStringVector>(const Utils::SmallStringVector &filePaths,
+                                                   const Utils::SmallStringVector &arguments);
+extern template
+void ClangTool::addFiles<Utils::PathStringVector>(const Utils::PathStringVector &filePaths,
+                                                  const Utils::SmallStringVector &arguments);
+
 } // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h
index ceaf0ee85b7530d31e2559d93c65da4ff073bf5b..1ddd34b595f77ffea36f9d778eee927bb9b3fe63 100644
--- a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h
+++ b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h
@@ -35,12 +35,14 @@
 
 #include <clang/Frontend/FrontendAction.h>
 
+#include <mutex>
+
 namespace ClangBackEnd {
 
 class CollectSymbolsAction
 {
 public:
-    CollectSymbolsAction(FilePathCache<> &filePathCache)
+    CollectSymbolsAction(FilePathCache<std::mutex> &filePathCache)
         : m_filePathCache(filePathCache)
     {}
 
@@ -64,7 +66,7 @@ public:
 private:
     SymbolEntries m_symbolEntries;
     SourceLocationEntries m_sourceLocationEntries;
-    FilePathCache<> &m_filePathCache;
+    FilePathCache<std::mutex> &m_filePathCache;
 
 };
 
diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h
index 837ede57dae6db784a896621847a88c34bd4644a..fcedd6a6d04e2fb8ce4516dfc06f4e05f062f76c 100644
--- a/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h
+++ b/src/tools/clangrefactoringbackend/source/collectsymbolsastvisitor.h
@@ -50,7 +50,7 @@ class CollectSymbolsASTVisitor : public clang::RecursiveASTVisitor<CollectSymbol
 public:
     CollectSymbolsASTVisitor(SymbolEntries &symbolEntries,
                              SourceLocationEntries &sourceLocationEntries,
-                             FilePathCache<> &filePathCache,
+                             FilePathCache<std::mutex> &filePathCache,
                              const clang::SourceManager &sourceManager)
         : m_symbolEntries(symbolEntries),
           m_sourceLocationEntries(sourceLocationEntries),
@@ -58,8 +58,16 @@ public:
           m_sourceManager(sourceManager)
     {}
 
+    bool shouldVisitTemplateInstantiations() const
+    {
+        return true;
+    }
+
     bool VisitNamedDecl(const clang::NamedDecl *declaration)
     {
+        if (!declaration->getIdentifier())
+            return true;
+
         SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl());
         auto sourceLocation = declaration->getLocation();
 
@@ -141,7 +149,7 @@ private:
     SymbolEntries &m_symbolEntries;
     std::unordered_map<uint, FilePathIndex> m_filePathIndices;
     SourceLocationEntries &m_sourceLocationEntries;
-    FilePathCache<> &m_filePathCache;
+    FilePathCache<std::mutex> &m_filePathCache;
     const clang::SourceManager &m_sourceManager;
 };
 
diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h b/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h
index 035db37ebcb8d3903d850cc65ba052f9728e1fb9..0eeb7a73f241bbe14a476f930e1505477a882463 100644
--- a/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h
+++ b/src/tools/clangrefactoringbackend/source/collectsymbolsconsumer.h
@@ -40,13 +40,14 @@ class CollectSymbolsConsumer : public clang::ASTConsumer
 public:
     CollectSymbolsConsumer(SymbolEntries &symbolEntries,
                            SourceLocationEntries &sourceLocationEntries,
-                           FilePathCache<> &filePathCache)
+                           FilePathCache<std::mutex> &filePathCache)
         : m_symbolEntries(symbolEntries),
           m_sourceLocationEntries(sourceLocationEntries),
           m_filePathCache(filePathCache)
     {}
 
-    void HandleTranslationUnit(clang::ASTContext &astContext) override {
+    void HandleTranslationUnit(clang::ASTContext &astContext) override
+    {
         CollectSymbolsASTVisitor visitor{m_symbolEntries,
                                          m_sourceLocationEntries,
                                          m_filePathCache,
@@ -54,9 +55,20 @@ public:
         visitor.TraverseDecl(astContext.getTranslationUnitDecl());
     }
 
+     bool shouldSkipFunctionBody(clang::Decl *declation) override
+     {
+         const clang::SourceManager &sourceManager =  declation->getASTContext().getSourceManager();
+         const clang::SourceLocation location = declation->getLocation();
+
+         if (sourceManager.isInSystemHeader(location))
+             return true;
+
+         return false;
+     }
+
 private:
     SymbolEntries &m_symbolEntries;
     SourceLocationEntries &m_sourceLocationEntries;
-    FilePathCache<> &m_filePathCache;
+    FilePathCache<std::mutex> &m_filePathCache;
 };
 }
diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
index 043fa87711285779975ed597e0c2aa67dab7174f..84b588118e6a436dc59279f9b8002547f5785e00 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
+++ b/src/tools/clangrefactoringbackend/source/refactoringserver.cpp
@@ -27,6 +27,7 @@
 
 #include "symbolfinder.h"
 #include "clangquery.h"
+#include "symbolindexing.h"
 
 #include <refactoringclientinterface.h>
 #include <clangrefactoringmessages.h>
@@ -38,7 +39,10 @@
 
 namespace ClangBackEnd {
 
-RefactoringServer::RefactoringServer()
+RefactoringServer::RefactoringServer(SymbolIndexingInterface &symbolIndexing,
+                                     FilePathCache<std::mutex> &filePathCache)
+    : m_symbolIndexing(symbolIndexing),
+      m_filePathCache(filePathCache)
 {
     m_pollTimer.setInterval(100);
 
@@ -88,7 +92,17 @@ void RefactoringServer::requestSourceRangesForQueryMessage(RequestSourceRangesFo
 {
     gatherSourceRangesForQueryMessages(message.takeSources(),
                                                      message.takeUnsavedContent(),
-                                                     message.takeQuery());
+                                       message.takeQuery());
+}
+
+void RefactoringServer::updatePchProjectParts(UpdatePchProjectPartsMessage &&message)
+{
+    m_symbolIndexing.updateProjectParts(message.takeProjectsParts(), message.takeGeneratedFiles());
+}
+
+void RefactoringServer::removePchProjectParts(RemovePchProjectPartsMessage &&)
+{
+
 }
 
 void RefactoringServer::cancel()
diff --git a/src/tools/clangrefactoringbackend/source/refactoringserver.h b/src/tools/clangrefactoringbackend/source/refactoringserver.h
index 33eaee2a0a4c49c97e81499be0e83f777d8c64c3..b11cf3fc2151fd2d697fd0411d8b9edc26d0328c 100644
--- a/src/tools/clangrefactoringbackend/source/refactoringserver.h
+++ b/src/tools/clangrefactoringbackend/source/refactoringserver.h
@@ -42,6 +42,7 @@
 namespace ClangBackEnd {
 
 class SourceRangesForQueryMessage;
+class SymbolIndexingInterface;
 
 namespace V2 {
 class FileContainer;
@@ -52,12 +53,15 @@ class RefactoringServer : public RefactoringServerInterface,
 {
     using Future = std::future<SourceRangesForQueryMessage>;
 public:
-    RefactoringServer();
+    RefactoringServer(SymbolIndexingInterface &symbolIndexing,
+                      FilePathCache<std::mutex> &filePathCache);
 
     void end() override;
     void requestSourceLocationsForRenamingMessage(RequestSourceLocationsForRenamingMessage &&message) override;
     void requestSourceRangesAndDiagnosticsForQueryMessage(RequestSourceRangesAndDiagnosticsForQueryMessage &&message) override;
     void requestSourceRangesForQueryMessage(RequestSourceRangesForQueryMessage &&message) override;
+    void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) override;
+    void removePchProjectParts(RemovePchProjectPartsMessage &&message) override;
     void cancel() override;
 
     bool isCancelingJobs() const;
@@ -75,9 +79,10 @@ private:
                                                           Utils::SmallString &&query);
 
 private:
-    FilePathCache<std::mutex> m_filePathCache;
     ClangQueryGatherer m_gatherer;
     QTimer m_pollTimer;
+    SymbolIndexingInterface &m_symbolIndexing;
+    FilePathCache<std::mutex> &m_filePathCache;
 };
 
 } // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h b/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h
index 22bd7cf5f5c85844a2814e0b2a9b7ad8605fb296..8e1149ca3ffa15016b3807c0a7b364fbfb4a8d86 100644
--- a/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h
+++ b/src/tools/clangrefactoringbackend/source/storagesqlitestatementfactory.h
@@ -53,8 +53,9 @@ public:
         table.setUseIfNotExists(true);
         table.setName("symbols");
         table.addColumn("symbolId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
-        table.addColumn("usr", Sqlite::ColumnType::Text);
+        const Sqlite::SqliteColumn &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
         table.addColumn("symbolName", Sqlite::ColumnType::Text);
+        table.addIndex({usrColumn});
 
         Sqlite::SqliteImmediateTransaction<DatabaseType> transaction(database);
         table.initialize(database);
@@ -71,7 +72,8 @@ public:
         table.addColumn("symbolId", Sqlite::ColumnType::Integer);
         table.addColumn("line", Sqlite::ColumnType::Integer);
         table.addColumn("column", Sqlite::ColumnType::Integer);
-        table.addColumn("sourceId", Sqlite::ColumnType::Integer);
+        const Sqlite::SqliteColumn &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
+        table.addIndex({sourceIdColumn});
 
         Sqlite::SqliteImmediateTransaction<DatabaseType> transaction(database);
         table.initialize(database);
@@ -101,9 +103,11 @@ public:
         table.setName("newSymbols");
         table.setUseTemporaryTable(true);
         table.addColumn("temporarySymbolId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
-        table.addColumn("symbolId", Sqlite::ColumnType::Integer);
-        table.addColumn("usr", Sqlite::ColumnType::Text);
-        table.addColumn("symbolName", Sqlite::ColumnType::Text);
+        const Sqlite::SqliteColumn &symbolIdColumn = table.addColumn("symbolId", Sqlite::ColumnType::Integer);
+        const Sqlite::SqliteColumn &usrColumn = table.addColumn("usr", Sqlite::ColumnType::Text);
+        const Sqlite::SqliteColumn &symbolNameColumn = table.addColumn("symbolName", Sqlite::ColumnType::Text);
+        table.addIndex({usrColumn, symbolNameColumn});
+        table.addIndex({symbolIdColumn});
 
         Sqlite::SqliteImmediateTransaction<DatabaseType> transaction(database);
         table.initialize(database);
@@ -121,7 +125,8 @@ public:
         table.addColumn("symbolId", Sqlite::ColumnType::Integer);
         table.addColumn("line", Sqlite::ColumnType::Integer);
         table.addColumn("column", Sqlite::ColumnType::Integer);
-        table.addColumn("sourceId", Sqlite::ColumnType::Integer);
+        const Sqlite::SqliteColumn &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
+        table.addIndex({sourceIdColumn});
 
         Sqlite::SqliteImmediateTransaction<DatabaseType> transaction(database);
         table.initialize(database);
@@ -142,39 +147,49 @@ public:
         database};
     WriteStatement insertLocationsToNewLocationsStatement{
         "INSERT INTO newLocations(temporarySymbolId, line, column, sourceId) VALUES(?,?,?,?)",
-        database};
+        database
+    };
 //    WriteStatement syncNewLocationsToLocationsStatement{
 //        "INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations",
 //        database};
     ReadStatement selectNewSourceIdsStatement{
         "SELECT DISTINCT sourceId FROM newLocations WHERE NOT EXISTS (SELECT sourceId FROM sources WHERE newLocations.sourceId == sources.sourceId)",
-        database};
+        database
+    };
     WriteStatement addNewSymbolsToSymbolsStatement{
-        "INSERT INTO symbols(usr, symbolname) "
-        "SELECT usr, symbolname FROM newsymbols WHERE NOT EXISTS "
-        "(SELECT usr FROM symbols WHERE usr == newsymbols.usr)",
-        database};
+        "INSERT INTO symbols(usr, symbolName) "
+        "SELECT usr, symbolName FROM newSymbols WHERE NOT EXISTS "
+        "(SELECT usr FROM symbols WHERE symbols.usr == newSymbols.usr)",
+        database
+    };
     WriteStatement insertSourcesStatement{
         "INSERT INTO sources(sourceId, sourcePath) VALUES(?,?)",
-        database};
+        database
+    };
     WriteStatement syncNewSymbolsFromSymbolsStatement{
         "UPDATE newSymbols SET symbolId = (SELECT symbolId FROM symbols WHERE newSymbols.usr = symbols.usr)",
-        database};
+        database
+    };
     WriteStatement syncSymbolsIntoNewLocationsStatement{
         "UPDATE newLocations SET symbolId = (SELECT symbolId FROM newSymbols WHERE newSymbols.temporarySymbolId = newLocations.temporarySymbolId)",
-        database};
+        database
+    };
     WriteStatement deleteAllLocationsFromUpdatedFilesStatement{
         "DELETE FROM locations WHERE sourceId IN (SELECT DISTINCT sourceId FROM newLocations)",
-        database};
+        database
+    };
     WriteStatement insertNewLocationsInLocationsStatement{
         "INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations",
-        database};
+        database
+    };
     WriteStatement deleteNewSymbolsTableStatement{
         "DELETE FROM newSymbols",
-        database};
+        database
+    };
     WriteStatement deleteNewLocationsTableStatement{
         "DELETE FROM newLocations",
-        database};
+        database
+    };
 };
 
 } // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
index 477c7c72f476c85d95c78ae4bf7a3970dded833c..ed48d920a6f1051240a02841074c5f9c95d9f054 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
@@ -33,11 +33,14 @@ SymbolIndexer::SymbolIndexer(SymbolsCollectorInterface &symbolsCollector, Symbol
 {
 }
 
-void SymbolIndexer::updateProjectParts(V2::ProjectPartContainers &&projectParts)
+void SymbolIndexer::updateProjectParts(V2::ProjectPartContainers &&projectParts,
+                                       V2::FileContainers &&generatedFiles)
 {
     for (const V2::ProjectPartContainer &projectPart : projectParts)
         m_symbolsCollector.addFiles(projectPart.sourcePaths(), projectPart.arguments());
 
+    m_symbolsCollector.addUnsavedFiles(generatedFiles);
+
     m_symbolsCollector.collectSymbols();
 
     m_symbolStorage.addSymbolsAndSourceLocations(m_symbolsCollector.symbols(),
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.h b/src/tools/clangrefactoringbackend/source/symbolindexer.h
index 625fc21c98e85efc8e06480fbbc90e9f05592ec9..283e761da582c719f192d2899fef7556d37b3a77 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexer.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.h
@@ -29,6 +29,7 @@
 #include "symbolstorageinterface.h"
 
 #include <projectpartcontainerv2.h>
+#include <filecontainerv2.h>
 
 namespace ClangBackEnd {
 
@@ -38,7 +39,8 @@ public:
     SymbolIndexer(SymbolsCollectorInterface &symbolsCollector,
                   SymbolStorageInterface &symbolStorage);
 
-    void updateProjectParts(V2::ProjectPartContainers &&projectParts);
+    void updateProjectParts(V2::ProjectPartContainers &&projectParts,
+                            V2::FileContainers &&generatedFiles);
 
 private:
     SymbolsCollectorInterface &m_symbolsCollector;
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.cpp b/src/tools/clangrefactoringbackend/source/symbolindexing.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..11e34e449fe40f29e03780df32db908c41e521cc
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolindexing.cpp
@@ -0,0 +1,30 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "symbolindexing.h"
+
+namespace ClangBackEnd {
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h
new file mode 100644
index 0000000000000000000000000000000000000000..2986f6e4ce99bf19d43264e049d98e9060297ff8
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "symbolindexinginterface.h"
+
+#include "storagesqlitestatementfactory.h"
+#include "symbolindexer.h"
+#include "symbolscollector.h"
+#include "symbolstorage.h"
+
+#include <stringcache.h>
+
+#include <sqlitedatabase.h>
+#include <sqlitereadstatement.h>
+#include <sqlitewritestatement.h>
+
+namespace ClangBackEnd {
+
+class SymbolIndexing final : public SymbolIndexingInterface
+{
+public:
+    using StatementFactory = ClangBackEnd::StorageSqliteStatementFactory<Sqlite::SqliteDatabase,
+                                                                         Sqlite::SqliteReadStatement,
+                                                                         Sqlite::SqliteWriteStatement>;
+    using Storage = ClangBackEnd::SymbolStorage<StatementFactory>;
+
+    SymbolIndexing(FilePathCache<std::mutex> &filePathCache,
+                   Utils::PathString &&databaseFilePath)
+        : m_filePathCache(filePathCache),
+          m_database(std::move(databaseFilePath))
+
+    {
+    }
+
+    SymbolIndexer &indexer()
+    {
+        return m_indexer;
+    }
+
+    Sqlite::SqliteDatabase &database()
+    {
+        return m_database;
+    }
+
+    void updateProjectParts(V2::ProjectPartContainers &&projectParts,
+                            V2::FileContainers &&generatedFiles)
+    {
+        m_indexer.updateProjectParts(std::move(projectParts), std::move(generatedFiles));
+    }
+
+private:
+    FilePathCache<std::mutex> &m_filePathCache;
+    Sqlite::SqliteDatabase m_database;
+    SymbolsCollector m_collector{m_filePathCache};
+    StatementFactory m_statementFactory{m_database};
+    Storage m_symbolStorage{m_statementFactory, m_filePathCache};
+    SymbolIndexer m_indexer{m_collector, m_symbolStorage};
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h b/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c331aadce73dad4b5505c8994a8ebff8b856c33
--- /dev/null
+++ b/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectpartcontainerv2.h>
+#include <filecontainerv2.h>
+
+namespace ClangBackEnd {
+
+class SymbolIndexingInterface
+{
+public:
+    virtual void updateProjectParts(V2::ProjectPartContainers &&projectParts,
+                                    V2::FileContainers &&generatedFiles) = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
index f83d71e1c1492760cb1b772ef5f200f94ee3f3b2..c759232a04b681fba4142de25d64f6cc47371799 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
@@ -27,7 +27,7 @@
 
 namespace ClangBackEnd {
 
-SymbolsCollector::SymbolsCollector(FilePathCache<> &filePathCache)
+SymbolsCollector::SymbolsCollector(FilePathCache<std::mutex> &filePathCache)
     : m_collectSymbolsAction(filePathCache)
 {
 }
@@ -37,6 +37,11 @@ void SymbolsCollector::addFiles(const Utils::PathStringVector &filePaths, const
     ClangTool::addFiles(filePaths, arguments);
 }
 
+void SymbolsCollector::addUnsavedFiles(const V2::FileContainers &unsavedFiles)
+{
+    ClangTool::addUnsavedFiles(unsavedFiles);
+}
+
 void SymbolsCollector::collectSymbols()
 {
     auto tool = createTool();
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.h b/src/tools/clangrefactoringbackend/source/symbolscollector.h
index d0eb020158c3fe5fbc3ba89be8a486d682991ace..6bbdfbcf9e5c2c37a7719c6eee00351c976318cf 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollector.h
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.h
@@ -37,11 +37,13 @@ namespace ClangBackEnd {
 class SymbolsCollector : public ClangTool, public SymbolsCollectorInterface
 {
 public:
-    SymbolsCollector(FilePathCache<> &filePathCache);
+    SymbolsCollector(FilePathCache<std::mutex> &filePathCache);
 
     void addFiles(const Utils::PathStringVector &filePaths,
                   const Utils::SmallStringVector &arguments) override;
 
+    void addUnsavedFiles(const V2::FileContainers &unsavedFiles) override;
+
     void collectSymbols() override;
 
     const SymbolEntries &symbols() const override;
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
index a34705382e06f65a07adb3db573475eb70063def..fcb909bdc8f873bd99abf4ac11c59abd9f488d3f 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
+++ b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h
@@ -28,6 +28,8 @@
 #include "symbolentry.h"
 #include "sourcelocationentry.h"
 
+#include <filecontainerv2.h>
+
 #include <utils/smallstringvector.h>
 
 #include <string>
@@ -41,6 +43,8 @@ public:
     virtual void addFiles(const Utils::PathStringVector &filePaths,
                           const Utils::SmallStringVector &arguments) = 0;
 
+    virtual void addUnsavedFiles(const V2::FileContainers &unsavedFiles) = 0;
+
     virtual void collectSymbols() = 0;
 
     virtual const SymbolEntries &symbols() const = 0;
diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.h b/src/tools/clangrefactoringbackend/source/symbolstorage.h
index 12163b0f25cce4e61155d60202f36126c02add46..cbe2e570dacfcfd0af281741824a855d55930661 100644
--- a/src/tools/clangrefactoringbackend/source/symbolstorage.h
+++ b/src/tools/clangrefactoringbackend/source/symbolstorage.h
@@ -27,9 +27,12 @@
 
 #include "symbolstorageinterface.h"
 
+#include <sqliteexception.h>
 #include <sqlitetransaction.h>
 #include <stringcache.h>
 
+#include <mutex>
+
 namespace ClangBackEnd {
 
 template <typename StatementFactory>
@@ -42,7 +45,7 @@ class SymbolStorage : public SymbolStorageInterface
 
 public:
     SymbolStorage(StatementFactory &statementFactory,
-                  FilePathCache<> &filePathCache)
+                  FilePathCache<std::mutex> &filePathCache)
         : m_statementFactory(statementFactory),
           m_filePathCache(filePathCache)
     {
@@ -149,7 +152,7 @@ public:
 
 private:
     StatementFactory &m_statementFactory;
-    FilePathCache<> &m_filePathCache;
+    FilePathCache<std::mutex> &m_filePathCache;
 };
 
 } // namespace ClangBackEnd
diff --git a/tests/unit/unittest/data/symbolindexing_main1.cpp b/tests/unit/unittest/data/symbolindexing_main1.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..58df77916a0228a23e5a09cd1e2a049ba41dc42c
--- /dev/null
+++ b/tests/unit/unittest/data/symbolindexing_main1.cpp
@@ -0,0 +1,36 @@
+void function();
+
+void function()
+{
+    int x;
+    x = 20;
+}
+
+template <typename T>
+T templateFunction(T t)
+{
+    return t;
+}
+
+template <>
+int templateFunction(int t)
+{
+    return t;
+}
+
+extern template double templateFunction<double>(double);
+template double templateFunction<double>(double);
+
+template<typename T>
+using TemplateFunctionType = T(&)(T);
+
+
+TemplateFunctionType<int> aliasToTemplateFunction = templateFunction<int>;
+
+void f()
+{
+    aliasToTemplateFunction(1);
+}
+
+void f(int);
+void f(double);
diff --git a/tests/unit/unittest/data/symbolscollector_unsaved.cpp b/tests/unit/unittest/data/symbolscollector_unsaved.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a57a4e69f7428c80756c01c1fcea39b232780dc8
--- /dev/null
+++ b/tests/unit/unittest/data/symbolscollector_unsaved.cpp
@@ -0,0 +1 @@
+#include "symbolscollector_generated_file.h"
diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h
index 7792475d8fbd1a858a5f1f2ecbb3ff4494b468e3..814130f2272a531327b7d2848ab7fdf95640d85d 100644
--- a/tests/unit/unittest/gtest-creator-printing.h
+++ b/tests/unit/unittest/gtest-creator-printing.h
@@ -25,6 +25,8 @@
 
 #pragma once
 
+#include <utils/smallstringio.h>
+
 #include <QtGlobal>
 
 #include <iosfwd>
diff --git a/tests/unit/unittest/mockrefactoringserver.h b/tests/unit/unittest/mockrefactoringserver.h
index abafc15244ecda16dd28708f7a85022490a570de..c265f88cbcf6f1d15ad0772a707f3602312dbd8a 100644
--- a/tests/unit/unittest/mockrefactoringserver.h
+++ b/tests/unit/unittest/mockrefactoringserver.h
@@ -44,6 +44,12 @@ public:
     MOCK_METHOD1(requestSourceRangesForQueryMessage,
                  void (const ClangBackEnd::RequestSourceRangesForQueryMessage&));
 
+    MOCK_METHOD1(updatePchProjectParts,
+                 void (const ClangBackEnd::UpdatePchProjectPartsMessage&));
+
+    MOCK_METHOD1(removePchProjectParts,
+                 void (const ClangBackEnd::RemovePchProjectPartsMessage&));
+
     MOCK_METHOD0(cancel,
                  void());
 
@@ -61,4 +67,14 @@ public:
     {
         requestSourceRangesForQueryMessage(message);
     }
+
+    void updatePchProjectParts(ClangBackEnd::UpdatePchProjectPartsMessage &&message) override
+    {
+        updatePchProjectParts(message);
+    }
+
+    void removePchProjectParts(ClangBackEnd::RemovePchProjectPartsMessage &&message) override
+    {
+        removePchProjectParts(message);
+    }
 };
diff --git a/tests/unit/unittest/mocksymbolindexing.h b/tests/unit/unittest/mocksymbolindexing.h
new file mode 100644
index 0000000000000000000000000000000000000000..8a42ebfbc915031d85ba2ca529b091891522a42b
--- /dev/null
+++ b/tests/unit/unittest/mocksymbolindexing.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "googletest.h"
+
+#include <symbolindexinginterface.h>
+
+class MockSymbolIndexing : public ClangBackEnd::SymbolIndexingInterface
+{
+public:
+   MOCK_METHOD2(updateProjectParts,
+                void(const ClangBackEnd::V2::ProjectPartContainers &projectParts,
+                     const ClangBackEnd::V2::FileContainers &generatedFiles));
+
+   void updateProjectParts(ClangBackEnd::V2::ProjectPartContainers &&projectParts,
+                           ClangBackEnd::V2::FileContainers &&generatedFiles) override
+   {
+       updateProjectParts(projectParts, generatedFiles);
+   }
+};
+
diff --git a/tests/unit/unittest/mocksymbolscollector.h b/tests/unit/unittest/mocksymbolscollector.h
index 75e7b7442338e3ef85e2dcafa2c7c2c2d930246a..14f8f6cdf580f187a6469f932e84868aaf17f19b 100644
--- a/tests/unit/unittest/mocksymbolscollector.h
+++ b/tests/unit/unittest/mocksymbolscollector.h
@@ -39,6 +39,9 @@ public:
                  void(const Utils::PathStringVector &filePaths,
                       const Utils::SmallStringVector &arguments));
 
+    MOCK_METHOD1(addUnsavedFiles,
+                 void(const ClangBackEnd::V2::FileContainers &unsavedFiles));
+
     MOCK_CONST_METHOD0(symbols,
                        const ClangBackEnd::SymbolEntries &());
 
diff --git a/tests/unit/unittest/pchmanagerclient-test.cpp b/tests/unit/unittest/pchmanagerclient-test.cpp
index 3f26243cc594c66d66a55a93fea6fdd34b5c0e45..53a544841d65d31337d5a064029681c29f09928b 100644
--- a/tests/unit/unittest/pchmanagerclient-test.cpp
+++ b/tests/unit/unittest/pchmanagerclient-test.cpp
@@ -29,7 +29,7 @@
 #include "mockpchmanagerserver.h"
 
 #include <pchmanagerclient.h>
-#include <projectupdater.h>
+#include <pchmanagerprojectupdater.h>
 
 #include <precompiledheadersupdatedmessage.h>
 #include <removepchprojectpartsmessage.h>
@@ -49,7 +49,7 @@ protected:
     MockPchManagerServer mockPchManagerServer;
     ClangPchManager::PchManagerClient client;
     MockPchManagerNotifier mockPchManagerNotifier{client};
-    ClangPchManager::ProjectUpdater projectUpdater{mockPchManagerServer, client};
+    ClangPchManager::PchManagerProjectUpdater projectUpdater{mockPchManagerServer, client};
     Utils::SmallString projectPartId{"projectPartId"};
     Utils::SmallString pchFilePath{"/path/to/pch"};
     PrecompiledHeadersUpdatedMessage message{{{projectPartId.clone(), pchFilePath.clone()}}};
diff --git a/tests/unit/unittest/projectupdater-test.cpp b/tests/unit/unittest/projectupdater-test.cpp
index 98cb1b05d8d6e3b7624217ac04a42220b891c5d6..071f9ea5db2e6f1221c7fb185378968b8df663ec 100644
--- a/tests/unit/unittest/projectupdater-test.cpp
+++ b/tests/unit/unittest/projectupdater-test.cpp
@@ -29,7 +29,7 @@
 #include "mockpchmanagernotifier.h"
 #include "mockpchmanagerserver.h"
 
-#include <projectupdater.h>
+#include <pchmanagerprojectupdater.h>
 
 #include <pchmanagerclient.h>
 #include <precompiledheadersupdatedmessage.h>
@@ -60,7 +60,7 @@ protected:
     ClangPchManager::PchManagerClient pchManagerClient;
     MockPchManagerNotifier mockPchManagerNotifier{pchManagerClient};
     NiceMock<MockPchManagerServer> mockPchManagerServer;
-    ClangPchManager::ProjectUpdater updater{mockPchManagerServer, pchManagerClient};
+    ClangPchManager::ProjectUpdater updater{mockPchManagerServer};
     Utils::SmallString projectPartId{"project1"};
     Utils::SmallString projectPartId2{"project2"};
     Utils::PathStringVector headerPaths = {"/path/to/header1.h", "/path/to/header2.h"};
@@ -87,7 +87,7 @@ TEST_F(ProjectUpdater, CallUpdatePchProjectParts)
 
 TEST_F(ProjectUpdater, CallRemovePchProjectParts)
 {
-    EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(_)).Times(AnyNumber());
+
     ClangBackEnd::RemovePchProjectPartsMessage message{{projectPartId, projectPartId2}};
 
     EXPECT_CALL(mockPchManagerServer, removePchProjectParts(message));
@@ -95,14 +95,15 @@ TEST_F(ProjectUpdater, CallRemovePchProjectParts)
     updater.removeProjectParts({QString(projectPartId), QString(projectPartId2)});
 }
 
-TEST_F(ProjectUpdater, CallPrecompiledHeaderRemoved)
+TEST_F(ProjectUpdater, CallPrecompiledHeaderRemovedInPchManagerProjectUpdater)
 {
+    ClangPchManager::PchManagerProjectUpdater pchUpdater{mockPchManagerServer, pchManagerClient};
     ClangBackEnd::RemovePchProjectPartsMessage message{{projectPartId, projectPartId2}};
 
     EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId.toQString()));
     EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId2.toQString()));
 
-    updater.removeProjectParts({QString(projectPartId), QString(projectPartId2)});
+    pchUpdater.removeProjectParts({QString(projectPartId), QString(projectPartId2)});
 }
 
 TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainer)
diff --git a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
index aaac7c14335f2df238a962205a1504765f1aee31..f1ce7a9f5f16bc5db766f2ea7dd3bcdc1f87ddcd 100644
--- a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
+++ b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
@@ -47,6 +47,11 @@ using ::testing::Args;
 using ::testing::Property;
 using ::testing::Eq;
 
+using ClangBackEnd::UpdatePchProjectPartsMessage;
+using ClangBackEnd::V2::FileContainer;
+using ClangBackEnd::V2::ProjectPartContainer;
+using ClangBackEnd::RemovePchProjectPartsMessage;
+
 class RefactoringClientServerInProcess : public ::testing::Test
 {
 protected:
@@ -169,6 +174,31 @@ TEST_F(RefactoringClientServerInProcess, RequestSourceRangesForQueryMessage)
     scheduleServerMessages();
 }
 
+TEST_F(RefactoringClientServerInProcess, SendUpdatePchProjectPartsMessage)
+{
+    ProjectPartContainer projectPart2{"projectPartId",
+                                      {"-x", "c++-header", "-Wno-pragma-once-outside-header"},
+                                      {TESTDATA_DIR "/includecollector_header.h"},
+                                      {TESTDATA_DIR "/includecollector_main.cpp"}};
+    FileContainer fileContainer{{"/path/to/", "file"}, "content", {}};
+    UpdatePchProjectPartsMessage message{{projectPart2}, {fileContainer}};
+
+    EXPECT_CALL(mockRefactoringServer, updatePchProjectParts(message));
+
+    serverProxy.updatePchProjectParts(message.clone());
+    scheduleServerMessages();
+}
+
+TEST_F(RefactoringClientServerInProcess, SendRemovePchProjectPartsMessage)
+{
+    RemovePchProjectPartsMessage message{{"projectPartId1", "projectPartId2"}};
+
+    EXPECT_CALL(mockRefactoringServer, removePchProjectParts(message));
+
+    serverProxy.removePchProjectParts(message.clone());
+    scheduleServerMessages();
+}
+
 TEST_F(RefactoringClientServerInProcess, CancelMessage)
 {
     EXPECT_CALL(mockRefactoringServer, cancel());
diff --git a/tests/unit/unittest/refactoringserver-test.cpp b/tests/unit/unittest/refactoringserver-test.cpp
index b07d490a12dbb24ecdfc21fe04e011b78a71918e..8b2586ba0bf20eb20f66e94381ade4429c72d206 100644
--- a/tests/unit/unittest/refactoringserver-test.cpp
+++ b/tests/unit/unittest/refactoringserver-test.cpp
@@ -27,6 +27,7 @@
 
 #include "filesystem-utilities.h"
 #include "mockrefactoringclient.h"
+#include "mocksymbolindexing.h"
 #include "sourcerangecontainer-matcher.h"
 
 #include <refactoringserver.h>
@@ -57,6 +58,9 @@ using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage;
 using ClangBackEnd::SourceRangesForQueryMessage;
 using ClangBackEnd::SourceRangesContainer;
 using ClangBackEnd::V2::FileContainer;
+using ClangBackEnd::V2::FileContainers;
+using ClangBackEnd::V2::ProjectPartContainer;
+using ClangBackEnd::V2::ProjectPartContainers;
 
 MATCHER_P2(IsSourceLocation, line, column,
            std::string(negation ? "isn't " : "is ")
@@ -76,8 +80,10 @@ protected:
     void TearDown() override;
 
 protected:
-    ClangBackEnd::RefactoringServer refactoringServer;
     NiceMock<MockRefactoringClient> mockRefactoringClient;
+    NiceMock<MockSymbolIndexing> mockSymbolIndexing;
+    ClangBackEnd::FilePathCache<std::mutex> filePathCache;
+    ClangBackEnd::RefactoringServer refactoringServer{mockSymbolIndexing, filePathCache};
     Utils::SmallString sourceContent{"void f()\n {}"};
     FileContainer source{{TESTDATA_DIR, "query_simplefunction.cpp"},
                          sourceContent.clone(),
@@ -283,6 +289,23 @@ TEST_F(RefactoringServerSlowTest, ForInvalidRequestSourceRangesAndDiagnosticsGet
     refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message));
 }
 
+TEST_F(RefactoringServer, UpdatePchProjectPartsCallsSymbolIndexingUpdateProjectParts)
+{
+    ProjectPartContainers projectParts{{{"projectPartId",
+                                        {"-I", TESTDATA_DIR},
+                                        {"header1.h"},
+                                        {"main.cpp"}}}};
+    FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
+                            "void f();",
+                            {}}};
+
+
+    EXPECT_CALL(mockSymbolIndexing,
+                updateProjectParts(projectParts, unsaved));
+
+    refactoringServer.updatePchProjectParts({Utils::clone(projectParts), Utils::clone(unsaved)});
+}
+
 void RefactoringServer::SetUp()
 {
     temporaryFile.open();
diff --git a/tests/unit/unittest/sqlitedatabase-test.cpp b/tests/unit/unittest/sqlitedatabase-test.cpp
index 85b8a68e80904c6592923eb0e83d29da183e25e4..7c9cd9cf0e14bfeb511eb3ea695a8c2c478c09ee 100644
--- a/tests/unit/unittest/sqlitedatabase-test.cpp
+++ b/tests/unit/unittest/sqlitedatabase-test.cpp
@@ -96,6 +96,18 @@ TEST_F(SqliteDatabase, AddTable)
     ASSERT_THAT(database.tables(), Contains(sqliteTable));
 }
 
+TEST_F(SqliteDatabase, TableIsReadyAfterOpenDatabase)
+{
+    database.close();
+    auto &table = database.addTable();
+    table.setName("foo");
+    table.addColumn("name");
+
+    database.open();
+
+    ASSERT_TRUE(table.isReady());
+}
+
 void SqliteDatabase::SetUp()
 {
     database.setJournalMode(JournalMode::Memory);
diff --git a/tests/unit/unittest/sqliteindex-test.cpp b/tests/unit/unittest/sqliteindex-test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dcf02fa02cb913ddebcc0031a4a88016dd443b55
--- /dev/null
+++ b/tests/unit/unittest/sqliteindex-test.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <sqliteindex.h>
+
+namespace {
+
+using Sqlite::SqliteException;
+using Sqlite::SqliteIndex;
+
+TEST(SqliteIndex, OneColumn)
+{
+    SqliteIndex index{"tableName", {"column1"}};
+
+    auto sqlStatement = index.sqlStatement();
+
+    ASSERT_THAT(sqlStatement, Eq("CREATE INDEX IF NOT EXISTS index_tableName_column1 ON tableName(column1)"));
+}
+
+TEST(SqliteIndex, TwoColumn)
+{
+    SqliteIndex index{"tableName", {"column1", "column2"}};
+
+    auto sqlStatement = index.sqlStatement();
+
+    ASSERT_THAT(sqlStatement, Eq("CREATE INDEX IF NOT EXISTS index_tableName_column1_column2 ON tableName(column1, column2)"));
+}
+
+TEST(SqliteIndex, EmptyTableName)
+{
+    SqliteIndex index{"", {"column1", "column2"}};
+
+    ASSERT_THROW(index.sqlStatement(), SqliteException);
+}
+
+TEST(SqliteIndex, EmptyColumns)
+{
+    SqliteIndex index{"tableName", {}};
+
+    ASSERT_THROW(index.sqlStatement(), SqliteException);
+}
+}
diff --git a/tests/unit/unittest/sqlitetable-test.cpp b/tests/unit/unittest/sqlitetable-test.cpp
index 7873181580c7fedc18fffcb3841886edbed4cc5f..fc5917d29671480c3a14d76c293e0b030e4d6e6f 100644
--- a/tests/unit/unittest/sqlitetable-test.cpp
+++ b/tests/unit/unittest/sqlitetable-test.cpp
@@ -27,7 +27,7 @@
 #include "spydummy.h"
 
 #include <sqlitecolumn.h>
-#include <sqlitedatabase.h>
+#include <mocksqlitedatabase.h>
 #include <sqlitetable.h>
 
 namespace {
@@ -41,13 +41,8 @@ using Sqlite::SqliteDatabase;
 class SqliteTable : public ::testing::Test
 {
 protected:
-    void SetUp() override;
-    void TearDown() override;
-
-protected:
-    SpyDummy spyDummy;
-    SqliteDatabase database;
-    Sqlite::SqliteTable &table = database.addTable();
+    NiceMock<MockSqliteDatabase> mockDatabase;
+    Sqlite::SqliteTable table;
     Utils::SmallString tableName = "testTable";
 };
 
@@ -73,26 +68,46 @@ TEST_F(SqliteTable, SetUseWithoutRowid)
     ASSERT_TRUE(table.useWithoutRowId());
 }
 
-TEST_F(SqliteTable, TableIsReadyAfterOpenDatabase)
+TEST_F(SqliteTable, AddIndex)
 {
     table.setName(tableName.clone());
-    table.addColumn("name");
+    auto &column = table.addColumn("name");
+    auto &column2 = table.addColumn("value");
 
-    database.open();
+    auto index = table.addIndex({column, column2});
 
-    ASSERT_TRUE(table.isReady());
+    ASSERT_THAT(Utils::SmallStringView(index.sqlStatement()),
+                Eq("CREATE INDEX IF NOT EXISTS index_testTable_name_value ON testTable(name, value)"));
 }
 
-void SqliteTable::SetUp()
+TEST_F(SqliteTable, InitializeTable)
 {
-    database.setJournalMode(JournalMode::Memory);
-    database.setDatabaseFilePath( QStringLiteral(":memory:"));
+    table.setName(tableName.clone());
+    table.setUseIfNotExists(true);
+    table.setUseTemporaryTable(true);
+    table.setUseWithoutRowId(true);
+    table.addColumn("name");
+    table.addColumn("value");
+
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE IF NOT EXISTS testTable(name NUMERIC, value NUMERIC) WITHOUT ROWID")));
+
+    table.initialize(mockDatabase);
 }
 
-void SqliteTable::TearDown()
+TEST_F(SqliteTable, InitializeTableWithIndex)
 {
-    if (database.isOpen())
-        database.close();
+    InSequence sequence;
+    table.setName(tableName.clone());
+    auto &column = table.addColumn("name");
+    auto &column2 = table.addColumn("value");
+    table.addIndex({column});
+    table.addIndex({column2});
+
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE testTable(name NUMERIC, value NUMERIC)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_name ON testTable(name)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_value ON testTable(value)")));
+
+    table.initialize(mockDatabase);
 }
 
 }
diff --git a/tests/unit/unittest/storagesqlitestatementfactory-test.cpp b/tests/unit/unittest/storagesqlitestatementfactory-test.cpp
index 98c99d908e22534a2129aa79c4b62e91f1c09bb6..1553ad76f9be9c7927c28e4e2c764d909d8aa315 100644
--- a/tests/unit/unittest/storagesqlitestatementfactory-test.cpp
+++ b/tests/unit/unittest/storagesqlitestatementfactory-test.cpp
@@ -52,6 +52,7 @@ TEST_F(StorageSqliteStatementFactory, AddSymbolsTable)
 
     EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE")));
     EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_usr ON symbols(usr)")));
     EXPECT_CALL(mockDatabase, execute(Eq("COMMIT")));
 
     factory.createSymbolsTable();
@@ -63,6 +64,7 @@ TEST_F(StorageSqliteStatementFactory, AddLocationsTable)
 
     EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE")));
     EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId ON locations(sourceId)")));
     EXPECT_CALL(mockDatabase, execute(Eq("COMMIT")));
 
     factory.createLocationsTable();
@@ -85,6 +87,8 @@ TEST_F(StorageSqliteStatementFactory, AddNewSymbolsTable)
 
     EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE")));
     EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_usr_symbolName ON newSymbols(usr, symbolName)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_symbolId ON newSymbols(symbolId)")));
     EXPECT_CALL(mockDatabase, execute(Eq("COMMIT")));
 
     factory.createNewSymbolsTable();
@@ -97,6 +101,7 @@ TEST_F(StorageSqliteStatementFactory, AddNewLocationsTable)
 
     EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE")));
     EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newLocations_sourceId ON newLocations(sourceId)")));
     EXPECT_CALL(mockDatabase, execute(Eq("COMMIT")));
 
     factory.createNewLocationsTable();
@@ -108,10 +113,15 @@ TEST_F(StorageSqliteStatementFactory, AddTablesInConstructor)
     EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))).Times(5);
 
     EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_usr ON symbols(usr)")));
     EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId ON locations(sourceId)")));
     EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, sourcePath TEXT)")));
     EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_usr_symbolName ON newSymbols(usr, symbolName)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_symbolId ON newSymbols(symbolId)")));
     EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)")));
+    EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newLocations_sourceId ON newLocations(sourceId)")));
 
     StatementFactory factory{mockDatabase};
 }
@@ -137,7 +147,7 @@ TEST_F(StorageSqliteStatementFactory, SelectNewSourceIdsStatement)
 TEST_F(StorageSqliteStatementFactory, AddNewSymbolsToSymbolsStatement)
 {
     ASSERT_THAT(factory.addNewSymbolsToSymbolsStatement.sqlStatement,
-                Eq("INSERT INTO symbols(usr, symbolname) SELECT usr, symbolname FROM newsymbols WHERE NOT EXISTS (SELECT usr FROM symbols WHERE usr == newsymbols.usr)"));
+                Eq("INSERT INTO symbols(usr, symbolName) SELECT usr, symbolName FROM newSymbols WHERE NOT EXISTS (SELECT usr FROM symbols WHERE symbols.usr == newSymbols.usr)"));
 }
 
 TEST_F(StorageSqliteStatementFactory, InsertSourcesStatement)
diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp
index 35a09fbef0d8ec90e1e8f526e8753d6ffb7c390d..6684b2cddb2659790ba47e8aaa9ce5642246508f 100644
--- a/tests/unit/unittest/symbolindexer-test.cpp
+++ b/tests/unit/unittest/symbolindexer-test.cpp
@@ -46,6 +46,7 @@ using testing::Sequence;
 using Utils::PathString;
 using ClangBackEnd::V2::ProjectPartContainer;
 using ClangBackEnd::V2::ProjectPartContainers;
+using ClangBackEnd::V2::FileContainers;
 using ClangBackEnd::SymbolEntries;
 using ClangBackEnd::SymbolEntry;
 using ClangBackEnd::SourceLocationEntries;
@@ -72,6 +73,9 @@ protected:
                                       {"-I", TESTDATA_DIR, "-x", "c++-header", "-Wno-pragma-once-outside-header"},
                                       {header2Path.clone()},
                                       {main2Path.clone()}};
+    FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
+                            "void f();",
+                            {}}};
     SymbolEntries symbolEntries{{1, {"function", "function"}}};
     SourceLocationEntries sourceLocations{{1, 1, {42, 23}, SymbolType::Declaration}};
     NiceMock<MockSymbolsCollector> mockCollector;
@@ -83,7 +87,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollector)
 {
     EXPECT_CALL(mockCollector, addFiles(projectPart1.sourcePaths(), projectPart1.arguments()));
 
-    indexer.updateProjectParts({projectPart1});
+    indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
 }
 
 TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollectorForEveryProjectPart)
@@ -91,7 +95,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollectorForEveryProjectP
     EXPECT_CALL(mockCollector, addFiles(_, _))
             .Times(2);
 
-    indexer.updateProjectParts({projectPart1, projectPart2});
+    indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved));
 }
 
 TEST_F(SymbolIndexer, UpdateProjectPartsDoesNotCallAddFilesInCollectorForEmptyEveryProjectParts)
@@ -99,48 +103,54 @@ TEST_F(SymbolIndexer, UpdateProjectPartsDoesNotCallAddFilesInCollectorForEmptyEv
     EXPECT_CALL(mockCollector, addFiles(_, _))
             .Times(0);
 
-    indexer.updateProjectParts({});
+    indexer.updateProjectParts({}, {});
 }
 
 TEST_F(SymbolIndexer, UpdateProjectPartsCallscollectSymbolsInCollector)
 {
     EXPECT_CALL(mockCollector, collectSymbols());
 
-    indexer.updateProjectParts({projectPart1});
+    indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
 }
 
 TEST_F(SymbolIndexer, UpdateProjectPartsCallsSymbolsInCollector)
 {
     EXPECT_CALL(mockCollector, symbols());
 
-    indexer.updateProjectParts({projectPart1});
+    indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
 }
 
 TEST_F(SymbolIndexer, UpdateProjectPartsCallsSourceLocationsInCollector)
 {
     EXPECT_CALL(mockCollector, sourceLocations());
 
-    indexer.updateProjectParts({projectPart1});
+    indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
+}
+
+TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddUnsavedFilesInCollector)
+{
+    EXPECT_CALL(mockCollector, addUnsavedFiles(unsaved));
+
+    indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
 }
 
 TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddSymbolsAndSourceLocationsInStorage)
 {
     EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
 
-    indexer.updateProjectParts({projectPart1});
+    indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
 }
 
 TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrder)
 {
-    Sequence sequence;
-
     EXPECT_CALL(mockCollector, addFiles(_, _));
+    EXPECT_CALL(mockCollector, addUnsavedFiles(unsaved));
     EXPECT_CALL(mockCollector, collectSymbols());
     EXPECT_CALL(mockCollector, symbols());
     EXPECT_CALL(mockCollector, sourceLocations());
     EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
 
-    indexer.updateProjectParts({projectPart1});
+    indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved));
 }
 
 void SymbolIndexer::SetUp()
diff --git a/tests/unit/unittest/symbolindexing-test.cpp b/tests/unit/unittest/symbolindexing-test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1ed64e6debc9971e944eb9e17b296dd892a431b0
--- /dev/null
+++ b/tests/unit/unittest/symbolindexing-test.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <projectpartcontainerv2.h>
+
+#include <symbolindexing.h>
+#include <symbolquery.h>
+#include <querysqlitestatementfactory.h>
+
+#include <QDir>
+
+namespace {
+
+using Sqlite::SqliteDatabase;
+using Sqlite::SqliteReadStatement;
+using ClangBackEnd::SymbolIndexer;
+using ClangBackEnd::SymbolsCollector;
+using ClangBackEnd::SymbolStorage;
+using ClangBackEnd::FilePathCache;
+using ClangBackEnd::FilePathCache;
+using ClangBackEnd::V2::ProjectPartContainer;
+using ClangBackEnd::V2::ProjectPartContainer;
+using ClangRefactoring::SymbolQuery;
+using ClangRefactoring::QuerySqliteStatementFactory;
+using Utils::PathString;
+using SL = ClangRefactoring::SourceLocations;
+
+using StatementFactory = QuerySqliteStatementFactory<SqliteDatabase, SqliteReadStatement>;
+using Query = SymbolQuery<StatementFactory>;
+
+MATCHER_P3(IsLocation, sourceId, line, column,
+           std::string(negation ? "isn't" : "is")
+           + " source id " + PrintToString(sourceId)
+           + " line " + PrintToString(line)
+           + " and column " + PrintToString(column)
+           )
+{
+    const SL::Location &location = arg;
+
+    return location.sourceId == sourceId
+        && location.line == line
+        && location.column == column;
+};
+
+class SymbolIndexing : public testing::Test
+{
+protected:
+    FilePathCache<std::mutex> filePathCache;
+    ClangBackEnd::SymbolIndexing indexing{filePathCache, QDir::tempPath() + "/symbol.db"};
+    StatementFactory queryFactory{indexing.database()};
+    Query query{queryFactory};
+    PathString main1Path = TESTDATA_DIR "/symbolindexing_main1.cpp";
+    ProjectPartContainer projectPart1{"project1",
+                                      {"cc", "-I", TESTDATA_DIR, "-std=c++1z"},
+                                      {},
+                                      {main1Path.clone()}};
+};
+
+TEST_F(SymbolIndexing, Locations)
+{
+    indexing.indexer().updateProjectParts({projectPart1}, {});
+
+    auto locations = query.locationsAt(TESTDATA_DIR "/symbolindexing_main1.cpp", 6, 5);
+    ASSERT_THAT(locations.locations,
+                ElementsAre(
+                    IsLocation(0, 5, 9),
+                    IsLocation(0, 6, 5)));
+}
+
+TEST_F(SymbolIndexing, Sources)
+{
+    indexing.indexer().updateProjectParts({projectPart1}, {});
+
+    auto locations = query.locationsAt(TESTDATA_DIR "/symbolindexing_main1.cpp", 6, 5);
+    ASSERT_THAT(locations.sources, ElementsAre(Pair(0, Eq(TESTDATA_DIR "/symbolindexing_main1.cpp"))));
+}
+
+TEST_F(SymbolIndexing, DISABLED_TemplateFunction)
+{
+    indexing.indexer().updateProjectParts({projectPart1}, {});
+
+    auto locations = query.locationsAt(TESTDATA_DIR "/symbolindexing_main1.cpp", 21, 24);
+    ASSERT_THAT(locations.locations,
+                ElementsAre(
+                    IsLocation(0, 5, 9),
+                    IsLocation(0, 6, 5)));
+}
+}
diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp
index 4543c61e446c07598bca52a8aa5d618d297944c5..9b1f046cbd7e5b372670dd86bad03319af22d5a8 100644
--- a/tests/unit/unittest/symbolscollector-test.cpp
+++ b/tests/unit/unittest/symbolscollector-test.cpp
@@ -39,6 +39,7 @@ using testing::Pair;
 using testing::Value;
 using testing::_;
 
+using ClangBackEnd::V2::FileContainers;
 using ClangBackEnd::SourceLocationEntry;
 using ClangBackEnd::SymbolEntry;
 using ClangBackEnd::SymbolType;
@@ -57,7 +58,7 @@ protected:
     SymbolIndex symbolIdForSymbolName(const Utils::SmallString &symbolName);
 
 protected:
-    ClangBackEnd::FilePathCache<> filePathCache;
+    ClangBackEnd::FilePathCache<std::mutex> filePathCache;
     ClangBackEnd::SymbolsCollector collector{filePathCache};
 };
 
@@ -150,6 +151,21 @@ TEST_F(SymbolsCollector, ReferencedSymboldMatchesLocation)
                           Field(&SourceLocationEntry::column, 5))));
 }
 
+TEST_F(SymbolsCollector, DISABLED_ON_WINDOWS(CollectInUnsavedFile))
+{
+    FileContainers unsaved{{{TESTDATA_DIR, "symbolscollector_generated_file.h"},
+                            "void function();",
+                            {}}};
+    collector.addFile(TESTDATA_DIR, "symbolscollector_unsaved.cpp", "", {"cc", TESTDATA_DIR"/symbolscollector_unsaved.cpp"});
+    collector.addUnsavedFiles(std::move(unsaved));
+
+    collector.collectSymbols();
+
+    ASSERT_THAT(collector.symbols(),
+                Contains(
+                    Pair(_, Field(&SymbolEntry::symbolName, "function"))));
+}
+
 SymbolIndex SymbolsCollector::symbolIdForSymbolName(const Utils::SmallString &symbolName)
 {
     for (const auto &entry : collector.symbols()) {
diff --git a/tests/unit/unittest/symbolstorage-test.cpp b/tests/unit/unittest/symbolstorage-test.cpp
index ec30b9289df93306c2c140c5561c37f3bed7f3ae..fbe9ab9cc455390cbb10e6eaa577c4de8b7d5211 100644
--- a/tests/unit/unittest/symbolstorage-test.cpp
+++ b/tests/unit/unittest/symbolstorage-test.cpp
@@ -58,7 +58,7 @@ protected:
     void SetUp();
 
 protected:
-    FilePathCache<> filePathCache;
+    FilePathCache<std::mutex> filePathCache;
     NiceMock<MockSqliteDatabase> mockDatabase;
     StatementFactory statementFactory{mockDatabase};
 
diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro
index db1b818c8a15d94e6fddd992fcb80e7b8dfbd876..1f1b490536a03e3943ceafa16831faac9119328d 100644
--- a/tests/unit/unittest/unittest.pro
+++ b/tests/unit/unittest/unittest.pro
@@ -74,7 +74,9 @@ SOURCES += \
     mocksqlitereadstatement.cpp \
     symbolquery-test.cpp \
     storagesqlitestatementfactory-test.cpp \
-    querysqlitestatementfactory-test.cpp
+    querysqlitestatementfactory-test.cpp \
+    symbolindexing-test.cpp \
+    sqliteindex-test.cpp
 
 !isEmpty(LIBCLANG_LIBS) {
 SOURCES += \
@@ -197,7 +199,8 @@ HEADERS += \
     mocksqlitewritestatement.h \
     mocksqlitedatabase.h \
     mocksqlitereadstatement.h \
-    google-using-declarations.h
+    google-using-declarations.h \
+    mocksymbolindexing.h
 
 !isEmpty(LIBCLANG_LIBS) {
 HEADERS += \