diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
index d2f21c90b16bec162cb907322bb2f6ce53784cf4..c86e7f5d646623ae54ae5796db65d02308ec60a6 100644
--- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp
@@ -27,6 +27,8 @@
 
 #include <projectexplorer/kit.h>
 
+#include <utils/algorithm.h>
+#include <utils/fileutils.h>
 #include <utils/macroexpander.h>
 #include <utils/qtcassert.h>
 
@@ -219,6 +221,91 @@ CMakeConfigItem CMakeConfigItem::fromString(const QString &s)
     return item;
 }
 
+static QByteArray trimCMakeCacheLine(const QByteArray &in) {
+    int start = 0;
+    while (start < in.count() && (in.at(start) == ' ' || in.at(start) == '\t'))
+        ++start;
+
+    return in.mid(start, in.count() - start - 1);
+}
+
+static QByteArrayList splitCMakeCacheLine(const QByteArray &line) {
+    const int colonPos = line.indexOf(':');
+    if (colonPos < 0)
+        return QByteArrayList();
+
+    const int equalPos = line.indexOf('=', colonPos + 1);
+    if (equalPos < colonPos)
+        return QByteArrayList();
+
+    return QByteArrayList() << line.mid(0, colonPos)
+                            << line.mid(colonPos + 1, equalPos - colonPos - 1)
+                            << line.mid(equalPos + 1);
+}
+
+QList<CMakeConfigItem> CMakeConfigItem::itemsFromFile(const Utils::FileName &cacheFile, QString *errorMessage)
+{
+    CMakeConfig result;
+    QFile cache(cacheFile.toString());
+    if (!cache.open(QIODevice::ReadOnly | QIODevice::Text)) {
+        if (errorMessage)
+            *errorMessage = QCoreApplication::translate("CMakeProjectManager::CMakeConfigItem", "Failed to open %1 for reading.")
+                .arg(cacheFile.toUserOutput());
+        return CMakeConfig();
+    }
+
+    QSet<QByteArray> advancedSet;
+    QMap<QByteArray, QByteArray> valuesMap;
+    QByteArray documentation;
+    while (!cache.atEnd()) {
+        const QByteArray line = trimCMakeCacheLine(cache.readLine());
+
+        if (line.isEmpty() || line.startsWith('#'))
+            continue;
+
+        if (line.startsWith("//")) {
+            documentation = line.mid(2);
+            continue;
+        }
+
+        const QByteArrayList pieces = splitCMakeCacheLine(line);
+        if (pieces.isEmpty())
+            continue;
+
+        QTC_ASSERT(pieces.count() == 3, continue);
+        const QByteArray key = pieces.at(0);
+        const QByteArray type = pieces.at(1);
+        const QByteArray value = pieces.at(2);
+
+        if (key.endsWith("-ADVANCED") && value == "1") {
+            advancedSet.insert(key.left(key.count() - 9 /* "-ADVANCED" */));
+        } else if (key.endsWith("-STRINGS") && CMakeConfigItem::typeStringToType(type) == CMakeConfigItem::INTERNAL) {
+            valuesMap[key.left(key.count() - 8) /* "-STRINGS" */] = value;
+        } else {
+            CMakeConfigItem::Type t = CMakeConfigItem::typeStringToType(type);
+            result << CMakeConfigItem(key, t, documentation, value);
+        }
+    }
+
+    // Set advanced flags:
+    for (int i = 0; i < result.count(); ++i) {
+        CMakeConfigItem &item = result[i];
+        item.isAdvanced = advancedSet.contains(item.key);
+
+        if (valuesMap.contains(item.key)) {
+            item.values = CMakeConfigItem::cmakeSplitValue(QString::fromUtf8(valuesMap[item.key]));
+        } else if (item.key  == "CMAKE_BUILD_TYPE") {
+            // WA for known options
+            item.values << "" << "Debug" << "Release" << "MinSizeRel" << "RelWithDebInfo";
+        }
+    }
+
+    Utils::sort(result, CMakeConfigItem::sortOperator());
+
+    return result;
+
+}
+
 QString CMakeConfigItem::toString(const Utils::MacroExpander *expander) const
 {
     if (key.isEmpty() || type == CMakeProjectManager::CMakeConfigItem::STATIC)
diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
index e52a3ee535a91febe0f08d0186387ef51ead18da..392d727647007b892cf48a1c64616e6c54020c90 100644
--- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
+++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
@@ -31,7 +31,10 @@
 #include <functional>
 
 namespace ProjectExplorer { class Kit; }
-namespace Utils { class MacroExpander; }
+namespace Utils {
+class FileName;
+class MacroExpander;
+} // namespace Utils
 
 namespace CMakeProjectManager {
 
@@ -55,6 +58,7 @@ public:
 
     static std::function<bool(const CMakeConfigItem &a, const CMakeConfigItem &b)> sortOperator();
     static CMakeConfigItem fromString(const QString &s);
+    static QList<CMakeConfigItem> itemsFromFile(const Utils::FileName &input, QString *errorMessage);
     QString toString(const Utils::MacroExpander *expander = nullptr) const;
     QString toArgument(const Utils::MacroExpander *expander = nullptr) const;
 
diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
index 17469565f79c77455c6d09cbb6e95cf518f7f637..41b32e954a77526c54cb0c681e1cbdb9affe5cce 100644
--- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp
+++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
@@ -123,28 +123,6 @@ static QStringList toArguments(const CMakeConfig &config, const MacroExpander *e
     });
 }
 
-static QByteArray trimCMakeCacheLine(const QByteArray &in) {
-    int start = 0;
-    while (start < in.count() && (in.at(start) == ' ' || in.at(start) == '\t'))
-        ++start;
-
-    return in.mid(start, in.count() - start - 1);
-}
-
-static QByteArrayList splitCMakeCacheLine(const QByteArray &line) {
-    const int colonPos = line.indexOf(':');
-    if (colonPos < 0)
-        return QByteArrayList();
-
-    const int equalPos = line.indexOf('=', colonPos + 1);
-    if (equalPos < colonPos)
-        return QByteArrayList();
-
-    return QByteArrayList() << line.mid(0, colonPos)
-                            << line.mid(colonPos + 1, equalPos - colonPos - 1)
-                            << line.mid(equalPos + 1);
-}
-
 // --------------------------------------------------------------------
 // TeaLeafReader:
 // --------------------------------------------------------------------
@@ -242,7 +220,7 @@ CMakeConfig TeaLeafReader::parsedConfiguration() const
     if (!cacheFile.exists())
         return result;
     QString errorMessage;
-    m_cmakeCache = parseConfiguration(cacheFile, &errorMessage);
+    m_cmakeCache = CMakeConfigItem::itemsFromFile(cacheFile, &errorMessage);
     if (!errorMessage.isEmpty())
         emit errorOccured(errorMessage);
     const FileName sourceOfBuildDir
@@ -257,67 +235,6 @@ CMakeConfig TeaLeafReader::parsedConfiguration() const
     return result;
 }
 
-CMakeConfig TeaLeafReader::parseConfiguration(const FileName &cacheFile, QString *errorMessage) const
-{
-    CMakeConfig result;
-    QFile cache(cacheFile.toString());
-    if (!cache.open(QIODevice::ReadOnly | QIODevice::Text)) {
-        if (errorMessage)
-            *errorMessage = tr("Failed to open %1 for reading.").arg(cacheFile.toUserOutput());
-        return CMakeConfig();
-    }
-
-    QSet<QByteArray> advancedSet;
-    QMap<QByteArray, QByteArray> valuesMap;
-    QByteArray documentation;
-    while (!cache.atEnd()) {
-        const QByteArray line = trimCMakeCacheLine(cache.readLine());
-
-        if (line.isEmpty() || line.startsWith('#'))
-            continue;
-
-        if (line.startsWith("//")) {
-            documentation = line.mid(2);
-            continue;
-        }
-
-        const QByteArrayList pieces = splitCMakeCacheLine(line);
-        if (pieces.isEmpty())
-            continue;
-
-        QTC_ASSERT(pieces.count() == 3, continue);
-        const QByteArray key = pieces.at(0);
-        const QByteArray type = pieces.at(1);
-        const QByteArray value = pieces.at(2);
-
-        if (key.endsWith("-ADVANCED") && value == "1") {
-            advancedSet.insert(key.left(key.count() - 9 /* "-ADVANCED" */));
-        } else if (key.endsWith("-STRINGS") && CMakeConfigItem::typeStringToType(type) == CMakeConfigItem::INTERNAL) {
-            valuesMap[key.left(key.count() - 8) /* "-STRINGS" */] = value;
-        } else {
-            CMakeConfigItem::Type t = CMakeConfigItem::typeStringToType(type);
-            result << CMakeConfigItem(key, t, documentation, value);
-        }
-    }
-
-    // Set advanced flags:
-    for (int i = 0; i < result.count(); ++i) {
-        CMakeConfigItem &item = result[i];
-        item.isAdvanced = advancedSet.contains(item.key);
-
-        if (valuesMap.contains(item.key)) {
-            item.values = CMakeConfigItem::cmakeSplitValue(QString::fromUtf8(valuesMap[item.key]));
-        } else if (item.key  == "CMAKE_BUILD_TYPE") {
-            // WA for known options
-            item.values << "" << "Debug" << "Release" << "MinSizeRel" << "RelWithDebInfo";
-        }
-    }
-
-    sort(result, CMakeConfigItem::sortOperator());
-
-    return result;
-}
-
 void TeaLeafReader::generateProjectTree(CMakeListsNode *root, const QList<FileNode *> &allFiles)
 {
     root->setDisplayName(m_projectName);
diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.h b/src/plugins/cmakeprojectmanager/tealeafreader.h
index 45ecc2486d0376612a2560db3f9330e477b4bdf7..9c54472d61ba8f5b96e8a6394581a3319214f388 100644
--- a/src/plugins/cmakeprojectmanager/tealeafreader.h
+++ b/src/plugins/cmakeprojectmanager/tealeafreader.h
@@ -70,8 +70,6 @@ private:
     bool extractCXXFlagsFromMake(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache);
     bool extractCXXFlagsFromNinja(const CMakeBuildTarget &buildTarget, QHash<QString, QStringList> &cache);
 
-    CMakeConfig parseConfiguration(const Utils::FileName &cacheFile, QString *errorMessage) const;
-
     Utils::QtcProcess *m_cmakeProcess = nullptr;
 
     // For error reporting: