diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index 053abf0da40963746f5ea1ad230a3b54f252ca9d..ed417742a9ac974917f341c366706b53e63e3220 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -161,10 +161,27 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters)
 {
     m_conn = 0;
     m_client = 0;
-    m_engineQuery = 0;
-    m_contextQuery = 0;
-
+    m_engineDebugInterface = 0;
     m_frameRate = 0;
+
+    /*
+    m_watchTableModel = new Internal::WatchTableModel(0, this);
+
+    m_objectTreeWidget = new Internal::ObjectTree;
+    m_propertiesWidget = new Internal::ObjectPropertiesView(m_watchTableModel);
+    m_watchTableView = new Internal::WatchTableView(m_watchTableModel);
+    m_expressionWidget = new Internal::ExpressionQueryWidget(Internal::ExpressionQueryWidget::SeparateEntryMode);
+//    m_frameRateWidget = new Internal::CanvasFrameRate;
+//    m_frameRateWidget->setObjectName(QLatin1String("QmlDebugFrameRate"));
+
+    connect(Debugger::DebuggerPlugin::instance(),
+        SIGNAL(stateChanged(int)), this, SLOT(debuggerStateChanged(int)));
+
+    m_editablePropertyTypes = QStringList() << "qreal" << "bool" << "QString"
+                                            << "int" << "QVariant" << "QUrl" << "QColor";
+
+    connect(m_connectionTimer, SIGNAL(timeout()), SLOT(pollInspector()));
+    */
 }
 
 QmlEngine::~QmlEngine()
@@ -189,6 +206,10 @@ void QmlEngine::executeDebuggerCommand(const QString &command)
 void QmlEngine::shutdown()
 {
     exitDebugger();
+
+    //m_objectTreeWidget->saveSettings(m_settings);
+    //m_propertiesWidget->saveSettings(m_settings);
+    //m_settings.saveSettings(Core::ICore::instance()->settings());
 }
 
 void QmlEngine::exitDebugger()
@@ -254,14 +275,16 @@ void QmlEngine::setupConnection()
     m_client = new QmlDebuggerClient(m_conn, this);
     (void) new QmlFrameRateClient(m_conn, this);
 
-    //m_objectTreeWidget->setEngineDebug(m_client);
-    //m_propertiesWidget->setEngineDebug(m_client);
-    //m_watchTableModel->setEngineDebug(m_client);
-    //m_expressionWidget->setEngineDebug(m_client);
 
-    //   resetViews();
-    //   m_frameRateWidget->reset(m_conn);
-    //   reloadEngines();
+    QTC_ASSERT(m_engineDebugInterface == 0, /**/);
+    m_engineDebugInterface = new QDeclarativeEngineDebug(m_conn, this);
+
+    //m_objectTreeWidget->setEngineDebug(m_engineDebugInterface);
+    //m_propertiesWidget->setEngineDebug(m_engineDebugInterface);
+    //m_watchTableModel->setEngineDebug(m_engineDebugInterface);
+    //m_expressionWidget->setEngineDebug(m_engineDebugInterface);
+    //resetViews();
+    //m_frameRateWidget->reset(m_conn);
 
     QHostAddress ha(QHostAddress::LocalHost);
 
@@ -278,6 +301,8 @@ void QmlEngine::setupConnection()
     qDebug() << "CONNECTION SUCCESSFUL";
     setState(InferiorRunning);
     startSuccessful();
+
+    reloadEngines();
 }
 
 void QmlEngine::continueInferior()
@@ -462,10 +487,12 @@ void QmlEngine::assignValueInDebugger(const QString &expression,
 
 void QmlEngine::updateLocals()
 {
+    qDebug() << "UPDATE LOCALS";
 }
 
 void QmlEngine::updateWatchData(const WatchData &data)
 {
+    qDebug() << "UPDATE WATCH DATA" << data.toString();
     //watchHandler()->rebuildModel();
     showStatusMessage(tr("Stopped."), 5000);
 
@@ -624,6 +651,14 @@ void QmlEngine::messageReceived(const QByteArray &message)
 
         watchHandler()->endCycle();
 
+        foreach (QDeclarativeDebugWatch *watch, m_watches) {
+            qDebug() << "WATCH"
+                << watch->objectName()
+                << watch->queryId()
+                << watch->state()
+                << watch->objectDebugId();
+        }
+
     } else if (command == "RESULT") {
         WatchData data;
         QVariant variant;
@@ -710,12 +745,6 @@ void QmlEngine::connectionStateChanged()
         case QAbstractSocket::UnconnectedState:
         {
             showStatusMessage(tr("[QmlEngine] disconnected.\n\n"));
-
-            delete m_engineQuery;
-            m_engineQuery = 0;
-            delete m_contextQuery;
-            m_contextQuery = 0;
-
 //            resetViews();
 
 //            updateMenuActions();
@@ -762,6 +791,950 @@ void QmlEngine::connectionConnected()
 }
 
 
+#if 0
+class EngineComboBox : public QComboBox
+{
+    Q_OBJECT
+public:
+    struct EngineInfo
+    {
+        QString name;
+        int id;
+    };
+
+    EngineComboBox(QWidget *parent = 0);
+
+    void addEngine(int engine, const QString &name);
+    void clearEngines();
+
+protected:
+
+private:
+    QList<EngineInfo> m_engines;
+};
+
+EngineComboBox::EngineComboBox(QWidget *parent)
+    : QComboBox(parent)
+{
+    setEnabled(false);
+    setEditable(false);
+}
+
+void EngineComboBox::addEngine(int engine, const QString &name)
+{
+    EngineInfo info;
+    info.id = engine;
+    if (name.isEmpty())
+        info.name = tr("Engine %1", "engine number").arg(engine);
+    else
+        info.name = name;
+    m_engines << info;
+
+    addItem(info.name);
+}
+
+void EngineComboBox::clearEngines()
+{
+    m_engines.clear();
+    clear();
+}
+
+} // Internal
+
+
+bool QmlEngine::setDebugConfigurationDataFromProject(ProjectExplorer::Project *projectToDebug)
+{
+    if (!projectToDebug) {
+        emit statusMessage(tr("Invalid project, debugging canceled."));
+        return false;
+    }
+
+    QmlProjectManager::QmlProjectRunConfiguration* config =
+            qobject_cast<QmlProjectManager::QmlProjectRunConfiguration*>(projectToDebug->activeTarget()->activeRunConfiguration());
+    if (!config) {
+        emit statusMessage(tr("Cannot find project run configuration, debugging canceled."));
+        return false;
+    }
+    m_runConfigurationDebugData.serverAddress = config->debugServerAddress();
+    m_runConfigurationDebugData.serverPort = config->debugServerPort();
+    m_connectionTimer->setInterval(ConnectionAttemptDefaultInterval);
+
+    return true;
+}
+
+void QmlEngine::startQmlProjectDebugger()
+{
+    m_simultaneousCppAndQmlDebugMode = false;
+    m_connectionTimer->start();
+}
+
+bool QmlEngine::connectToViewer()
+{
+    if (m_conn && m_conn->state() != QAbstractSocket::UnconnectedState)
+        return false;
+
+    delete m_engineDebugInterface; m_engineDebugInterface = 0;
+
+    if (m_conn) {
+        m_conn->disconnectFromHost();
+        delete m_conn;
+        m_conn = 0;
+    }
+
+    QString host = m_runConfigurationDebugData.serverAddress;
+    quint16 port = quint16(m_runConfigurationDebugData.serverPort);
+
+    m_conn = new QDeclarativeDebugConnection(this);
+    connect(m_conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
+            SLOT(connectionStateChanged()));
+    connect(m_conn, SIGNAL(error(QAbstractSocket::SocketError)),
+            SLOT(connectionError()));
+
+    emit statusMessage(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;
+
+    QTC_ASSERT(m_debuggerRunControl, return false);
+    QmlEngine *engine = qobject_cast<QmlEngine *>(m_debuggerRunControl->engine());
+    QTC_ASSERT(engine, return false);
+
+    (void) new DebuggerClient(m_conn, engine);
+
+    return true;
+}
+
+void QmlEngine::disconnectFromViewer()
+{
+    m_conn->disconnectFromHost();
+    updateMenuActions();
+}
+
+void QmlEngine::connectionStateChanged()
+{
+    switch (m_conn->state()) {
+        case QAbstractSocket::UnconnectedState:
+        {
+            emit statusMessage(tr("[Inspector] disconnected.\n\n"));
+            resetViews();
+            updateMenuActions();
+            break;
+        }
+        case QAbstractSocket::HostLookupState:
+            emit statusMessage(tr("[Inspector] resolving host..."));
+            break;
+        case QAbstractSocket::ConnectingState:
+            emit statusMessage(tr("[Inspector] connecting to debug server..."));
+            break;
+        case QAbstractSocket::ConnectedState:
+        {
+            emit statusMessage(tr("[Inspector] connected.\n"));
+
+            resetViews();
+//            m_frameRateWidget->reset(m_conn);
+
+            break;
+        }
+        case QAbstractSocket::ClosingState:
+            emit statusMessage(tr("[Inspector] closing..."));
+            break;
+        case QAbstractSocket::BoundState:
+        case QAbstractSocket::ListeningState:
+            break;
+    }
+}
+
+void QmlEngine::resetViews()
+{
+    m_objectTreeWidget->cleanup();
+    m_propertiesWidget->clear();
+    m_expressionWidget->clear();
+    m_watchTableModel->removeAllWatches();
+}
+
+void QmlEngine::createDockWidgets()
+{
+
+    m_engineComboBox = new Internal::EngineComboBox;
+    m_engineComboBox->setEnabled(false);
+    connect(m_engineComboBox, SIGNAL(currentIndexChanged(int)),
+            SLOT(queryEngineContext(int)));
+
+    // FancyMainWindow uses widgets' window titles for tab labels
+//    m_frameRateWidget->setWindowTitle(tr("Frame rate"));
+
+    Utils::StyledBar *treeOptionBar = new Utils::StyledBar;
+    QHBoxLayout *treeOptionBarLayout = new QHBoxLayout(treeOptionBar);
+    treeOptionBarLayout->setContentsMargins(5, 0, 5, 0);
+    treeOptionBarLayout->setSpacing(5);
+    treeOptionBarLayout->addWidget(new QLabel(tr("QML engine:")));
+    treeOptionBarLayout->addWidget(m_engineComboBox);
+
+    QWidget *treeWindow = new QWidget;
+    treeWindow->setObjectName(QLatin1String("QmlDebugTree"));
+    treeWindow->setWindowTitle(tr("Object Tree"));
+    QVBoxLayout *treeWindowLayout = new QVBoxLayout(treeWindow);
+    treeWindowLayout->setMargin(0);
+    treeWindowLayout->setSpacing(0);
+    treeWindowLayout->setContentsMargins(0,0,0,0);
+    treeWindowLayout->addWidget(treeOptionBar);
+    treeWindowLayout->addWidget(m_objectTreeWidget);
+
+
+    m_watchTableView->setModel(m_watchTableModel);
+    Internal::WatchTableHeaderView *header = new Internal::WatchTableHeaderView(m_watchTableModel);
+    m_watchTableView->setHorizontalHeader(header);
+
+    connect(m_objectTreeWidget, SIGNAL(activated(QDeclarativeDebugObjectReference)),
+            this, SLOT(treeObjectActivated(QDeclarativeDebugObjectReference)));
+
+    connect(m_objectTreeWidget, SIGNAL(currentObjectChanged(QDeclarativeDebugObjectReference)),
+            m_propertiesWidget, SLOT(reload(QDeclarativeDebugObjectReference)));
+
+    connect(m_objectTreeWidget, SIGNAL(expressionWatchRequested(QDeclarativeDebugObjectReference,QString)),
+            m_watchTableModel, SLOT(expressionWatchRequested(QDeclarativeDebugObjectReference,QString)));
+
+    connect(m_propertiesWidget, SIGNAL(watchToggleRequested(QDeclarativeDebugObjectReference,QDeclarativeDebugPropertyReference)),
+            m_watchTableModel, SLOT(togglePropertyWatch(QDeclarativeDebugObjectReference,QDeclarativeDebugPropertyReference)));
+
+    connect(m_watchTableModel, SIGNAL(watchCreated(QDeclarativeDebugWatch*)),
+            m_propertiesWidget, SLOT(watchCreated(QDeclarativeDebugWatch*)));
+
+    connect(m_watchTableModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
+            m_watchTableView, SLOT(scrollToBottom()));
+
+    connect(m_watchTableView, SIGNAL(objectActivated(int)),
+            m_objectTreeWidget, SLOT(setCurrentObject(int)));
+
+    connect(m_objectTreeWidget, SIGNAL(currentObjectChanged(QDeclarativeDebugObjectReference)),
+            m_expressionWidget, SLOT(setCurrentObject(QDeclarativeDebugObjectReference)));
+
+
+    Core::MiniSplitter *propSplitter = new Core::MiniSplitter(Qt::Horizontal);
+    Core::MiniSplitter *propWatcherSplitter = new Core::MiniSplitter(Qt::Vertical);
+    propWatcherSplitter->addWidget(m_propertiesWidget);
+    propWatcherSplitter->addWidget(m_watchTableView);
+    propWatcherSplitter->setStretchFactor(0, 2);
+    propWatcherSplitter->setStretchFactor(1, 1);
+    propWatcherSplitter->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
+
+    propSplitter->setWindowTitle(tr("Properties and Watchers"));
+    propSplitter->setObjectName(QLatin1String("QmlDebugProperties"));
+    propSplitter->addWidget(m_objectTreeWidget);
+    propSplitter->addWidget(propWatcherSplitter);
+    propSplitter->setStretchFactor(0, 1);
+    propSplitter->setStretchFactor(1, 3);
+
+    InspectorOutputWidget *inspectorOutput = new InspectorOutputWidget();
+    inspectorOutput->setObjectName(QLatin1String("QmlDebugInspectorOutput"));
+    connect(this, SIGNAL(statusMessage(QString)),
+            inspectorOutput, SLOT(addInspectorStatus(QString)));
+
+    Debugger::DebuggerUISwitcher *uiSwitcher = Debugger::DebuggerUISwitcher::instance();
+
+    m_watchTableView->hide();
+//    m_objectTreeDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
+//                                                            treeWindow, Qt::BottomDockWidgetArea);
+//    m_frameRateDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
+//                                                            m_frameRateWidget, Qt::BottomDockWidgetArea);
+    m_propertyWatcherDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
+                                                            propSplitter, Qt::BottomDockWidgetArea);
+    m_inspectorOutputDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
+                                                            inspectorOutput, Qt::BottomDockWidgetArea);
+
+    m_expressionWidget->setWindowTitle(tr("Script Console"));
+    m_expressionQueryDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
+                                                         m_expressionWidget, Qt::BottomDockWidgetArea);
+
+    m_inspectorOutputDock->setToolTip(tr("Output of the QML inspector, such as information on connecting to the server."));
+
+    m_dockWidgets << /*m_objectTreeDock << *//*m_frameRateDock << */ m_propertyWatcherDock
+                  << m_inspectorOutputDock << m_expressionQueryDock;
+
+    m_context = new Internal::InspectorContext(m_objectTreeWidget);
+    m_propWatcherContext = new Internal::InspectorContext(m_propertyWatcherDock);
+
+    Core::ICore *core = Core::ICore::instance();
+    core->addContextObject(m_propWatcherContext);
+    core->addContextObject(m_context);
+
+    m_simultaneousDebugAction = new QAction(this);
+    m_simultaneousDebugAction->setText(tr("Start Debugging C++ and QML Simultaneously..."));
+    connect(m_simultaneousDebugAction, SIGNAL(triggered()),
+        this, SLOT(simultaneouslyDebugQmlCppApplication()));
+
+    Core::ActionManager *am = core->actionManager();
+    Core::ActionContainer *mstart = am->actionContainer(ProjectExplorer::Constants::M_DEBUG_STARTDEBUGGING);
+    Core::Command *cmd = am->registerAction(m_simultaneousDebugAction, Constants::M_DEBUG_SIMULTANEOUSLY,
+                                            m_context->context());
+    cmd->setAttribute(Core::Command::CA_Hide);
+    mstart->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
+
+    m_settings.readSettings(core->settings());
+    m_objectTreeWidget->readSettings(m_settings);
+    m_propertiesWidget->readSettings(m_settings);
+
+    connect(m_objectTreeWidget, SIGNAL(contextHelpIdChanged(QString)), m_context,
+            SLOT(setContextHelpId(QString)));
+    connect(m_watchTableView, SIGNAL(contextHelpIdChanged(QString)), m_propWatcherContext,
+            SLOT(setContextHelpId(QString)));
+    connect(m_propertiesWidget, SIGNAL(contextHelpIdChanged(QString)), m_propWatcherContext,
+            SLOT(setContextHelpId(QString)));
+    connect(m_expressionWidget, SIGNAL(contextHelpIdChanged(QString)), m_propWatcherContext,
+            SLOT(setContextHelpId(QString)));
+}
+
+void QmlEngine::simultaneouslyDebugQmlCppApplication()
+{
+    QString errorMessage;
+    ProjectExplorer::ProjectExplorerPlugin *pex = ProjectExplorer::ProjectExplorerPlugin::instance();
+    ProjectExplorer::Project *project = pex->startupProject();
+
+    if (!project)
+         errorMessage = QString(tr("No project was found."));
+    else {
+        if (project->id() == "QmlProjectManager.QmlProject")
+            errorMessage = attachToQmlViewerAsExternalApp(project);
+        else {
+            errorMessage = attachToExternalCppAppWithQml(project);
+        }
+    }
+
+    if (!errorMessage.isEmpty())
+        QMessageBox::warning(Core::ICore::instance()->mainWindow(), "Failed to debug C++ and QML", errorMessage);
+}
+
+QString QmlEngine::attachToQmlViewerAsExternalApp(ProjectExplorer::Project *project)
+{
+    m_debugMode = QmlProjectWithCppPlugins;
+
+    QmlProjectManager::QmlProjectRunConfiguration* runConfig =
+                qobject_cast<QmlProjectManager::QmlProjectRunConfiguration*>(project->activeTarget()->activeRunConfiguration());
+
+    if (!runConfig)
+        return QString(tr("No run configurations were found for the project '%1'.").arg(project->displayName()));
+
+    Internal::StartExternalQmlDialog dlg(Debugger::DebuggerUISwitcher::instance()->mainWindow());
+
+    QString importPathArgument = "-I";
+    QString execArgs;
+    if (runConfig->viewerArguments().contains(importPathArgument))
+        execArgs = runConfig->viewerArguments().join(" ");
+    else {
+        QFileInfo qmlFileInfo(runConfig->viewerArguments().last());
+        importPathArgument.append(" " + qmlFileInfo.absolutePath() + " ");
+        execArgs = importPathArgument + runConfig->viewerArguments().join(" ");
+    }
+
+
+    dlg.setPort(runConfig->debugServerPort());
+    dlg.setDebuggerUrl(runConfig->debugServerAddress());
+    dlg.setProjectDisplayName(project->displayName());
+    dlg.setDebugMode(Internal::StartExternalQmlDialog::QmlProjectWithCppPlugins);
+    dlg.setQmlViewerArguments(execArgs);
+    dlg.setQmlViewerPath(runConfig->viewerPath());
+
+    if (dlg.exec() != QDialog::Accepted)
+        return QString();
+
+    m_runConfigurationDebugData.serverAddress = dlg.debuggerUrl();
+    m_runConfigurationDebugData.serverPort = dlg.port();
+    m_settings.setExternalPort(dlg.port());
+    m_settings.setExternalUrl(dlg.debuggerUrl());
+
+    ProjectExplorer::Environment customEnv = ProjectExplorer::Environment::systemEnvironment(); // empty env by default
+    customEnv.set(QmlProjectManager::Constants::E_QML_DEBUG_SERVER_PORT, QString::number(m_settings.externalPort()));
+
+    Debugger::DebuggerRunControl *debuggableRunControl =
+     createDebuggerRunControl(runConfig, dlg.qmlViewerPath(), dlg.qmlViewerArguments());
+
+    return executeDebuggerRunControl(debuggableRunControl, &customEnv);
+}
+
+QString QmlEngine::attachToExternalCppAppWithQml(ProjectExplorer::Project *project)
+{
+    m_debugMode = CppProjectWithQmlEngines;
+
+    ProjectExplorer::LocalApplicationRunConfiguration* runConfig =
+                qobject_cast<ProjectExplorer::LocalApplicationRunConfiguration*>(project->activeTarget()->activeRunConfiguration());
+
+    if (!project->activeTarget() || !project->activeTarget()->activeRunConfiguration())
+        return QString(tr("No run configurations were found for the project '%1'.").arg(project->displayName()));
+    else if (!runConfig)
+        return QString(tr("No valid run configuration was found for the project %1. "
+                                  "Only locally runnable configurations are supported.\n"
+                                  "Please check your project settings.").arg(project->displayName()));
+
+    Internal::StartExternalQmlDialog dlg(Debugger::DebuggerUISwitcher::instance()->mainWindow());
+
+    dlg.setPort(m_settings.externalPort());
+    dlg.setDebuggerUrl(m_settings.externalUrl());
+    dlg.setProjectDisplayName(project->displayName());
+    dlg.setDebugMode(Internal::StartExternalQmlDialog::CppProjectWithQmlEngine);
+    if (dlg.exec() != QDialog::Accepted)
+        return QString();
+
+    m_runConfigurationDebugData.serverAddress = dlg.debuggerUrl();
+    m_runConfigurationDebugData.serverPort = dlg.port();
+    m_settings.setExternalPort(dlg.port());
+    m_settings.setExternalUrl(dlg.debuggerUrl());
+
+    ProjectExplorer::Environment customEnv = runConfig->environment();
+    customEnv.set(QmlProjectManager::Constants::E_QML_DEBUG_SERVER_PORT, QString::number(m_settings.externalPort()));
+    Debugger::DebuggerRunControl *debuggableRunControl = createDebuggerRunControl(runConfig);
+    return executeDebuggerRunControl(debuggableRunControl, &customEnv);
+}
+
+QString QmlEngine::executeDebuggerRunControl(Debugger::DebuggerRunControl *debuggableRunControl, ProjectExplorer::Environment *environment)
+{
+    ProjectExplorer::ProjectExplorerPlugin *pex = ProjectExplorer::ProjectExplorerPlugin::instance();
+
+    // to make sure we have a valid, debuggable run control, find the correct factory for it
+    if (debuggableRunControl) {
+
+        // modify the env
+        debuggableRunControl->setCustomEnvironment(*environment);
+
+        pex->startRunControl(debuggableRunControl, ProjectExplorer::Constants::DEBUGMODE);
+        m_simultaneousCppAndQmlDebugMode = true;
+
+        return QString();
+    }
+    return QString(tr("A valid run control was not registered in Qt Creator for this project run configuration."));;
+}
+
+Debugger::DebuggerRunControl *QmlEngine::createDebuggerRunControl(ProjectExplorer::RunConfiguration *runConfig,
+                                                                     const QString &executableFile, const QString &executableArguments)
+{
+    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
+    const QList<Debugger::DebuggerRunControlFactory *> factories = pm->getObjects<Debugger::DebuggerRunControlFactory>();
+    ProjectExplorer::RunControl *runControl = 0;
+
+    if (m_debugMode == QmlProjectWithCppPlugins) {
+        Debugger::DebuggerStartParameters sp;
+        sp.startMode = Debugger::StartExternal;
+        sp.executable = executableFile;
+        sp.processArgs = executableArguments.split(QLatin1Char(' '));
+        runControl = factories.first()->create(sp);
+        return qobject_cast<Debugger::DebuggerRunControl *>(runControl);
+    }
+
+    if (m_debugMode == CppProjectWithQmlEngines) {
+        if (factories.length() && factories.first()->canRun(runConfig, ProjectExplorer::Constants::DEBUGMODE)) {
+            runControl = factories.first()->create(runConfig, ProjectExplorer::Constants::DEBUGMODE);
+            return qobject_cast<Debugger::DebuggerRunControl *>(runControl);
+        }
+    }
+
+    return 0;
+}
+
+void QmlEngine::updateMenuActions()
+{
+
+    bool enabled = true;
+    if (m_simultaneousCppAndQmlDebugMode)
+        enabled = (m_cppDebuggerState == Debugger::DebuggerNotReady && (!m_conn || m_conn->state() == QAbstractSocket::UnconnectedState));
+    else
+        enabled = (!m_conn || m_conn->state() == QAbstractSocket::UnconnectedState);
+
+    m_simultaneousDebugAction->setEnabled(enabled);
+}
+
+
+void QmlEngine::debuggerStateChanged(int newState)
+{
+    if (m_simultaneousCppAndQmlDebugMode) {
+
+        switch(newState) {
+        case Debugger::EngineStarting:
+            {
+                m_connectionInitialized = false;
+                break;
+            }
+        case Debugger::AdapterStartFailed:
+        case Debugger::InferiorStartFailed:
+            emit statusMessage(QString(tr("Debugging failed: could not start C++ debugger.")));
+            break;
+        case Debugger::InferiorRunningRequested:
+            {
+                if (m_cppDebuggerState == Debugger::InferiorStopped) {
+                    // re-enable UI again
+                    m_objectTreeWidget->setEnabled(true);
+                    m_propertiesWidget->setEnabled(true);
+                    m_expressionWidget->setEnabled(true);
+                }
+                break;
+            }
+        case Debugger::InferiorRunning:
+            {
+                if (!m_connectionInitialized) {
+                    m_connectionInitialized = true;
+                    m_connectionTimer->setInterval(ConnectionAttemptSimultaneousInterval);
+                    m_connectionTimer->start();
+                }
+                break;
+            }
+        case Debugger::InferiorStopped:
+            {
+                m_objectTreeWidget->setEnabled(false);
+                m_propertiesWidget->setEnabled(false);
+                m_expressionWidget->setEnabled(false);
+                break;
+            }
+        case Debugger::EngineShuttingDown:
+            {
+                m_connectionInitialized = false;
+                // here it's safe to enable the debugger windows again -
+                // disabled ones look ugly.
+                m_objectTreeWidget->setEnabled(true);
+                m_propertiesWidget->setEnabled(true);
+                m_expressionWidget->setEnabled(true);
+                m_simultaneousCppAndQmlDebugMode = false;
+                break;
+            }
+        default:
+            break;
+        }
+    }
+
+    m_cppDebuggerState = newState;
+    updateMenuActions();
+}
+
+
+void QmlEngine::setSimpleDockWidgetArrangement()
+{
+    Utils::FancyMainWindow *mainWindow = Debugger::DebuggerUISwitcher::instance()->mainWindow();
+
+    mainWindow->setTrackingEnabled(false);
+    QList<QDockWidget *> dockWidgets = mainWindow->dockWidgets();
+    foreach (QDockWidget *dockWidget, dockWidgets) {
+        if (m_dockWidgets.contains(dockWidget)) {
+            dockWidget->setFloating(false);
+            mainWindow->removeDockWidget(dockWidget);
+        }
+    }
+
+    foreach (QDockWidget *dockWidget, dockWidgets) {
+        if (m_dockWidgets.contains(dockWidget)) {
+            mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
+            dockWidget->show();
+        }
+    }
+    mainWindow->splitDockWidget(mainWindow->toolBarDockWidget(), m_propertyWatcherDock, Qt::Vertical);
+    //mainWindow->tabifyDockWidget(m_frameRateDock, m_propertyWatcherDock);
+    mainWindow->tabifyDockWidget(m_propertyWatcherDock, m_expressionQueryDock);
+    mainWindow->tabifyDockWidget(m_propertyWatcherDock, m_inspectorOutputDock);
+    m_propertyWatcherDock->raise();
+
+    m_inspectorOutputDock->setVisible(false);
+
+    mainWindow->setTrackingEnabled(true);
+}
+#endif
+
+void QmlEngine::reloadEngines()
+{
+    //m_engineComboBox->setEnabled(false);
+
+    QDeclarativeDebugEnginesQuery *query =
+           m_engineDebugInterface->queryAvailableEngines(this);
+    if (!query->isWaiting())
+        enginesChanged(query);
+    else
+        QObject::connect(query, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
+                         this, SLOT(enginesChanged()));
+}
+
+void QmlEngine::enginesChanged()
+{
+    enginesChanged(qobject_cast<QDeclarativeDebugEnginesQuery *>(sender()));
+}
+
+void QmlEngine::enginesChanged(QDeclarativeDebugEnginesQuery *query)
+{
+    //m_engineComboBox->clearEngines();
+    QList<QDeclarativeDebugEngineReference> engines = query->engines();
+    if (engines.isEmpty())
+        qWarning("qmldebugger: no engines found!");
+
+    //m_engineComboBox->setEnabled(true);
+
+    for (int i = 0; i < engines.count(); ++i)
+        qDebug() << "ENGINE: "  <<  engines.at(i).debugId() << engines.at(i).name();
+    //    m_engineComboBox->addEngine(engines.at(i).debugId(), engines.at(i).name());
+
+    if (engines.count() > 0) {
+    //    m_engineComboBox->setCurrentIndex(engines.at(0).debugId());
+        queryEngineContext(engines.at(0));
+    }
+}
+
+void QmlEngine::queryEngineContext(const QDeclarativeDebugEngineReference &engine)
+{
+    QDeclarativeDebugRootContextQuery *query =
+        m_engineDebugInterface->queryRootContexts(engine, this);
+
+    if (!query->isWaiting())
+        contextChanged();
+    else
+        QObject::connect(query, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
+                         this, SLOT(contextChanged()));
+}
+
+void QmlEngine::contextChanged()
+{
+    contextChanged(qobject_cast<QDeclarativeDebugRootContextQuery *>(sender()));
+}
+
+void QmlEngine::contextChanged(QDeclarativeDebugRootContextQuery *query)
+{
+    QTC_ASSERT(query, return);
+    //dump(query->rootContext(), 0);
+    foreach (const QDeclarativeDebugObjectReference &object, query->rootContext().objects())
+        reloadObject(object);
+}
+
+void QmlEngine::reloadObject(const QDeclarativeDebugObjectReference &object)
+{
+    qDebug() << "RELOAD OBJECT: " << object.debugId() << object.idString()
+            << object.className();
+    QDeclarativeDebugObjectQuery *query =
+        m_engineDebugInterface->queryObjectRecursive(object, this);
+    if (!query->isWaiting())
+        objectFetched(query, QDeclarativeDebugQuery::Completed);
+    else
+        QObject::connect(query, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
+                         this, SLOT(objectFetched(QDeclarativeDebugQuery::State)));
+}
+
+void QmlEngine::objectFetched(QDeclarativeDebugQuery::State state)
+{
+    objectFetched(qobject_cast<QDeclarativeDebugObjectQuery *>(sender()), state);
+}
+
+void QmlEngine::objectFetched(QDeclarativeDebugObjectQuery *query,
+    QDeclarativeDebugQuery::State state)
+{
+    QTC_ASSERT(query, return);
+    QTC_ASSERT(state == QDeclarativeDebugQuery::Completed, return);
+    //dump(m_query->object(), 0);
+
+    m_watches.clear();
+    buildTree(query->object(), "local");
+
+    qDebug() << "WATCHES CREATED: " << m_watches.size();
+    //watchHandler()->beginCycle();
+    //watchHandler()->insertBulkData(list);
+    //watchHandler()->endCycle();
+    //setCurrentItem(topLevelItem(0));
+
+    // this ugly hack is needed if user wants to see internal structs
+    // on startup - debugger does not load them until towards the end,
+    // so essentially loading twice gives us the full list as everything
+    // is already loaded.
+    //if (m_showUninspectableItems && !m_showUninspectableOnInitDone) {
+    //    m_showUninspectableOnInitDone = true;
+    //    reloadObject(m_currentObjectDebugId);
+    //}
+}
+
+void QmlEngine::buildTree(const QDeclarativeDebugObjectReference &obj,
+    const QByteArray &iname)
+{
+    //QTC_ASSERT(obj.contextDebugId() >= 0, return);
+    WatchData data;
+    data.iname = iname;
+
+    if (obj.idString().isEmpty())
+        data.name = QString("<%1>").arg(obj.className());
+    else
+        data.name = obj.idString();
+
+    data.value = "?";
+    data.type = "?";
+    data.setHasChildren(!obj.children().isEmpty());
+    data.setAllUnneeded();
+    qDebug() << "CREATED ITEM " << data.iname << data.name;
+    m_watches.append(m_engineDebugInterface->addWatch(obj, data.name, 0));
+    //QDeclarativeDebugPropertyWatch *QDeclarativeEngineDebug::addWatch(const QDeclarativeDebugPropertyReference &property, QObject *parent)
+
+    //data.userRole = qVariantFromValue(obj);
+    /*
+    if (parent && obj.contextDebugId() >= 0
+            && obj.contextDebugId() != parent->data(0, Qt::UserRole
+                    ).value<QDeclarativeDebugObjectReference>().contextDebugId())
+    {
+
+        QDeclarativeDebugFileReference source = obj.source();
+        if (!source.url().isEmpty()) {
+            QString toolTipString = QLatin1String("URL: ") + source.url().toString();
+            item->setToolTip(0, toolTipString);
+        }
+
+    } else {
+        item->setExpanded(true);
+    }
+
+    if (obj.contextDebugId() < 0)
+        item->setHasValidDebugId(false);
+*/
+
+    for (int i = 0; i < obj.children().size(); ++i)
+        buildTree(obj.children().at(i), iname + '.' + QByteArray::number(i));
+}
+
+#if 0
+void QmlEngine::treeObjectActivated(const QDeclarativeDebugObjectReference &obj)
+{
+    QDeclarativeDebugFileReference source = obj.source();
+    QString fileName = source.url().toLocalFile();
+
+    if (source.lineNumber() < 0 || !QFile::exists(fileName))
+        return;
+
+    Core::EditorManager *editorManager = Core::EditorManager::instance();
+    Core::IEditor *editor = editorManager->openEditor(fileName, QString(), Core::EditorManager::NoModeSwitch);
+    TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor*>(editor);
+
+    if (textEditor) {
+        editorManager->addCurrentPositionToNavigationHistory();
+        textEditor->gotoLine(source.lineNumber());
+        textEditor->widget()->setFocus();
+    }
+}
+
+bool QmlEngine::canEditProperty(const QString &propertyType)
+{
+    return m_editablePropertyTypes.contains(propertyType);
+}
+
+QDeclarativeDebugExpressionQuery *QmlEngine::executeExpression(int objectDebugId, const QString &objectId,
+                                                                  const QString &propertyName, const QVariant &value)
+{
+    //qDebug() << entity.property << entity.title << entity.objectId;
+    if (objectId.length()) {
+
+        QString quoteWrappedValue = value.toString();
+        if (addQuotesForData(value))
+            quoteWrappedValue = QString("'%1'").arg(quoteWrappedValue);
+
+        QString constructedExpression = objectId + "." + propertyName + "=" + quoteWrappedValue;
+        //qDebug() << "EXPRESSION:" << constructedExpression;
+        return m_client->queryExpressionResult(objectDebugId, constructedExpression, this);
+    }
+
+    return 0;
+}
+
+bool QmlEngine::addQuotesForData(const QVariant &value) const
+{
+    switch (value.type()) {
+    case QVariant::String:
+    case QVariant::Color:
+    case QVariant::Date:
+        return true;
+    default:
+        break;
+    }
+
+    return false;
+}
+
+ObjectTree::ObjectTree(QDeclarativeEngineDebug *client, QWidget *parent)
+    : QTreeWidget(parent),
+      m_client(client),
+      m_query(0), m_clickedItem(0), m_showUninspectableItems(false),
+      m_currentObjectDebugId(0), m_showUninspectableOnInitDone(false)
+{
+    setAttribute(Qt::WA_MacShowFocusRect, false);
+    setFrameStyle(QFrame::NoFrame);
+    setHeaderHidden(true);
+    setExpandsOnDoubleClick(false);
+
+    m_addWatchAction = new QAction(tr("Add watch expression..."), this);
+    m_toggleUninspectableItemsAction = new QAction(tr("Show uninspectable items"), this);
+    m_toggleUninspectableItemsAction->setCheckable(true);
+    m_goToFileAction = new QAction(tr("Go to file"), this);
+    connect(m_toggleUninspectableItemsAction, SIGNAL(triggered()), SLOT(toggleUninspectableItems()));
+    connect(m_addWatchAction, SIGNAL(triggered()), SLOT(addWatch()));
+    connect(m_goToFileAction, SIGNAL(triggered()), SLOT(goToFile()));
+
+    connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
+            SLOT(currentItemChanged(QTreeWidgetItem *)));
+    connect(this, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
+            SLOT(activated(QTreeWidgetItem *)));
+    connect(this, SIGNAL(itemSelectionChanged()), SLOT(selectionChanged()));
+}
+
+void ObjectTree::readSettings(const InspectorSettings &settings)
+{
+    if (settings.showUninspectableItems() != m_showUninspectableItems)
+        toggleUninspectableItems();
+}
+void ObjectTree::saveSettings(InspectorSettings &settings)
+{
+    settings.setShowUninspectableItems(m_showUninspectableItems);
+}
+
+void ObjectTree::setEngineDebug(QDeclarativeEngineDebug *client)
+{
+    m_client = client;
+}
+
+void ObjectTree::toggleUninspectableItems()
+{
+    m_showUninspectableItems = !m_showUninspectableItems;
+    m_toggleUninspectableItemsAction->setChecked(m_showUninspectableItems);
+    reload(m_currentObjectDebugId);
+}
+
+void ObjectTree::selectionChanged()
+{
+    if (selectedItems().isEmpty())
+        return;
+
+    QTreeWidgetItem *item = selectedItems().first();
+    if (item)
+        emit contextHelpIdChanged(InspectorContext::contextHelpIdForItem(item->text(0)));
+}
+
+
+void ObjectTree::setCurrentObject(int debugId)
+{
+    QTreeWidgetItem *item = findItemByObjectId(debugId);
+    if (item) {
+        setCurrentItem(item);
+        scrollToItem(item);
+        item->setExpanded(true);
+    }
+
+
+}
+
+{
+    if (!item)
+        return;
+
+    QDeclarativeDebugObjectReference obj = item->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
+    if (obj.debugId() >= 0)
+        emit currentObjectChanged(obj);
+}
+
+void ObjectTree::activated(QTreeWidgetItem *item)
+{
+    if (!item)
+        return;
+
+    QDeclarativeDebugObjectReference obj = item->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
+    if (obj.debugId() >= 0)
+        emit activated(obj);
+}
+
+void ObjectTree::cleanup()
+{
+    m_showUninspectableOnInitDone = false;
+    clear();
+}
+
+void ObjectTree::dump(const QDeclarativeDebugContextReference &ctxt, int ind)
+{
+    QByteArray indent(ind * 4, ' ');
+    qWarning().nospace() << indent.constData() << ctxt.debugId() << " "
+                         << qPrintable(ctxt.name());
+
+    for (int ii = 0; ii < ctxt.contexts().count(); ++ii)
+        dump(ctxt.contexts().at(ii), ind + 1);
+
+    for (int ii = 0; ii < ctxt.objects().count(); ++ii)
+        dump(ctxt.objects().at(ii), ind);
+}
+
+void ObjectTree::dump(const QDeclarativeDebugObjectReference &obj, int ind)
+{
+    QByteArray indent(ind * 4, ' ');
+    qWarning().nospace() << indent.constData() << qPrintable(obj.className())
+                         << " " << qPrintable(obj.idString()) << " "
+                         << obj.debugId();
+
+    for (int ii = 0; ii < obj.children().count(); ++ii)
+        dump(obj.children().at(ii), ind + 1);
+}
+
+QTreeWidgetItem *ObjectTree::findItemByObjectId(int debugId) const
+{
+    for (int i=0; i<topLevelItemCount(); ++i) {
+        QTreeWidgetItem *item = findItem(topLevelItem(i), debugId);
+        if (item)
+            return item;
+    }
+
+    return 0;
+}
+
+QTreeWidgetItem *ObjectTree::findItem(QTreeWidgetItem *item, int debugId) const
+{
+    if (item->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>().debugId() == debugId)
+        return item;
+
+    QTreeWidgetItem *child;
+    for (int i=0; i<item->childCount(); ++i) {
+        child = findItem(item->child(i), debugId);
+        if (child)
+            return child;
+    }
+
+    return 0;
+}
+
+void ObjectTree::addWatch()
+{
+    QDeclarativeDebugObjectReference obj =
+            currentItem()->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
+
+    bool ok = false;
+    QString watch = QInputDialog::getText(this, tr("Watch expression"),
+            tr("Expression:"), QLineEdit::Normal, QString(), &ok);
+    if (ok && !watch.isEmpty())
+        emit expressionWatchRequested(obj, watch);
+
+}
+
+void ObjectTree::goToFile()
+{
+    QDeclarativeDebugObjectReference obj =
+            currentItem()->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
+
+    if (obj.debugId() >= 0)
+        emit activated(obj);
+}
+
+void ObjectTree::contextMenuEvent(QContextMenuEvent *event)
+{
+
+    m_clickedItem = itemAt(QPoint(event->pos().x(),
+                                  event->pos().y() ));
+    if (!m_clickedItem)
+        return;
+
+    QMenu menu;
+    menu.addAction(m_addWatchAction);
+    menu.addAction(m_goToFileAction);
+    if (m_currentObjectDebugId) {
+        menu.addSeparator();
+        menu.addAction(m_toggleUninspectableItemsAction);
+    }
+
+    menu.exec(event->globalPos());
+}
+
+} // Internal
+} // Qml
+#endif
+
 } // namespace Internal
 } // namespace Debugger
 
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index 1b6976bbdd49e90cb5715f21bfe02ac792f88838..8e53808852bedcf2019e8772b8aec7002af355cd 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -32,6 +32,10 @@
 
 #include "debuggerengine.h"
 
+#include "private/qdeclarativedebug_p.h"
+#include "private/qdeclarativedebugclient_p.h"
+#include "private/qdeclarativeenginedebug_p.h"
+
 #include <QtCore/QByteArray>
 #include <QtCore/QHash>
 #include <QtCore/QObject>
@@ -44,6 +48,7 @@
 #include <QtNetwork/QAbstractSocket>
 #include <QtNetwork/QTcpSocket>
 
+
 QT_BEGIN_NAMESPACE
 class QTcpSocket;
 class QDeclarativeDebugConnection;
@@ -74,6 +79,7 @@ public:
 
 private:
     // DebuggerEngine implementation
+    bool isSynchroneous() const { return true; }
     void executeStep();
     void executeStepOut();
     void executeNext();
@@ -130,15 +136,93 @@ private slots:
     void connectionConnected();
     void connectionStateChanged();
 
+    void reloadEngines();
+    void enginesChanged();
+    void queryEngineContext(const QDeclarativeDebugEngineReference& engine);
+    void contextChanged();
+
+    void reloadObject(const QDeclarativeDebugObjectReference &object);
+    void objectFetched(QDeclarativeDebugQuery::State state);
+
 private:
+    void objectFetched(QDeclarativeDebugObjectQuery *query, QDeclarativeDebugQuery::State state);
+    void contextChanged(QDeclarativeDebugRootContextQuery *query);
+    void enginesChanged(QDeclarativeDebugEnginesQuery *query);
+
+    void buildTree(const QDeclarativeDebugObjectReference &obj, const QByteArray &iname);
+
     QString errorMessage(QProcess::ProcessError error);
     QProcess m_proc;
 
     QDeclarativeDebugConnection *m_conn;
+    QDeclarativeEngineDebug *m_engineDebugInterface;
     QmlDebuggerClient *m_client;
+    CanvasFrameRate *m_frameRate;
+
+    enum DebugMode {
+        StandaloneMode,
+        CppProjectWithQmlEngines,
+        QmlProjectWithCppPlugins
+    };
+
+    QList<QDeclarativeDebugWatch *> m_watches;
+
+#if 0
+    void createDockWidgets();
+    bool connectToViewer(); // using host, port from widgets
+
+    // returns false if project is not debuggable.
+    bool setDebugConfigurationDataFromProject(ProjectExplorer::Project *projectToDebug);
+    void startQmlProjectDebugger();
+
+    bool canEditProperty(const QString &propertyType);
+    QDeclarativeDebugExpressionQuery *executeExpression(int objectDebugId,
+        const QString &objectId, const QString &propertyName, const QVariant &value);
+
+public slots:
+    void disconnectFromViewer();
+    void setSimpleDockWidgetArrangement();
+
+private slots:
+    void treeObjectActivated(const QDeclarativeDebugObjectReference &obj);
+    void simultaneouslyDebugQmlCppApplication();
+
+private:
+    void updateMenuActions();
+    QString attachToQmlViewerAsExternalApp(ProjectExplorer::Project *project);
+    QString attachToExternalCppAppWithQml(ProjectExplorer::Project *project);
+
+    bool addQuotesForData(const QVariant &value) const;
+    void resetViews();
+
     QDeclarativeDebugEnginesQuery *m_engineQuery;
     QDeclarativeDebugRootContextQuery *m_contextQuery;
-    CanvasFrameRate *m_frameRate;
+
+    Internal::ObjectTree *m_objectTreeWidget;
+    Internal::ObjectPropertiesView *m_propertiesWidget;
+    Internal::WatchTableModel *m_watchTableModel;
+    Internal::WatchTableView *m_watchTableView;
+    Internal::CanvasFrameRate *m_frameRateWidget;
+    Internal::ExpressionQueryWidget *m_expressionWidget;
+
+    Internal::EngineComboBox *m_engineComboBox;
+
+    QDockWidget *m_objectTreeDock;
+    QDockWidget *m_frameRateDock;
+    QDockWidget *m_expressionQueryDock;
+    QDockWidget *m_propertyWatcherDock;
+    QDockWidget *m_inspectorOutputDock;
+
+    Internal::InspectorSettings m_settings;
+    QmlProjectManager::QmlProjectRunConfigurationDebugData m_runConfigurationDebugData;
+
+    QStringList m_editablePropertyTypes;
+
+    // simultaneous debug mode stuff
+    int m_cppDebuggerState;
+    bool m_connectionInitialized;
+    bool m_simultaneousCppAndQmlDebugMode;
+#endif
 };
 
 } // namespace Internal