diff --git a/src/plugins/debugger/debugger.pri b/src/plugins/debugger/debugger.pri
new file mode 100644
index 0000000000000000000000000000000000000000..e8ed70aa9e84f46dde4affeedd6b136ad3ee100c
--- /dev/null
+++ b/src/plugins/debugger/debugger.pri
@@ -0,0 +1,3 @@
+include(debugger_dependencies.pri)
+
+LIBS *= -l$$qtLibraryTarget(Debugger)
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
index 9b2846fffaa0b9d16a2405560b5ad38022a261c1..ca17cbfe66ae41add0389a1a4621d1b1af67a2a7 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -43,7 +43,12 @@
 #include <projectexplorer/projectexplorerconstants.h>
 #include <projectexplorer/project.h>
 
+#include <debugger/debuggermanager.h>
+
 #include <QtGui/QRadioButton>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QComboBox>
 
 using namespace ProjectExplorer;
 using namespace Qt4ProjectManager::Internal;
@@ -83,14 +88,19 @@ S60DeviceRunConfiguration::~S60DeviceRunConfiguration()
 
 QString S60DeviceRunConfiguration::type() const
 {
-    return "Qt4ProjectManager.DeviceRunConfiguration";
+    return QLatin1String("Qt4ProjectManager.DeviceRunConfiguration");
+}
+
+ProjectExplorer::ToolChain::ToolChainType S60DeviceRunConfiguration::toolChainType() const
+{
+    if (const Qt4Project *pro = qobject_cast<const Qt4Project*>(project()))
+        return pro->toolChainType(pro->activeBuildConfiguration());
+    return ProjectExplorer::ToolChain::INVALID;
 }
 
 bool S60DeviceRunConfiguration::isEnabled() const
 {
-    Qt4Project *pro = qobject_cast<Qt4Project*>(project());
-    QTC_ASSERT(pro, return false);
-    ToolChain::ToolChainType type = pro->toolChainType(pro->activeBuildConfiguration());
+    const ToolChain::ToolChainType type = toolChainType();
     return type == ToolChain::GCCE || type == ToolChain::RVCT_ARMV5 || type == ToolChain::RVCT_ARMV6;
 }
 
@@ -481,42 +491,14 @@ QSharedPointer<RunConfiguration> S60DeviceRunConfigurationFactory::create(Projec
     return rc;
 }
 
-// ======== S60DeviceRunControlFactory
-
-S60DeviceRunControlFactory::S60DeviceRunControlFactory(QObject *parent)
-    : IRunControlFactory(parent)
-{
-}
-
-bool S60DeviceRunControlFactory::canRun(const QSharedPointer<RunConfiguration> &runConfiguration, const QString &mode) const
-{
-    return (mode == ProjectExplorer::Constants::RUNMODE)
-            && (!runConfiguration.objectCast<S60DeviceRunConfiguration>().isNull());
-}
-
-RunControl* S60DeviceRunControlFactory::create(const QSharedPointer<RunConfiguration> &runConfiguration, const QString &mode)
-{
-    QSharedPointer<S60DeviceRunConfiguration> rc = runConfiguration.objectCast<S60DeviceRunConfiguration>();
-    QTC_ASSERT(!rc.isNull() && mode == ProjectExplorer::Constants::RUNMODE, return 0);
-    return new S60DeviceRunControl(rc);
-}
-
-QString S60DeviceRunControlFactory::displayName() const
-{
-    return tr("Run on Device");
-}
+// ======== S60DeviceRunControlBase
 
-QWidget *S60DeviceRunControlFactory::configurationWidget(const QSharedPointer<ProjectExplorer::RunConfiguration>  & /* runConfiguration */)
-{
-    return 0;
-}
-
-// ======== S60DeviceRunControl
-
-S60DeviceRunControl::S60DeviceRunControl(const QSharedPointer<RunConfiguration> &runConfiguration)
-    : RunControl(runConfiguration), m_launcher(0)
-{
-    m_makesis = new QProcess(this);
+S60DeviceRunControlBase::S60DeviceRunControlBase(const QSharedPointer<RunConfiguration> &runConfiguration) :
+    RunControl(runConfiguration),    
+    m_makesis(new QProcess(this)),
+    m_signsis(new QProcess(this)),
+    m_launcher(0)
+{    
     connect(m_makesis, SIGNAL(readyReadStandardError()),
             this, SLOT(readStandardError()));
     connect(m_makesis, SIGNAL(readyReadStandardOutput()),
@@ -525,7 +507,7 @@ S60DeviceRunControl::S60DeviceRunControl(const QSharedPointer<RunConfiguration>
             this, SLOT(makesisProcessFailed()));
     connect(m_makesis, SIGNAL(finished(int,QProcess::ExitStatus)),
             this, SLOT(makesisProcessFinished()));
-    m_signsis = new QProcess(this);
+
     connect(m_signsis, SIGNAL(readyReadStandardError()),
             this, SLOT(readStandardError()));
     connect(m_signsis, SIGNAL(readyReadStandardOutput()),
@@ -558,7 +540,7 @@ S60DeviceRunControl::S60DeviceRunControl(const QSharedPointer<RunConfiguration>
     m_packageFile = QFileInfo(s60runConfig->packageFileName()).fileName();
 }
 
-void S60DeviceRunControl::start()
+void S60DeviceRunControlBase::start()
 {
     emit started();
 
@@ -571,7 +553,7 @@ void S60DeviceRunControl::start()
     m_makesis->start(m_makesisTool, QStringList(m_packageFile), QIODevice::ReadOnly);
 }
 
-void S60DeviceRunControl::stop()
+void S60DeviceRunControlBase::stop()
 {
     m_makesis->kill();
     m_signsis->kill();
@@ -579,31 +561,31 @@ void S60DeviceRunControl::stop()
         m_launcher->terminate();
 }
 
-bool S60DeviceRunControl::isRunning() const
+bool S60DeviceRunControlBase::isRunning() const
 {
     return m_makesis->state() != QProcess::NotRunning;
 }
 
-void S60DeviceRunControl::readStandardError()
+void S60DeviceRunControlBase::readStandardError()
 {
     QProcess *process = static_cast<QProcess *>(sender());
     QByteArray data = process->readAllStandardError();
     emit addToOutputWindowInline(this, QString::fromLocal8Bit(data.constData(), data.length()));
 }
 
-void S60DeviceRunControl::readStandardOutput()
+void S60DeviceRunControlBase::readStandardOutput()
 {
     QProcess *process = static_cast<QProcess *>(sender());
     QByteArray data = process->readAllStandardOutput();
     emit addToOutputWindowInline(this, QString::fromLocal8Bit(data.constData(), data.length()));
 }
 
-void S60DeviceRunControl::makesisProcessFailed()
+void S60DeviceRunControlBase::makesisProcessFailed()
 {
     processFailed("makesis.exe", m_makesis->error());
 }
 
-void S60DeviceRunControl::makesisProcessFinished()
+void S60DeviceRunControlBase::makesisProcessFinished()
 {
     if (m_makesis->exitCode() != 0) {
         error(this, tr("An error occurred while creating the package."));
@@ -626,12 +608,12 @@ void S60DeviceRunControl::makesisProcessFinished()
     m_signsis->start(signsisTool, arguments, QIODevice::ReadOnly);
 }
 
-void S60DeviceRunControl::signsisProcessFailed()
+void S60DeviceRunControlBase::signsisProcessFailed()
 {
     processFailed("signsis.exe", m_signsis->error());
 }
 
-void S60DeviceRunControl::signsisProcessFinished()
+void S60DeviceRunControlBase::signsisProcessFinished()
 {
     if (m_signsis->exitCode() != 0) {
         error(this, tr("An error occurred while creating the package."));
@@ -639,14 +621,10 @@ void S60DeviceRunControl::signsisProcessFinished()
         return;
     }
     m_launcher = new trk::Launcher;
-    connect(m_launcher, SIGNAL(finished()), this, SLOT(runFinished()));
+    connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
     connect(m_launcher, SIGNAL(copyingStarted()), this, SLOT(printCopyingNotice()));
     connect(m_launcher, SIGNAL(canNotCreateFile(QString,QString)), this, SLOT(printCreateFileFailed(QString,QString)));
     connect(m_launcher, SIGNAL(installingStarted()), this, SLOT(printInstallingNotice()));
-    connect(m_launcher, SIGNAL(startingApplication()), this, SLOT(printStartingNotice()));
-    connect(m_launcher, SIGNAL(applicationRunning(uint)), this, SLOT(printRunNotice(uint)));
-    connect(m_launcher, SIGNAL(canNotRun(QString)), this, SLOT(printRunFailNotice(QString)));
-    connect(m_launcher, SIGNAL(applicationOutputReceived(QString)), this, SLOT(printApplicationOutput(QString)));
     connect(m_launcher, SIGNAL(copyProgress(int)), this, SLOT(printCopyProgress(int)));
 
     //TODO sisx destination and file path user definable
@@ -656,7 +634,7 @@ void S60DeviceRunControl::signsisProcessFinished()
     const QString runFileName = QString("C:\\sys\\bin\\%1.exe").arg(m_targetName);
     m_launcher->setCopyFileName(copySrc, copyDst);
     m_launcher->setInstallFileName(copyDst);
-    m_launcher->setFileName(runFileName);
+    initLauncher(runFileName, m_launcher);
     emit addToOutputWindow(this, tr("Package: %1\nDeploying application to '%2'...").arg(lsFile(copySrc), m_serialPortFriendlyName));
     QString errorMessage;
     if (!m_launcher->startServer(&errorMessage)) {
@@ -668,27 +646,72 @@ void S60DeviceRunControl::signsisProcessFinished()
     }
 }
 
-void S60DeviceRunControl::printCopyingNotice()
+void S60DeviceRunControlBase::printCreateFileFailed(const QString &filename, const QString &errorMessage)
 {
-    emit addToOutputWindow(this, tr("Copying install file..."));
-    emit addToOutputWindow(this, tr("0% copied."));
+    emit addToOutputWindow(this, tr("Could not create file %1 on device: %2").arg(filename, errorMessage));
 }
 
-void S60DeviceRunControl::printCreateFileFailed(const QString &filename, const QString &errorMessage)
+void S60DeviceRunControlBase::printCopyingNotice()
 {
-    emit addToOutputWindow(this, tr("Could not create file %1 on device: %2").arg(filename, errorMessage));
+    emit addToOutputWindow(this, tr("Copying install file..."));
+    emit addToOutputWindow(this, tr("0% copied."));
 }
 
-void S60DeviceRunControl::printCopyProgress(int progress)
+void S60DeviceRunControlBase::printCopyProgress(int progress)
 {
     emit addToOutputWindow(this, tr("%1% copied.").arg(progress));
 }
 
-void S60DeviceRunControl::printInstallingNotice()
+void S60DeviceRunControlBase::printInstallingNotice()
 {
     emit addToOutputWindow(this, tr("Installing application..."));
 }
 
+void S60DeviceRunControlBase::launcherFinished()
+{
+    m_launcher->deleteLater();
+    m_launcher = 0;
+    handleLauncherFinished();
+}
+
+void S60DeviceRunControlBase::processFailed(const QString &program, QProcess::ProcessError errorCode)
+{
+    QString errorString;
+    switch (errorCode) {
+    case QProcess::FailedToStart:
+        errorString = tr("Failed to start %1.");
+        break;
+    case QProcess::Crashed:
+        errorString = tr("%1 has unexpectedly finished.");
+        break;
+    default:
+        errorString = tr("An error has occurred while running %1.");
+    }
+    error(this, errorString.arg(program));
+    emit finished();
+}
+
+// =============== S60DeviceRunControl
+S60DeviceRunControl::S60DeviceRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration) :
+    S60DeviceRunControlBase(runConfiguration)
+{
+}
+
+void S60DeviceRunControl::initLauncher(const QString &executable, trk::Launcher *launcher)
+{
+     connect(launcher, SIGNAL(startingApplication()), this, SLOT(printStartingNotice()));
+     connect(launcher, SIGNAL(applicationRunning(uint)), this, SLOT(printRunNotice(uint)));
+     connect(launcher, SIGNAL(canNotRun(QString)), this, SLOT(printRunFailNotice(QString)));
+     connect(launcher, SIGNAL(applicationOutputReceived(QString)), this, SLOT(printApplicationOutput(QString)));
+     launcher->setFileName(executable);
+}
+
+void S60DeviceRunControl::handleLauncherFinished()
+{
+     emit finished();
+     emit addToOutputWindow(this, tr("Finished."));
+ }
+
 void S60DeviceRunControl::printStartingNotice()
 {
     emit addToOutputWindow(this, tr("Starting application..."));
@@ -708,27 +731,54 @@ void S60DeviceRunControl::printApplicationOutput(const QString &output)
     emit addToOutputWindowInline(this, output);
 }
 
-void S60DeviceRunControl::runFinished()
+// ======== S60DeviceDebugRunControl
+
+S60DeviceDebugRunControl::S60DeviceDebugRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration) :
+    S60DeviceRunControlBase(runConfiguration),
+    m_startParams(new Debugger::DebuggerStartParameters)
 {
-    m_launcher->deleteLater();
-    m_launcher = 0;
-    emit addToOutputWindow(this, tr("Finished."));
-    emit finished();
+    Debugger::DebuggerManager *dm = Debugger::DebuggerManager::instance();
+    const QSharedPointer<S60DeviceRunConfiguration> rc = runConfiguration.objectCast<S60DeviceRunConfiguration>();
+    QTC_ASSERT(dm && !rc.isNull(), return);
+
+    connect(dm, SIGNAL(debuggingFinished()),
+            this, SLOT(debuggingFinished()), Qt::QueuedConnection);
+    connect(dm, SIGNAL(applicationOutputAvailable(QString)),
+            this, SLOT(slotAddToOutputWindow(QString)),
+            Qt::QueuedConnection);
+
+    m_startParams->remoteChannel = rc->serialPortName();
+    m_startParams->startMode = Debugger::StartInternal;
+    m_startParams->toolChainType = rc->toolChainType();
 }
 
-void S60DeviceRunControl::processFailed(const QString &program, QProcess::ProcessError errorCode)
+void S60DeviceDebugRunControl::stop()
 {
-    QString errorString;
-    switch (errorCode) {
-    case QProcess::FailedToStart:
-        errorString = tr("Failed to start %1.");
-        break;
-    case QProcess::Crashed:
-        errorString = tr("%1 has unexpectedly finished.");
-        break;
-    default:
-        errorString = tr("An error has occurred while running %1.");
-    }
-    error(this, errorString.arg(program));
+    S60DeviceRunControlBase::stop();
+    Debugger::DebuggerManager *dm = Debugger::DebuggerManager::instance();
+    QTC_ASSERT(dm, return)
+    if (dm->state() == Debugger::DebuggerNotReady)
+        dm->exitDebugger();
+}
+
+S60DeviceDebugRunControl::~S60DeviceDebugRunControl()
+{
+}
+
+void S60DeviceDebugRunControl::initLauncher(const QString &executable, trk::Launcher *)
+{
+    // No setting an executable on the launcher causes it to deploy only
+    m_startParams->executable = executable;
+}
+
+void S60DeviceDebugRunControl::handleLauncherFinished()
+{
+    emit addToOutputWindow(this, tr("Launching debugger..."));
+    Debugger::DebuggerManager::instance()->startNewDebugger(m_startParams);
+}
+
+void S60DeviceDebugRunControl::debuggingFinished()
+{
+    emit addToOutputWindow(this, tr("Debugging finished."));
     emit finished();
 }
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
index 48cafb8c7f1faaf9e86ecf67c7235094b7f39284..c2da9c6240733dd4ae9d91b4b2da3e3d3e733fc1 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -33,12 +33,21 @@
 #include "launcher.h"
 
 #include <projectexplorer/runconfiguration.h>
+#include <projectexplorer/toolchain.h>
 
-#include <QtCore/QProcess>
 #include <QtGui/QWidget>
-#include <QtGui/QLabel>
-#include <QtGui/QLineEdit>
-#include <QtGui/QComboBox>
+
+#include <QtCore/QProcess>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+class QLineEdit;
+class QComboBox;
+QT_END_NAMESPACE
+
+namespace Debugger {
+    class DebuggerStartParameters;
+}
 
 namespace Qt4ProjectManager {
 namespace Internal {
@@ -75,6 +84,8 @@ public:
     QString packageFileName() const;
     QString executableFileName() const;
 
+    ProjectExplorer::ToolChain::ToolChainType toolChainType() const;
+
 signals:
     void targetInformationChanged();
 
@@ -131,26 +142,23 @@ public:
     QSharedPointer<ProjectExplorer::RunConfiguration> create(ProjectExplorer::Project *project, const QString &type);
 };
 
-class S60DeviceRunControlFactory : public ProjectExplorer::IRunControlFactory
-{
-    Q_OBJECT
-public:
-    explicit S60DeviceRunControlFactory(QObject *parent = 0);
-    bool canRun(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, const QString &mode) const;
-    ProjectExplorer::RunControl* create(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, const QString &mode);
-    QString displayName() const;
-    QWidget *configurationWidget(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration);
-};
+/* S60DeviceRunControlBase: Builds and signs package and starts launcher
+ * to deploy. Subclasses can configure the launcher to run or start a debugger. */
 
-class S60DeviceRunControl : public ProjectExplorer::RunControl
+class S60DeviceRunControlBase : public ProjectExplorer::RunControl
 {
     Q_OBJECT
 public:
-    explicit S60DeviceRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration);
-    ~S60DeviceRunControl() {}
-    void start();
-    void stop();
-    bool isRunning() const;
+    explicit S60DeviceRunControlBase(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration);
+    ~S60DeviceRunControlBase() {}
+    virtual void start();
+    virtual void stop();
+    virtual bool isRunning() const;
+
+protected:
+    virtual void initLauncher(const QString &executable, trk::Launcher *) = 0;
+    virtual void handleLauncherFinished() = 0;
+    void processFailed(const QString &program, QProcess::ProcessError errorCode);
 
 private slots:
     void readStandardError();
@@ -163,15 +171,9 @@ private slots:
     void printCreateFileFailed(const QString &filename, const QString &errorMessage);
     void printCopyProgress(int progress);
     void printInstallingNotice();
-    void printStartingNotice();
-    void printRunNotice(uint pid);
-    void printRunFailNotice(const QString &errorMessage);
-    void printApplicationOutput(const QString &output);
-    void runFinished();
+    void launcherFinished();
 
 private:
-    void processFailed(const QString &program, QProcess::ProcessError errorCode);
-
     QString m_serialPortName;
     QString m_serialPortFriendlyName;
     QString m_targetName;
@@ -191,6 +193,46 @@ private:
     trk::Launcher *m_launcher;
 };
 
+// Configure launcher to run the application
+class S60DeviceRunControl : public S60DeviceRunControlBase
+{
+    Q_OBJECT
+public:
+    explicit S60DeviceRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration);
+
+protected:
+    virtual void initLauncher(const QString &executable, trk::Launcher *);
+    virtual void handleLauncherFinished();
+
+private slots:
+    void printStartingNotice();
+    void printRunNotice(uint pid);
+    void printRunFailNotice(const QString &errorMessage);
+    void printApplicationOutput(const QString &output);
+
+private:
+};
+
+class S60DeviceDebugRunControl : public S60DeviceRunControlBase
+{
+    Q_DISABLE_COPY(S60DeviceDebugRunControl)
+    Q_OBJECT
+public:
+    explicit S60DeviceDebugRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration);
+    virtual ~S60DeviceDebugRunControl();
+
+    virtual void stop();
+
+protected:
+    virtual void initLauncher(const QString &executable, trk::Launcher *);
+    virtual void handleLauncherFinished();
+
+private slots:
+    void debuggingFinished();
+private:
+    QSharedPointer<Debugger::DebuggerStartParameters> m_startParams;
+};
+
 } // namespace Internal
 } // namespace Qt4ProjectManager
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
index bd53d834dc6195670756f3ffc8c9d4411f08989f..c17daed13d91e447d996e7388f94311cd78eef74 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
@@ -254,36 +254,6 @@ QSharedPointer<RunConfiguration> S60EmulatorRunConfigurationFactory::create(Proj
     return rc;
 }
 
-// ======== S60EmulatorRunControlFactory
-
-S60EmulatorRunControlFactory::S60EmulatorRunControlFactory(QObject *parent)
-    : IRunControlFactory(parent)
-{
-}
-
-bool S60EmulatorRunControlFactory::canRun(const QSharedPointer<RunConfiguration> &runConfiguration, const QString &mode) const
-{
-    return (mode == ProjectExplorer::Constants::RUNMODE)
-            && (!runConfiguration.objectCast<S60EmulatorRunConfiguration>().isNull());
-}
-
-RunControl* S60EmulatorRunControlFactory::create(const QSharedPointer<RunConfiguration> &runConfiguration, const QString &mode)
-{
-    QSharedPointer<S60EmulatorRunConfiguration> rc = runConfiguration.objectCast<S60EmulatorRunConfiguration>();
-    QTC_ASSERT(!rc.isNull() && mode == ProjectExplorer::Constants::RUNMODE, return 0);
-    return new S60EmulatorRunControl(rc);
-}
-
-QString S60EmulatorRunControlFactory::displayName() const
-{
-    return tr("Run in Emulator");
-}
-
-QWidget *S60EmulatorRunControlFactory::configurationWidget(const QSharedPointer<ProjectExplorer::RunConfiguration> & /* runConfiguration */)
-{
-    return 0;
-}
-
 // ======== S60EmulatorRunControl
 
 S60EmulatorRunControl::S60EmulatorRunControl(const QSharedPointer<RunConfiguration> &runConfiguration)
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
index 30b7d31303e7f0658aba38b351d64f3cd70be349..1682478d95a234789994d7574b9eb56a9db35be9 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.h
@@ -99,17 +99,6 @@ public:
     QSharedPointer<ProjectExplorer::RunConfiguration> create(ProjectExplorer::Project *project, const QString &type);
 };
 
-class S60EmulatorRunControlFactory : public ProjectExplorer::IRunControlFactory
-{
-    Q_OBJECT
-public:
-    explicit S60EmulatorRunControlFactory(QObject *parent = 0);
-    bool canRun(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, const QString &mode) const;
-    ProjectExplorer::RunControl* create(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, const QString &mode);
-    QString displayName() const;
-    QWidget *configurationWidget(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration);
-};
-
 class S60EmulatorRunControl : public ProjectExplorer::RunControl
 {
     Q_OBJECT
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
index 06198963bd02c3f637f6806da71a715c06062350..bb1f6027574ea4458c7c3a528bfea60bafd859da 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
@@ -39,10 +39,14 @@
 
 #include <coreplugin/icore.h>
 #include <extensionsystem/pluginmanager.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <debugger/debuggermanager.h>
+#include <utils/qtcassert.h>
 
 #include <QtGui/QMainWindow>
 
-using namespace Qt4ProjectManager::Internal;
+namespace Qt4ProjectManager {
+namespace Internal {
 
 S60Manager *S60Manager::m_instance = 0;
 
@@ -50,30 +54,72 @@ namespace {
 static const char *S60_AUTODETECTION_SOURCE = "QTS60";
 }
 
+// ======== Parametrizable Factory for RunControls, depending on the configuration
+// class and mode.
+
+template <class RunControl, class RunConfiguration>
+        class RunControlFactory : public ProjectExplorer::IRunControlFactory
+{
+public:
+    explicit RunControlFactory(const QString &mode,
+                               const QString &name,
+                               QObject *parent = 0) :
+    IRunControlFactory(parent), m_mode(mode), m_name(name) {}
+
+    bool canRun(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, const QString &mode) const {
+        return (mode == m_mode)
+                && (!runConfiguration.objectCast<RunConfiguration>().isNull());
+    }
+
+    ProjectExplorer::RunControl* create(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration, const QString &mode) {
+        const QSharedPointer<RunConfiguration> rc = runConfiguration.objectCast<RunConfiguration>();
+        QTC_ASSERT(!rc.isNull() && mode == m_mode, return 0);
+        return new RunControl(rc);
+    }
+
+    QString displayName() const {
+        return m_name;
+    }
+
+    QWidget *configurationWidget(const QSharedPointer<ProjectExplorer::RunConfiguration> & /*runConfiguration */) {
+        return 0;
+    }
+
+private:
+    const QString m_mode;
+    const QString m_name;
+};
+
+// ======== S60Manager
+
 S60Manager *S60Manager::instance() { return m_instance; }
 
 S60Manager::S60Manager(QObject *parent)
         : QObject(parent),
         m_devices(new S60Devices(this)),
-        m_devicesPreferencePane(new S60DevicesPreferencePane(m_devices, this)),
-        m_s60EmulatorRunConfigurationFactory(new S60EmulatorRunConfigurationFactory(this)),
-        m_s60EmulatorRunConfigurationRunner(new S60EmulatorRunControlFactory(this)),
-        m_s60DeviceRunConfigurationFactory(new S60DeviceRunConfigurationFactory(this)),
-        m_s60DeviceRunConfigurationRunner(new S60DeviceRunControlFactory(this)),
         m_serialDeviceLister(new SerialDeviceLister(this))
 {
     m_instance = this;
-    m_devices->detectQtForDevices();
-    ExtensionSystem::PluginManager::instance()
-            ->addObject(m_devicesPreferencePane);
-    ExtensionSystem::PluginManager::instance()
-            ->addObject(m_s60EmulatorRunConfigurationFactory);
-    ExtensionSystem::PluginManager::instance()
-            ->addObject(m_s60EmulatorRunConfigurationRunner);
-    ExtensionSystem::PluginManager::instance()
-            ->addObject(m_s60DeviceRunConfigurationFactory);
-    ExtensionSystem::PluginManager::instance()
-            ->addObject(m_s60DeviceRunConfigurationRunner);
+ 
+    addAutoReleasedObject(new S60DevicesPreferencePane(m_devices, this));
+    m_devices->detectQtForDevices(); // Order!
+  
+    addAutoReleasedObject(new S60EmulatorRunConfigurationFactory(this));
+    addAutoReleasedObject(new RunControlFactory<S60EmulatorRunControl,
+                                                S60EmulatorRunConfiguration>
+                                                (QLatin1String(ProjectExplorer::Constants::RUNMODE),
+                                                 tr("Run in Emulator"), parent));
+    addAutoReleasedObject(new S60DeviceRunConfigurationFactory(this));
+    addAutoReleasedObject(new RunControlFactory<S60DeviceRunControl,
+                                                S60DeviceRunConfiguration>
+                                                (QLatin1String(ProjectExplorer::Constants::RUNMODE),
+                                                 tr("Run on Device"), parent));
+
+    if (Debugger::DebuggerManager::instance())
+        addAutoReleasedObject(new RunControlFactory<S60DeviceDebugRunControl,
+                                                S60DeviceRunConfiguration>
+                                                (QLatin1String(ProjectExplorer::Constants::DEBUGMODE),
+                                                 tr("Debug on Device"), parent));
     updateQtVersions();
     connect(m_devices, SIGNAL(qtVersionsChanged()),
             this, SLOT(updateQtVersions()));
@@ -83,23 +129,22 @@ S60Manager::S60Manager(QObject *parent)
 
 S60Manager::~S60Manager()
 {
-    ExtensionSystem::PluginManager::instance()
-            ->removeObject(m_s60DeviceRunConfigurationRunner);
-    ExtensionSystem::PluginManager::instance()
-            ->removeObject(m_s60DeviceRunConfigurationFactory);
-    ExtensionSystem::PluginManager::instance()
-            ->removeObject(m_s60EmulatorRunConfigurationRunner);
-    ExtensionSystem::PluginManager::instance()
-            ->removeObject(m_s60EmulatorRunConfigurationFactory);
-    ExtensionSystem::PluginManager::instance()
-            ->removeObject(m_devicesPreferencePane);
+    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
+    for (int i = m_pluginObjects.size() - 1; i >= 0; i--)
+        pm->removeObject(m_pluginObjects.at(i));
+}
+
+void S60Manager::addAutoReleasedObject(QObject *o)
+{
+    ExtensionSystem::PluginManager::instance()->addObject(o);
+    m_pluginObjects.push_back(o);
 }
 
 QString S60Manager::deviceIdFromDetectionSource(const QString &autoDetectionSource) const
 {
     if (autoDetectionSource.startsWith(S60_AUTODETECTION_SOURCE))
         return autoDetectionSource.mid(QString(S60_AUTODETECTION_SOURCE).length()+1);
-    return "";
+    return QString();
 }
 
 void S60Manager::updateQtVersions()
@@ -185,3 +230,6 @@ S60Devices::Device S60Manager::deviceForQtVersion(const Qt4ProjectManager::QtVer
     }
     return device;
 }
+
+}
+}
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.h b/src/plugins/qt4projectmanager/qt-s60/s60manager.h
index 3853a5cdf6211645a3fd2b650846f47156f8f5c8..08c0be623d58f1a136468c0ec228cbf75259a8ac 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60manager.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.h
@@ -42,12 +42,6 @@
 namespace Qt4ProjectManager {
 namespace Internal {
 
-class S60DevicesPreferencePane;
-class S60EmulatorRunConfigurationFactory;
-class S60EmulatorRunControlFactory;
-class S60DeviceRunConfigurationFactory;
-class S60DeviceRunControlFactory;
-
 class S60Manager : public QObject
 {
     Q_OBJECT
@@ -71,13 +65,12 @@ private slots:
     void updateQtVersions();
 
 private:
+    void addAutoReleasedObject(QObject *p);
+
     static S60Manager *m_instance;
+
     S60Devices *m_devices;
-    S60DevicesPreferencePane *m_devicesPreferencePane;
-    S60EmulatorRunConfigurationFactory *m_s60EmulatorRunConfigurationFactory;
-    S60EmulatorRunControlFactory *m_s60EmulatorRunConfigurationRunner;
-    S60DeviceRunConfigurationFactory *m_s60DeviceRunConfigurationFactory;
-    S60DeviceRunControlFactory *m_s60DeviceRunConfigurationRunner;
+    QObjectList m_pluginObjects;
     SerialDeviceLister *m_serialDeviceLister;
 };
 
diff --git a/src/plugins/qt4projectmanager/qt4projectmanager_dependencies.pri b/src/plugins/qt4projectmanager/qt4projectmanager_dependencies.pri
index 9a493156ad5a2d69369b1f77fa1f3c33dd960d9b..59284cb3d25951ca634e6a961b1970d65760663c 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanager_dependencies.pri
+++ b/src/plugins/qt4projectmanager/qt4projectmanager_dependencies.pri
@@ -3,3 +3,4 @@ include(../../plugins/cpptools/cpptools.pri)
 include(../../plugins/cppeditor/cppeditor.pri)
 include(../../plugins/help/help.pri)
 include(../../plugins/designer/designer.pri)
+include(../../plugins/debugger/debugger.pri)
diff --git a/src/shared/trk/launcher.cpp b/src/shared/trk/launcher.cpp
index e74318ad93554aefb4279a2b15ac568a9918e555..36272bf14325f16800e3fdc9bc034afd7fa1c2a6 100644
--- a/src/shared/trk/launcher.cpp
+++ b/src/shared/trk/launcher.cpp
@@ -497,7 +497,11 @@ void Launcher::installRemotePackageSilently(const QString &fileName)
 
 void Launcher::handleInstallPackageFinished(const TrkResult &)
 {
-    startInferiorIfNeeded();
+    if (d->m_fileName.isEmpty()) {
+        emit finished();
+    } else {
+        startInferiorIfNeeded();
+    }
 }
 
 void Launcher::startInferiorIfNeeded()
diff --git a/tests/manual/trklauncher/main.cpp b/tests/manual/trklauncher/main.cpp
index 372a2d87b40e23c191db5699d1b7f05ea7977a14..b888e6bf25fc0029e8a29ae43fb5eff6bdc87e7b 100644
--- a/tests/manual/trklauncher/main.cpp
+++ b/tests/manual/trklauncher/main.cpp
@@ -5,15 +5,19 @@
 #include <QtCore/QStringList>
 
 static const char *usageC =
-"\nUsage: %1 <trk_port_name> [-v] [-i remote_sis_file | -I local_sis_file remote_sis_file] <remote_executable_name>\n"
+"\nUsage: %1 <trk_port_name> [-v] [-i remote_sis_file | -I local_sis_file remote_sis_file] [<remote_executable_name>]\n"
 "\nOptions:\n    -v verbose\n"
             "    -f turn serial message frame off\n\n"
 "\nPing:\n"
 "%1 COM5\n"
 "\nRemote launch:\n"
 "%1 COM5 C:\\sys\\bin\\test.exe\n"
+"\nInstallation:\n"
+"%1 -i COM5 C:\\Data\\test_gcce_udeb.sisx\n"
 "\nInstallation and remote launch:\n"
 "%1 -i COM5 C:\\Data\\test_gcce_udeb.sisx C:\\sys\\bin\\test.exe\n"
+"\nCopy from local file, installation:\n"
+"%1 -I COM5 C:\\Projects\\test\\test_gcce_udeb.sisx C:\\Data\\test_gcce_udeb.sisx\n"
 "\nCopy from local file, installation and remote launch:\n"
 "%1 -I COM5 C:\\Projects\\test\\test_gcce_udeb.sisx C:\\Data\\test_gcce_udeb.sisx C:\\sys\\bin\\test.exe\n";
 
@@ -68,17 +72,19 @@ static bool parseArguments(const QStringList &arguments, trk::Launcher &launcher
         launcher.setFileName(arguments.at(a + 1));
         return true;
     }
-    if (remainingArgsCount == 3 && install && !customInstall) {
+    if ((remainingArgsCount == 3 || remainingArgsCount == 2) && install && !customInstall) {
         launcher.setTrkServerName(arguments.at(a)); // ping
         launcher.setInstallFileName(arguments.at(a + 1));
-        launcher.setFileName(arguments.at(a + 2));
+        if (remainingArgsCount == 3)
+            launcher.setFileName(arguments.at(a + 2));
         return true;
     }
-    if (remainingArgsCount == 4 && !install && customInstall) {
+    if ((remainingArgsCount == 4 || remainingArgsCount == 3) && !install && customInstall) {
         launcher.setTrkServerName(arguments.at(a)); // ping
         launcher.setCopyFileName(arguments.at(a + 1), arguments.at(a + 2));
         launcher.setInstallFileName(arguments.at(a + 2));
-        launcher.setFileName(arguments.at(a + 3));
+        if (remainingArgsCount == 4)
+            launcher.setFileName(arguments.at(a + 3));
         return true;
     }
     return false;