diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index 1dbd12a9076562813b10ab8abb16bbffab472cbe..2f59f7c0aa4c2a0fbeea04cb045a0ea51cf1e339 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -47,7 +47,7 @@ Check::~Check()
 {
 }
 
-const Interpreter::Value *Check::operator()(AST::ExpressionNode *ast, const Interpreter::ObjectValue *scope)
+const Interpreter::Value *Check::operator()(AST::Node *ast, const Interpreter::ObjectValue *scope)
 {
     const Interpreter::ObjectValue *previousScope = switchScope(scope);
     const Interpreter::Value *result = check(ast);
@@ -55,7 +55,7 @@ const Interpreter::Value *Check::operator()(AST::ExpressionNode *ast, const Inte
     return result;
 }
 
-const Interpreter::Value *Check::check(AST::ExpressionNode *ast)
+const Interpreter::Value *Check::check(AST::Node *ast)
 {
     const Value *previousResult = switchResult(0);
     accept(ast);
@@ -151,8 +151,31 @@ bool Check::visit(AST::UiArrayMemberList *)
     return false;
 }
 
-bool Check::visit(AST::UiQualifiedId *)
+bool Check::visit(AST::UiQualifiedId *ast)
 {
+    if (! ast->name)
+         return false;
+
+    const Value *value = _scope->lookup(ast->name->asString());
+    if (! ast->next) {
+        _result = value;
+
+    } else {
+        const ObjectValue *base = value_cast<const ObjectValue *>(value);
+
+        for (AST::UiQualifiedId *it = ast->next; base && it; it = it->next) {
+            NameId *name = it->name;
+            if (! name)
+                break;
+
+            const Value *value = base->property(name->asString());
+            if (! it->next)
+                _result = value;
+            else
+                base = value_cast<const ObjectValue *>(value);
+        }
+    }
+
     return false;
 }
 
diff --git a/src/libs/qmljs/qmljscheck.h b/src/libs/qmljs/qmljscheck.h
index 6864de4f8c927d215375afea4986a90739d84689..f9a395cbe093e7dd5c9d8e5f505339fda2e48941 100644
--- a/src/libs/qmljs/qmljscheck.h
+++ b/src/libs/qmljs/qmljscheck.h
@@ -48,11 +48,11 @@ public:
     Check(Interpreter::Engine *engine);
     virtual ~Check();
 
-    const Interpreter::Value *operator()(AST::ExpressionNode *ast, const Interpreter::ObjectValue *scope);
-    const Interpreter::Value *check(AST::ExpressionNode *ast);
+    const Interpreter::Value *operator()(AST::Node *ast, const Interpreter::ObjectValue *scope);
 
 protected:
     void accept(AST::Node *node);
+    const Interpreter::Value *check(AST::Node *ast);
 
     Interpreter::Engine *switchEngine(Interpreter::Engine *engine);
     const Interpreter::Value *switchResult(const Interpreter::Value *result);
diff --git a/src/plugins/qmljseditor/qmlhoverhandler.cpp b/src/plugins/qmljseditor/qmlhoverhandler.cpp
index f247aa9a800a1589df9e08e0e1a20e132ecf88a6..71e7012bfc36400734598e2c6c1daddbe3419dae 100644
--- a/src/plugins/qmljseditor/qmlhoverhandler.cpp
+++ b/src/plugins/qmljseditor/qmlhoverhandler.cpp
@@ -142,11 +142,13 @@ void QmlHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
         return;
 
     const SemanticInfo semanticInfo = edit->semanticInfo();
-    const Snapshot snapshot = semanticInfo.snapshot;
-    Document::Ptr qmlDocument = semanticInfo.document;
-    if (qmlDocument.isNull())
+
+    if (semanticInfo.revision() != edit->documentRevision())
         return;
 
+    const Snapshot snapshot = semanticInfo.snapshot;
+    const Document::Ptr qmlDocument = semanticInfo.document;
+
     if (m_helpEngineNeedsSetup && m_helpEngine->registeredDocumentations().count() > 0) {
         m_helpEngine->setupData();
         m_helpEngineNeedsSetup = false;
@@ -169,10 +171,10 @@ void QmlHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
             AST::UiObjectMember *declaringMember = semanticInfo.declaringMember(pos);
 
             Interpreter::Engine interp;
-            Interpreter::ObjectValue *scope = Bind::scopeChainAt(qmlDocument, snapshot, &interp, declaringMember);
+            const Interpreter::ObjectValue *scope = Bind::scopeChainAt(qmlDocument, snapshot, &interp, declaringMember);
 
             Check check(&interp);
-            const Interpreter::Value *value = check(node->expressionCast(), scope);
+            const Interpreter::Value *value = check(node, scope);
 
             QStringList baseClasses;
             m_toolTip = prettyPrint(value, &interp, &baseClasses);
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index 0b25fccbbad8eeb738c4375b0d3351d75badcf90..56c8790b5bf27749a7f08bcbea75ad3156636c59 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -567,6 +567,16 @@ QmlJSTextEditor::~QmlJSTextEditor()
 {
 }
 
+SemanticInfo QmlJSTextEditor::semanticInfo() const
+{
+    return m_semanticInfo;
+}
+
+int QmlJSTextEditor::documentRevision() const
+{
+    return document()->revision();
+}
+
 Core::IEditor *QmlJSEditorEditable::duplicate(QWidget *parent)
 {
     QmlJSTextEditor *newEditor = new QmlJSTextEditor(parent);
diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h
index 3991eefa19ae588177a2330bcf8d8748709a5353..28e50bb89001c7cdeccc78d16bc358b459546bdb 100644
--- a/src/plugins/qmljseditor/qmljseditor.h
+++ b/src/plugins/qmljseditor/qmljseditor.h
@@ -131,7 +131,8 @@ public:
 
     virtual void unCommentSelection();
 
-    SemanticInfo semanticInfo() const { return m_semanticInfo; }
+    SemanticInfo semanticInfo() const;
+    int documentRevision() const;
 
 public slots:
     virtual void setFontSettings(const TextEditor::FontSettings &);