diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.cpp b/src/plugins/qmljsinspector/qmljsclientproxy.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..abceafd0cad788519f8343800124b604b15aacde
--- /dev/null
+++ b/src/plugins/qmljsinspector/qmljsclientproxy.cpp
@@ -0,0 +1,301 @@
+#include "qmljsclientproxy.h"
+#include "qmljsdebuggerclient.h"
+
+#include <utils/qtcassert.h>
+
+#include <private/qdeclarativedebug_p.h>
+#include <private/qdeclarativedebugclient_p.h>
+
+#include <QUrl>
+#include <QAbstractSocket>
+#include <QDebug>
+
+using namespace QmlJSInspector::Internal;
+
+ClientProxy *ClientProxy::m_instance = 0;
+
+ClientProxy::ClientProxy(QObject *parent) :
+    QObject(parent),
+    m_conn(0),
+    m_client(0),
+    m_engineQuery(0),
+    m_contextQuery(0),
+    m_objectTreeQuery(0),
+    m_debuggerRunControl(0)
+{
+    m_instance = this;
+}
+
+ClientProxy *ClientProxy::instance()
+{
+    return m_instance;
+}
+
+bool ClientProxy::connectToViewer(const QString &host, quint16 port)
+{
+    if (m_conn && m_conn->state() != QAbstractSocket::UnconnectedState)
+        return false;
+
+    qDebug() << Q_FUNC_INFO;
+    if (m_client) {
+        disconnect(m_client, SIGNAL(propertyDumpReceived(QDeclarativeDebugPropertyDump)),
+                   this,     SIGNAL(propertyDumpReceived(QDeclarativeDebugPropertyDump)));
+        disconnect(m_client, SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)),
+                   this,     SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)));
+
+        emit aboutToDisconnect();
+
+        delete m_client; m_client = 0;
+    }
+
+    if (m_conn) {
+        m_conn->disconnectFromHost();
+        delete m_conn;
+        m_conn = 0;
+    }
+
+    m_conn = new QDeclarativeDebugConnection(this);
+    connect(m_conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
+            SLOT(connectionStateChanged()));
+    connect(m_conn, SIGNAL(error(QAbstractSocket::SocketError)),
+            SLOT(connectionError()));
+
+    emit connectionStatusMessage(tr("[Inspector] set to connect to debug server %1:%2").arg(host).arg(port));
+    m_conn->connectToHost(host, port);
+
+
+    // blocks until connected; if no connection is available, will fail immediately
+    if (!m_conn->waitForConnected())
+        return false;
+
+//  ### commented out as the code resulted in asserts
+//    QTC_ASSERT(m_debuggerRunControl, return false);
+//    Debugger::Internal::QmlEngine *engine = qobject_cast<Debugger::Internal::QmlEngine *>(m_debuggerRunControl->engine());
+//    QTC_ASSERT(engine, return false);
+//    (void) new DebuggerClient(m_conn, engine);
+
+    return true;
+}
+
+void ClientProxy::disconnectFromViewer()
+{
+    m_conn->disconnectFromHost();
+    emit disconnected();
+}
+
+void ClientProxy::connectionError()
+{
+    emit connectionStatusMessage(tr("[Inspector] error: (%1) %2", "%1=error code, %2=error message")
+                                .arg(m_conn->error()).arg(m_conn->errorString()));
+}
+
+void ClientProxy::connectionStateChanged()
+{
+    switch (m_conn->state()) {
+        case QAbstractSocket::UnconnectedState:
+        {
+            emit connectionStatusMessage(tr("[Inspector] disconnected.\n\n"));
+
+            delete m_engineQuery;
+            m_engineQuery = 0;
+            delete m_contextQuery;
+            m_contextQuery = 0;
+
+            if (m_objectTreeQuery) {
+                delete m_objectTreeQuery;
+                m_objectTreeQuery = 0;
+            }
+
+            emit disconnected();
+
+            break;
+        }
+        case QAbstractSocket::HostLookupState:
+            emit connectionStatusMessage(tr("[Inspector] resolving host..."));
+            break;
+        case QAbstractSocket::ConnectingState:
+            emit connectionStatusMessage(tr("[Inspector] connecting to debug server..."));
+            break;
+        case QAbstractSocket::ConnectedState:
+        {
+            emit connectionStatusMessage(tr("[Inspector] connected.\n"));
+
+            if (!m_client) {
+                qDebug() << "CREATING ENGINE";
+                m_client = new QDeclarativeEngineDebug(m_conn, this);
+                emit connected(m_client);
+
+                connect(m_client,
+                        SIGNAL(propertyDumpReceived(QDeclarativeDebugPropertyDump)),
+                        SIGNAL(propertyDumpReceived(QDeclarativeDebugPropertyDump)));
+                connect(m_client,
+                        SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)),
+                        SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)));
+            }
+
+            reloadEngines();
+
+            break;
+        }
+        case QAbstractSocket::ClosingState:
+            emit connectionStatusMessage(tr("[Inspector] closing..."));
+            break;
+        case QAbstractSocket::BoundState:
+        case QAbstractSocket::ListeningState:
+            break;
+    }
+}
+
+bool ClientProxy::isConnected() const
+{
+    return (m_conn && m_client && m_conn->state() == QAbstractSocket::ConnectedState);
+}
+
+bool ClientProxy::isUnconnected() const
+{
+    return (!m_conn || m_conn->state() == QAbstractSocket::UnconnectedState);
+}
+
+void ClientProxy::setSelectedItemByObjectId(int engineId, const QDeclarativeDebugObjectReference &objectRef)
+{
+    qDebug() << "TODO:" << Q_FUNC_INFO;
+#if 0
+    if (isConnected())
+        m_client->setSelectedItemByObjectId(engineId, objectRef);
+#endif
+}
+
+QList<QDeclarativeDebugObjectReference> ClientProxy::objectReferences(const QUrl &url) const
+{
+    return objectReferences(url, m_rootObject);
+}
+
+QList<QDeclarativeDebugObjectReference> ClientProxy::objectReferences(const QUrl &url,
+                                                                      const QDeclarativeDebugObjectReference &objectRef) const
+{
+    QList<QDeclarativeDebugObjectReference> result;
+    if (objectRef.source().url() == url)
+        result.append(objectRef);
+
+    foreach(const QDeclarativeDebugObjectReference &child, objectRef.children()) {
+        result.append(objectReferences(url, child));
+    }
+
+    return result;
+}
+
+QDeclarativeDebugExpressionQuery *ClientProxy::setBindingForObject(int objectDebugId,
+                                                                   const QString &propertyName,
+                                                                   const QVariant &value,
+                                                                   bool isLiteralValue)
+{
+    qDebug() << "TODO:" << Q_FUNC_INFO;
+#if 0
+    if (propertyName == QLatin1String("id") || objectDebugId == -1)
+        return 0;
+
+    qDebug() << "executeBinding():" << objectDebugId << propertyName << value << "isLiteral:" << isLiteralValue;
+
+    return m_client->setBindingForObject(objectDebugId, propertyName, value.toString(), isLiteralValue, 0);
+#else
+    return 0;
+#endif
+}
+
+void ClientProxy::queryEngineContext(int id)
+{
+    if (id < 0)
+        return;
+
+    if (m_contextQuery) {
+        delete m_contextQuery;
+        m_contextQuery = 0;
+    }
+
+    m_contextQuery = m_client->queryRootContexts(QDeclarativeDebugEngineReference(id), this);
+    if (!m_contextQuery->isWaiting())
+        contextChanged();
+    else
+        QObject::connect(m_contextQuery, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
+                         this, SLOT(contextChanged()));
+}
+
+void ClientProxy::contextChanged()
+{
+    if (m_contextQuery) {
+
+        if (m_contextQuery->rootContext().objects().isEmpty()) {
+            m_rootObject = QDeclarativeDebugObjectReference();
+            emit objectTreeUpdated(m_rootObject);
+        } else {
+            m_rootObject = m_contextQuery->rootContext().objects().first();
+        }
+
+        delete m_contextQuery; m_contextQuery = 0;
+
+        m_objectTreeQuery = m_client->queryObjectRecursive(m_rootObject, this);
+        if (!m_objectTreeQuery->isWaiting()) {
+            objectTreeFetched();
+        } else {
+            connect(m_objectTreeQuery,
+                    SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
+                    SLOT(objectTreeFetched(QDeclarativeDebugQuery::State)));
+        }
+    }
+
+}
+
+void ClientProxy::objectTreeFetched(QDeclarativeDebugQuery::State state)
+{
+    if (state != QDeclarativeDebugQuery::Completed) {
+        m_rootObject = QDeclarativeDebugObjectReference();
+        return;
+    }
+
+    m_rootObject = m_objectTreeQuery->object();
+
+    delete m_objectTreeQuery;
+    m_objectTreeQuery = 0;
+
+    emit objectTreeUpdated(m_rootObject);
+}
+
+void ClientProxy::reloadQmlViewer(int engineId)
+{
+    qDebug() << "TODO:" << Q_FUNC_INFO;
+#if 0
+    if (m_client && m_conn->isConnected()) {
+        m_client->reloadQmlViewer(engineId);
+    }
+#endif
+}
+
+void ClientProxy::reloadEngines()
+{
+    if (m_engineQuery) {
+        emit connectionStatusMessage("[Inspector] Waiting for response to previous engine query");
+        return;
+    }
+
+    emit aboutToReloadEngines();
+
+    m_engineQuery = m_client->queryAvailableEngines(this);
+    if (!m_engineQuery->isWaiting())
+        updateEngineList();
+    else
+        QObject::connect(m_engineQuery, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
+                         this, SLOT(updateEngineList()));
+}
+
+QList<QDeclarativeDebugEngineReference> ClientProxy::engines() const
+{
+    return m_engines;
+}
+
+void ClientProxy::updateEngineList()
+{
+    m_engines = m_engineQuery->engines();
+    delete m_engineQuery; m_engineQuery = 0;
+
+    emit enginesChanged();
+}
diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.h b/src/plugins/qmljsinspector/qmljsclientproxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..80ed41de9409f32f9cef529e18822d5eff7b76d3
--- /dev/null
+++ b/src/plugins/qmljsinspector/qmljsclientproxy.h
@@ -0,0 +1,101 @@
+#ifndef QMLJSCLIENTPROXY_H
+#define QMLJSCLIENTPROXY_H
+
+#include "qmljsinspectorplugin.h"
+
+#include <private/qdeclarativedebug_p.h>
+#include <QObject>
+
+QT_FORWARD_DECLARE_CLASS(QUrl)
+QT_FORWARD_DECLARE_CLASS(QDeclarativeEngineDebug)
+QT_FORWARD_DECLARE_CLASS(QDeclarativeDebugConnection)
+QT_FORWARD_DECLARE_CLASS(QDeclarativeDebugExpressionQuery)
+QT_FORWARD_DECLARE_CLASS(QDeclarativeDebugPropertyDump)
+
+namespace Debugger {
+    class DebuggerRunControl;
+}
+
+namespace QmlJSInspector {
+namespace Internal {
+
+class QmlInspectorPlugin;
+
+class ClientProxy : public QObject
+{
+    Q_OBJECT
+
+public:
+    static ClientProxy *instance();
+    QDeclarativeDebugExpressionQuery *setBindingForObject(int objectDebugId,
+                                                          const QString &propertyName,
+                                                          const QVariant &value,
+                                                          bool isLiteralValue);
+
+    // returns the object references for the given url.
+    QList<QDeclarativeDebugObjectReference> objectReferences(const QUrl &url) const;
+
+    bool isConnected() const;
+    bool isUnconnected() const;
+
+    void setSelectedItemByObjectId(int engineId, const QDeclarativeDebugObjectReference &objectRef);
+
+    bool connectToViewer(const QString &host, quint16 port);
+    void disconnectFromViewer();
+
+    QList<QDeclarativeDebugEngineReference> engines() const;
+
+signals:
+    void objectTreeUpdated(const QDeclarativeDebugObjectReference &rootObject);
+    void connectionStatusMessage(const QString &text);
+
+    void aboutToReloadEngines();
+    void enginesChanged();
+
+    void propertyDumpReceived(const QDeclarativeDebugPropertyDump &propertyDump);
+    void selectedItemsChanged(const QList<QDeclarativeDebugObjectReference> &selectedItems);
+
+    void connected(QDeclarativeEngineDebug *client);
+    void aboutToDisconnect();
+    void disconnected();
+
+public slots:
+    void queryEngineContext(int id);
+    void reloadQmlViewer(int engineId);
+
+private slots:
+    void contextChanged();
+    void connectionStateChanged();
+    void connectionError();
+
+    void updateEngineList();
+    void objectTreeFetched(QDeclarativeDebugQuery::State state = QDeclarativeDebugQuery::Completed);
+
+private:
+    void reloadEngines();
+    QList<QDeclarativeDebugObjectReference> objectReferences(const QUrl &url, const QDeclarativeDebugObjectReference &objectRef) const;
+
+private:
+    explicit ClientProxy(QObject *parent = 0);
+    Q_DISABLE_COPY(ClientProxy);
+
+    static ClientProxy *m_instance;
+
+    QDeclarativeDebugConnection *m_conn;
+    QDeclarativeEngineDebug *m_client;
+
+    QDeclarativeDebugEnginesQuery *m_engineQuery;
+    QDeclarativeDebugRootContextQuery *m_contextQuery;
+    QDeclarativeDebugObjectQuery *m_objectTreeQuery;
+
+    QDeclarativeDebugObjectReference m_rootObject;
+    QList<QDeclarativeDebugEngineReference> m_engines;
+
+    Debugger::DebuggerRunControl *m_debuggerRunControl;
+    friend class QmlJSInspector::Internal::QmlInspectorPlugin;
+};
+
+} // namespace Internal
+} // namespace QmlJSInspector
+
+#endif // QMLJSCLIENTPROXY_H
diff --git a/src/plugins/qmljsinspector/qmljsinspector.pro b/src/plugins/qmljsinspector/qmljsinspector.pro
index 0f8b6abb015a4c3dbc71929481ec64501457acdd..67b65460fdbc28c16b07afa28166aa9a9e7e4f32 100644
--- a/src/plugins/qmljsinspector/qmljsinspector.pro
+++ b/src/plugins/qmljsinspector/qmljsinspector.pro
@@ -2,7 +2,7 @@ TEMPLATE = lib
 TARGET = QmlJSInspector
 INCLUDEPATH += .
 DEPENDPATH += .
-QT += declarative
+QT += declarative network
 
 include(../../private_headers.pri)
 
@@ -13,12 +13,14 @@ qmljsdebuggerclient.h \
 qmljsinspector_global.h \
 qmljsinspectorconstants.h \
 qmljsinspectorcontext.h \
-qmljsinspectorplugin.h
+qmljsinspectorplugin.h \
+qmljsclientproxy.h
 
 SOURCES += \
 qmljsdebuggerclient.cpp \
 qmljsinspectorcontext.cpp \
-qmljsinspectorplugin.cpp
+qmljsinspectorplugin.cpp \
+qmljsclientproxy.cpp
 
 OTHER_FILES += QmlJSInspector.pluginspec
 RESOURCES += qmljsinspector.qrc