diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index f6b5384b45715bf15854b7c293f6b8883d6e1123..b3f9fb604c3c46e6866f9a03eb6065a63942c13a 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -129,9 +129,12 @@ public:
     void setProjectFiles(const QStringList &files)
     { m_projectFiles = files; }
 
-    void operator()(QString &fileName)
+    void run(QString &fileName)
     { sourceNeeded(fileName, IncludeGlobal); }
 
+    void operator()(QString &fileName)
+    { run(fileName); }
+
 protected:
     bool includeFile(const QString &absoluteFilePath, QByteArray *result)
     {
@@ -409,6 +412,8 @@ CppModelManager::CppModelManager(QObject *parent) :
     CppModelManagerInterface(parent),
     m_core(ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>())
 {
+    m_dirty = true;
+
     m_projectExplorer = ExtensionSystem::PluginManager::instance()
                         ->getObject<ProjectExplorer::ProjectExplorerPlugin>();
 
@@ -417,6 +422,9 @@ CppModelManager::CppModelManager(QObject *parent) :
     ProjectExplorer::SessionManager *session = m_projectExplorer->session();
     Q_ASSERT(session != 0);
 
+    connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
+            this, SLOT(onProjectAdded(ProjectExplorer::Project*)));
+
     connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)),
             this, SLOT(onAboutToRemoveProject(ProjectExplorer::Project *)));
 
@@ -448,7 +456,7 @@ Document::Ptr CppModelManager::document(const QString &fileName)
 CppModelManager::DocumentTable CppModelManager::documents()
 { return m_documents; }
 
-QStringList CppModelManager::projectFiles() const
+QStringList CppModelManager::updateProjectFiles() const
 {
     QStringList files;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -460,7 +468,7 @@ QStringList CppModelManager::projectFiles() const
     return files;
 }
 
-QStringList CppModelManager::includePaths() const
+QStringList CppModelManager::updateIncludePaths() const
 {
     QStringList includePaths;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -472,7 +480,7 @@ QStringList CppModelManager::includePaths() const
     return includePaths;
 }
 
-QStringList CppModelManager::frameworkPaths() const
+QStringList CppModelManager::updateFrameworkPaths() const
 {
     QStringList frameworkPaths;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -484,7 +492,7 @@ QStringList CppModelManager::frameworkPaths() const
     return frameworkPaths;
 }
 
-QByteArray CppModelManager::definedMacros() const
+QByteArray CppModelManager::updateDefinedMacros() const
 {
     QByteArray macros;
     QMapIterator<ProjectExplorer::Project *, ProjectInfo> it(m_projects);
@@ -496,7 +504,7 @@ QByteArray CppModelManager::definedMacros() const
     return macros;
 }
 
-QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList() const
+QMap<QString, QByteArray> CppModelManager::buildWorkingCopyList()
 {
     QMap<QString, QByteArray> workingCopy;
     QMapIterator<TextEditor::ITextEditor *, CppEditorSupport *> it(m_editorSupport);
@@ -527,8 +535,14 @@ QFuture<void> CppModelManager::refreshSourceFiles(const QStringList &sourceFiles
     if (! sourceFiles.isEmpty() && qgetenv("QTCREATOR_NO_CODE_INDEXER").isNull()) {
         const QMap<QString, QByteArray> workingCopy = buildWorkingCopyList();
 
-        QFuture<void> result = QtConcurrent::run(&CppModelManager::parse, this,
-                                                 sourceFiles, workingCopy);
+        CppPreprocessor *preproc = new CppPreprocessor(this);
+        preproc->setProjectFiles(projectFiles());
+        preproc->setIncludePaths(includePaths());
+        preproc->setFrameworkPaths(frameworkPaths());
+        preproc->setWorkingCopy(workingCopy);
+
+        QFuture<void> result = QtConcurrent::run(&CppModelManager::parse,
+                                                 preproc, sourceFiles);
 
         if (sourceFiles.count() > 1) {
             m_core->progressManager()->addTask(result, tr("Indexing"),
@@ -675,22 +689,29 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
     }
 }
 
+void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
+{
+    m_dirty = true;
+}
+
 void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
 {
+    m_dirty = true;
     m_projects.remove(project);
     GC();
 }
 
 void CppModelManager::onSessionUnloaded()
 {
-    if (m_core->progressManager())
+    if (m_core->progressManager()) {
         m_core->progressManager()->cancelTasks(CppTools::Constants::TASK_INDEX);
+        m_dirty = true;
+    }
 }
 
 void CppModelManager::parse(QFutureInterface<void> &future,
-                            CppModelManager *model,
-                            QStringList files,
-                            QMap<QString, QByteArray> workingCopy)
+                            CppPreprocessor *preproc,
+                            QStringList files)
 {
     Q_ASSERT(! files.isEmpty());
 
@@ -699,14 +720,8 @@ void CppModelManager::parse(QFutureInterface<void> &future,
 
     future.setProgressRange(0, files.size());
 
-    CppPreprocessor preproc(model);
-    preproc.setWorkingCopy(workingCopy);
-    preproc.setProjectFiles(model->projectFiles());
-    preproc.setIncludePaths(model->includePaths());
-    preproc.setFrameworkPaths(model->frameworkPaths());
-
     QString conf = QLatin1String(pp_configuration_file);
-    (void) preproc(conf);
+    (void) preproc->run(conf);
 
     const int STEP = 10;
 
@@ -725,7 +740,7 @@ void CppModelManager::parse(QFutureInterface<void> &future,
 #endif
 
         QString fileName = files.at(i);
-        preproc(fileName);
+        preproc->run(fileName);
 
         if (! (i % STEP)) // Yields execution of the current thread.
             QThread::yieldCurrentThread();
@@ -739,6 +754,8 @@ void CppModelManager::parse(QFutureInterface<void> &future,
 
     // Restore the previous thread priority.
     QThread::currentThread()->setPriority(QThread::NormalPriority);
+
+    delete preproc;
 }
 
 void CppModelManager::GC()
@@ -746,7 +763,7 @@ void CppModelManager::GC()
     DocumentTable documents = m_documents;
 
     QSet<QString> processed;
-    QStringList todo = m_projectFiles;
+    QStringList todo = projectFiles();
 
     while (! todo.isEmpty()) {
         QString fn = todo.last();
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index 187187cc5d313586293cd3fdb0e7d5186dc30c01..a91a414e4803e2464a68a149b5f1eac9ae43068a 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -58,6 +58,7 @@ namespace CppTools {
 namespace Internal {
 
 class CppEditorSupport;
+class CppPreprocessor;
 class CppHoverHandler;
 
 class CppModelManager : public CppModelManagerInterface
@@ -97,18 +98,54 @@ private Q_SLOTS:
     void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
     void onAboutToRemoveProject(ProjectExplorer::Project *project);
     void onSessionUnloaded();
+    void onProjectAdded(ProjectExplorer::Project *project);
 
 private:
-    QMap<QString, QByteArray> buildWorkingCopyList() const;
-    QStringList projectFiles() const;
-    QStringList includePaths() const;
-    QStringList frameworkPaths() const;
-    QByteArray definedMacros() const;
+    QMap<QString, QByteArray> buildWorkingCopyList();
+
+    QStringList projectFiles()
+    {
+        ensureUpdated();
+        return m_projectFiles;
+    }
+
+    QStringList includePaths()
+    {
+        ensureUpdated();
+        return m_includePaths;
+    }
+
+    QStringList frameworkPaths()
+    {
+        ensureUpdated();
+        return m_frameworkPaths;
+    }
+
+    QByteArray definedMacros()
+    {
+        ensureUpdated();
+        return m_definedMacros;
+    }
+
+    QStringList updateProjectFiles() const;
+    QStringList updateIncludePaths() const;
+    QStringList updateFrameworkPaths() const;
+    QByteArray updateDefinedMacros() const;
+
+    void ensureUpdated() {
+        if (! m_dirty)
+            return;
+
+        m_projectFiles = updateProjectFiles();
+        m_includePaths = updateIncludePaths();
+        m_frameworkPaths = updateFrameworkPaths();
+        m_definedMacros = updateDefinedMacros();
+        m_dirty = false;
+    }
 
     static void parse(QFutureInterface<void> &future,
-                      CppModelManager *model,
-                      QStringList files,
-                      QMap<QString, QByteArray> workingCopy);
+                      CppPreprocessor *preproc,
+                      QStringList files);
 
 private:
     Core::ICore *m_core;
@@ -116,8 +153,12 @@ private:
     CppHoverHandler *m_hoverHandler;
     DocumentTable m_documents;
 
-    // List of available source files
+    // cache
+    bool m_dirty;
     QStringList m_projectFiles;
+    QStringList m_includePaths;
+    QStringList m_frameworkPaths;
+    QByteArray m_definedMacros;
 
     // editor integration
     QMap<TextEditor::ITextEditor *, CppEditorSupport *> m_editorSupport;