From 75f4b9cf2561d53b0d4bacd41f1047c75860ddfe Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Thu, 24 Feb 2011 16:50:15 +0100
Subject: [PATCH] Debugger: Add toolchain combos to start dialogs, refactor
 detection.

Add combo box listing toolchains with debuggers to start external,
attach and core.
Another attempt at streamlining engine detection:
Split in detection functions that first collect a list of
available engines by preference, then remove disabled and
wrongly configured engines and use the remaining best.
matching. checkconfiguration is now the central place where
engine detection and config check takes place.

Rubber-stamped-by: hjk
---
 src/plugins/debugger/attachcoredialog.ui      |  59 +-
 src/plugins/debugger/attachexternaldialog.ui  |  25 +-
 src/plugins/debugger/cdb/cdbengine.cpp        |  72 ++-
 src/plugins/debugger/debugger.pro             |   6 +-
 src/plugins/debugger/debuggercore.h           |   3 +-
 src/plugins/debugger/debuggerdialogs.cpp      |  97 ++-
 src/plugins/debugger/debuggerdialogs.h        |  22 +
 src/plugins/debugger/debuggerplugin.cpp       |  77 ++-
 .../debugger/debuggerruncontrolfactory.h      |   6 +
 src/plugins/debugger/debuggerrunner.cpp       | 599 ++++++++++--------
 src/plugins/debugger/debuggerrunner.h         |  16 +-
 .../debugger/debuggerstartparameters.h        |   2 -
 .../debugger/debuggertoolchaincombobox.cpp    |  90 +++
 .../debugger/debuggertoolchaincombobox.h      |  65 ++
 src/plugins/debugger/gdb/gdbengine.cpp        |  16 +-
 src/plugins/debugger/qml/qmlcppengine.cpp     |  62 +-
 src/plugins/debugger/qml/qmlcppengine.h       |   4 +-
 src/plugins/debugger/startexternaldialog.ui   |  73 ++-
 src/plugins/debugger/startremotedialog.ui     |  53 +-
 .../debugger/startremoteenginedialog.ui       | 165 ++---
 .../qt-s60/s60devicerunconfiguration.cpp      |  50 +-
 .../qt-s60/s60devicerunconfiguration.h        |  14 +-
 .../qt4projectmanager/qt-s60/s60manager.cpp   |   4 +-
 23 files changed, 1048 insertions(+), 532 deletions(-)
 create mode 100644 src/plugins/debugger/debuggertoolchaincombobox.cpp
 create mode 100644 src/plugins/debugger/debuggertoolchaincombobox.h

diff --git a/src/plugins/debugger/attachcoredialog.ui b/src/plugins/debugger/attachcoredialog.ui
index 6fa4f764d94..7a0dae81674 100644
--- a/src/plugins/debugger/attachcoredialog.ui
+++ b/src/plugins/debugger/attachcoredialog.ui
@@ -2,14 +2,6 @@
 <ui version="4.0">
  <class>AttachCoreDialog</class>
  <widget class="QDialog" name="AttachCoreDialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>567</width>
-    <height>126</height>
-   </rect>
-  </property>
   <property name="windowTitle">
    <string>Start Debugger</string>
   </property>
@@ -21,32 +13,54 @@
     <number>9</number>
    </property>
    <item>
-    <layout class="QGridLayout">
-     <property name="margin">
-      <number>0</number>
+    <layout class="QFormLayout" name="formLayout">
+     <property name="horizontalSpacing">
+      <number>6</number>
      </property>
-     <property name="spacing">
+     <property name="verticalSpacing">
       <number>6</number>
      </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
      <item row="0" column="0">
       <widget class="QLabel" name="execLabel">
        <property name="text">
-        <string>Executable:</string>
+        <string>&amp;Executable:</string>
+       </property>
+       <property name="buddy">
+        <cstring>execFileName</cstring>
        </property>
       </widget>
      </item>
+     <item row="0" column="1">
+      <widget class="Utils::PathChooser" name="execFileName"/>
+     </item>
      <item row="1" column="0">
       <widget class="QLabel" name="coreLabel">
        <property name="text">
-        <string>Core file:</string>
+        <string>&amp;Core file:</string>
+       </property>
+       <property name="buddy">
+        <cstring>coreFileName</cstring>
        </property>
       </widget>
      </item>
-     <item row="0" column="1">
-      <widget class="Utils::PathChooser" name="execFileName" native="true"/>
-     </item>
      <item row="1" column="1">
-      <widget class="Utils::PathChooser" name="coreFileName" native="true"/>
+      <widget class="Utils::PathChooser" name="coreFileName"/>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="toolchainLabel">
+       <property name="text">
+        <string>&amp;Toolchain:</string>
+       </property>
+       <property name="buddy">
+        <cstring>toolchainComboBox</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="Debugger::Internal::DebuggerToolChainComboBox" name="toolchainComboBox"/>
      </item>
     </layout>
    </item>
@@ -57,8 +71,8 @@
      </property>
      <property name="sizeHint" stdset="0">
       <size>
-       <width>407</width>
-       <height>16</height>
+       <width>0</width>
+       <height>0</height>
       </size>
      </property>
     </spacer>
@@ -89,6 +103,11 @@
    <header location="global">utils/pathchooser.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>DebuggerToolChainComboBox</class>
+   <extends>QComboBox</extends>
+   <header>debuggertoolchaincombobox.h</header>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
diff --git a/src/plugins/debugger/attachexternaldialog.ui b/src/plugins/debugger/attachexternaldialog.ui
index 5e157a2f3ce..b68122cabe2 100644
--- a/src/plugins/debugger/attachexternaldialog.ui
+++ b/src/plugins/debugger/attachexternaldialog.ui
@@ -28,16 +28,32 @@
      <item row="0" column="0">
       <widget class="QLabel" name="pidLabel">
        <property name="text">
-        <string>Attach to process ID:</string>
+        <string>Attach to &amp;process ID:</string>
+       </property>
+       <property name="buddy">
+        <cstring>pidLineEdit</cstring>
        </property>
       </widget>
      </item>
      <item row="0" column="1">
       <widget class="QLineEdit" name="pidLineEdit"/>
      </item>
-     <item row="1" column="0" colspan="2">
+     <item row="2" column="0" colspan="2">
       <widget class="Utils::FilterLineEdit" name="filterWidget"/>
      </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="toolchainLabel">
+       <property name="text">
+        <string>&amp;Toolchain:</string>
+       </property>
+       <property name="buddy">
+        <cstring>toolchainComboBox</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="Debugger::Internal::DebuggerToolChainComboBox" name="toolchainComboBox"/>
+     </item>
     </layout>
    </item>
    <item>
@@ -77,6 +93,11 @@
    <extends>Utils::FancyLineEdit</extends>
    <header location="global">utils/filterlineedit.h</header>
   </customwidget>
+  <customwidget>
+   <class>Debugger::Internal::DebuggerToolChainComboBox</class>
+   <extends>QComboBox</extends>
+   <header>debuggertoolchaincombobox.h</header>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index 1538dc191c8..771bf6f65c2 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -59,6 +59,7 @@
 #include <coreplugin/icore.h>
 #include <texteditor/itexteditor.h>
 #include <projectexplorer/toolchain.h>
+#include <projectexplorer/projectexplorerconstants.h>
 
 #include <utils/synchronousprocess.h>
 #include <utils/winutils.h>
@@ -299,24 +300,14 @@ static inline bool validMode(DebuggerStartMode sm)
     return true;
 }
 
-static inline QString msgCdbDisabled(const Abi &abi)
-{
-    return CdbEngine::tr("The CDB debug engine required for %1 is currently disabled.").
-            arg(abi.toString());
-}
-
 // Accessed by RunControlFactory
 DebuggerEngine *createCdbEngine(const DebuggerStartParameters &sp,
     DebuggerEngine *masterEngine, QString *errorMessage)
 {
 #ifdef Q_OS_WIN
     CdbOptionsPage *op = CdbOptionsPage::instance();
-    if (!op || !op->options()->isValid()) {
-        *errorMessage = msgCdbDisabled(sp.toolChainAbi);
-        return 0;
-    }
-    if (!validMode(sp.startMode)) {
-        *errorMessage = CdbEngine::tr("The CDB debug engine does not support start mode %1.").arg(sp.startMode);
+    if (!op || !op->options()->isValid() || !validMode(sp.startMode)) {
+        *errorMessage = QLatin1String("Internal error: Invalid start parameters passed for thre CDB engine.");
         return 0;
     }
     return new CdbEngine(sp, masterEngine, op->options());
@@ -337,21 +328,45 @@ bool isCdbEngineEnabled()
 #endif
 }
 
-ConfigurationCheck checkCdbConfiguration(const Abi &abi)
+static inline QString msgNoCdbBinaryForToolChain(const ProjectExplorer::Abi &tc)
 {
-    ConfigurationCheck check;
-    if (abi.binaryFormat() == Abi::PEFormat
-            && abi.osFlavor() != Abi::WindowsMSysFlavor) {
-        if (!isCdbEngineEnabled()) {
-            check.errorMessage = msgCdbDisabled(abi);
-            check.settingsPage = CdbOptionsPage::settingsId();
-        }
-    } else {
-        check.errorMessage = CdbEngine::tr("The CDB debug engine does not support the %1 ABI.").
-                    arg(abi.toString());
-        check.settingsPage = CdbOptionsPage::settingsId();
+    return CdbEngine::tr("There is no CDB binary available for binaries in format '%1'").arg(tc.toString());
+}
+
+bool checkCdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check)
+{
+#ifdef Q_OS_WIN
+    if (!isCdbEngineEnabled()) {
+        check->errorMessage = CdbEngine::tr("The CDB debug engine required for %1 is currently disabled.").
+                              arg(sp.toolChainAbi.toString());
+        check->settingsCategory = QLatin1String(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY);
+        check->settingsPage = CdbOptionsPage::settingsId();
+        return false;
     }
-    return check;
+
+    if (debuggerCore()->debuggerForAbi(sp.toolChainAbi, CdbEngineType).isEmpty()) {
+        check->errorMessage = msgNoCdbBinaryForToolChain(sp.toolChainAbi);
+        check->settingsCategory = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY);
+        check->settingsPage = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY);
+        return false;
+    }
+
+    if (!validMode(sp.startMode)) {
+        check->errorMessage = CdbEngine::tr("The CDB engine does not support start mode %1.").arg(sp.startMode);
+        return false;
+    }
+
+    if (sp.toolChainAbi.binaryFormat() != Abi::PEFormat || sp.toolChainAbi.os() != Abi::WindowsOS) {
+        check->errorMessage = CdbEngine::tr("The CDB debug engine does not support the %1 ABI.").
+                                            arg(sp.toolChainAbi.toString());
+        return false;
+    }
+    return true;
+#else
+    Q_UNUSED(sp);
+    check->errorMessage = QString::fromLatin1("Unsupported debug mode");
+    return false;
+#endif
 }
 
 void addCdbOptionPages(QList<Core::IOptionsPage *> *opts)
@@ -637,12 +652,7 @@ bool CdbEngine::launchCDB(const DebuggerStartParameters &sp, QString *errorMessa
     // Determine binary (force MSVC), extension lib name and path to use
     // The extension is passed as relative name with the path variable set
     //(does not work with absolute path names)
-    Abi abi = sp.toolChainAbi;
-    if (abi.osFlavor() == Abi::UnknownFlavor
-            || abi.osFlavor() == Abi::WindowsMSysFlavor)
-        abi = Abi(abi.architecture(), abi.os(), Abi::WindowsMsvcFlavor,
-                  abi.binaryFormat(), abi.wordWidth());
-    const QString executable = debuggerCore()->debuggerForAbi(abi);
+    const QString executable = debuggerCore()->debuggerForAbi(sp.toolChainAbi, CdbEngineType);
     if (executable.isEmpty()) {
         *errorMessage = tr("There is no CDB executable specified.");
         return false;
diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index f58c1eee987..6e0100065fa 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -62,7 +62,8 @@ HEADERS += breakhandler.h \
     threadshandler.h \
     watchdelegatewidgets.h \
     debuggerruncontrolfactory.h \
-    debuggertooltipmanager.h
+    debuggertooltipmanager.h \
+    debuggertoolchaincombobox.h
 
 SOURCES += breakhandler.cpp \
     breakpoint.cpp \
@@ -104,7 +105,8 @@ SOURCES += breakhandler.cpp \
     watchwindow.cpp \
     stackframe.cpp \
     watchdelegatewidgets.cpp \
-    debuggertooltipmanager.cpp
+    debuggertooltipmanager.cpp \
+    debuggertoolchaincombobox.cpp
 
 FORMS += attachexternaldialog.ui \
     attachcoredialog.ui \
diff --git a/src/plugins/debugger/debuggercore.h b/src/plugins/debugger/debuggercore.h
index caa23bb381e..3cbd1b79078 100644
--- a/src/plugins/debugger/debuggercore.h
+++ b/src/plugins/debugger/debuggercore.h
@@ -98,12 +98,13 @@ public:
     virtual void runControlFinished(DebuggerEngine *engine) = 0;
     virtual void displayDebugger(DebuggerEngine *engine, bool updateEngine) = 0;
     virtual DebuggerLanguages activeLanguages() const = 0;
+    virtual unsigned enabledEngines() const = 0;
     virtual void synchronizeBreakpoints() = 0;
 
     virtual bool initialize(const QStringList &arguments, QString *errorMessage) = 0;
     virtual QWidget *mainWindow() const = 0;
     virtual bool isDockVisible(const QString &objectName) const = 0;
-    virtual QString debuggerForAbi(const ProjectExplorer::Abi &abi) const = 0;
+    virtual QString debuggerForAbi(const ProjectExplorer::Abi &abi, DebuggerEngineType et = NoEngineType) const = 0;
     virtual void showModuleSymbols(const QString &moduleName,
         const QVector<Symbol> &symbols) = 0;
     virtual void openMemoryEditor() = 0;
diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp
index 164d4f4617b..51c1de66526 100644
--- a/src/plugins/debugger/debuggerdialogs.cpp
+++ b/src/plugins/debugger/debuggerdialogs.cpp
@@ -48,6 +48,7 @@
 #endif
 
 #include <coreplugin/icore.h>
+#include <projectexplorer/abi.h>
 #include <utils/synchronousprocess.h>
 #include <utils/historycompleter.h>
 #include <utils/qtcassert.h>
@@ -180,7 +181,9 @@ void ProcessListFilterModel::populate
 AttachCoreDialog::AttachCoreDialog(QWidget *parent)
   : QDialog(parent), m_ui(new Ui::AttachCoreDialog)
 {
+    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
     m_ui->setupUi(this);
+    m_ui->toolchainComboBox->init(false);
 
     m_ui->execFileName->setExpectedKind(PathChooser::File);
     m_ui->execFileName->setPromptDialogTitle(tr("Select Executable"));
@@ -192,6 +195,9 @@ AttachCoreDialog::AttachCoreDialog(QWidget *parent)
 
     connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
     connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+    connect(m_ui->coreFileName, SIGNAL(changed(QString)), this, SLOT(changed()));
+    connect(m_ui->execFileName, SIGNAL(changed(QString)), this, SLOT(changed()));
+    changed();
 }
 
 AttachCoreDialog::~AttachCoreDialog()
@@ -207,6 +213,7 @@ QString AttachCoreDialog::executableFile() const
 void AttachCoreDialog::setExecutableFile(const QString &fileName)
 {
     m_ui->execFileName->setPath(fileName);
+    changed();
 }
 
 QString AttachCoreDialog::coreFile() const
@@ -217,8 +224,29 @@ QString AttachCoreDialog::coreFile() const
 void AttachCoreDialog::setCoreFile(const QString &fileName)
 {
     m_ui->coreFileName->setPath(fileName);
+    changed();
+}
+
+ProjectExplorer::Abi AttachCoreDialog::abi() const
+{
+    return m_ui->toolchainComboBox->abi();
 }
 
+void AttachCoreDialog::setAbi(const ProjectExplorer::Abi &abi)
+{
+    m_ui->toolchainComboBox->setAbi(abi);
+}
+
+bool AttachCoreDialog::isValid() const
+{
+    return m_ui->toolchainComboBox->currentIndex() >= 0 &&
+           !coreFile().isEmpty();
+}
+
+void AttachCoreDialog::changed()
+{
+    m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(isValid());
+}
 
 ///////////////////////////////////////////////////////////////////////
 //
@@ -333,7 +361,9 @@ AttachExternalDialog::AttachExternalDialog(QWidget *parent)
     m_ui(new Ui::AttachExternalDialog),
     m_model(new ProcessListFilterModel(this))
 {
+    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
     m_ui->setupUi(this);
+    m_ui->toolchainComboBox->init(true);
     okButton()->setDefault(true);
     okButton()->setEnabled(false);
 
@@ -429,9 +459,20 @@ QString AttachExternalDialog::executable() const
     return m_model->executableForPid(attachPIDText());
 }
 
+ProjectExplorer::Abi AttachExternalDialog::abi() const
+{
+    return m_ui->toolchainComboBox->abi();
+}
+
+void AttachExternalDialog::setAbi(const ProjectExplorer::Abi &abi)
+{
+    m_ui->toolchainComboBox->setAbi(abi);
+}
+
 void AttachExternalDialog::pidChanged(const QString &pid)
 {
-    bool enabled = !pid.isEmpty() && pid != QLatin1String("0") && pid != m_selfPid;
+    const bool enabled = !pid.isEmpty() && pid != QLatin1String("0") && pid != m_selfPid
+            && m_ui->toolchainComboBox->currentIndex() >= 0;
     okButton()->setEnabled(enabled);
 }
 
@@ -460,14 +501,15 @@ AttachTcfDialog::AttachTcfDialog(QWidget *parent)
   : QDialog(parent),
     m_ui(new Ui::AttachTcfDialog)
 {
+    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
     m_ui->setupUi(this);
     m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
     m_ui->serverStartScript->setExpectedKind(PathChooser::File);
     m_ui->serverStartScript->setPromptDialogTitle(tr("Select Executable"));
 
-    connect(m_ui->useServerStartScriptCheckBox, SIGNAL(toggled(bool)), 
+    connect(m_ui->useServerStartScriptCheckBox, SIGNAL(toggled(bool)),
         this, SLOT(updateState()));
-    
+
     connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
     connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
 
@@ -548,27 +590,25 @@ void AttachTcfDialog::updateState()
 StartExternalDialog::StartExternalDialog(QWidget *parent)
   : QDialog(parent), m_ui(new Ui::StartExternalDialog)
 {
+    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
     m_ui->setupUi(this);
+    m_ui->toolChainComboBox->init(true);
     m_ui->execFile->setExpectedKind(PathChooser::File);
     m_ui->execFile->setPromptDialogTitle(tr("Select Executable"));
     m_ui->execFile->lineEdit()->setCompleter(
         new HistoryCompleter(m_ui->execFile->lineEdit()));
+    connect(m_ui->execFile, SIGNAL(changed(QString)), this, SLOT(changed()));
     m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
     m_ui->workingDirectory->setExpectedKind(PathChooser::ExistingDirectory);
     m_ui->workingDirectory->setPromptDialogTitle(tr("Select Working Directory"));
     m_ui->workingDirectory->lineEdit()->setCompleter(
         new HistoryCompleter(m_ui->workingDirectory->lineEdit()));
 
-    //execLabel->setHidden(false);
-    //execEdit->setHidden(false);
-    //browseButton->setHidden(false);
-
-    m_ui->execLabel->setText(tr("Executable:"));
-    m_ui->argsLabel->setText(tr("Arguments:"));
     m_ui->argsEdit->setCompleter(new HistoryCompleter(m_ui->argsEdit));
 
     connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
     connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+    changed();
 }
 
 StartExternalDialog::~StartExternalDialog()
@@ -579,6 +619,7 @@ StartExternalDialog::~StartExternalDialog()
 void StartExternalDialog::setExecutableFile(const QString &str)
 {
     m_ui->execFile->setPath(str);
+    changed();
 }
 
 QString StartExternalDialog::executableFile() const
@@ -611,6 +652,27 @@ bool StartExternalDialog::breakAtMain() const
     return m_ui->checkBoxBreakAtMain->isChecked();
 }
 
+ProjectExplorer::Abi StartExternalDialog::abi() const
+{
+    return m_ui->toolChainComboBox->abi();
+}
+
+void StartExternalDialog::setAbi(const ProjectExplorer::Abi &abi)
+{
+    m_ui->toolChainComboBox->setAbi(abi);
+}
+
+bool StartExternalDialog::isValid() const
+{
+    return m_ui->toolChainComboBox->currentIndex() >= 0
+           && !executableFile().isEmpty();
+}
+
+void StartExternalDialog::changed()
+{
+    m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(isValid());
+}
+
 ///////////////////////////////////////////////////////////////////////
 //
 // StartRemoteDialog
@@ -621,6 +683,7 @@ StartRemoteDialog::StartRemoteDialog(QWidget *parent)
   : QDialog(parent),
     m_ui(new Ui::StartRemoteDialog)
 {
+    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
     m_ui->setupUi(this);
     m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
     m_ui->debuggerPathChooser->setExpectedKind(PathChooser::File);
@@ -912,13 +975,14 @@ StartRemoteEngineDialog::StartRemoteEngineDialog(QWidget *parent) :
     QDialog(parent) ,
     m_ui(new Ui::StartRemoteEngineDialog)
 {
-     m_ui->setupUi(this);
-     m_ui->host->setCompleter(new HistoryCompleter(m_ui->host));
-     m_ui->username->setCompleter(new HistoryCompleter(m_ui->username));
-     m_ui->enginepath->setCompleter(new HistoryCompleter(m_ui->enginepath));
-     m_ui->inferiorpath->setCompleter(new HistoryCompleter(m_ui->inferiorpath));
-     connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
-     connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+    m_ui->setupUi(this);
+    m_ui->host->setCompleter(new HistoryCompleter(m_ui->host));
+    m_ui->username->setCompleter(new HistoryCompleter(m_ui->username));
+    m_ui->enginepath->setCompleter(new HistoryCompleter(m_ui->enginepath));
+    m_ui->inferiorpath->setCompleter(new HistoryCompleter(m_ui->inferiorpath));
+    connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+    connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
 }
 
 StartRemoteEngineDialog::~StartRemoteEngineDialog()
@@ -950,6 +1014,5 @@ QString StartRemoteEngineDialog::enginePath() const
     return m_ui->enginepath->text();
 }
 
-
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h
index a0d468049f5..cf489defc52 100644
--- a/src/plugins/debugger/debuggerdialogs.h
+++ b/src/plugins/debugger/debuggerdialogs.h
@@ -54,6 +54,9 @@ class StartRemoteEngineDialog;
 
 QT_END_NAMESPACE
 
+namespace ProjectExplorer {
+class Abi;
+}
 
 namespace Debugger {
 namespace Internal {
@@ -82,7 +85,15 @@ public:
     QString executableFile() const;
     QString coreFile() const;
 
+    ProjectExplorer::Abi abi() const;
+    void setAbi(const ProjectExplorer::Abi &);
+
+private slots:
+    void changed();
+
 private:
+    bool isValid() const;
+
     Ui::AttachCoreDialog *m_ui;
 };
 
@@ -97,6 +108,9 @@ public:
     qint64 attachPID() const;
     QString executable() const;
 
+    ProjectExplorer::Abi abi() const;
+    void setAbi(const ProjectExplorer::Abi &);
+
     virtual void accept();
 
 private slots:
@@ -159,8 +173,16 @@ public:
     QString workingDirectory() const;
     void setWorkingDirectory(const QString &str);
 
+    ProjectExplorer::Abi abi() const;
+    void setAbi(const ProjectExplorer::Abi &);
+
     bool breakAtMain() const;
 
+    bool isValid() const;
+
+private slots:
+    void changed();
+
 private:
     Ui::StartExternalDialog *m_ui;
 };
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 86f111d37d0..9371f8f6593 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -94,6 +94,7 @@
 #include <projectexplorer/toolchainmanager.h>
 #include <projectexplorer/session.h>
 #include <projectexplorer/target.h>
+#include <projectexplorer/abi.h>
 
 #include <qt4projectmanager/qt4projectmanagerconstants.h>
 
@@ -695,10 +696,11 @@ public slots:
     void startRemoteApplication();
     void startRemoteEngine();
     void attachExternalApplication();
-    void attachExternalApplication(qint64 pid, const QString &binary);
+    void attachExternalApplication(qint64 pid, const QString &binary,
+                                   const ProjectExplorer::Abi &abi = ProjectExplorer::Abi());
     void runScheduled();
     void attachCore();
-    void attachCore(const QString &core, const QString &exeFileName);
+    void attachCore(const QString &core, const QString &exeFileName, const ProjectExplorer::Abi &abi = ProjectExplorer::Abi());
     void attachRemote(const QString &spec);
     void attachRemoteTcf();
 
@@ -720,7 +722,8 @@ public slots:
     void runControlStarted(DebuggerEngine *engine);
     void runControlFinished(DebuggerEngine *engine);
     DebuggerLanguages activeLanguages() const;
-    QString debuggerForAbi(const Abi &abi) const;
+    unsigned enabledEngines() const { return m_cmdLineEnabledEngines; }
+    QString debuggerForAbi(const Abi &abi, DebuggerEngineType et = NoEngineType) const;
     void remoteCommand(const QStringList &options, const QStringList &);
 
     bool isReverseDebugging() const;
@@ -1339,6 +1342,10 @@ void DebuggerPluginPrivate::startExternalApplication()
             configValue(_("LastExternalExecutableArguments")).toString());
     dlg.setWorkingDirectory(
             configValue(_("LastExternalWorkingDirectory")).toString());
+    const QString abiString = configValue(_("LastExternalAbi")).toString();
+    if (!abiString.isEmpty())
+        dlg.setAbi(ProjectExplorer::Abi(abiString));
+
     if (dlg.exec() != QDialog::Accepted)
         return;
 
@@ -1348,9 +1355,12 @@ void DebuggerPluginPrivate::startExternalApplication()
                    dlg.executableArguments());
     setConfigValue(_("LastExternalWorkingDirectory"),
                    dlg.workingDirectory());
+    setConfigValue(_("LastExternalAbi"),
+                   dlg.abi().toString());
+
     sp.executable = dlg.executableFile();
     sp.startMode = StartExternal;
-    sp.toolChainAbi = abiOfBinary(sp.executable);
+    sp.toolChainAbi = dlg.abi();
     sp.workingDirectory = dlg.workingDirectory();
     if (!dlg.executableArguments().isEmpty())
         sp.processArgs = dlg.executableArguments();
@@ -1375,12 +1385,20 @@ void DebuggerPluginPrivate::startExternalApplication()
 void DebuggerPluginPrivate::attachExternalApplication()
 {
     AttachExternalDialog dlg(mainWindow());
-    if (dlg.exec() == QDialog::Accepted)
-        attachExternalApplication(dlg.attachPID(), dlg.executable());
+
+    const QString abiString = configValue(_("LastAttachExternalAbi")).toString();
+    if (!abiString.isEmpty())
+        dlg.setAbi(ProjectExplorer::Abi(abiString));
+
+    if (dlg.exec() != QDialog::Accepted)
+        return;
+
+    setConfigValue(_("LastAttachExternalAbi"), dlg.abi().toString());
+    attachExternalApplication(dlg.attachPID(), dlg.executable(), dlg.abi());
 }
 
 void DebuggerPluginPrivate::attachExternalApplication
-    (qint64 pid, const QString &binary)
+    (qint64 pid, const QString &binary, const ProjectExplorer::Abi &abi)
 {
     if (pid == 0) {
         QMessageBox::warning(mainWindow(), tr("Warning"),
@@ -1392,7 +1410,7 @@ void DebuggerPluginPrivate::attachExternalApplication
     sp.displayName = tr("Process %1").arg(pid);
     sp.executable = binary;
     sp.startMode = AttachExternal;
-    sp.toolChainAbi = abiOfBinary(sp.executable);
+    sp.toolChainAbi = abi.isValid() ? abi : abiOfBinary(sp.executable);
     if (DebuggerRunControl *rc = createDebugger(sp))
         startDebugger(rc);
 }
@@ -1402,21 +1420,27 @@ void DebuggerPluginPrivate::attachCore()
     AttachCoreDialog dlg(mainWindow());
     dlg.setExecutableFile(configValue(_("LastExternalExecutableFile")).toString());
     dlg.setCoreFile(configValue(_("LastExternalCoreFile")).toString());
+    const QString abiString = configValue(_("LastExternalCoreAbi")).toString();
+    if (!abiString.isEmpty())
+        dlg.setAbi(ProjectExplorer::Abi(abiString));
+
     if (dlg.exec() != QDialog::Accepted)
         return;
+
     setConfigValue(_("LastExternalExecutableFile"), dlg.executableFile());
     setConfigValue(_("LastExternalCoreFile"), dlg.coreFile());
-    attachCore(dlg.coreFile(), dlg.executableFile());
+    setConfigValue(_("LastExternalCoreAbi"), dlg.abi().toString());
+    attachCore(dlg.coreFile(), dlg.executableFile(), dlg.abi());
 }
 
-void DebuggerPluginPrivate::attachCore(const QString &core, const QString &exe)
+void DebuggerPluginPrivate::attachCore(const QString &core, const QString &exe, const ProjectExplorer::Abi &abi)
 {
     DebuggerStartParameters sp;
     sp.executable = exe;
     sp.coreFile = core;
     sp.displayName = tr("Core file \"%1\"").arg(core);
     sp.startMode = AttachCore;
-    sp.toolChainAbi = abiOfBinary(sp.coreFile);
+    sp.toolChainAbi = abi.isValid() ? abi : abiOfBinary(sp.coreFile);
     if (DebuggerRunControl *rc = createDebugger(sp))
         startDebugger(rc);
 }
@@ -2368,9 +2392,26 @@ void DebuggerPluginPrivate::remoteCommand(const QStringList &options,
     runScheduled();
 }
 
-QString DebuggerPluginPrivate::debuggerForAbi(const Abi &abi) const
+QString DebuggerPluginPrivate::debuggerForAbi(const Abi &abi, DebuggerEngineType et) const
 {
-    foreach (const ToolChain *tc, ToolChainManager::instance()->findToolChains(abi)) {
+    Abi searchAbi = abi;
+    // Pick the right toolchain in case cdb/gdb were started with other toolchains.
+    // Also, lldb should be preferred over gdb.
+    if (searchAbi.os() == ProjectExplorer::Abi::WindowsOS) {
+        switch (et) {
+        case CdbEngineType:
+            searchAbi = Abi(abi.architecture(), abi.os(), Abi::WindowsMsvcFlavor,
+                            abi.binaryFormat(), abi.wordWidth());
+            break;
+        case GdbEngineType:
+            searchAbi = Abi(abi.architecture(), abi.os(), Abi::WindowsMSysFlavor,
+                            abi.binaryFormat(), abi.wordWidth());
+            break;
+        default:
+            break;
+        }
+    }
+    foreach (const ToolChain *tc, ToolChainManager::instance()->findToolChains(searchAbi)) {
         const QString debugger = tc->debuggerCommand();
         if (!debugger.isEmpty())
             return debugger;
@@ -2680,11 +2721,6 @@ void DebuggerPluginPrivate::extensionsInitialized()
     cmd->setAttribute(Command::CA_Hide);
     mstart->addAction(cmd, CC::G_DEFAULT_ONE);
 
-    cmd = am->registerAction(m_startRemoteLldbAction,
-        Constants::STARTREMOTELLDB, globalcontext);
-    cmd->setAttribute(Command::CA_Hide);
-    mstart->addAction(cmd, CC::G_DEFAULT_ONE);
-
     cmd = am->registerAction(m_attachExternalAction,
         Constants::ATTACHEXTERNAL, globalcontext);
     cmd->setAttribute(Command::CA_Hide);
@@ -2705,6 +2741,11 @@ void DebuggerPluginPrivate::extensionsInitialized()
     cmd->setAttribute(Command::CA_Hide);
     mstart->addAction(cmd, CC::G_DEFAULT_ONE);
 
+    cmd = am->registerAction(m_startRemoteLldbAction,
+        Constants::STARTREMOTELLDB, globalcontext);
+    cmd->setAttribute(Command::CA_Hide);
+    mstart->addAction(cmd, CC::G_DEFAULT_ONE);
+
     if (m_startRemoteCdbAction) {
         cmd = am->registerAction(m_startRemoteCdbAction,
                                  Constants::ATTACHREMOTECDB, globalcontext);
diff --git a/src/plugins/debugger/debuggerruncontrolfactory.h b/src/plugins/debugger/debuggerruncontrolfactory.h
index 0cccd1a7075..5ef663cbff3 100644
--- a/src/plugins/debugger/debuggerruncontrolfactory.h
+++ b/src/plugins/debugger/debuggerruncontrolfactory.h
@@ -37,6 +37,7 @@
 #include <projectexplorer/runconfiguration.h>
 
 namespace Debugger {
+class DebuggerEngine;
 namespace Internal {
 
 class DebuggerRunControlFactory
@@ -57,6 +58,11 @@ public:
     RunControl *create(RunConfiguration *runConfiguration, const QString &mode);
     bool canRun(RunConfiguration *runConfiguration, const QString &mode) const;
 
+    static DebuggerEngine *createEngine(DebuggerEngineType et,
+                                        const DebuggerStartParameters &sp,
+                                        DebuggerEngine *masterEngine,
+                                        QString *errorMessage);
+
 private:
     QString displayName() const;
     QWidget *createConfigurationWidget(RunConfiguration *runConfiguration);
diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp
index ecf74e14a2a..27919378834 100644
--- a/src/plugins/debugger/debuggerrunner.cpp
+++ b/src/plugins/debugger/debuggerrunner.cpp
@@ -74,7 +74,7 @@ namespace Debugger {
 namespace Internal {
 
 bool isCdbEngineEnabled(); // Check the configuration page
-ConfigurationCheck checkCdbConfiguration(const Abi &abi);
+bool checkCdbConfiguration(const DebuggerStartParameters &sp, ConfigurationCheck *check);
 
 DebuggerEngine *createCdbEngine(const DebuggerStartParameters &sp,
     DebuggerEngine *masterEngine, QString *error);
@@ -85,17 +85,50 @@ DebuggerEngine *createPdbEngine(const DebuggerStartParameters &sp);
 DebuggerEngine *createTcfEngine(const DebuggerStartParameters &sp);
 QmlEngine *createQmlEngine(const DebuggerStartParameters &sp,
     DebuggerEngine *masterEngine);
-DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &sp);
+DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &sp,
+                                   DebuggerEngineType slaveEngineType,
+                                   QString *errorMessage);
 DebuggerEngine *createLldbEngine(const DebuggerStartParameters &sp);
 
 extern QString msgNoBinaryForToolChain(const Abi &abi);
 
+static const char *engineTypeName(DebuggerEngineType et)
+{
+    switch (et) {
+    case Debugger::NoEngineType:
+        break;
+    case Debugger::GdbEngineType:
+        return "Gdb";
+    case Debugger::ScriptEngineType:
+        return "Script engine";
+    case Debugger::CdbEngineType:
+        return "Cdb engine";
+    case Debugger::PdbEngineType:
+        return "Pdb engine";    case Debugger::TcfEngineType:
+        return "Tcf engine";
+    case Debugger::QmlEngineType:
+        return "QML engine";
+    case Debugger::QmlCppEngineType:
+        return "QML C++ engine";
+    case Debugger::LldbEngineType:
+        return "LLDB engine";
+    case Debugger::AllEngineTypes:
+        break;
+    }
+    return "No engine";
+}
+
 static QString msgEngineNotAvailable(const char *engine)
 {
     return DebuggerPlugin::tr("The application requires the debugger engine '%1', "
         "which is disabled.").arg(_(engine));
 }
 
+static inline QString msgEngineNotAvailable(DebuggerEngineType et)
+{
+    return msgEngineNotAvailable(engineTypeName(et));
+}
+
 ////////////////////////////////////////////////////////////////////////
 //
 // DebuggerRunControlPrivate
@@ -105,8 +138,8 @@ static QString msgEngineNotAvailable(const char *engine)
 class DebuggerRunControlPrivate
 {
 public:
-    DebuggerRunControlPrivate(DebuggerRunControl *parent,
-        RunConfiguration *runConfiguration);
+    explicit DebuggerRunControlPrivate(DebuggerRunControl *parent,
+                                       RunConfiguration *runConfiguration);
 
     DebuggerEngineType engineForExecutable(unsigned enabledEngineTypes,
         const QString &executable);
@@ -118,12 +151,10 @@ public:
     DebuggerEngine *m_engine;
     const QWeakPointer<RunConfiguration> m_myRunConfiguration;
     bool m_running;
-    QString m_errorMessage;
-    QString m_settingsIdHint;
 };
 
 DebuggerRunControlPrivate::DebuggerRunControlPrivate(DebuggerRunControl *parent,
-        RunConfiguration *runConfiguration)
+                                                     RunConfiguration *runConfiguration)
     : q(parent)
     , m_engine(0)
     , m_myRunConfiguration(runConfiguration)
@@ -131,222 +162,27 @@ DebuggerRunControlPrivate::DebuggerRunControlPrivate(DebuggerRunControl *parent,
 {
 }
 
-// Figure out the debugger type of an executable. Analyze executable
-// unless the toolchain provides a hint.
-DebuggerEngineType DebuggerRunControlPrivate::engineForExecutable
-    (unsigned enabledEngineTypes, const QString &executable)
-{
-    if (executable.endsWith(_(".js"))) {
-        if (enabledEngineTypes & ScriptEngineType)
-            return ScriptEngineType;
-        m_errorMessage = msgEngineNotAvailable("Script Engine");
-    }
-
-    if (executable.endsWith(_(".py"))) {
-        if (enabledEngineTypes & PdbEngineType)
-            return PdbEngineType;
-        m_errorMessage = msgEngineNotAvailable("Pdb Engine");
-    }
-
-#ifdef Q_OS_WIN
-    // A remote executable?
-    if (!executable.endsWith(_(".exe")))
-        return GdbEngineType;
-
-    // If a file has PDB files, it has been compiled by VS.
-    QStringList pdbFiles;
-    if (!getPDBFiles(executable, &pdbFiles, &m_errorMessage)) {
-        qWarning("Cannot determine type of executable %s: %s",
-                 qPrintable(executable), qPrintable(m_errorMessage));
-        return NoEngineType;
-    }
-    if (pdbFiles.empty())
-        return GdbEngineType;
-
-    // We need the CDB debugger in order to be able to debug VS
-    // executables.
-    Abi hostAbi = Abi::hostAbi();
-    ConfigurationCheck check = checkDebugConfiguration(Abi(hostAbi.architecture(),
-                                                           Abi::WindowsOS,
-                                                           hostAbi.osFlavor(),
-                                                           Abi::PEFormat,
-                                                           hostAbi.wordWidth()));
-    if (!check) {
-        m_errorMessage = check.errorMessage;
-        m_settingsIdHint = check.settingsPage;
-        if (enabledEngineTypes & CdbEngineType)
-            return CdbEngineType;
-        m_errorMessage = msgEngineNotAvailable("Cdb Engine");
-        return NoEngineType;
-    }
-#else
-    if (enabledEngineTypes & GdbEngineType)
-        return GdbEngineType;
-    m_errorMessage = msgEngineNotAvailable("Gdb Engine");
-#endif
-
-    return NoEngineType;
-}
-
-// Debugger type for mode.
-DebuggerEngineType DebuggerRunControlPrivate::engineForMode
-    (unsigned enabledEngineTypes, DebuggerStartMode startMode)
-{
-    if (startMode == AttachTcf)
-        return TcfEngineType;
-
-#ifdef Q_OS_WIN
-    // Preferably Windows debugger for attaching locally.
-    if (startMode != AttachToRemote && (enabledEngineTypes & CdbEngineType))
-        return CdbEngineType;
-    if (startMode == AttachCrashedExternal) {
-        m_errorMessage = DebuggerRunControl::tr("There is no debugging engine available for post-mortem debugging.");
-        return NoEngineType;
-    }
-    return GdbEngineType;
-#else
-    Q_UNUSED(startMode)
-    Q_UNUSED(enabledEngineTypes)
-    //  >m_errorMessage = msgEngineNotAvailable("Gdb Engine");
-    return GdbEngineType;
-#endif
-}
-
 } // namespace Internal
 
-
-////////////////////////////////////////////////////////////////////////
-//
-// DebuggerRunControl
-//
-////////////////////////////////////////////////////////////////////////
-
-static DebuggerEngineType engineForToolChain(const Abi &toolChain)
-{
-    switch (toolChain.binaryFormat()) {
-    case Abi::ElfFormat:
-    case Abi::MachOFormat:
-#ifdef WITH_LLDB
-            // lldb override
-            if (Core::ICore::instance()->settings()->value("LLDB/enabled").toBool())
-                return LldbEngineType;
-#endif
-            return GdbEngineType;
-   case Abi::PEFormat:
-        if (toolChain.osFlavor() == Abi::WindowsMSysFlavor)
-            return GdbEngineType;
-        return CdbEngineType;
-    default:
-        break;
-    }
-    return NoEngineType;
-}
-
-
-unsigned filterEngines(unsigned enabledEngineTypes)
-{
-#ifdef CDB_ENABLED
-    if (!isCdbEngineEnabled() && !Cdb::isCdbEngineEnabled())
-       enabledEngineTypes &= ~CdbEngineType;
-#endif
-    return enabledEngineTypes;
-}
-
 DebuggerRunControl::DebuggerRunControl(RunConfiguration *runConfiguration,
-        const DebuggerStartParameters &startParams)
+                                       const DebuggerStartParameters &sp,
+                                       const QPair<DebuggerEngineType, DebuggerEngineType> &masterSlaveEngineTypes)
     : RunControl(runConfiguration, Constants::DEBUGMODE),
       d(new DebuggerRunControlPrivate(this, runConfiguration))
 {
     connect(this, SIGNAL(finished()), SLOT(handleFinished()));
-
-    // Figure out engine according to toolchain, executable, attach or default.
-    DebuggerEngineType engineType = NoEngineType;
-    DebuggerLanguages activeLangs = debuggerCore()->activeLanguages();
-    DebuggerStartParameters sp = startParams;
-    unsigned enabledEngineTypes = filterEngines(sp.enabledEngines);
-
-    if (sp.executable.endsWith(_(".js")))
-        engineType = ScriptEngineType;
-    else if (sp.executable.endsWith(_(".py")))
-        engineType = PdbEngineType;
-    else {
-        engineType = engineForToolChain(sp.toolChainAbi);
-        if (engineType == CdbEngineType && !(enabledEngineTypes & CdbEngineType)) {
-            d->m_errorMessage = msgEngineNotAvailable("Cdb Engine");
-            engineType = NoEngineType;
-        }
-    }
-
-    // FIXME: Unclean ipc override. Someone please have a better idea.
-    if (sp.startMode == StartRemoteEngine)
-        // For now thats the only supported IPC engine.
-        engineType = LldbEngineType;
-
-    // FIXME: 1 of 3 testing hacks.
-    if (sp.processArgs.startsWith(__("@tcf@ ")))
-        engineType = GdbEngineType;
-
-    // Override CDB by gdb if no PDB sections are found in executable
-    // (pending proper MinGW/MSys detection).
-    if ((engineType == NoEngineType || engineType == CdbEngineType)
-         && sp.startMode != AttachToRemote && !sp.executable.isEmpty())
-        engineType = d->engineForExecutable(enabledEngineTypes, sp.executable);
-
-    if (engineType == NoEngineType)
-        engineType = d->engineForMode(enabledEngineTypes, sp.startMode);
-
-    if ((engineType != QmlEngineType && engineType != NoEngineType)
-        && (activeLangs & QmlLanguage)) {
-        if (activeLangs & CppLanguage) {
-            sp.cppEngineType = engineType;
-            engineType = QmlCppEngineType;
-        } else {
-            engineType = QmlEngineType;
-        }
-    }
-
-    // qDebug() << "USING ENGINE : " << engineType;
-
-    switch (engineType) {
-        case GdbEngineType:
-            d->m_engine = createGdbEngine(sp, 0);
-            break;
-        case ScriptEngineType:
-            d->m_engine = createScriptEngine(sp);
-            break;
-        case CdbEngineType:
-            d->m_engine = createCdbEngine(sp, 0, &d->m_errorMessage);
-            break;
-        case PdbEngineType:
-            d->m_engine = createPdbEngine(sp);
-            break;
-        case TcfEngineType:
-            d->m_engine = createTcfEngine(sp);
-            break;
-        case QmlEngineType:
-            d->m_engine = createQmlEngine(sp, 0);
-            break;
-        case QmlCppEngineType:
-            d->m_engine = createQmlCppEngine(sp);
-            break;
-        case LldbEngineType:
-            d->m_engine = createLldbEngine(sp);
-        case NoEngineType:
-        case AllEngineTypes:
-            break;
-    }
-
+    // Create the engine. Could arguably be moved to the factory, but
+    // we still have a derived S60DebugControl. Should rarely fail, though.
+    QString errorMessage;
+    d->m_engine = masterSlaveEngineTypes.first == QmlCppEngineType ?
+            createQmlCppEngine(sp, masterSlaveEngineTypes.second, &errorMessage) :
+            DebuggerRunControlFactory::createEngine(masterSlaveEngineTypes.first, sp,
+                                                    0, &errorMessage);
     if (d->m_engine) {
         DebuggerToolTipManager::instance()->registerEngine(d->m_engine);
     } else {
-        // Could not find anything suitable.
         debuggingFinished();
-        // Create Message box with possibility to go to settings.
-        const QString msg = tr("Cannot debug '%1' (binary format: '%2'): %3")
-            .arg(sp.executable, sp.toolChainAbi.toString(), d->m_errorMessage);
-        Core::ICore::instance()->showWarningWithOptions(tr("Warning"),
-            msg, QString(), _(Constants::DEBUGGER_SETTINGS_CATEGORY),
-            d->m_settingsIdHint);
+        Core::ICore::instance()->showWarningWithOptions(DebuggerRunControl::tr("Debugger"), errorMessage);
     }
 }
 
@@ -378,40 +214,6 @@ void DebuggerRunControl::setCustomEnvironment(Utils::Environment env)
     d->m_engine->startParameters().environment = env;
 }
 
-ConfigurationCheck checkDebugConfiguration(const Abi &abi)
-{
-    ConfigurationCheck result;
-
-    if (!(debuggerCore()->activeLanguages() & CppLanguage))
-        return result;
-
-    if (abi.binaryFormat() == Abi::ElfFormat ||
-            abi.binaryFormat() == Abi::MachOFormat ||
-            (abi.binaryFormat() == Abi::PEFormat && abi.osFlavor() == Abi::WindowsMSysFlavor)) {
-        if (debuggerCore()->debuggerForAbi(abi).isEmpty()) {
-            result.errorMessage = msgNoBinaryForToolChain(abi);
-            if (!result.errorMessage.isEmpty())
-                result.errorMessage += QLatin1Char('\n');
-            result.errorMessage += QLatin1Char(' ') + msgEngineNotAvailable("Gdb");
-            result.settingsPage = _(Constants::DEBUGGER_COMMON_SETTINGS_ID);
-        }
-    } else if (abi.binaryFormat() == Abi::PEFormat
-                && abi.osFlavor() != Abi::WindowsMSysFlavor) {
-        result = checkCdbConfiguration(abi);
-        if (!result) {
-            if (!result.errorMessage.isEmpty())
-                result.errorMessage += QLatin1Char('\n');
-            result.errorMessage += msgEngineNotAvailable("Cdb");
-            result.settingsPage = _("Cdb");
-        }
-    }
-
-    if (!result && !result.settingsPage.isEmpty())
-        result.settingsCategory = _(Constants::DEBUGGER_SETTINGS_CATEGORY);
-
-    return result;
-}
-
 void DebuggerRunControl::start()
 {
     QTC_ASSERT(d->m_engine, return);
@@ -503,6 +305,266 @@ RunConfiguration *DebuggerRunControl::runConfiguration() const
     return d->m_myRunConfiguration.data();
 }
 
+////////////////////////////////////////////////////////////////////////
+//
+// Engine detection logic: Detection functions depending on toolchain, binary,
+// etc. Return a list of possible engines (order of prefererence) without
+// consideration of configuration, etc.
+//
+////////////////////////////////////////////////////////////////////////
+
+static QList<DebuggerEngineType> enginesForToolChain(const Abi &toolChain)
+{
+    QList<DebuggerEngineType> result;
+    switch (toolChain.binaryFormat()) {
+    case Abi::ElfFormat:
+    case Abi::MachOFormat:
+        result.push_back(LldbEngineType);
+        result.push_back(GdbEngineType);
+        break;
+   case Abi::PEFormat:
+        if (toolChain.osFlavor() == Abi::WindowsMSysFlavor) {
+            result.push_back(GdbEngineType);
+            result.push_back(CdbEngineType);
+        } else {
+            result.push_back(CdbEngineType);
+            result.push_back(GdbEngineType);
+        }
+        break;
+    case Abi::RuntimeQmlFormat:
+        result.push_back(QmlEngineType);
+        break;
+    default:
+        break;
+    }
+    return result;
+}
+
+static inline QList<DebuggerEngineType> enginesForScriptExecutables(const QString &executable)
+{
+    QList<DebuggerEngineType> result;
+    if (executable.endsWith(_(".js"))) {
+        result.push_back(ScriptEngineType);
+    } else if (executable.endsWith(_(".py"))) {
+        result.push_back(PdbEngineType);
+    }
+    return result;
+}
+
+static QList<DebuggerEngineType> enginesForExecutable(const QString &executable)
+{
+    QList<DebuggerEngineType> result = enginesForScriptExecutables(executable);
+    if (!result.isEmpty())
+        return result;
+#ifdef Q_OS_WIN
+    // A remote executable?
+    if (!executable.endsWith(_(".exe"), Qt::CaseInsensitive)) {
+        result.push_back(GdbEngineType);
+        return result;
+    }
+
+    // If a file has PDB files, it has been compiled by VS.
+    QStringList pdbFiles;
+    QString errorMessage;
+    if (getPDBFiles(executable, &pdbFiles, &errorMessage) && !pdbFiles.isEmpty()) {
+        result.push_back(CdbEngineType);
+        result.push_back(GdbEngineType);
+        return result;
+    }
+    // Fixme: Gdb should only be preferred if MinGW can positively be detected.
+    result.push_back(GdbEngineType);
+    result.push_back(CdbEngineType);
+#else
+    result.push_back(LldbEngineType);
+    result.push_back(GdbEngineType);
+#endif
+    return result;
+}
+
+// Debugger type for mode.
+static QList<DebuggerEngineType> enginesForMode(DebuggerStartMode startMode,
+                                                bool hardConstraintsOnly)
+{
+    QList<DebuggerEngineType> result;
+    switch (startMode) {
+    case Debugger::NoStartMode:
+        break;
+    case Debugger::StartInternal:
+    case Debugger::StartExternal:
+    case AttachExternal:
+        if (!hardConstraintsOnly) {
+#ifdef Q_OS_WIN
+            result.push_back(CdbEngineType); // Preferably Windows debugger for attaching locally.
+#endif
+            result.push_back(GdbEngineType);
+        }
+        break;
+    case Debugger::AttachCore:
+    case Debugger::StartRemoteGdb:
+        result.push_back(GdbEngineType);
+        break;
+    case Debugger::AttachToRemote:
+        if (!hardConstraintsOnly) {
+#ifdef Q_OS_WIN
+            result.push_back(CdbEngineType);
+#endif
+            result.push_back(GdbEngineType);
+        }
+        break;
+    case AttachTcf:
+        result.push_back(TcfEngineType);
+        break;
+    case AttachCrashedExternal:
+        result.push_back(CdbEngineType); // Only CDB can do this
+        break;
+    case StartRemoteEngine:
+        // FIXME: Unclear IPC override. Someone please have a better idea.
+        // For now thats the only supported IPC engine.
+        result.push_back(LldbEngineType);
+        break;
+    }
+    return result;
+}
+
+// Engine detection logic: Call all detection functions in order.
+
+static QList<DebuggerEngineType> engineTypes(const DebuggerStartParameters &sp)
+{
+    // Script executables and certain start modes are 'hard constraints'.
+    QList<DebuggerEngineType> result = enginesForScriptExecutables(sp.executable);
+    if (!result.isEmpty())
+        return result;
+
+    result = enginesForMode(sp.startMode, true);
+    if (!result.isEmpty())
+        return result;
+
+    //  'hard constraints' done (with the exception of QML ABI checked here),
+    // further try to restrict available engines.
+    if (sp.toolChainAbi.isValid()) {
+        result = enginesForToolChain(sp.toolChainAbi);
+        if (!result.isEmpty())
+            return result;
+    }
+
+    // FIXME: 1 of 3 testing hacks.
+    if (sp.processArgs.startsWith(__("@tcf@ "))) {
+        result.push_back(GdbEngineType);
+        return result;
+    }
+
+    if (sp.startMode != AttachToRemote && !sp.executable.isEmpty())
+        result = enginesForExecutable(sp.executable);
+    if (!result.isEmpty())
+        return result;
+
+    result = enginesForMode(sp.startMode, false);
+    return result;
+}
+
+// Engine detection logic: Configuration checks.
+
+QString msgNoBinaryForToolChain(const ProjectExplorer::Abi &tc, DebuggerEngineType et)
+{
+    return DebuggerPlugin::tr("There is no binary available for debugging binaries of type '%1' using the engine '%2'").
+            arg(tc.toString(), QLatin1String(engineTypeName(et)));
+}
+
+static inline bool engineConfigurationCheck(const DebuggerStartParameters &sp,
+                                            DebuggerEngineType et,
+                                            ConfigurationCheck *check)
+{
+    switch (et) {
+    case Debugger::CdbEngineType:
+        return checkCdbConfiguration(sp, check);
+    case Debugger::GdbEngineType:
+        if (debuggerCore()->debuggerForAbi(sp.toolChainAbi, et).isEmpty()) {
+            check->errorMessage = msgNoBinaryForToolChain(sp.toolChainAbi, et);
+            check->settingsCategory = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY);
+            check->settingsPage = QLatin1String(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY);
+            return false;
+        }
+    default:
+        break;
+    }
+    return true;
+}
+
+// Engine detection logic: ConfigurationCheck.
+ConfigurationCheck::ConfigurationCheck() :
+    masterSlaveEngineTypes(NoEngineType, NoEngineType)
+{
+}
+
+ConfigurationCheck::operator bool() const
+{
+    return errorMessage.isEmpty() &&  masterSlaveEngineTypes.first != NoEngineType;
+}
+
+/*!
+    \fn ConfigurationCheck checkDebugConfiguration(unsigned cmdLineEnabledEngines,
+                                                   const DebuggerStartParameters &sp)
+
+    This is the master engine detection function that returns the
+    engine types for a given set of start parameters and checks their
+    configuration.
+*/
+
+DEBUGGER_EXPORT ConfigurationCheck checkDebugConfiguration(const DebuggerStartParameters &sp)
+{
+    ConfigurationCheck result;
+    const unsigned activeLangs = debuggerCore()->activeLanguages();
+    const bool qmlLanguage = activeLangs & QmlLanguage;
+    const bool cppLanguage = activeLangs & CppLanguage;
+    // Get all applicable types.
+    QList<DebuggerEngineType> requiredTypes;
+    if (qmlLanguage && !cppLanguage) {
+        requiredTypes.push_back(QmlEngineType);
+    } else {
+        requiredTypes = engineTypes(sp);
+    }
+    if (requiredTypes.isEmpty()) {
+        result.errorMessage = DebuggerPlugin::tr("Internal error: Unable to determine debugger engine type for this configuration");
+        return result;
+    }
+    // Filter out disables types, command line + current settings.
+    unsigned cmdLineEnabledEngines = debuggerCore()->enabledEngines();
+#ifdef CDB_ENABLED
+     if (!isCdbEngineEnabled() && !Cdb::isCdbEngineEnabled())
+         cmdLineEnabledEngines &= ~CdbEngineType;
+#endif
+#ifdef WITH_LLDB
+    if (!Core::ICore::instance()->settings()->value(QLatin1String("LLDB/enabled")).toBool())
+        cmdLineEnabledEngines &= ~LldbEngineType;
+#else
+     cmdLineEnabledEngines &= ~LldbEngineType;
+#endif
+    QList<DebuggerEngineType> usableTypes;
+    foreach (DebuggerEngineType et, requiredTypes)
+        if (et & cmdLineEnabledEngines)
+            usableTypes.push_back(et);
+    if (usableTypes.isEmpty()) {
+        result.errorMessage = DebuggerPlugin::tr("This configuration requires the debugger engine %1, which is disabled.").
+                arg(QLatin1String(engineTypeName(usableTypes.front())));
+        return result;
+    }
+    // Configuration check: Strip off non-configured engines.
+    while (!usableTypes.isEmpty() && !engineConfigurationCheck(sp, usableTypes.front(), &result))
+        usableTypes.pop_front();
+    if (usableTypes.isEmpty()) {
+        result.errorMessage = DebuggerPlugin::tr("The debugger engine required for this configuration is not correctly configured:\n%1")
+                .arg(result.errorMessage);
+        return result;
+    }
+    // Anything left: Happy.
+    if (qmlLanguage && cppLanguage) {
+        result.masterSlaveEngineTypes.first = QmlCppEngineType;
+        result.masterSlaveEngineTypes.second = usableTypes.front();
+    } else {
+        result.masterSlaveEngineTypes.first = usableTypes.front();
+    }
+    return result;
+}
 
 ////////////////////////////////////////////////////////////////////////
 //
@@ -621,11 +683,9 @@ QWidget *DebuggerRunControlFactory::createConfigurationWidget
 }
 
 DebuggerRunControl *DebuggerRunControlFactory::create
-    (const DebuggerStartParameters &sp0, RunConfiguration *runConfiguration)
+    (const DebuggerStartParameters &sp, RunConfiguration *runConfiguration)
 {
-    DebuggerStartParameters sp = sp0;
-    sp.enabledEngines = m_enabledEngines;
-    ConfigurationCheck check = checkDebugConfiguration(sp.toolChainAbi);
+    const ConfigurationCheck check = checkDebugConfiguration(sp);
 
     if (!check) {
         //appendMessage(errorMessage, true);
@@ -634,12 +694,41 @@ DebuggerRunControl *DebuggerRunControlFactory::create
         return 0;
     }
 
-    DebuggerRunControl *runControl =
-        new DebuggerRunControl(runConfiguration, sp);
-    if (runControl->d->m_engine)
-        return runControl;
-    delete runControl;
+    return new DebuggerRunControl(runConfiguration, sp, check.masterSlaveEngineTypes);
+}
+
+DebuggerEngine *
+    DebuggerRunControlFactory::createEngine(DebuggerEngineType et,
+                                            const DebuggerStartParameters &sp,
+                                            DebuggerEngine *masterEngine,
+                                            QString *errorMessage)
+{
+    switch (et) {
+    case GdbEngineType:
+        return createGdbEngine(sp, masterEngine);
+    case ScriptEngineType:
+        return createScriptEngine(sp);
+    case CdbEngineType:
+        return createCdbEngine(sp, masterEngine, errorMessage);
+        break;
+    case PdbEngineType:
+        return createPdbEngine(sp);
+        break;
+    case TcfEngineType:
+        return createTcfEngine(sp);
+        break;
+    case QmlEngineType:
+        return createQmlEngine(sp, masterEngine);
+        break;
+    case LldbEngineType:
+        return createLldbEngine(sp);
+    default:
+        break;
+    }
+    *errorMessage = DebuggerRunControl::tr("Unable to create a debugger engine of the type '%1'").
+                    arg(_(engineTypeName(et)));
     return 0;
 }
 
+
 } // namespace Debugger
diff --git a/src/plugins/debugger/debuggerrunner.h b/src/plugins/debugger/debuggerrunner.h
index 1da943d02a2..0a864a1ad67 100644
--- a/src/plugins/debugger/debuggerrunner.h
+++ b/src/plugins/debugger/debuggerrunner.h
@@ -35,11 +35,13 @@
 #define DEBUGGERRUNNER_H
 
 #include "debugger_global.h"
+#include "debuggerconstants.h"
 
 #include <projectexplorer/abi.h>
 #include <projectexplorer/runconfiguration.h>
 
 #include <QtCore/QScopedPointer>
+#include <QtCore/QPair>
 
 namespace Utils {
 class Environment;
@@ -59,16 +61,16 @@ class DebuggerRunControlFactory;
 class DEBUGGER_EXPORT ConfigurationCheck
 {
 public:
-    ConfigurationCheck() {}
-    operator bool() const { return errorMessage.isEmpty(); }
+    ConfigurationCheck();
+    operator bool() const;
 
-public:
     QString errorMessage;
     QString settingsCategory;
     QString settingsPage;
+    QPair<DebuggerEngineType, DebuggerEngineType> masterSlaveEngineTypes;
 };
 
-DEBUGGER_EXPORT ConfigurationCheck checkDebugConfiguration(const ProjectExplorer::Abi &abi);
+DEBUGGER_EXPORT ConfigurationCheck checkDebugConfiguration(const DebuggerStartParameters &sp);
 
 // This is a job description containing all data "local" to the jobs, including
 // the models of the individual debugger views.
@@ -79,8 +81,10 @@ class DEBUGGER_EXPORT DebuggerRunControl
 
 public:
     typedef ProjectExplorer::RunConfiguration RunConfiguration;
-    DebuggerRunControl(RunConfiguration *runConfiguration,
-        const DebuggerStartParameters &sp);
+    explicit DebuggerRunControl(RunConfiguration *runConfiguration,
+                                const DebuggerStartParameters &sp,
+                                const QPair<DebuggerEngineType, DebuggerEngineType> &masterSlaveEngineTypes);
+
     ~DebuggerRunControl();
 
     // ProjectExplorer::RunControl
diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h
index 1d9c4a78a08..64f0199ee01 100644
--- a/src/plugins/debugger/debuggerstartparameters.h
+++ b/src/plugins/debugger/debuggerstartparameters.h
@@ -65,7 +65,6 @@ public:
       : isSnapshot(false),
         attachPID(-1),
         useTerminal(false),
-        enabledEngines(AllEngineTypes),
         qmlServerAddress(QLatin1String("127.0.0.1")),
         qmlServerPort(0),
         useServerStartScript(false),
@@ -87,7 +86,6 @@ public:
     QString workingDirectory;
     qint64 attachPID;
     bool useTerminal;
-    unsigned enabledEngines;
 
     // Used by AttachCrashedExternal.
     QString crashParameter;
diff --git a/src/plugins/debugger/debuggertoolchaincombobox.cpp b/src/plugins/debugger/debuggertoolchaincombobox.cpp
new file mode 100644
index 00000000000..1f2acfe370d
--- /dev/null
+++ b/src/plugins/debugger/debuggertoolchaincombobox.cpp
@@ -0,0 +1,90 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "debuggertoolchaincombobox.h"
+
+#include <projectexplorer/toolchainmanager.h>
+#include <utils/qtcassert.h>
+
+#include <QtCore/QFileInfo>
+
+Q_DECLARE_METATYPE(ProjectExplorer::Abi)
+
+namespace Debugger {
+namespace Internal {
+
+DebuggerToolChainComboBox::DebuggerToolChainComboBox(QWidget *parent) :
+    QComboBox(parent)
+{
+}
+
+void DebuggerToolChainComboBox::init(bool hostAbiOnly)
+{
+    const ProjectExplorer::Abi hostAbi = ProjectExplorer::Abi::hostAbi();
+    foreach (const ProjectExplorer::ToolChain *tc, ProjectExplorer::ToolChainManager::instance()->toolChains()) {
+        if (!hostAbiOnly || hostAbi.isCompatibleWith(tc->targetAbi())) {
+            const QString debuggerCommand = tc->debuggerCommand();
+            if (!debuggerCommand.isEmpty()) {
+                const QString name = tr("%1 (%2)").arg(tc->displayName(), QFileInfo(debuggerCommand).baseName());
+                addItem(name, qVariantFromValue(tc->targetAbi()));
+            }
+        }
+    }
+    setEnabled(count() > 1);
+}
+
+void DebuggerToolChainComboBox::setAbi(const ProjectExplorer::Abi &abi)
+{
+    QTC_ASSERT(abi.isValid(), return; )
+    const int c = count();
+    for (int i = 0; i < c; i++) {
+        if (abiAt(i) == abi) {
+            setCurrentIndex(i);
+            break;
+        }
+    }
+}
+
+ProjectExplorer::Abi DebuggerToolChainComboBox::abi() const
+{
+    return abiAt(currentIndex());
+}
+
+ProjectExplorer::Abi DebuggerToolChainComboBox::abiAt(int index) const
+{
+    return index >= 0 ? qvariant_cast<ProjectExplorer::Abi>(itemData(index)) :
+                        ProjectExplorer::Abi();
+}
+
+} // namespace Debugger
+} // namespace Internal
diff --git a/src/plugins/debugger/debuggertoolchaincombobox.h b/src/plugins/debugger/debuggertoolchaincombobox.h
new file mode 100644
index 00000000000..bf198da3039
--- /dev/null
+++ b/src/plugins/debugger/debuggertoolchaincombobox.h
@@ -0,0 +1,65 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef DEBUGGERTOOLCHAINCOMBOBOX_H
+#define DEBUGGERTOOLCHAINCOMBOBOX_H
+
+#include <QtGui/QComboBox>
+
+namespace ProjectExplorer {
+class Abi;
+}
+
+namespace Debugger {
+namespace Internal {
+
+// Let the user pick a toolchain/ABI associated with a debugger.
+class DebuggerToolChainComboBox : public QComboBox
+{
+    Q_OBJECT
+public:
+    explicit DebuggerToolChainComboBox(QWidget *parent);
+
+    void init(bool hostAbiOnly);
+
+    void setAbi(const ProjectExplorer::Abi &abi);
+    ProjectExplorer::Abi abi() const;
+
+private:
+    ProjectExplorer::Abi abiAt(int index) const;
+};
+
+} // namespace Debugger
+} // namespace Internal
+
+#endif // DEBUGGERTOOLCHAINCOMBOBOX_H
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index c1198365980..2acecec49b5 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -1804,9 +1804,8 @@ int GdbEngine::currentFrame() const
     return stackHandler()->currentIndex();
 }
 
-QString msgNoBinaryForToolChain(const ProjectExplorer::Abi &tc)
+QString msgNoGdbBinaryForToolChain(const ProjectExplorer::Abi &tc)
 {
-    using namespace ProjectExplorer;
     return GdbEngine::tr("There is no gdb binary available for binaries in format '%1'")
         .arg(tc.toString());
 }
@@ -4217,22 +4216,13 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb,
     const DebuggerStartParameters &sp = startParameters();
     m_gdb = QString::fromLocal8Bit(qgetenv("QTC_DEBUGGER_PATH"));
     if (m_gdb.isEmpty() && sp.startMode != StartRemoteGdb) {
-        // We want the MinGW gdb also in case we got started using
-        // some compatible ABI.
-        Abi abi = startParameters().toolChainAbi;
-        if (abi.os() == Abi::WindowsOS) {
-            if (abi.osFlavor() == Abi::UnknownFlavor
-                    || abi.osFlavor() == Abi::WindowsMsvcFlavor)
-                abi = Abi(abi.architecture(), abi.os(), Abi::WindowsMSysFlavor,
-                          abi.binaryFormat(), abi.wordWidth());
-        }
-        m_gdb = debuggerCore()->debuggerForAbi(abi);
+        m_gdb = debuggerCore()->debuggerForAbi(startParameters().toolChainAbi, GdbEngineType);
     }
     if (m_gdb.isEmpty())
         m_gdb = gdb;
     if (m_gdb.isEmpty()) {
         handleAdapterStartFailed(
-            msgNoBinaryForToolChain(sp.toolChainAbi),
+            msgNoGdbBinaryForToolChain(sp.toolChainAbi),
             _(Constants::DEBUGGER_COMMON_SETTINGS_ID));
         return false;
     }
diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp
index 96d63357bb8..9d39a2e5b4c 100644
--- a/src/plugins/debugger/qml/qmlcppengine.cpp
+++ b/src/plugins/debugger/qml/qmlcppengine.cpp
@@ -32,7 +32,7 @@
 **************************************************************************/
 
 #include "qmlcppengine.h"
-
+#include "debuggerruncontrolfactory.h"
 #include "debuggercore.h"
 #include "debuggerstartparameters.h"
 #include "stackhandler.h"
@@ -40,7 +40,6 @@
 
 #include <utils/qtcassert.h>
 
-
 namespace Debugger {
 namespace Internal {
 
@@ -50,16 +49,14 @@ enum { debug = 0 };
 
 const int ConnectionWaitTimeMs = 5000;
 
-DebuggerEngine *createCdbEngine(const DebuggerStartParameters &,
-    DebuggerEngine *masterEngine, QString *);
-DebuggerEngine *createGdbEngine(const DebuggerStartParameters &,
-    DebuggerEngine *masterEngine);
 QmlEngine *createQmlEngine(const DebuggerStartParameters &,
     DebuggerEngine *masterEngine);
 
-DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &sp)
+DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &sp,
+                                   DebuggerEngineType slaveEngineType,
+                                   QString *errorMessage)
 {
-    QmlCppEngine *newEngine = new QmlCppEngine(sp);
+    QmlCppEngine *newEngine = new QmlCppEngine(sp, slaveEngineType, errorMessage);
     if (newEngine->cppEngine())
         return newEngine;
     delete newEngine;
@@ -98,32 +95,10 @@ private:
 
 QmlCppEnginePrivate::QmlCppEnginePrivate(QmlCppEngine *parent,
         const DebuggerStartParameters &sp)
-  : q(parent)
+    : q(parent), m_qmlEngine(createQmlEngine(sp, q)),
+      m_cppEngine(0), m_activeEngine(0)
 {
-    m_stackBoundary = 0;
-    m_cppEngine = 0;
-    m_activeEngine = 0;
-    m_qmlEngine = createQmlEngine(sp, q);
-
-    if (sp.cppEngineType == GdbEngineType) {
-        m_cppEngine = createGdbEngine(sp, q);
-    } else {
-        QString errorMessage;
-        m_cppEngine = createCdbEngine(sp, q, &errorMessage);
-        if (!m_cppEngine) {
-            qWarning("%s", qPrintable(errorMessage));
-            return;
-        }
-    }
-
-    m_activeEngine = m_cppEngine;
-
-    connect(m_cppEngine->stackHandler()->model(), SIGNAL(modelReset()),
-        SLOT(cppStackChanged()), Qt::QueuedConnection);
-    connect(m_qmlEngine->stackHandler()->model(), SIGNAL(modelReset()),
-        SLOT(qmlStackChanged()), Qt::QueuedConnection);
-    connect(m_cppEngine, SIGNAL(stackFrameCompleted()), q, SIGNAL(stackFrameCompleted()));
-    connect(m_qmlEngine, SIGNAL(stackFrameCompleted()), q, SIGNAL(stackFrameCompleted()));
+    setObjectName(QLatin1String("QmlCppEnginePrivate"));
 }
 
 void QmlCppEnginePrivate::cppStackChanged()
@@ -158,12 +133,25 @@ void QmlCppEnginePrivate::qmlStackChanged()
 //
 ////////////////////////////////////////////////////////////////////////
 
-QmlCppEngine::QmlCppEngine(const DebuggerStartParameters &sp)
+QmlCppEngine::QmlCppEngine(const DebuggerStartParameters &sp,
+                           DebuggerEngineType slaveEngineType,
+                           QString *errorMessage)
     : DebuggerEngine(sp), d(new QmlCppEnginePrivate(this, sp))
 {
-//    setStateDebugging(true);
-//    d->m_cppEngine->setStateDebugging(true);
-//    d->m_qmlEngine->setStateDebugging(true);
+    setObjectName(QLatin1String("QmlCppEngine"));
+    d->m_cppEngine = DebuggerRunControlFactory::createEngine(slaveEngineType, sp, this, errorMessage);
+    if (!d->m_cppEngine) {
+        *errorMessage = tr("The slave debugging engine requires for combined QML/C++-Debugging could not be created:").arg(*errorMessage);
+        return;
+    }
+    d->m_activeEngine = d->m_cppEngine;
+
+    connect(d->m_cppEngine->stackHandler()->model(), SIGNAL(modelReset()),
+            d.data(), SLOT(cppStackChanged()), Qt::QueuedConnection);
+    connect(d->m_qmlEngine->stackHandler()->model(), SIGNAL(modelReset()),
+            d.data(), SLOT(qmlStackChanged()), Qt::QueuedConnection);
+    connect(d->m_cppEngine, SIGNAL(stackFrameCompleted()), this, SIGNAL(stackFrameCompleted()));
+    connect(d->m_qmlEngine, SIGNAL(stackFrameCompleted()), this, SIGNAL(stackFrameCompleted()));
 }
 
 QmlCppEngine::~QmlCppEngine()
diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h
index c946b2fde31..822787b51fc 100644
--- a/src/plugins/debugger/qml/qmlcppengine.h
+++ b/src/plugins/debugger/qml/qmlcppengine.h
@@ -48,7 +48,9 @@ class DEBUGGER_EXPORT QmlCppEngine : public DebuggerEngine
     Q_OBJECT
 
 public:
-    explicit QmlCppEngine(const DebuggerStartParameters &sp);
+    explicit QmlCppEngine(const DebuggerStartParameters &sp,
+                          DebuggerEngineType slaveEngineType,
+                          QString *errorMessage);
     ~QmlCppEngine();
 
     bool setToolTipExpression(const QPoint &mousePos,
diff --git a/src/plugins/debugger/startexternaldialog.ui b/src/plugins/debugger/startexternaldialog.ui
index fcde484ce73..6e9c94dd95c 100644
--- a/src/plugins/debugger/startexternaldialog.ui
+++ b/src/plugins/debugger/startexternaldialog.ui
@@ -6,42 +6,45 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>425</width>
-    <height>151</height>
+    <width>443</width>
+    <height>213</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Start Debugger</string>
   </property>
-  <layout class="QVBoxLayout">
-   <property name="spacing">
-    <number>6</number>
-   </property>
-   <property name="margin">
-    <number>9</number>
-   </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <layout class="QGridLayout">
-     <property name="margin">
-      <number>0</number>
+    <layout class="QFormLayout" name="formLayout">
+     <property name="horizontalSpacing">
+      <number>6</number>
      </property>
-     <property name="spacing">
+     <property name="verticalSpacing">
       <number>6</number>
      </property>
+     <property name="margin">
+      <number>0</number>
+     </property>
      <item row="0" column="0">
       <widget class="QLabel" name="execLabel">
        <property name="text">
-        <string>Executable:</string>
+        <string>&amp;Executable:</string>
+       </property>
+       <property name="buddy">
+        <cstring>execFile</cstring>
        </property>
       </widget>
      </item>
      <item row="0" column="1">
-      <widget class="Utils::PathChooser" name="execFile" native="true"/>
+      <widget class="Utils::PathChooser" name="execFile"/>
      </item>
      <item row="1" column="0">
       <widget class="QLabel" name="argsLabel">
        <property name="text">
-        <string>Arguments:</string>
+        <string>&amp;Arguments:</string>
+       </property>
+       <property name="buddy">
+        <cstring>argsEdit</cstring>
        </property>
       </widget>
      </item>
@@ -51,24 +54,43 @@
      <item row="2" column="0">
       <widget class="QLabel" name="workingDirectoryLabel">
        <property name="text">
-        <string>Working directory:</string>
+        <string>&amp;Working directory:</string>
+       </property>
+       <property name="buddy">
+        <cstring>workingDirectory</cstring>
        </property>
       </widget>
      </item>
      <item row="2" column="1">
-      <widget class="Utils::PathChooser" name="workingDirectory" native="true"/>
+      <widget class="Utils::PathChooser" name="workingDirectory"/>
      </item>
-     <item row="3" column="1">
+     <item row="4" column="0">
+      <widget class="QLabel" name="labelBreakAtMain">
+       <property name="text">
+        <string>Break at '&amp;main':</string>
+       </property>
+       <property name="buddy">
+        <cstring>checkBoxBreakAtMain</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="1">
       <widget class="QCheckBox" name="checkBoxBreakAtMain">
        <property name="text">
         <string/>
        </property>
       </widget>
      </item>
+     <item row="3" column="1">
+      <widget class="Debugger::Internal::DebuggerToolChainComboBox" name="toolChainComboBox"/>
+     </item>
      <item row="3" column="0">
-      <widget class="QLabel" name="labelBreakAtMain">
+      <widget class="QLabel" name="toolChainLabel">
        <property name="text">
-        <string>Break at 'main':</string>
+        <string>&amp;ToolChain:</string>
+       </property>
+       <property name="buddy">
+        <cstring>toolChainComboBox</cstring>
        </property>
       </widget>
      </item>
@@ -81,8 +103,8 @@
      </property>
      <property name="sizeHint" stdset="0">
       <size>
-       <width>407</width>
-       <height>16</height>
+       <width>0</width>
+       <height>0</height>
       </size>
      </property>
     </spacer>
@@ -113,6 +135,11 @@
    <header location="global">utils/pathchooser.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>Debugger::Internal::DebuggerToolChainComboBox</class>
+   <extends>QComboBox</extends>
+   <header>debuggertoolchaincombobox.h</header>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
diff --git a/src/plugins/debugger/startremotedialog.ui b/src/plugins/debugger/startremotedialog.ui
index f02da26c86f..8495cc69a47 100644
--- a/src/plugins/debugger/startremotedialog.ui
+++ b/src/plugins/debugger/startremotedialog.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>446</width>
-    <height>269</height>
+    <width>476</width>
+    <height>294</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -19,27 +19,36 @@
      <item row="0" column="0">
       <widget class="QLabel" name="debuggerLabel">
        <property name="text">
-        <string>Debugger:</string>
+        <string>&amp;Debugger:</string>
+       </property>
+       <property name="buddy">
+        <cstring>debuggerPathChooser</cstring>
        </property>
       </widget>
      </item>
      <item row="0" column="1">
-      <widget class="Utils::PathChooser" name="debuggerPathChooser" native="true"/>
+      <widget class="Utils::PathChooser" name="debuggerPathChooser"/>
      </item>
      <item row="1" column="0">
       <widget class="QLabel" name="executableLabel">
        <property name="text">
-        <string>Local executable:</string>
+        <string>Local &amp;executable:</string>
+       </property>
+       <property name="buddy">
+        <cstring>executablePathChooser</cstring>
        </property>
       </widget>
      </item>
      <item row="1" column="1">
-      <widget class="Utils::PathChooser" name="executablePathChooser" native="true"/>
+      <widget class="Utils::PathChooser" name="executablePathChooser"/>
      </item>
      <item row="2" column="0">
       <widget class="QLabel" name="channelLabel">
        <property name="text">
-        <string>Host and port:</string>
+        <string>&amp;Host and port:</string>
+       </property>
+       <property name="buddy">
+        <cstring>channelLineEdit</cstring>
        </property>
       </widget>
      </item>
@@ -53,7 +62,10 @@
      <item row="3" column="0">
       <widget class="QLabel" name="architectureLabel">
        <property name="text">
-        <string>Architecture:</string>
+        <string>&amp;Architecture:</string>
+       </property>
+       <property name="buddy">
+        <cstring>architectureComboBox</cstring>
        </property>
       </widget>
      </item>
@@ -67,7 +79,10 @@
      <item row="4" column="0">
       <widget class="QLabel" name="gnuTargetLabel">
        <property name="text">
-        <string>GNU target</string>
+        <string>&amp;GNU target</string>
+       </property>
+       <property name="buddy">
+        <cstring>gnuTargetComboBox</cstring>
        </property>
       </widget>
      </item>
@@ -81,17 +96,23 @@
      <item row="5" column="0">
       <widget class="QLabel" name="sysrootLabel">
        <property name="text">
-        <string>Sysroot:</string>
+        <string>Sys&amp;root:</string>
+       </property>
+       <property name="buddy">
+        <cstring>sysrootPathChooser</cstring>
        </property>
       </widget>
      </item>
      <item row="5" column="1">
-      <widget class="Utils::PathChooser" name="sysrootPathChooser" native="true"/>
+      <widget class="Utils::PathChooser" name="sysrootPathChooser"/>
      </item>
      <item row="6" column="0">
       <widget class="QLabel" name="useServerStartScriptLabel">
        <property name="text">
-        <string>Use server start script:</string>
+        <string>&amp;Use server start script:</string>
+       </property>
+       <property name="buddy">
+        <cstring>useServerStartScriptCheckBox</cstring>
        </property>
       </widget>
      </item>
@@ -101,12 +122,15 @@
      <item row="7" column="0">
       <widget class="QLabel" name="serverStartScriptLabel">
        <property name="text">
-        <string>Server start script:</string>
+        <string>Server st&amp;art script:</string>
+       </property>
+       <property name="buddy">
+        <cstring>serverStartScript</cstring>
        </property>
       </widget>
      </item>
      <item row="7" column="1">
-      <widget class="Utils::PathChooser" name="serverStartScript" native="true"/>
+      <widget class="Utils::PathChooser" name="serverStartScript"/>
      </item>
     </layout>
    </item>
@@ -127,6 +151,7 @@
    <class>Utils::PathChooser</class>
    <extends>QWidget</extends>
    <header location="global">utils/pathchooser.h</header>
+   <container>1</container>
   </customwidget>
  </customwidgets>
  <resources/>
diff --git a/src/plugins/debugger/startremoteenginedialog.ui b/src/plugins/debugger/startremoteenginedialog.ui
index ff7fc669360..83d647e0fc0 100644
--- a/src/plugins/debugger/startremoteenginedialog.ui
+++ b/src/plugins/debugger/startremoteenginedialog.ui
@@ -6,95 +6,114 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>884</width>
-    <height>601</height>
+    <width>233</width>
+    <height>207</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Start Remote Engine</string>
   </property>
-  <layout class="QGridLayout" name="gridLayout">
-   <item row="0" column="0">
-    <widget class="QLabel" name="channelLabel">
-     <property name="text">
-      <string>Host:</string>
-     </property>
-    </widget>
-   </item>
-   <item row="8" column="0" colspan="4">
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-     </property>
-    </widget>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QFormLayout" name="formLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="channelLabel">
+       <property name="text">
+        <string>&amp;Host:</string>
+       </property>
+       <property name="buddy">
+        <cstring>host</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QLineEdit" name="host">
+       <property name="text">
+        <string notr="true"/>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QLabel" name="userLabel">
+       <property name="text">
+        <string>&amp;Username:</string>
+       </property>
+       <property name="buddy">
+        <cstring>username</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QLineEdit" name="username"/>
+     </item>
+     <item row="2" column="0">
+      <widget class="QLabel" name="passwordLabel">
+       <property name="text">
+        <string>&amp;Password:</string>
+       </property>
+       <property name="buddy">
+        <cstring>password</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <widget class="QLineEdit" name="password">
+       <property name="echoMode">
+        <enum>QLineEdit::Password</enum>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="0">
+      <widget class="QLabel" name="engineLabel">
+       <property name="text">
+        <string>&amp;Engine path:</string>
+       </property>
+       <property name="buddy">
+        <cstring>enginepath</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="1">
+      <widget class="QLineEdit" name="enginepath"/>
+     </item>
+     <item row="4" column="0">
+      <widget class="QLabel" name="inferiorLabel">
+       <property name="text">
+        <string>&amp;Inferior path:</string>
+       </property>
+       <property name="buddy">
+        <cstring>inferiorpath</cstring>
+       </property>
+      </widget>
+     </item>
+     <item row="4" column="1">
+      <widget class="QLineEdit" name="inferiorpath"/>
+     </item>
+    </layout>
    </item>
-   <item row="3" column="0">
-    <widget class="QLabel" name="label">
-     <property name="text">
-      <string>Engine path:</string>
-     </property>
-    </widget>
-   </item>
-   <item row="4" column="0">
-    <widget class="QLabel" name="label_2">
-     <property name="text">
-      <string>Inferior path:</string>
-     </property>
-    </widget>
-   </item>
-   <item row="4" column="2">
-    <widget class="QLineEdit" name="inferiorpath"/>
-   </item>
-   <item row="3" column="2">
-    <widget class="QLineEdit" name="enginepath"/>
-   </item>
-   <item row="0" column="2">
-    <widget class="QLineEdit" name="host">
-     <property name="text">
-      <string notr="true"/>
-     </property>
-    </widget>
-   </item>
-   <item row="2" column="2">
-    <widget class="QLineEdit" name="password">
-     <property name="echoMode">
-      <enum>QLineEdit::Password</enum>
-     </property>
-    </widget>
-   </item>
-   <item row="1" column="2">
-    <widget class="QLineEdit" name="username"/>
-   </item>
-   <item row="1" column="0">
-    <widget class="QLabel" name="label_3">
-     <property name="text">
-      <string>Username:</string>
-     </property>
-    </widget>
-   </item>
-   <item row="2" column="0">
-    <widget class="QLabel" name="label_4">
-     <property name="text">
-      <string>Password:</string>
-     </property>
-    </widget>
-   </item>
-   <item row="6" column="1" colspan="2">
+   <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
-       <width>20</width>
-       <height>40</height>
+       <width>0</width>
+       <height>0</height>
       </size>
      </property>
     </spacer>
    </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <tabstops>
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
index 69fe327193d..44c7c564d24 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -468,7 +468,6 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR
     sp.toolChainAbi = rc->abi();
     sp.executable = debugFileName;
     sp.executableUid = rc->executableUid();
-    sp.enabledEngines = Debugger::GdbEngineType;
     sp.serverAddress = activeDeployConf->deviceAddress();
     sp.serverPort = activeDeployConf->devicePort().toInt();
 
@@ -489,8 +488,9 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR
 }
 
 S60DeviceDebugRunControl::S60DeviceDebugRunControl(S60DeviceRunConfiguration *rc,
-                                                   const QString &) :
-    Debugger::DebuggerRunControl(rc, s60DebuggerStartParams(rc))
+                                                   const Debugger::DebuggerStartParameters &sp,
+                                                   const QPair<Debugger::DebuggerEngineType, Debugger::DebuggerEngineType> &masterSlaveEngineTypes) :
+    Debugger::DebuggerRunControl(rc, sp, masterSlaveEngineTypes)
 {
     if (startParameters().symbolFileName.isEmpty()) {
         const QString msg = tr("Warning: Cannot locate the symbol file belonging to %1.").
@@ -501,23 +501,47 @@ S60DeviceDebugRunControl::S60DeviceDebugRunControl(S60DeviceRunConfiguration *rc
 
 void S60DeviceDebugRunControl::start()
 {
-    Debugger::ConfigurationCheck check =
-        Debugger::checkDebugConfiguration(startParameters().toolChainAbi);
+    appendMessage(tr("Launching debugger..."), NormalMessageFormat);
+    Debugger::DebuggerRunControl::start();
+}
+
+bool S60DeviceDebugRunControl::promptToStop(bool *) const
+{
+    // We override the settings prompt
+    return Debugger::DebuggerRunControl::promptToStop(0);
+}
+
+S60DeviceDebugRunControlFactory::S60DeviceDebugRunControlFactory(QObject *parent) :
+    IRunControlFactory(parent)
+{
+}
+
+bool S60DeviceDebugRunControlFactory::canRun(ProjectExplorer::RunConfiguration *runConfiguration, const QString &mode) const
+{
+    return mode == QLatin1String(Debugger::Constants::DEBUGMODE)
+            && qobject_cast<S60DeviceRunConfiguration *>(runConfiguration) != 0;
+}
 
+ProjectExplorer::RunControl* S60DeviceDebugRunControlFactory::create(ProjectExplorer::RunConfiguration *runConfiguration, const QString &mode)
+{
+    S60DeviceRunConfiguration *rc = qobject_cast<S60DeviceRunConfiguration *>(runConfiguration);
+    QTC_ASSERT(rc && mode == QLatin1String(Debugger::Constants::DEBUGMODE), return 0);
+    const Debugger::DebuggerStartParameters startParameters = s60DebuggerStartParams(rc);
+    const Debugger::ConfigurationCheck check = Debugger::checkDebugConfiguration(startParameters);
     if (!check) {
-        appendMessage(check.errorMessage, ErrorMessageFormat);
-        emit finished();
         Core::ICore::instance()->showWarningWithOptions(tr("Debugger for Symbian Platform"),
             check.errorMessage, QString(), check.settingsCategory, check.settingsPage);
-        return;
+        return 0;
     }
+    return new S60DeviceDebugRunControl(rc, startParameters, check.masterSlaveEngineTypes);
+}
 
-    appendMessage(tr("Launching debugger..."), NormalMessageFormat);
-    Debugger::DebuggerRunControl::start();
+QString S60DeviceDebugRunControlFactory::displayName() const
+{
+    return tr("Debug on Device");
 }
 
-bool S60DeviceDebugRunControl::promptToStop(bool *) const
+QWidget *S60DeviceDebugRunControlFactory::createConfigurationWidget(ProjectExplorer::RunConfiguration * /*runConfiguration */)
 {
-    // We override the settings prompt
-    return Debugger::DebuggerRunControl::promptToStop(0);
+    return 0;
 }
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
index 71de1644c0e..4998c1bf633 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -136,11 +136,23 @@ class S60DeviceDebugRunControl : public Debugger::DebuggerRunControl
     Q_OBJECT
 public:
     explicit S60DeviceDebugRunControl(S60DeviceRunConfiguration *runConfiguration,
-                                      const QString &mode);
+                                      const Debugger::DebuggerStartParameters &sp,
+                                      const QPair<Debugger::DebuggerEngineType, Debugger::DebuggerEngineType> &masterSlaveEngineTypes);
     virtual void start();
     virtual bool promptToStop(bool *optionalPrompt = 0) const;
 };
 
+class S60DeviceDebugRunControlFactory : public ProjectExplorer::IRunControlFactory
+{
+public:
+    explicit S60DeviceDebugRunControlFactory(QObject *parent = 0);
+    bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, const QString &mode) const;
+
+    ProjectExplorer::RunControl* create(ProjectExplorer::RunConfiguration *runConfiguration, const QString &mode);
+    QString displayName() const;
+    QWidget *createConfigurationWidget(ProjectExplorer::RunConfiguration * /*runConfiguration */);
+};
+
 } // namespace Internal
 } // namespace Qt4ProjectManager
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
index 2b10720bfdb..0fc522a3a71 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
@@ -131,9 +131,7 @@ S60Manager::S60Manager(QObject *parent)
     addAutoReleasedObject(new S60CreatePackageStepFactory);
     addAutoReleasedObject(new S60DeployStepFactory);
 
-    addAutoReleasedObject(new RunControlFactory<S60DeviceDebugRunControl, S60DeviceRunConfiguration>
-                          (QLatin1String(Debugger::Constants::DEBUGMODE),
-                           tr("Debug on Device"), parent));
+    addAutoReleasedObject(new S60DeviceDebugRunControlFactory);
     addAutoReleasedObject(new Qt4SymbianTargetFactory);
 
     updateQtVersions();
-- 
GitLab