diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index d8c2ac69c4601073808b53d219774da96366d570..bde16e30dc540fb6edce3bced1c13f1fef503ad8 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -30,6 +30,7 @@
 #include "qmlengine.h"
 #include "qmladapter.h"
 
+#include "debuggertooltip.h"
 #include "debuggerconstants.h"
 #include "debuggerplugin.h"
 #include "debuggerdialogs.h"
@@ -170,6 +171,7 @@ void QmlEngine::connectionEstablished()
 
     ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
     pluginManager->addObject(m_adapter);
+    pluginManager->addObject(this);
     m_addedAdapterToObjectPool = true;
 
     plugin()->showMessage(tr("QML Debugger connected."), StatusBar);
@@ -233,6 +235,7 @@ void QmlEngine::shutdownEngineAsSlave()
     if (m_addedAdapterToObjectPool) {
         ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
         pluginManager->removeObject(m_adapter);
+        pluginManager->removeObject(this);
     }
 
     if (m_attachToRunningExternalApp) {
@@ -445,9 +448,8 @@ static QHash<QString, WatchData> m_toolTipCache;
 
 void QmlEngine::setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos)
 {
-    Q_UNUSED(mousePos)
-    Q_UNUSED(editor)
-    Q_UNUSED(cursorPos)
+    // this is processed by QML inspector, which has deps to qml js editor. Makes life easier.
+    emit tooltipRequested(mousePos, editor, cursorPos);
 }
 
 //////////////////////////////////////////////////////////////////////
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index 5c0854acf28045f7a4f777215365a76e00eceebd..31f08d027986262721adc5986345b586d2b28efd 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -46,6 +46,10 @@
 
 #include <projectexplorer/applicationlauncher.h>
 
+namespace Core {
+    class TextEditor;
+}
+
 namespace Debugger {
 namespace Internal {
 
@@ -120,6 +124,7 @@ private:
 
 signals:
     void sendMessage(const QByteArray &msg);
+    void tooltipRequested(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
 
 private slots:
     void connectionEstablished();
diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h
index b95cd0d7efddc6586713831e754c2d25d077ee32..b70ad1ae8895e9dfda4bcd84af25f6667c536245 100644
--- a/src/plugins/qmljseditor/qmljseditor.h
+++ b/src/plugins/qmljseditor/qmljseditor.h
@@ -116,7 +116,7 @@ public: // attributes
 
 class SemanticHighlighter;
 
-class SemanticInfo
+class QMLJSEDITOR_EXPORT SemanticInfo
 {
 public:
     SemanticInfo() {}
diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.cpp b/src/plugins/qmljsinspector/qmljsclientproxy.cpp
index 9db56a375ae26ab9ed6ebb62c5ced4c7b316323e..4ca4a1d49233a03d6f51b7e60772c3005b007b82 100644
--- a/src/plugins/qmljsinspector/qmljsclientproxy.cpp
+++ b/src/plugins/qmljsinspector/qmljsclientproxy.cpp
@@ -198,6 +198,29 @@ QDeclarativeDebugObjectReference ClientProxy::objectReferenceForId(int debugId,
     return QDeclarativeDebugObjectReference();
 }
 
+QDeclarativeDebugObjectReference ClientProxy::objectReferenceForId(const QString &objectId) const
+{
+    if (!objectId.isEmpty() && objectId[0].isLower()) {
+        const QList<QDeclarativeDebugObjectReference> refs = objectReferences();
+        foreach (const QDeclarativeDebugObjectReference &ref, refs) {
+            if (ref.idString() == objectId)
+                return ref;
+        }
+    }
+    return QDeclarativeDebugObjectReference();
+}
+
+QDeclarativeDebugObjectReference ClientProxy::objectReferenceForLocation(const int line, const int column) const
+{
+    const QList<QDeclarativeDebugObjectReference> refs = objectReferences();
+    foreach (const QDeclarativeDebugObjectReference &ref, refs) {
+        if (ref.source().lineNumber() == line && ref.source().columnNumber() == column)
+            return ref;
+    }
+
+    return QDeclarativeDebugObjectReference();
+}
+
 QList<QDeclarativeDebugObjectReference> ClientProxy::objectReferences() const
 {
     QList<QDeclarativeDebugObjectReference> result;
@@ -253,6 +276,13 @@ bool ClientProxy::resetBindingForObject(int objectDebugId, const QString& proper
     return m_client->resetBindingForObject(objectDebugId, propertyName);
 }
 
+QDeclarativeDebugExpressionQuery *ClientProxy::queryExpressionResult(int objectDebugId, const QString &expr, QObject *parent)
+{
+    if (objectDebugId != -1)
+        return m_client->queryExpressionResult(objectDebugId,expr,parent);
+    return 0;
+}
+
 void ClientProxy::clearComponentCache()
 {
     if (isDesignClientConnected())
diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.h b/src/plugins/qmljsinspector/qmljsclientproxy.h
index ca87e6f7d09ba9b62e445906c310512190a29447..245e04c7160d7a67c8d2cd4c54afec1ba8b40565 100644
--- a/src/plugins/qmljsinspector/qmljsclientproxy.h
+++ b/src/plugins/qmljsinspector/qmljsclientproxy.h
@@ -65,11 +65,14 @@ public:
 
     bool setMethodBodyForObject(int objectDebugId, const QString &methodName, const QString &methodBody);
     bool resetBindingForObject(int objectDebugId, const QString &propertyName);
+    QDeclarativeDebugExpressionQuery *queryExpressionResult(int objectDebugId, const QString &expr, QObject *parent=0);
     void clearComponentCache();
 
     // returns the object references
     QList<QDeclarativeDebugObjectReference> objectReferences() const;
     QDeclarativeDebugObjectReference objectReferenceForId(int debugId) const;
+    QDeclarativeDebugObjectReference objectReferenceForId(const QString &objectId) const;
+    QDeclarativeDebugObjectReference objectReferenceForLocation(const int line, const int column) const;
     QList<QDeclarativeDebugObjectReference> rootObjectReference() const;
     DebugIdHash debugIdHash() const { return m_debugIdHash; };
 
diff --git a/src/plugins/qmljsinspector/qmljsinspector.cpp b/src/plugins/qmljsinspector/qmljsinspector.cpp
index 79dbae1e5a789e5f151cc6a6f5181d51809e87eb..fc2d5957a1cc84f7a5b060be04f59c16befeb9df 100644
--- a/src/plugins/qmljsinspector/qmljsinspector.cpp
+++ b/src/plugins/qmljsinspector/qmljsinspector.cpp
@@ -38,9 +38,11 @@
 
 #include <qmljseditor/qmljseditorconstants.h>
 
+#include <qmljseditor/qmljseditor.h>
 #include <qmljs/qmljsmodelmanagerinterface.h>
 #include <qmljs/qmljsdocument.h>
 
+#include <qmljs/parser/qmljsast_p.h>
 #include <debugger/debuggerrunner.h>
 #include <debugger/debuggerconstants.h>
 #include <debugger/debuggerengine.h>
@@ -49,6 +51,7 @@
 #include <debugger/debuggerrunner.h>
 #include <debugger/debuggeruiswitcher.h>
 #include <debugger/debuggerconstants.h>
+#include <debugger/qml/qmlengine.h>
 
 #include <utils/qtcassert.h>
 #include <utils/styledbar.h>
@@ -100,6 +103,8 @@
 #include <QtGui/QMessageBox>
 #include <QtGui/QTextBlock>
 
+#include <QtGui/QToolTip>
+#include <QtGui/QCursor>
 #include <QtNetwork/QHostAddress>
 
 using namespace QmlJS;
@@ -131,6 +136,8 @@ InspectorUi::InspectorUi(QObject *parent)
     , m_inspectorDockWidget(0)
     , m_settings(new InspectorSettings(this))
     , m_clientProxy(0)
+    , m_qmlEngine(0)
+    , m_debugQuery(0)
     , m_debugProject(0)
 {
     m_instance = this;
@@ -157,6 +164,103 @@ void InspectorUi::restoreSettings()
     m_settings->restoreSettings(Core::ICore::instance()->settings());
 }
 
+void InspectorUi::setDebuggerEngine(Debugger::Internal::QmlEngine *qmlEngine)
+{
+    if (m_qmlEngine && !qmlEngine) {
+        disconnect(m_qmlEngine, SIGNAL(tooltipRequested(QPoint, TextEditor::ITextEditor*, int)),
+                   this, SLOT(showDebuggerTooltip(QPoint, TextEditor::ITextEditor*, int)));
+    }
+
+    m_qmlEngine = qmlEngine;
+    if (m_qmlEngine) {
+        connect(m_qmlEngine, SIGNAL(tooltipRequested(QPoint, TextEditor::ITextEditor*, int)),
+                this, SLOT(showDebuggerTooltip(QPoint, TextEditor::ITextEditor*, int)));
+    }
+}
+
+Debugger::Internal::QmlEngine *InspectorUi::debuggerEngine() const
+{
+    return m_qmlEngine;
+}
+
+void InspectorUi::showDebuggerTooltip(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos)
+{
+    Q_UNUSED(mousePos);
+    if (editor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID) {
+        QmlJSEditor::Internal::QmlJSTextEditor *qmlEditor = static_cast<QmlJSEditor::Internal::QmlJSTextEditor*>(editor->widget());
+
+        QTextCursor tc(qmlEditor->document());
+        tc.setPosition(cursorPos);
+        tc.movePosition(QTextCursor::StartOfWord);
+        tc.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+
+        QString wordAtCursor = tc.selectedText();
+        QString query;
+        QLatin1Char doubleQuote('"');
+
+        QmlJS::AST::Node *qmlNode = qmlEditor->semanticInfo().nodeUnderCursor(cursorPos);
+        if (!qmlNode)
+            return;
+        QmlJS::AST::Node *node = qmlEditor->semanticInfo().declaringMemberNoProperties(cursorPos);
+        if (!node)
+            return;
+        QDeclarativeDebugObjectReference ref = m_clientProxy->objectReferenceForLocation(node->uiObjectMemberCast()->firstSourceLocation().startLine, node->uiObjectMemberCast()->firstSourceLocation().startColumn);
+
+        if (ref.debugId() == -1)
+            return;
+
+        if (wordAtCursor == QString("id")) {
+            query = QString("\"id:") + ref.idString() + doubleQuote;
+        } else {
+            if ((qmlNode->kind == QmlJS::AST::Node::Kind_IdentifierExpression) ||
+                (qmlNode->kind == QmlJS::AST::Node::Kind_FieldMemberExpression)) {
+                tc.setPosition(qmlNode->expressionCast()->firstSourceLocation().begin());
+                tc.setPosition(qmlNode->expressionCast()->lastSourceLocation().end(),QTextCursor::KeepAnchor);
+                QString refToLook = tc.selectedText();
+                if ((qmlNode->kind == QmlJS::AST::Node::Kind_IdentifierExpression) &&
+                    (m_clientProxy->objectReferenceForId(refToLook).debugId() == -1)) {
+                    query = doubleQuote + QString("local: ") + refToLook + doubleQuote;
+                    foreach(QDeclarativeDebugPropertyReference property, ref.properties()) {
+                        if (property.name() == wordAtCursor && !property.valueTypeName().isEmpty()) {
+                            query =  doubleQuote + property.name() + QLatin1Char(':') + doubleQuote + QLatin1Char('+') + property.name();
+                            break;
+                        }
+                    }
+                }
+                else
+                    query =doubleQuote + refToLook + QLatin1Char(':') + doubleQuote + QLatin1Char('+') + refToLook;
+            } else {
+                // show properties
+                foreach(QDeclarativeDebugPropertyReference property, ref.properties()) {
+                    if (property.name() == wordAtCursor && !property.valueTypeName().isEmpty()) {
+                        query =  doubleQuote + property.name() + QLatin1Char(':') + doubleQuote + QLatin1Char('+') + property.name();
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (!query.isEmpty()) {
+            m_debugQuery = m_clientProxy->queryExpressionResult(ref.debugId(),query);
+            connect(m_debugQuery,SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),this,SLOT(debugQueryUpdated(QDeclarativeDebugQuery::State)));
+        }
+    }
+}
+
+void InspectorUi::debugQueryUpdated(QDeclarativeDebugQuery::State newState)
+{
+    if (newState != QDeclarativeDebugExpressionQuery::Completed)
+        return;
+    if (!m_debugQuery)
+        return;
+
+    QString text = m_debugQuery->result().toString();
+    if (!text.isEmpty())
+        QToolTip::showText(QCursor::pos(), text);
+
+    disconnect(m_debugQuery,SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),this,SLOT(debugQueryUpdated(QDeclarativeDebugQuery::State)));
+}
+
 void InspectorUi::connected(ClientProxy *clientProxy)
 {
     m_clientProxy = clientProxy;
@@ -203,6 +307,7 @@ void InspectorUi::disconnected()
                m_crumblePath, SLOT(updateContextPath(QStringList)));
 
     m_debugProject = 0;
+    m_qmlEngine = 0;
     resetViews();
 
     setupToolbar(false);
diff --git a/src/plugins/qmljsinspector/qmljsinspector.h b/src/plugins/qmljsinspector/qmljsinspector.h
index 3c53ce2daad362002420f1289da5b3a9dec8387f..8f1006fed74c4bcfb1138ea82f76cf0f69bdd55f 100644
--- a/src/plugins/qmljsinspector/qmljsinspector.h
+++ b/src/plugins/qmljsinspector/qmljsinspector.h
@@ -47,6 +47,10 @@ namespace ProjectExplorer {
     class Environment;
 }
 
+namespace TextEditor {
+    class ITextEditor;
+}
+
 namespace Core {
     class IContext;
 }
@@ -55,6 +59,12 @@ namespace QmlJS {
     class ModelManagerInterface;
 }
 
+namespace Debugger {
+namespace Internal {
+    class QmlEngine;
+}
+}
+
 QT_FORWARD_DECLARE_CLASS(QDockWidget)
 
 namespace QmlJSInspector {
@@ -97,6 +107,8 @@ public:
     void setupUi();
     void connected(ClientProxy *clientProxy);
     void disconnected();
+    void setDebuggerEngine(Debugger::Internal::QmlEngine *qmlEngine);
+    Debugger::Internal::QmlEngine *debuggerEngine() const;
 
 signals:
     void statusMessage(const QString &text);
@@ -125,6 +137,8 @@ private slots:
 
     void currentDebugProjectRemoved();
     void updatePendingPreviewDocuments(QmlJS::Document::Ptr doc);
+    void showDebuggerTooltip(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
+    void debugQueryUpdated(QDeclarativeDebugQuery::State);
 
 private:
     bool addQuotesForData(const QVariant &value) const;
@@ -146,6 +160,8 @@ private:
 
     InspectorSettings *m_settings;
     ClientProxy *m_clientProxy;
+    Debugger::Internal::QmlEngine *m_qmlEngine;
+    QDeclarativeDebugExpressionQuery *m_debugQuery;
 
     // Qml/JS integration
     QHash<QString, QmlJSLiveTextPreview *> m_textPreviews;
diff --git a/src/plugins/qmljsinspector/qmljsinspectorplugin.cpp b/src/plugins/qmljsinspector/qmljsinspectorplugin.cpp
index befce483c8f8aeeb091f8a24f789c5ee3f2079b1..bff091ab21491efc5affa461dce131f4666f6ec2 100644
--- a/src/plugins/qmljsinspector/qmljsinspectorplugin.cpp
+++ b/src/plugins/qmljsinspector/qmljsinspectorplugin.cpp
@@ -36,6 +36,7 @@
 #include <debugger/debuggeruiswitcher.h>
 #include <debugger/debuggerconstants.h>
 #include <debugger/qml/qmladapter.h>
+#include <debugger/qml/qmlengine.h>
 
 #include <qmlprojectmanager/qmlproject.h>
 #include <qmljseditor/qmljseditorconstants.h>
@@ -130,6 +131,12 @@ void InspectorPlugin::objectAdded(QObject *object)
     if (adapter) {
         m_clientProxy = new ClientProxy(adapter);
         m_inspectorUi->connected(m_clientProxy);
+        return;
+    }
+
+    Debugger::Internal::QmlEngine *engine = qobject_cast<Debugger::Internal::QmlEngine*>(object);
+    if (engine) {
+        m_inspectorUi->setDebuggerEngine(engine);
     }
 }
 
@@ -140,6 +147,10 @@ void InspectorPlugin::aboutToRemoveObject(QObject *obj)
         delete m_clientProxy;
         m_clientProxy = 0;
     }
+
+    if (m_inspectorUi->debuggerEngine() == obj) {
+        m_inspectorUi->setDebuggerEngine(0);
+    }
 }
 
 Q_EXPORT_PLUGIN(InspectorPlugin)
diff --git a/src/plugins/qmljsinspector/qmljslivetextpreview.cpp b/src/plugins/qmljsinspector/qmljslivetextpreview.cpp
index b3682395725d0860ac7332e0edd3a4a0c7edcc33..94dbe08ee725b6a85c71dd70d8da4c6eeff895ee 100644
--- a/src/plugins/qmljsinspector/qmljslivetextpreview.cpp
+++ b/src/plugins/qmljsinspector/qmljslivetextpreview.cpp
@@ -206,15 +206,7 @@ void QmlJSLiveTextPreview::changeSelectedElements(QList<int> offsets, const QStr
         return;
 
     QDeclarativeDebugObjectReference objectRefUnderCursor;
-    if (!wordAtCursor.isEmpty() && wordAtCursor[0].isLower()) {
-        QList<QDeclarativeDebugObjectReference> refs = m_clientProxy.data()->objectReferences();
-        foreach (const QDeclarativeDebugObjectReference &ref, refs) {
-            if (ref.idString() == wordAtCursor) {
-                objectRefUnderCursor = ref;
-                break;
-            }
-        }
-    }
+    objectRefUnderCursor = m_clientProxy.data()->objectReferenceForId(wordAtCursor);
 
     QList<int> selectedReferences;
     bool containsReferenceUnderCursor = false;