diff --git a/src/libs/qmljs/qmljs-lib.pri b/src/libs/qmljs/qmljs-lib.pri
index 53984c306336ac30f1f3d622e55b492081819e60..753619790f0c16ade33e8de332da156b2f25b39e 100644
--- a/src/libs/qmljs/qmljs-lib.pri
+++ b/src/libs/qmljs/qmljs-lib.pri
@@ -20,6 +20,7 @@ HEADERS += \
     $$PWD/qmljslink.h \
     $$PWD/qmljscheck.h \
     $$PWD/qmljsscopebuilder.h \
+    $$PWD/qmljslookupcontext.h \
     $$PWD/qmljslineinfo.h \
     $$PWD/qmljscompletioncontextfinder.h \
     $$PWD/qmljscomponentversion.h \
@@ -38,6 +39,7 @@ SOURCES += \
     $$PWD/qmljslink.cpp \
     $$PWD/qmljscheck.cpp \
     $$PWD/qmljsscopebuilder.cpp \
+    $$PWD/qmljslookupcontext.cpp \
     $$PWD/qmljslineinfo.cpp \
     $$PWD/qmljscompletioncontextfinder.cpp \
     $$PWD/qmljscomponentversion.cpp \
diff --git a/src/libs/qmljs/qmljslookupcontext.cpp b/src/libs/qmljs/qmljslookupcontext.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1b8e333754f6c39f14b042041993bcff36edd331
--- /dev/null
+++ b/src/libs/qmljs/qmljslookupcontext.cpp
@@ -0,0 +1,88 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "qmljslookupcontext.h"
+#include "qmljsinterpreter.h"
+#include "qmljslink.h"
+#include "qmljsscopebuilder.h"
+#include "qmljsmodelmanagerinterface.h"
+#include "qmljsevaluate.h"
+
+using namespace QmlJS;
+
+class QmlJS::LookupContextData
+{
+public:
+    LookupContextData(Document::Ptr doc, const Snapshot &snapshot, const QList<AST::Node *> &path)
+        : context(&interp),
+          doc(doc),
+          snapshot(snapshot),
+          link(&context, doc, snapshot, ModelManagerInterface::instance()->importPaths())
+    {
+        ScopeBuilder scopeBuilder(doc, &context);
+        scopeBuilder.push(path);
+    }
+
+    Interpreter::Engine interp;
+    Interpreter::Context context;
+    Document::Ptr doc;
+    Snapshot snapshot;
+    Link link;
+};
+
+LookupContext::LookupContext(Document::Ptr doc, const Snapshot &snapshot, const QList<AST::Node *> &path)
+    : d(new LookupContextData(doc, snapshot, path))
+{
+}
+
+LookupContext::~LookupContext()
+{
+}
+
+LookupContext::Ptr LookupContext::create(Document::Ptr doc, const Snapshot &snapshot, const QList<AST::Node *> &path)
+{
+    Ptr ptr(new LookupContext(doc, snapshot, path));
+    return ptr;
+}
+
+const Interpreter::Value *LookupContext::evaluate(AST::Node *node) const
+{
+    Evaluate check(&d->context);
+    return check(node);
+}
+
+Interpreter::Engine *LookupContext::engine() const
+{
+    return &d->interp;
+}
+
+Interpreter::Context *LookupContext::context() const
+{
+    return &d->context;
+}
diff --git a/src/libs/qmljs/qmljslookupcontext.h b/src/libs/qmljs/qmljslookupcontext.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ab35b99b3ddd051978d39da6f3f397980f1a88d
--- /dev/null
+++ b/src/libs/qmljs/qmljslookupcontext.h
@@ -0,0 +1,72 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef QMLJSLOOKUPCONTEXT_H
+#define QMLJSLOOKUPCONTEXT_H
+
+#include "qmljsdocument.h"
+#include "parser/qmljsastfwd_p.h"
+
+#include <QtCore/QSharedPointer>
+#include <QtCore/QScopedPointer>
+
+namespace QmlJS {
+
+class LookupContextData;
+
+namespace Interpreter {
+class Value;
+class Engine;
+class Context;
+}
+
+class QMLJS_EXPORT LookupContext
+{
+    LookupContext(const Document::Ptr doc, const Snapshot &snapshot, const QList<AST::Node *> &path);
+
+public:
+    ~LookupContext();
+
+    typedef QSharedPointer<LookupContext> Ptr;
+
+    static Ptr create(const Document::Ptr doc, const Snapshot &snapshot,
+                      const QList<AST::Node *> &path);
+
+    const Interpreter::Value *evaluate(AST::Node *node) const;
+    Interpreter::Engine *engine() const;
+    Interpreter::Context *context() const;
+
+private:
+    QScopedPointer<LookupContextData> d;
+};
+
+} // end of namespace QmlJS
+
+#endif // QMLJSLOOKUPCONTEXT_H
+
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
index 90917547f54b1d36d3bc88d62e957724063837fc..fbd340587e3a28914dab7fb66d81cc0ccb39c051 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
@@ -31,12 +31,20 @@
 
 using namespace QmlJS;
 
+static ModelManagerInterface *g_instance = 0;
+
 ModelManagerInterface::ModelManagerInterface(QObject *parent)
     : QObject(parent)
 {
+    Q_ASSERT(! g_instance);
+    g_instance = this;
 }
 
 ModelManagerInterface::~ModelManagerInterface()
 {
 }
 
+ModelManagerInterface *ModelManagerInterface::instance()
+{
+    return g_instance;
+}
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.h b/src/libs/qmljs/qmljsmodelmanagerinterface.h
index bf00b137453389bec4e3213cd9f4871f26aab5f8..7cd4e9bc47dbaaef30af0fab8c42aa168d8c1fb7 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.h
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.h
@@ -80,6 +80,8 @@ public:
     ModelManagerInterface(QObject *parent = 0);
     virtual ~ModelManagerInterface();
 
+    static ModelManagerInterface *instance();
+
     virtual QmlJS::Snapshot snapshot() const = 0;
     virtual void updateSourceFiles(const QStringList &files,
                                    bool emitDocumentOnDiskChanged) = 0;
diff --git a/src/plugins/qmljseditor/qmljscodecompletion.cpp b/src/plugins/qmljseditor/qmljscodecompletion.cpp
index 7a6e413858b5fecc26be21368dd6815fcd2c43a0..1bd3c77a52fc4fd020ff7170400a0c226a72ac9a 100644
--- a/src/plugins/qmljseditor/qmljscodecompletion.cpp
+++ b/src/plugins/qmljseditor/qmljscodecompletion.cpp
@@ -33,12 +33,10 @@
 
 #include <qmljs/qmljsmodelmanagerinterface.h>
 #include <qmljs/parser/qmljsast_p.h>
-#include <qmljs/qmljsbind.h>
 #include <qmljs/qmljsinterpreter.h>
+#include <qmljs/qmljslookupcontext.h>
 #include <qmljs/qmljsscanner.h>
-#include <qmljs/qmljsevaluate.h>
 #include <qmljs/qmljscompletioncontextfinder.h>
-#include <qmljs/qmljslink.h>
 #include <qmljs/qmljsscopebuilder.h>
 
 #include <texteditor/basetexteditor.h>
@@ -689,13 +687,9 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
     const QIcon symbolIcon = iconForColor(Qt::darkCyan);
     const QIcon keywordIcon = iconForColor(Qt::darkYellow);
 
-    Interpreter::Engine interp;
-    Interpreter::Context context(&interp);
-    Link link(&context, document, snapshot, m_modelManager->importPaths());
-
-    // Set up the current scope chain.
-    ScopeBuilder scopeBuilder(document, &context);
-    scopeBuilder.push(semanticInfo.astPath(editor->position()));
+    const QList<AST::Node *> path = semanticInfo.astPath(editor->position());
+    LookupContext::Ptr lookupContext = LookupContext::create(document, snapshot, path);
+    Interpreter::Context *context = lookupContext->context();
 
     // Search for the operator that triggered the completion.
     QChar completionOperator;
@@ -708,7 +702,7 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
 
     const Interpreter::ObjectValue *qmlScopeType = 0;
     if (contextFinder.isInQmlContext())
-         qmlScopeType = context.lookupType(document.data(), contextFinder.qmlObjectTypeName());
+         qmlScopeType = context->lookupType(document.data(), contextFinder.qmlObjectTypeName());
 
     if (completionOperator.isSpace() || completionOperator.isNull() || isDelimiter(completionOperator) ||
             (completionOperator == QLatin1Char('(') && m_startPosition != editor->position())) {
@@ -721,7 +715,7 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
             doGlobalCompletion = false;
             doJsKeywordCompletion = false;
 
-            EnumerateProperties enumerateProperties(&context);
+            EnumerateProperties enumerateProperties(context);
             enumerateProperties.setGlobalCompletion(true);
             enumerateProperties.setEnumerateGeneratedSlots(true);
 
@@ -733,11 +727,11 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
             m_completions.append(idPropertyCompletion);
 
             addCompletionsPropertyLhs(enumerateProperties(qmlScopeType), symbolIcon, PropertyOrder);
-            addCompletions(enumerateProperties(context.scopeChain().qmlTypes), symbolIcon, TypeOrder);
+            addCompletions(enumerateProperties(context->scopeChain().qmlTypes), symbolIcon, TypeOrder);
 
-            if (ScopeBuilder::isPropertyChangesObject(&context, qmlScopeType)
-                    && context.scopeChain().qmlScopeObjects.size() == 2) {
-                addCompletions(enumerateProperties(context.scopeChain().qmlScopeObjects.first()), symbolIcon, SymbolOrder);
+            if (ScopeBuilder::isPropertyChangesObject(context, qmlScopeType)
+                    && context->scopeChain().qmlScopeObjects.size() == 2) {
+                addCompletions(enumerateProperties(context->scopeChain().qmlScopeObjects.first()), symbolIcon, SymbolOrder);
             }
         }
 
@@ -748,7 +742,7 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
                 const Interpreter::Value *value = qmlScopeType;
                 foreach (const QString &name, contextFinder.bindingPropertyName()) {
                     if (const Interpreter::ObjectValue *objectValue = value->asObjectValue()) {
-                        value = objectValue->property(name, &context);
+                        value = objectValue->property(name, context);
                         if (!value)
                             break;
                     } else {
@@ -772,7 +766,7 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
 
         if (doGlobalCompletion) {
             // It's a global completion.
-            EnumerateProperties enumerateProperties(&context);
+            EnumerateProperties enumerateProperties(context);
             enumerateProperties.setGlobalCompletion(true);
             addCompletions(enumerateProperties(), symbolIcon, SymbolOrder);
         }
@@ -813,14 +807,13 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
         QmlJS::AST::ExpressionNode *expression = expressionUnderCursor(tc);
 
         if (expression != 0 && ! isLiteral(expression)) {
-            Evaluate evaluate(&context);
-
             // Evaluate the expression under cursor.
-            const Interpreter::Value *value = interp.convertToObject(evaluate(expression));
+            Interpreter::Engine *interp = lookupContext->engine();
+            const Interpreter::Value *value = interp->convertToObject(lookupContext->evaluate(expression));
             //qDebug() << "type:" << interp.typeId(value);
 
             if (value && completionOperator == QLatin1Char('.')) { // member completion
-                EnumerateProperties enumerateProperties(&context);
+                EnumerateProperties enumerateProperties(context);
                 if (contextFinder.isInLhsOfBinding() && qmlScopeType && expressionUnderCursor.text().at(0).isLower())
                     addCompletionsPropertyLhs(enumerateProperties(value), symbolIcon, PropertyOrder);
                 else
diff --git a/src/plugins/qmljseditor/qmljshoverhandler.cpp b/src/plugins/qmljseditor/qmljshoverhandler.cpp
index 31e923b40c24f4d88548d1381f14fb6d8122af59..88d1326a59d8d504f5394b691c0844ac605dfebd 100644
--- a/src/plugins/qmljseditor/qmljshoverhandler.cpp
+++ b/src/plugins/qmljseditor/qmljshoverhandler.cpp
@@ -37,11 +37,8 @@
 #include <coreplugin/editormanager/editormanager.h>
 #include <debugger/debuggerconstants.h>
 #include <extensionsystem/pluginmanager.h>
-#include <qmljs/qmljsbind.h>
-#include <qmljs/qmljsevaluate.h>
+#include <qmljs/qmljslookupcontext.h>
 #include <qmljs/qmljsinterpreter.h>
-#include <qmljs/qmljslink.h>
-#include <qmljs/qmljsscopebuilder.h>
 #include <qmljs/parser/qmljsast_p.h>
 #include <texteditor/itexteditor.h>
 #include <texteditor/basetexteditor.h>
@@ -151,17 +148,11 @@ void HoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int p
         if (node && !(AST::cast<AST::StringLiteral *>(node) != 0 || AST::cast<AST::NumericLiteral *>(node) != 0)) {
             QList<AST::Node *> astPath = semanticInfo.astPath(pos);
 
-            Interpreter::Engine interp;
-            Interpreter::Context context(&interp);
-            Link link(&context, qmlDocument, snapshot, m_modelManager->importPaths());
-            ScopeBuilder scopeBuilder(qmlDocument, &context);
-            scopeBuilder.push(astPath);
-
-            Evaluate check(&context);
-            const Interpreter::Value *value = check(node);
+            LookupContext::Ptr lookupContext = LookupContext::create(qmlDocument, snapshot, astPath);
+            const Interpreter::Value *value = lookupContext->evaluate(node);
 
             QStringList baseClasses;
-            m_toolTip = prettyPrint(value, &context, &baseClasses);
+            m_toolTip = prettyPrint(value, lookupContext->context(), &baseClasses);
 
             foreach (const QString &baseClass, baseClasses) {
                 QString helpId = QLatin1String("QML.");
@@ -193,7 +184,7 @@ void HoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int p
 }
 
 QString HoverHandler::prettyPrint(const QmlJS::Interpreter::Value *value, QmlJS::Interpreter::Context *context,
-                                     QStringList *baseClasses) const
+                                  QStringList *baseClasses) const
 {
     if (! value)
         return QString();