diff --git a/plugins/autotest/autotestconstants.h b/plugins/autotest/autotestconstants.h
index fc254e42283f2007b7c699514005bec11489d9f5..c82c5efbca2fc15d17434a4b7c05aeeb47904b3d 100644
--- a/plugins/autotest/autotestconstants.h
+++ b/plugins/autotest/autotestconstants.h
@@ -29,6 +29,7 @@ const char MENU_ID[]                    = "AutoTest.Menu";
 const char AUTOTEST_ID[]                = "AutoTest.ATP";
 const char AUTOTEST_CONTEXT[]           = "Auto Tests";
 const char TASK_INDEX[]                 = "AutoTest.Task.Index";
+const char TASK_PARSE[]                 = "AutoTest.Task.Parse";
 const char UNNAMED_QUICKTESTS[]         = QT_TR_NOOP("<unnamed>");
 const char AUTOTEST_SETTINGS_CATEGORY[] = "ZY.Tests";
 
diff --git a/plugins/autotest/autotestplugin.cpp b/plugins/autotest/autotestplugin.cpp
index 46e2a311d9a35dbb10e35ffbc5c9b52b94b1c567..0d6f7be04ffc128ceb4eca46fe0fb73e3d10a73e 100644
--- a/plugins/autotest/autotestplugin.cpp
+++ b/plugins/autotest/autotestplugin.cpp
@@ -21,6 +21,7 @@
 #include "testrunner.h"
 #include "testsettings.h"
 #include "testsettingspage.h"
+#include "testtreeitem.h"
 #include "testtreeview.h"
 #include "testtreemodel.h"
 #include "testresultspane.h"
@@ -57,7 +58,10 @@ AutotestPlugin::AutotestPlugin()
 {
     // needed to be used in QueuedConnection connects
     qRegisterMetaType<TestResult>();
-    // Create your members
+    qRegisterMetaType<TestTreeItem>();
+    qRegisterMetaType<TestCodeLocationAndType>();
+    qRegisterMetaType<TestTreeModel::Type>();
+
     m_instance = this;
 }
 
diff --git a/plugins/autotest/testcodeparser.cpp b/plugins/autotest/testcodeparser.cpp
index 2fc0fff3ca68d3001e2749eb36ee107cb7132d72..0a9b8b6893a168a60e411611d90b2a7433e8fa22 100644
--- a/plugins/autotest/testcodeparser.cpp
+++ b/plugins/autotest/testcodeparser.cpp
@@ -21,6 +21,7 @@
 #include "testinfo.h"
 #include "testvisitor.h"
 
+#include <coreplugin/progressmanager/futureprogress.h>
 #include <coreplugin/progressmanager/progressmanager.h>
 
 #include <cplusplus/LookupContext.h>
@@ -39,9 +40,13 @@
 #include <qmljs/qmljsdialect.h>
 #include <qmljstools/qmljsmodelmanager.h>
 
+#include <utils/multitask.h>
 #include <utils/qtcassert.h>
 #include <utils/textfileformat.h>
 
+#include <QFuture>
+#include <QFutureInterface>
+
 namespace Autotest {
 namespace Internal {
 
@@ -66,7 +71,7 @@ TestCodeParser::TestCodeParser(TestTreeModel *parent)
 
 TestCodeParser::~TestCodeParser()
 {
-    clearMaps();
+    clearCache();
 }
 
 void TestCodeParser::setState(State state)
@@ -112,7 +117,7 @@ void TestCodeParser::updateTestTree()
 
     m_pendingUpdate = false;
 
-    clearMaps();
+    clearCache();
     emit cacheCleared();
     scanForTests();
 }
@@ -353,6 +358,26 @@ static TestTreeItem constructTestTreeItem(const QString &fileName,
 
 /****** end of helpers ******/
 
+void performParse(QFutureInterface<void> &futureInterface, QStringList list,
+                  TestCodeParser *testCodeParser)
+{
+    int progressValue = 0;
+    futureInterface.setProgressRange(0, list.size());
+    futureInterface.setProgressValue(progressValue);
+    CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
+    CPlusPlus::Snapshot snapshot = cppMM->snapshot();
+
+    foreach (const QString &file, list) {
+        if (snapshot.contains(file)) {
+            CPlusPlus::Document::Ptr doc = snapshot.find(file).value();
+            futureInterface.setProgressValue(++progressValue);
+            testCodeParser->checkDocumentForTestCode(doc);
+        }
+    }
+    futureInterface.setProgressValue(list.size());
+}
+
+/****** threaded parsing stuff *******/
 void TestCodeParser::checkDocumentForTestCode(CPlusPlus::Document::Ptr document)
 {
     const QString fileName = document->fileName();
@@ -445,6 +470,14 @@ void TestCodeParser::handleQtQuickTest(CPlusPlus::Document::Ptr document)
 
 void TestCodeParser::onCppDocumentUpdated(const CPlusPlus::Document::Ptr &document)
 {
+    if (!m_parserEnabled) {
+        if (!m_pendingUpdate) {
+            m_partialUpdatePostPoned = true;
+            m_postPonedFiles.insert(document->fileName());
+        }
+        return;
+    }
+
     ProjectExplorer::Project *project = currentProject();
     if (!project)
         return;
@@ -463,6 +496,14 @@ void TestCodeParser::onCppDocumentUpdated(const CPlusPlus::Document::Ptr &docume
 
 void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &document)
 {
+    if (!m_parserEnabled) {
+        if (!m_pendingUpdate) {
+            m_partialUpdatePostPoned = true;
+            m_postPonedFiles.insert(document->fileName());
+        }
+        return;
+    }
+
     ProjectExplorer::Project *project = currentProject();
     if (!project)
         return;
@@ -482,7 +523,7 @@ void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &document)
             if (!m_quickDocMap[fileName].referencingFile().isEmpty())
                 scanForTests(QStringList(m_quickDocMap[fileName].referencingFile()));
     }
-    if (!m_quickDocMap.contains(tr(Constants::UNNAMED_QUICKTESTS)))
+    if (m_unnamedQuickDocList.size() == 0)
         return;
 
     // special case of having unnamed TestCases
@@ -548,8 +589,10 @@ void TestCodeParser::scanForTests(const QStringList &fileList)
     if (postponed(fileList))
         return;
 
+    bool isFullParse = fileList.isEmpty();
+    bool isSmallChange = !isFullParse && fileList.size() < 6;
     QStringList list;
-    if (fileList.isEmpty()) {
+    if (isFullParse) {
         list = currentProject()->files(ProjectExplorer::Project::AllFiles);
         if (list.isEmpty())
             return;
@@ -559,34 +602,33 @@ void TestCodeParser::scanForTests(const QStringList &fileList)
         m_parserState = PartialParse;
     }
 
-    CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
-    CPlusPlus::Snapshot snapshot = cppMM->snapshot();
-
-    foreach (const QString &file, list) {
-        if (snapshot.contains(file)) {
-            CPlusPlus::Document::Ptr doc = snapshot.find(file).value();
-            checkDocumentForTestCode(doc);
+    if (isSmallChange) { // no need to do this async or should we do this always async?
+        CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
+        CPlusPlus::Snapshot snapshot = cppMM->snapshot();
+        foreach (const QString &file, list) {
+            if (snapshot.contains(file)) {
+                CPlusPlus::Document::Ptr doc = snapshot.find(file).value();
+                checkDocumentForTestCode(doc);
+            }
         }
+        emit onFinished();
+        return;
     }
-    switch (m_parserState) {
-    case PartialParse:
-        m_parserState = Idle;
-        emit partialParsingFinished();
-        break;
-    case FullParse:
-        m_parserState = Idle;
-        emit parsingFinished();
-        break;
-    default:
-        qWarning("I should not be here...");
-        break;
-    }
+
+    QFuture<void> future = QtConcurrent::run(&performParse, list, this);
+    Core::FutureProgress *progress
+            = Core::ProgressManager::addTask(future, isFullParse ? tr("Scanning for Tests")
+                                                                 : tr("Updating Tests"),
+                                             Autotest::Constants::TASK_PARSE);
+    connect(progress, &Core::FutureProgress::finished,
+            this, &TestCodeParser::onFinished);
 }
 
-void TestCodeParser::clearMaps()
+void TestCodeParser::clearCache()
 {
     m_cppDocMap.clear();
     m_quickDocMap.clear();
+    m_unnamedQuickDocList.clear();
 }
 
 void TestCodeParser::removeTestsIfNecessary(const QString &fileName)
@@ -611,24 +653,14 @@ void TestCodeParser::removeTestsIfNecessary(const QString &fileName)
             emit testItemsRemoved(file, TestTreeModel::QuickTest);
         }
         // unnamed Quick Tests must be handled separately
+        removeUnnamedQuickTestsByName(fileName);
+
         QSet<QString> filePaths;
         QList<QString> functionNames;
         if (m_model->hasUnnamedQuickTests()) {
             m_model->qmlFilesAndFunctionNamesForMainFile(fileName, &filePaths, &functionNames);
             foreach (const QString &file, filePaths)
                 emit testItemsRemoved(file, TestTreeModel::QuickTest);
-            // update info map
-            TestInfo unnamedInfo = m_quickDocMap[tr(Constants::UNNAMED_QUICKTESTS)];
-            QStringList functions = unnamedInfo.testFunctions();
-            foreach (const QString &func, functionNames)
-                functions.removeOne(func);
-            unnamedInfo.setTestFunctions(functions);
-            if (functions.size() == 0)
-                m_quickDocMap.remove(tr(Constants::UNNAMED_QUICKTESTS));
-            else
-                m_quickDocMap.insert(tr(Constants::UNNAMED_QUICKTESTS), unnamedInfo);
-        } else {
-            m_quickDocMap.remove(tr(Constants::UNNAMED_QUICKTESTS));
         }
     }
 }
@@ -655,17 +687,10 @@ void TestCodeParser::removeTestsIfNecessaryByProFile(const QString &proFile)
     }
     // handle unnamed Quick Tests
     const QSet<QString> &filePaths = m_model->qmlFilesForProFile(proFile);
-    foreach (const QString &fileName, filePaths)
+    foreach (const QString &fileName, filePaths) {
+        removeUnnamedQuickTestsByName(fileName);
         emit unnamedQuickTestsRemoved(fileName);
-    // update info map
-    TestInfo unnamedInfo = m_quickDocMap.value(tr(Constants::UNNAMED_QUICKTESTS),
-                                               TestInfo(QString(), QStringList(), 666));
-
-    unnamedInfo.setTestFunctions(m_model->getUnnamedQuickTestFunctions());
-    if (unnamedInfo.testFunctions().isEmpty())
-        m_quickDocMap.remove(tr(Constants::UNNAMED_QUICKTESTS));
-    else
-        m_quickDocMap.insert(tr(Constants::UNNAMED_QUICKTESTS), unnamedInfo);
+    }
 }
 
 void TestCodeParser::onTaskStarted(Core::Id type)
@@ -683,6 +708,31 @@ void TestCodeParser::onAllTasksFinished(Core::Id type)
     m_parserEnabled = true;
     if (m_pendingUpdate)
         updateTestTree();
+    else if (m_partialUpdatePostPoned) {
+        m_partialUpdatePostPoned = false;
+        QStringList tmp;
+        foreach (const QString &file, m_postPonedFiles)
+            tmp << file;
+        m_postPonedFiles.clear();
+        scanForTests(tmp);
+    }
+}
+
+void TestCodeParser::onFinished()
+{
+    switch (m_parserState) {
+    case PartialParse:
+        m_parserState = Idle;
+        emit partialParsingFinished();
+        break;
+    case FullParse:
+        m_parserState = Idle;
+        emit parsingFinished();
+        break;
+    default:
+        qWarning("I should not be here...");
+        break;
+    }
 }
 
 void TestCodeParser::onPartialParsingFinished()
@@ -710,16 +760,13 @@ void TestCodeParser::updateUnnamedQuickTests(const QString &fileName, const QStr
     m_quickDocMap.remove(fileName);
     emit testItemsRemoved(fileName, TestTreeModel::QuickTest);
 
-    emit unnamedQuickTestsUpdated(fileName, mainFile, functions);
-
-    if (m_model->hasUnnamedQuickTests()) {
-        TestInfo info = m_quickDocMap.value(tr(Constants::UNNAMED_QUICKTESTS),
-                                            TestInfo(QString(), QStringList(), 666));
-        info.setTestFunctions(m_model->getUnnamedQuickTestFunctions());
-        m_quickDocMap.insert(tr(Constants::UNNAMED_QUICKTESTS), info);
-    } else {
-        m_quickDocMap.remove(tr(Constants::UNNAMED_QUICKTESTS));
+    removeUnnamedQuickTestsByName(fileName);
+    foreach (const QString &functionName, functions.keys()) {
+        UnnamedQuickTestInfo info(functionName, fileName);
+        m_unnamedQuickDocList.append(info);
     }
+
+    emit unnamedQuickTestsUpdated(fileName, mainFile, functions);
 }
 
 void TestCodeParser::updateModelAndCppDocMap(CPlusPlus::Document::Ptr document,
@@ -779,6 +826,7 @@ void TestCodeParser::updateModelAndQuickDocMap(QmlJS::Document::Ptr document,
         m_quickDocMap.insert(fileName, testInfo);
     } else {
         // if it was formerly unnamed remove the respective items
+        removeUnnamedQuickTestsByName(fileName);
         emit unnamedQuickTestsRemoved(fileName);
 
         emit testItemCreated(testItem, TestTreeModel::QuickTest);
@@ -789,6 +837,14 @@ void TestCodeParser::updateModelAndQuickDocMap(QmlJS::Document::Ptr document,
     }
 }
 
+void TestCodeParser::removeUnnamedQuickTestsByName(const QString &fileName)
+{
+    for (int i = m_unnamedQuickDocList.size() - 1; i >= 0; --i) {
+        if (m_unnamedQuickDocList.at(i).fileName() == fileName)
+            m_unnamedQuickDocList.removeAt(i);
+    }
+}
+
 void TestCodeParser::onProFileEvaluated()
 {
     ProjectExplorer::Project *project = currentProject();
@@ -822,16 +878,12 @@ int TestCodeParser::autoTestsCount() const
 
 int TestCodeParser::namedQuickTestsCount() const
 {
-    if (m_quickDocMap.contains(tr(Constants::UNNAMED_QUICKTESTS)))
-        return m_quickDocMap.size() - 1;
     return m_quickDocMap.size();
 }
 
 int TestCodeParser::unnamedQuickTestsCount() const
 {
-    if (m_quickDocMap.contains(tr(Constants::UNNAMED_QUICKTESTS)))
-        return m_quickDocMap.value(tr(Constants::UNNAMED_QUICKTESTS)).testFunctions().size();
-    return 0;
+    return m_unnamedQuickDocList.size();
 }
 #endif
 
diff --git a/plugins/autotest/testcodeparser.h b/plugins/autotest/testcodeparser.h
index 9b6670c320f7b0e9d52ca3d4f1c1598d660e2a5b..f2bb6de13ef844073d14aa6a817922373eadb6fb 100644
--- a/plugins/autotest/testcodeparser.h
+++ b/plugins/autotest/testcodeparser.h
@@ -38,6 +38,7 @@ namespace Internal {
 
 struct TestCodeLocationAndType;
 class TestInfo;
+class UnnamedQuickTestInfo;
 
 class TestCodeParser : public QObject
 {
@@ -86,12 +87,13 @@ public slots:
 private:
     bool postponed(const QStringList &fileList);
     void scanForTests(const QStringList &fileList = QStringList());
-    void clearMaps();
+    void clearCache();
     void removeTestsIfNecessary(const QString &fileName);
     void removeTestsIfNecessaryByProFile(const QString &proFile);
 
     void onTaskStarted(Core::Id type);
     void onAllTasksFinished(Core::Id type);
+    void onFinished();
     void onPartialParsingFinished();
     void updateUnnamedQuickTests(const QString &fileName, const QString &mainFile,
                                  const QMap<QString, TestCodeLocationAndType> &functions);
@@ -99,10 +101,12 @@ private:
                                  const QString &declaringFile, TestTreeItem &testItem);
     void updateModelAndQuickDocMap(QmlJS::Document::Ptr document,
                                    const QString &referencingFile, TestTreeItem &testItem);
+    void removeUnnamedQuickTestsByName(const QString &fileName);
 
     TestTreeModel *m_model;
     QMap<QString, TestInfo> m_cppDocMap;
     QMap<QString, TestInfo> m_quickDocMap;
+    QList<UnnamedQuickTestInfo> m_unnamedQuickDocList;
     bool m_parserEnabled;
     bool m_pendingUpdate;
     bool m_fullUpdatePostPoned;
diff --git a/plugins/autotest/testinfo.cpp b/plugins/autotest/testinfo.cpp
index ad904e9a0f1a4d79964e48879b859755c4ae819f..e3e13274f7c1dd496e5df64505c095d1be499cc2 100644
--- a/plugins/autotest/testinfo.cpp
+++ b/plugins/autotest/testinfo.cpp
@@ -35,5 +35,11 @@ TestInfo::~TestInfo()
     m_functions.clear();
 }
 
+UnnamedQuickTestInfo::UnnamedQuickTestInfo(const QString &function, const QString &fileName)
+    : m_function(function),
+      m_fileName(fileName)
+{
+}
+
 } // namespace Internal
 } // namespace Autotest
diff --git a/plugins/autotest/testinfo.h b/plugins/autotest/testinfo.h
index b974824f9e0763e56cb2969debe741fc1f1821b0..cadd57212f9a9a4bf92b475403b51c97f71a790f 100644
--- a/plugins/autotest/testinfo.h
+++ b/plugins/autotest/testinfo.h
@@ -54,6 +54,22 @@ private:
     QString m_proFile;
 };
 
+class UnnamedQuickTestInfo {
+public:
+    explicit UnnamedQuickTestInfo(const QString &function = QString(),
+                                  const QString& fileName = QString());
+    ~UnnamedQuickTestInfo() {}
+
+    const QString function() const { return m_function; }
+    void setFunction(const QString &function) { m_function = function; }
+    const QString fileName() const { return m_fileName; }
+    void setFileName(const QString &fileName) { m_fileName = fileName; }
+
+private:
+    QString m_function;
+    QString m_fileName;
+};
+
 } // namespace Internal
 } // namespace Autotest
 
diff --git a/plugins/autotest/testtreeitem.h b/plugins/autotest/testtreeitem.h
index 25a49f3edf7677e9d797861da643e3b74172b9e0..e1814db356f59a0b6c83d46c986fb8f3c9fb0184 100644
--- a/plugins/autotest/testtreeitem.h
+++ b/plugins/autotest/testtreeitem.h
@@ -21,6 +21,7 @@
 
 #include <QList>
 #include <QString>
+#include <QMetaType>
 
 namespace Autotest {
 namespace Internal {
@@ -37,7 +38,8 @@ public:
         TEST_SPECIALFUNCTION
     };
 
-    TestTreeItem(const QString &name, const QString &filePath, Type type, TestTreeItem *parent = 0);
+    TestTreeItem(const QString &name = QString(), const QString &filePath = QString(),
+                 Type type = ROOT, TestTreeItem *parent = 0);
     virtual ~TestTreeItem();
     TestTreeItem(const TestTreeItem& other);
 
@@ -90,4 +92,7 @@ struct TestCodeLocationAndType {
 } // namespace Internal
 } // namespace Autotest
 
+Q_DECLARE_METATYPE(Autotest::Internal::TestTreeItem)
+Q_DECLARE_METATYPE(Autotest::Internal::TestCodeLocationAndType)
+
 #endif // TESTTREEITEM_H
diff --git a/plugins/autotest/testtreemodel.cpp b/plugins/autotest/testtreemodel.cpp
index cc54b6969ae9ff67910254d04b9f5162f7fd7c8c..8b9de455ade49fed66ee2c5f1d0012503419911e 100644
--- a/plugins/autotest/testtreemodel.cpp
+++ b/plugins/autotest/testtreemodel.cpp
@@ -55,15 +55,20 @@ TestTreeModel::TestTreeModel(QObject *parent) :
     m_rootItem->appendChild(m_autoTestRootItem);
     m_rootItem->appendChild(m_quickTestRootItem);
 
-    connect(m_parser, &TestCodeParser::cacheCleared, this, &TestTreeModel::removeAllTestItems);
-    connect(m_parser, &TestCodeParser::testItemCreated, this, &TestTreeModel::addTestTreeItem);
-    connect(m_parser, &TestCodeParser::testItemsCreated, this, &TestTreeModel::addTestTreeItems);
-    connect(m_parser, &TestCodeParser::testItemModified, this, &TestTreeModel::modifyTestTreeItem);
-    connect(m_parser, &TestCodeParser::testItemsRemoved, this, &TestTreeModel::removeTestTreeItems);
+    connect(m_parser, &TestCodeParser::cacheCleared, this,
+            &TestTreeModel::removeAllTestItems, Qt::QueuedConnection);
+    connect(m_parser, &TestCodeParser::testItemCreated,
+            this, &TestTreeModel::addTestTreeItem, Qt::QueuedConnection);
+    connect(m_parser, &TestCodeParser::testItemsCreated,
+            this, &TestTreeModel::addTestTreeItems, Qt::QueuedConnection);
+    connect(m_parser, &TestCodeParser::testItemModified,
+            this, &TestTreeModel::modifyTestTreeItem, Qt::QueuedConnection);
+    connect(m_parser, &TestCodeParser::testItemsRemoved,
+            this, &TestTreeModel::removeTestTreeItems, Qt::QueuedConnection);
     connect(m_parser, &TestCodeParser::unnamedQuickTestsUpdated,
-            this, &TestTreeModel::updateUnnamedQuickTest);
+            this, &TestTreeModel::updateUnnamedQuickTest, Qt::QueuedConnection);
     connect(m_parser, &TestCodeParser::unnamedQuickTestsRemoved,
-            this, &TestTreeModel::removeUnnamedQuickTests);
+            this, &TestTreeModel::removeUnnamedQuickTests, Qt::QueuedConnection);
 
 //    CppTools::CppModelManagerInterface *cppMM = CppTools::CppModelManagerInterface::instance();
 //    if (cppMM) {
diff --git a/plugins/autotest/testtreemodel.h b/plugins/autotest/testtreemodel.h
index 46a7b28a95686cf5c5265c215dd3c936f03fac1e..44186285a9fbd53480a07726150105ce0e1a6a86 100644
--- a/plugins/autotest/testtreemodel.h
+++ b/plugins/autotest/testtreemodel.h
@@ -152,4 +152,6 @@ private:
 } // namespace Internal
 } // namespace Autotest
 
+Q_DECLARE_METATYPE(Autotest::Internal::TestTreeModel::Type)
+
 #endif // TESTTREEMODEL_H