diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
index 2575f7bdc478c1d47b5b0b4dbce4e05e6b5b84b7..5c5314b31d2e5af554e3b3f923e240fd7d048c17 100644
--- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
@@ -380,13 +380,15 @@ void BuildDirManager::clearCache()
 
 QList<CMakeBuildTarget> BuildDirManager::buildTargets() const
 {
-    QTC_ASSERT(m_reader, return QList<CMakeBuildTarget>());
+    if (!m_reader)
+        return QList<CMakeBuildTarget>();
     return m_reader->buildTargets();
 }
 
 CMakeConfig BuildDirManager::parsedConfiguration() const
 {
-    QTC_ASSERT(m_reader, return m_cmakeCache);
+    if (!m_reader)
+        return m_cmakeCache;
     if (m_cmakeCache.isEmpty())
         m_cmakeCache = m_reader->parsedConfiguration();
     return m_cmakeCache;
diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
index 37d9b4917694778e90cb1d1a579ee4a5414a8bbe..8a6fefda01fbff16c839993a6df5356d1d886597 100644
--- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp
+++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
@@ -320,10 +320,9 @@ CMakeConfig TeaLeafReader::parseConfiguration(const FileName &cacheFile, QString
 
 void TeaLeafReader::generateProjectTree(CMakeProjectNode *root, const QList<FileNode *> &allFiles)
 {
-    Q_UNUSED(allFiles);
     root->setDisplayName(m_projectName);
 
-    // Delete no longer necessary file watcher:
+    // Delete no longer necessary file watcher based on m_cmakeFiles:
     const QSet<FileName> currentWatched
             = transform(m_watchedFiles, [](CMakeFile *cmf) { return cmf->filePath(); });
     const QSet<FileName> toWatch = m_cmakeFiles;
@@ -346,8 +345,59 @@ void TeaLeafReader::generateProjectTree(CMakeProjectNode *root, const QList<File
         m_watchedFiles.insert(cm);
     }
 
-    QList<FileNode *> fileNodes = m_files;
-    root->buildTree(fileNodes);
+    QList<FileNode *> added;
+    QList<FileNode *> deleted;
+
+    ProjectExplorer::compareSortedLists(m_files, allFiles, deleted, added, Node::sortByPath);
+
+    QSet<FileName> allIncludePathSet;
+    for (const CMakeBuildTarget &bt : m_buildTargets) {
+        const QList<Utils::FileName> targetIncludePaths
+                = Utils::filtered(bt.includeFiles, [root](const Utils::FileName &fn) {
+            return fn.isChildOf(root->filePath());
+        });
+        allIncludePathSet.unite(QSet<FileName>::fromList(targetIncludePaths));
+    }
+    const QList<FileName> allIncludePaths = allIncludePathSet.toList();
+
+    QList<FileNode *> includedHeaderFiles;
+    QList<FileNode *> unusedFileNodes;
+    std::tie(includedHeaderFiles, unusedFileNodes)
+            = Utils::partition(allFiles, [&allIncludePaths](const FileNode *fn) -> bool {
+        if (fn->fileType() != FileType::Header)
+            return false;
+
+        for (const FileName &inc : allIncludePaths) {
+            if (fn->filePath().isChildOf(inc))
+                return true;
+        }
+        return false;
+    });
+
+    const auto knownFiles = QSet<FileName>::fromList(Utils::transform(m_files, [](const FileNode *fn) { return fn->filePath(); }));
+    QList<FileNode *> uniqueHeaders;
+    foreach (FileNode *ifn, includedHeaderFiles) {
+        if (!knownFiles.contains(ifn->filePath())) {
+            uniqueHeaders.append(ifn);
+            ifn->setEnabled(false);
+        }
+    }
+
+    QList<FileNode *> fileNodes = m_files + uniqueHeaders;
+
+    // Filter out duplicate nodes that e.g. the servermode reader introduces:
+    QSet<FileName> uniqueFileNames;
+    QSet<Node *> uniqueNodes;
+    foreach (FileNode *fn, root->recursiveFileNodes()) {
+        const int count = uniqueFileNames.count();
+        uniqueFileNames.insert(fn->filePath());
+        if (count != uniqueFileNames.count())
+            uniqueNodes.insert(static_cast<Node *>(fn));
+    }
+    root->trim(uniqueNodes);
+    root->removeProjectNodes(root->projectNodes()); // Remove all project nodes
+
+    root->buildTree(fileNodes, m_parameters.sourceDirectory);
     m_files.clear(); // Some of the FileNodes in files() were deleted!
 }