diff --git a/src/libs/qmljs/qmljsbind.h b/src/libs/qmljs/qmljsbind.h
index cc97b3f47ce0eee9371e789742329ae7ac07aca0..e4298f36a276f1e1392743b616ebeee5698d0368 100644
--- a/src/libs/qmljs/qmljsbind.h
+++ b/src/libs/qmljs/qmljsbind.h
@@ -43,7 +43,6 @@
 
 namespace QmlJS {
 
-class Link;
 class Document;
 
 class QMLJS_EXPORT Bind: protected AST::Visitor
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index 9761fd66567ffbbf9ff00d9b00214a656369d1c7..f9da2850886dee47d7ea1562b693a458ef7f92df 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -375,6 +375,7 @@ Check::Check(Document::Ptr doc, const Context *linkedContextNoScope)
           | WarnCaseWithoutFlowControlEnd | ErrCheckTypeErrors)
     , _lastValue(0)
 {
+    _scopeBuilder.initializeRootScope();
 }
 
 Check::~Check()
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index ba644b8ef4a0f2d16cacd8a8dead084129ec70e7..5298d0bdde4fad44579ca3ba8587aabdcf3d0918 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -3286,6 +3286,7 @@ const Value *ASTPropertyReference::value(const Context *context) const
         QmlJS::Document::Ptr doc = _doc->ptr();
         Context localContext(*context);
         QmlJS::ScopeBuilder builder(&localContext, doc);
+        builder.initializeRootScope();
 
         int offset = _ast->expression->firstSourceLocation().begin();
         builder.push(ScopeAstPath(doc)(offset));
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index 65639a98f8db880a5a9e677925ae5f3a383de84d..2e9f45b83d22625fbe77d295da33b54af38dbf18 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -110,8 +110,7 @@ public:
     \l{Context} with \l{Link}.
 */
 
-Link::Link(Context *context, const Snapshot &snapshot, const QStringList &importPaths,
-           QHash<QString, QList<DiagnosticMessage> > *messages)
+Link::Link(Context *context, const Snapshot &snapshot, const QStringList &importPaths)
     : d_ptr(new LinkPrivate)
 {
     Q_D(Link);
@@ -120,7 +119,7 @@ Link::Link(Context *context, const Snapshot &snapshot, const QStringList &import
     d->importPaths = importPaths;
 
     d->diagnosticMessages = 0;
-    d->allDiagnosticMessages = messages;
+    d->allDiagnosticMessages = 0;
 
     // populate engine with types from C++
     ModelManagerInterface *modelManager = ModelManagerInterface::instance();
@@ -129,31 +128,20 @@ Link::Link(Context *context, const Snapshot &snapshot, const QStringList &import
             engine()->cppQmlTypes().load(engine(), cppTypes);
         }
     }
+}
 
+void Link::operator()(QHash<QString, QList<DiagnosticMessage> > *messages)
+{
+    Q_D(Link);
+    d->allDiagnosticMessages = messages;
     linkImports();
 }
 
-Link::Link(Context *context, const Snapshot &snapshot, const QStringList &importPaths,
-           const Document::Ptr &doc, QList<DiagnosticMessage> *messages)
-    : d_ptr(new LinkPrivate)
+void Link::operator()(const Document::Ptr &doc, QList<DiagnosticMessage> *messages)
 {
     Q_D(Link);
-    d->context = context;
-    d->snapshot = snapshot;
-    d->importPaths = importPaths;
-
     d->doc = doc;
     d->diagnosticMessages = messages;
-    d->allDiagnosticMessages = 0;
-
-    // populate engine with types from C++
-    ModelManagerInterface *modelManager = ModelManagerInterface::instance();
-    if (modelManager) {
-        foreach (const QList<FakeMetaObject::ConstPtr> &cppTypes, modelManager->cppQmlTypes()) {
-            engine()->cppQmlTypes().load(engine(), cppTypes);
-        }
-    }
-
     linkImports();
 }
 
diff --git a/src/libs/qmljs/qmljslink.h b/src/libs/qmljs/qmljslink.h
index 2fb421dda41ad97704d37f417421c5220b33c6f4..80809d4328a6cb4c9b5d1811655e8f1585e44cbe 100644
--- a/src/libs/qmljs/qmljslink.h
+++ b/src/libs/qmljs/qmljslink.h
@@ -54,14 +54,15 @@ class QMLJS_EXPORT Link
     Q_DECLARE_TR_FUNCTIONS(QmlJS::Link)
 
 public:
-    // Link all documents in snapshot, collecting all diagnostic messages
     Link(Interpreter::Context *context, const Snapshot &snapshot,
-         const QStringList &importPaths, QHash<QString, QList<DiagnosticMessage> > *messages = 0);
+         const QStringList &importPaths);
+
+    // Link all documents in snapshot, collecting all diagnostic messages (if messages != 0)
+    void operator()(QHash<QString, QList<DiagnosticMessage> > *messages = 0);
 
     // Link all documents in snapshot, appending the diagnostic messages
     // for 'doc' in 'messages'
-    Link(Interpreter::Context *context, const Snapshot &snapshot,
-         const QStringList &importPaths, const Document::Ptr &doc, QList<DiagnosticMessage> *messages);
+    void operator()(const Document::Ptr &doc, QList<DiagnosticMessage> *messages);
 
     ~Link();
 
diff --git a/src/libs/qmljs/qmljslookupcontext.cpp b/src/libs/qmljs/qmljslookupcontext.cpp
index 269c9383b0432b0a30ba98389a0b13541bbc5970..72e6170b58a52e100861817b8d038e40bf477629 100644
--- a/src/libs/qmljs/qmljslookupcontext.cpp
+++ b/src/libs/qmljs/qmljslookupcontext.cpp
@@ -48,18 +48,21 @@ public:
     {
         // since we keep the document and snapshot around, we don't need to keep the Link instance
         Link link(&context, snapshot, ModelManagerInterface::instance()->importPaths());
+        link();
 
         ScopeBuilder scopeBuilder(&context, doc);
+        scopeBuilder.initializeRootScope();
         scopeBuilder.push(path);
     }
 
-    LookupContextData(Document::Ptr doc, const Snapshot &snapshot,
+    LookupContextData(Document::Ptr doc,
                       const Interpreter::Context &linkedContextWithoutScope,
                       const QList<AST::Node *> &path)
         : context(linkedContextWithoutScope),
           doc(doc)
     {
         ScopeBuilder scopeBuilder(&context, doc);
+        scopeBuilder.initializeRootScope();
         scopeBuilder.push(path);
     }
 
@@ -73,10 +76,10 @@ LookupContext::LookupContext(Document::Ptr doc, const Snapshot &snapshot, const
 {
 }
 
-LookupContext::LookupContext(const Document::Ptr doc, const Snapshot &snapshot,
+LookupContext::LookupContext(const Document::Ptr doc,
                              const Interpreter::Context &linkedContextWithoutScope,
                              const QList<AST::Node *> &path)
-    : d(new LookupContextData(doc, snapshot, linkedContextWithoutScope, path))
+    : d(new LookupContextData(doc, linkedContextWithoutScope, path))
 {
 }
 
@@ -90,11 +93,11 @@ LookupContext::Ptr LookupContext::create(Document::Ptr doc, const Snapshot &snap
     return ptr;
 }
 
-LookupContext::Ptr LookupContext::create(const Document::Ptr doc, const Snapshot &snapshot,
+LookupContext::Ptr LookupContext::create(const Document::Ptr doc,
                                          const Interpreter::Context &linkedContextWithoutScope,
                                          const QList<AST::Node *> &path)
 {
-    Ptr ptr(new LookupContext(doc, snapshot, linkedContextWithoutScope, path));
+    Ptr ptr(new LookupContext(doc, linkedContextWithoutScope, path));
     return ptr;
 }
 
diff --git a/src/libs/qmljs/qmljslookupcontext.h b/src/libs/qmljs/qmljslookupcontext.h
index 3fc9185f5a15e0494cdf69e4c6ceb98de19b15b0..5295b2c5af76736a13c607348fe1127dd7e17a71 100644
--- a/src/libs/qmljs/qmljslookupcontext.h
+++ b/src/libs/qmljs/qmljslookupcontext.h
@@ -54,7 +54,7 @@ class QMLJS_EXPORT LookupContext
     Q_DISABLE_COPY(LookupContext)
 
     LookupContext(const Document::Ptr doc, const Snapshot &snapshot, const QList<AST::Node *> &path);
-    LookupContext(const Document::Ptr doc, const Snapshot &snapshot,
+    LookupContext(const Document::Ptr doc,
                   const Interpreter::Context &linkedContextWithoutScope,
                   const QList<AST::Node *> &path);
 
@@ -66,7 +66,7 @@ public:
     // consider using SemanticInfo::lookupContext instead, it's faster
     static Ptr create(const Document::Ptr doc, const Snapshot &snapshot,
                       const QList<AST::Node *> &path);
-    static Ptr create(const Document::Ptr doc, const Snapshot &snapshot,
+    static Ptr create(const Document::Ptr doc,
                       const Interpreter::Context &linkedContextWithoutScope,
                       const QList<AST::Node *> &path);
 
diff --git a/src/libs/qmljs/qmljsscopebuilder.cpp b/src/libs/qmljs/qmljsscopebuilder.cpp
index 35e4d6d66ebb5c5529952d9989ede5bc313f487b..49888c1515229a225a8c17e457a732ee97be8ee3 100644
--- a/src/libs/qmljs/qmljsscopebuilder.cpp
+++ b/src/libs/qmljs/qmljsscopebuilder.cpp
@@ -45,7 +45,6 @@ ScopeBuilder::ScopeBuilder(Context *context, Document::Ptr doc)
     : _doc(doc)
     , _context(context)
 {
-    initializeScopeChain();
 }
 
 ScopeBuilder::~ScopeBuilder()
@@ -98,7 +97,7 @@ void ScopeBuilder::pop()
     _context->scopeChain().update();
 }
 
-void ScopeBuilder::initializeScopeChain()
+void ScopeBuilder::initializeRootScope()
 {
     ScopeChain &scopeChain = _context->scopeChain();
     if (scopeChain.qmlComponentScope
diff --git a/src/libs/qmljs/qmljsscopebuilder.h b/src/libs/qmljs/qmljsscopebuilder.h
index 49a4ccd98720b7788aaec2085e198c8f726ecfcd..529e128cbf0778814aaa66771fa1caddbd259438 100644
--- a/src/libs/qmljs/qmljsscopebuilder.h
+++ b/src/libs/qmljs/qmljsscopebuilder.h
@@ -50,6 +50,8 @@ public:
     ScopeBuilder(Interpreter::Context *context, Document::Ptr doc);
     ~ScopeBuilder();
 
+    void initializeRootScope();
+
     void push(AST::Node *node);
     void push(const QList<AST::Node *> &nodes);
     void pop();
@@ -57,7 +59,6 @@ public:
     static const Interpreter::ObjectValue *isPropertyChangesObject(const Interpreter::Context *context, const Interpreter::ObjectValue *object);
 
 private:
-    void initializeScopeChain();
     void makeComponentChain(Document::Ptr doc, const Snapshot &snapshot,
                             Interpreter::ScopeChain::QmlComponentChain *target,
                             QHash<Document *, Interpreter::ScopeChain::QmlComponentChain *> *components);
diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
index 49098405d5280a0442868ecd50810f9414ab9f8f..01ede18be778d680e13d300d76900500525e7987 100644
--- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
+++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
@@ -298,10 +298,12 @@ public:
         : m_snapshot(snapshot)
         , m_doc(doc)
         , m_context(new Interpreter::Context(snapshot))
-        , m_link(m_context, snapshot, importPaths, doc, &m_diagnosticLinkMessages)
-        , m_lookupContext(LookupContext::create(doc, snapshot, *m_context, QList<AST::Node*>()))
+        , m_link(m_context, snapshot, importPaths)
         , m_scopeBuilder(m_context, doc)
     {
+        m_lookupContext = LookupContext::create(doc, *m_context, QList<AST::Node*>());
+        // cheaper than calling m_scopeBuilder.initializeRootScope()
+        *m_context = *m_lookupContext->context();
     }
 
     ~ReadingContext()
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index 0e6861c3654772f8b60184db18f79e85015b1df9..7b2995e7d30a3e34836501100b921dc3bcfdc452 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -540,7 +540,7 @@ LookupContext::Ptr SemanticInfo::lookupContext(const QList<QmlJS::AST::Node *> &
     if (m_context.isNull())
         return LookupContext::create(document, snapshot, path);
 
-    return LookupContext::create(document, snapshot, *m_context, path);
+    return LookupContext::create(document, *m_context, path);
 }
 
 static bool importContainsCursor(UiImport *importAst, unsigned cursorPosition)
diff --git a/src/plugins/qmljseditor/qmljsfindreferences.cpp b/src/plugins/qmljseditor/qmljsfindreferences.cpp
index 496aa0c0c4d82d3896c16e2667be4f7957cc1635..fd15fe5828621912639a4e6270c8b6ad5357ab0e 100644
--- a/src/plugins/qmljseditor/qmljsfindreferences.cpp
+++ b/src/plugins/qmljseditor/qmljsfindreferences.cpp
@@ -83,6 +83,7 @@ public:
         , _context(context)
         , _builder(context, doc)
     {
+        _builder.initializeRootScope();
     }
 
     Result operator()(const QString &name, const ObjectValue *scope)
@@ -555,7 +556,10 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
         return;
 
     Link link(&context, snapshot, ModelManagerInterface::instance()->importPaths());
+    link();
+
     ScopeBuilder builder(&context, doc);
+    builder.initializeRootScope();
     ScopeAstPath astPath(doc);
     builder.push(astPath(offset));
 
diff --git a/src/plugins/qmljseditor/qmljssemantichighlighter.cpp b/src/plugins/qmljseditor/qmljssemantichighlighter.cpp
index e915493d8167f010bc27c973478a93f41d905b23..74c224ca23cedbc261555585191b0d09684baef4 100644
--- a/src/plugins/qmljseditor/qmljssemantichighlighter.cpp
+++ b/src/plugins/qmljseditor/qmljssemantichighlighter.cpp
@@ -133,7 +133,8 @@ SemanticInfo SemanticHighlighter::semanticInfo(const SemanticHighlighterSource &
     semanticInfo.document = doc;
 
     QmlJS::Interpreter::Context *ctx = new QmlJS::Interpreter::Context(snapshot);
-    QmlJS::Link link(ctx, snapshot, QmlJS::ModelManagerInterface::instance()->importPaths(), doc, &semanticInfo.semanticMessages);
+    QmlJS::Link link(ctx, snapshot, QmlJS::ModelManagerInterface::instance()->importPaths());
+    link(doc, &semanticInfo.semanticMessages);
     semanticInfo.m_context = QSharedPointer<const QmlJS::Interpreter::Context>(ctx);
 
     QmlJS::Check checker(doc, ctx);
diff --git a/src/plugins/qmljseditor/qmltaskmanager.cpp b/src/plugins/qmljseditor/qmltaskmanager.cpp
index 679c1c76f884421eb3e0fd485faa301b2d88048e..935d4500d7de938fa2c0dc088130ecf877660a9f 100644
--- a/src/plugins/qmljseditor/qmltaskmanager.cpp
+++ b/src/plugins/qmljseditor/qmltaskmanager.cpp
@@ -74,7 +74,8 @@ void QmlTaskManager::collectMessages(QFutureInterface<FileErrorMessages> &future
 {
     Interpreter::Context ctx(snapshot);
     QHash<QString, QList<DiagnosticMessage> > linkMessages;
-    Link link(&ctx, snapshot, importPaths, &linkMessages);
+    Link link(&ctx, snapshot, importPaths);
+    link(&linkMessages);
 
     foreach (const QString &fileName, files) {
         Document::Ptr document = snapshot.document(fileName);