diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
index b4f6dd6e547d9e7f26fcf2425db73376456e4cab..a32a0ba30e7d049d8ed92926a05e2bb2e2202c2e 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
@@ -31,6 +31,7 @@
 
 #include "maemodeviceconfigurations.h"
 #include "maemomanager.h"
+#include "maemoruncontrol.h"
 #include "maemosettingspage.h"
 #include "maemosshthread.h"
 #include "maemotoolchain.h"
@@ -38,10 +39,8 @@
 #include "qt4project.h"
 #include "qt4buildconfiguration.h"
 
-#include <coreplugin/progressmanager/progressmanager.h>
 #include <coreplugin/icore.h>
 #include <coreplugin/messagemanager.h>
-#include <debugger/debuggermanager.h>
 #include <extensionsystem/pluginmanager.h>
 #include <utils/pathchooser.h>
 #include <utils/qtcassert.h>
@@ -50,12 +49,9 @@
 #include <projectexplorer/session.h>
 
 #include <QtCore/QDebug>
-#include <QtCore/QFuture>
 #include <QtCore/QPair>
 #include <QtCore/QProcess>
-#include <QtCore/QScopedPointer>
 #include <QtCore/QSharedPointer>
-#include <QtCore/QStringBuilder>
 
 #include <QtGui/QComboBox>
 #include <QtGui/QCheckBox>
@@ -103,139 +99,6 @@ private:
     MaemoRunConfiguration *m_runConfiguration;
 };
 
-class AbstractMaemoRunControl : public ProjectExplorer::RunControl
-{
-    Q_OBJECT
-
-public:
-    AbstractMaemoRunControl(RunConfiguration *runConfig);
-    virtual ~AbstractMaemoRunControl() {}
-
-protected:
-    void startDeployment(bool forDebugging);
-    void deploy();
-    void stopDeployment();
-    bool isDeploying() const;
-    const QString executableOnHost() const;
-    const QString executableOnTarget() const;
-    const QString executableFileName() const;
-    const QString port() const;
-    const QString targetCmdLinePrefix() const;
-    const QString remoteDir() const;
-    const QStringList options() const;
-#ifndef USE_SSH_LIB
-    void deploymentFinished(bool success);
-    virtual bool setProcessEnvironment(QProcess &process);
-#endif // USE_SSH_LIB
-private slots:
-#ifndef USE_SSH_LIB
-    void readStandardError();
-    void readStandardOutput();
-#endif // USE_SSH_LIB
-    void deployProcessFinished();
-#ifdef USE_SSH_LIB
-    void handleFileCopied();
-#endif
-
-protected:
-    ErrorDumper dumper;
-    MaemoRunConfiguration *runConfig; // TODO this pointer can be invalid
-    const MaemoDeviceConfig devConfig;
-
-private:
-    virtual void handleDeploymentFinished(bool success)=0;
-
-    QFutureInterface<void> m_progress;
-#ifdef USE_SSH_LIB
-    QScopedPointer<MaemoSshDeployer> sshDeployer;
-#else
-    QProcess deployProcess;
-#endif // USE_SSH_LIB
-    struct Deployable
-    {
-        typedef void (MaemoRunConfiguration::*updateFunc)();
-        Deployable(const QString &f, const QString &d, updateFunc u)
-            : fileName(f), dir(d), updateTimestamp(u) {}
-        QString fileName;
-        QString dir;
-        updateFunc updateTimestamp;
-    };
-    QList<Deployable> deployables;
-};
-
-class MaemoRunControl : public AbstractMaemoRunControl
-{
-    Q_OBJECT
-public:
-    MaemoRunControl(RunConfiguration *runConfiguration);
-    ~MaemoRunControl();
-    void start();
-    void stop();
-    bool isRunning() const;
-
-private slots:
-    void executionFinished();
-#ifdef USE_SSH_LIB
-    void handleRemoteOutput(const QString &output);
-#endif
-
-private:
-    virtual void handleDeploymentFinished(bool success);    
-    void startExecution();
-
-#ifdef USE_SSH_LIB
-    QScopedPointer<MaemoSshRunner> sshRunner;
-    QScopedPointer<MaemoSshRunner> sshStopper;
-#else
-    QProcess sshProcess;
-    QProcess stopProcess;
-#endif // USE_SSH_LIB
-    bool stoppedByUser;
-};
-
-class MaemoDebugRunControl : public AbstractMaemoRunControl
-{
-    Q_OBJECT
-public:
-    MaemoDebugRunControl(RunConfiguration *runConfiguration);
-    ~MaemoDebugRunControl();
-    void start();
-    void stop();
-    bool isRunning() const;
-    Q_SLOT void debuggingFinished();
-
-signals:
-    void stopRequested();
-
-private slots:
-#ifdef USE_SSH_LIB
-    void gdbServerStarted(const QString &output);
-#else
-    void gdbServerStarted();
-#endif // USE_SSH_LIB
-
-    void debuggerOutput(const QString &output);
-
-private:
-    virtual void handleDeploymentFinished(bool success);
-
-    void startGdbServer();
-    void gdbServerStartFailed(const QString &reason);
-    void startDebugging();
-
-#ifdef USE_SSH_LIB
-    QScopedPointer<MaemoSshRunner> sshRunner;
-    QScopedPointer<MaemoSshRunner> sshStopper;
-#else
-    QProcess gdbServer;
-    QProcess stopProcess;
-#endif // USE_SSH_LIB
-    const QString gdbServerPort;
-    Debugger::DebuggerManager *debuggerManager;
-    QSharedPointer<Debugger::DebuggerStartParameters> startParams;
-    int inferiorPid;
-};
-
 void ErrorDumper::printToStream(QProcess::ProcessError error)
 {
     QString reason;
@@ -1016,611 +879,4 @@ QWidget* MaemoRunControlFactory::configurationWidget(RunConfiguration *config)
 
 // #pragma mark -- AbstractMaemoRunControl
 
-
-AbstractMaemoRunControl::AbstractMaemoRunControl(RunConfiguration *rc)
-    : RunControl(rc)
-    , runConfig(qobject_cast<MaemoRunConfiguration *>(rc))
-    , devConfig(runConfig ? runConfig->deviceConfig() : MaemoDeviceConfig())
-{
-#ifndef USE_SSH_LIB
-    setProcessEnvironment(deployProcess);
-    connect(&deployProcess, SIGNAL(readyReadStandardError()), this,
-        SLOT(readStandardError()));
-    connect(&deployProcess, SIGNAL(readyReadStandardOutput()), this,
-        SLOT(readStandardOutput()));
-    connect(&deployProcess, SIGNAL(error(QProcess::ProcessError)), &dumper,
-        SLOT(printToStream(QProcess::ProcessError)));
-    connect(&deployProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this,
-        SLOT(deployProcessFinished()));
-#endif // USE_SSH_LIB
-}
-
-void AbstractMaemoRunControl::startDeployment(bool forDebugging)
-{
-    QTC_ASSERT(runConfig, return);
-
-#ifndef USE_SSH_LIB
-    Core::ICore::instance()->progressManager()->addTask(m_progress.future(),
-        tr("Deploying"), QLatin1String("Maemo.Deploy"));
-#endif // USE_SSH_LIB
-    if (devConfig.isValid()) {
-        deployables.clear();
-        if (runConfig->currentlyNeedsDeployment()) {
-            deployables.append(Deployable(executableFileName(),
-                QFileInfo(executableOnHost()).canonicalPath(),
-                &MaemoRunConfiguration::wasDeployed));
-        }
-        if (forDebugging && runConfig->debuggingHelpersNeedDeployment()) {
-            const QFileInfo &info(runConfig->dumperLib());
-            deployables.append(Deployable(info.fileName(), info.canonicalPath(),
-                &MaemoRunConfiguration::debuggingHelpersDeployed));
-        }
-
-#ifndef USE_SSH_LIB
-        m_progress.setProgressRange(0, deployables.count());
-        m_progress.setProgressValue(0);
-        m_progress.reportStarted();
-#endif // USE_SSH_LIB
-        deploy();
-    } else {
-#ifdef USE_SSH_LIB
-        handleDeploymentFinished(false);
-#else
-        deploymentFinished(false);
-#endif // USE_SSH_LIB
-    }
-}
-
-void AbstractMaemoRunControl::deploy()
-{
-#ifdef USE_SSH_LIB
-    if (!deployables.isEmpty()) {
-        QStringList files;
-        QStringList targetDirs;
-        foreach (const Deployable &deployable, deployables) {
-            files << deployable.dir + QDir::separator() + deployable.fileName;
-            targetDirs << remoteDir();
-        }
-        emit addToOutputWindow(this, tr("Files to deploy: %1.").arg(files.join(" ")));
-        sshDeployer.reset(new MaemoSshDeployer(devConfig, files, targetDirs));
-        connect(sshDeployer.data(), SIGNAL(finished()),
-                this, SLOT(deployProcessFinished()));
-        connect(sshDeployer.data(), SIGNAL(fileCopied(QString)),
-                this, SLOT(handleFileCopied()));
-        Core::ICore::instance()->progressManager()
-                ->addTask(m_progress.future(), tr("Deploying"),
-                          QLatin1String("Maemo.Deploy"));
-        m_progress.setProgressRange(0, deployables.count());
-        m_progress.setProgressValue(0);
-        m_progress.reportStarted();
-        emit started();
-        sshDeployer->start();
-    } else {
-        handleDeploymentFinished(true);
-    }
-#else
-    if (!deployables.isEmpty()) {
-        const Deployable &deployable = deployables.first();
-        emit addToOutputWindow(this, tr("File to deploy: %1.").arg(deployable.fileName));
-
-        QStringList cmdArgs;
-        cmdArgs << "-P" << port() << options() << deployable.fileName
-            << (devConfig.uname + "@" + devConfig.host + ":" + remoteDir());
-        deployProcess.setWorkingDirectory(deployable.dir);
-
-        deployProcess.start(runConfig->scpCmd(), cmdArgs);
-        if (!deployProcess.waitForStarted()) {
-            emit error(this, tr("Could not start scp. Deployment failed."));
-            deployProcess.kill();
-        } else {
-            emit started();
-        }
-    } else {
-        deploymentFinished(true);
-    }
-#endif // USE_SSH_LIB
-}
-
-#ifdef USE_SSH_LIB
-void AbstractMaemoRunControl::handleFileCopied()
-{
-    Deployable deployable = deployables.takeFirst();
-    (runConfig->*deployable.updateTimestamp)();
-    m_progress.setProgressValue(m_progress.progressValue() + 1);
-}
-#endif // USE_SSH_LIB
-
-void AbstractMaemoRunControl::stopDeployment()
-{
-#ifdef USE_SSH_LIB
-    sshDeployer->stop();
-#else
-    deployProcess.kill();
-#endif // USE_SSH_LIB
-}
-
-bool AbstractMaemoRunControl::isDeploying() const
-{
-#ifdef USE_SSH_LIB
-    return !sshDeployer.isNull() && sshDeployer->isRunning();
-#else
-    return deployProcess.state() != QProcess::NotRunning;
-#endif // USE_SSH_LIB
-}
-
-void AbstractMaemoRunControl::deployProcessFinished()
-{
-#if USE_SSH_LIB
-    const bool success = !sshDeployer->hasError();
-    if (success) {
-        emit addToOutputWindow(this, tr("Deployment finished."));
-    } else {
-        emit error(this, tr("Deployment failed: ") % sshDeployer->error());
-        m_progress.reportCanceled();
-    }
-    m_progress.reportFinished();
-    handleDeploymentFinished(success);
-#else
-    bool success;
-    if (deployProcess.exitCode() == 0) {
-        emit addToOutputWindow(this, tr("Target deployed."));
-        success = true;
-        Deployable deployable = deployables.takeFirst();
-        (runConfig->*deployable.updateTimestamp)();
-        m_progress.setProgressValue(m_progress.progressValue() + 1);
-    } else {
-        emit error(this, tr("Deployment failed."));
-        success = false;
-    }
-    if (deployables.isEmpty() || !success)
-        deploymentFinished(success);
-    else
-        deploy();
-#endif // USE_SSH_LIB
-}
-
-#ifndef USE_SSH_LIB
-void AbstractMaemoRunControl::deploymentFinished(bool success)
-{
-    m_progress.reportFinished();
-    handleDeploymentFinished(success);
-}
-#endif // USE_SSH_LIB
-
-const QString AbstractMaemoRunControl::executableOnHost() const
-{
-    return runConfig->executable();
-}
-
-const QString AbstractMaemoRunControl::port() const
-{
-    return QString::number(devConfig.port);
-}
-
-const QString AbstractMaemoRunControl::executableFileName() const
-{
-    return QFileInfo(executableOnHost()).fileName();
-}
-
-const QString AbstractMaemoRunControl::remoteDir() const
-{
-    return devConfig.uname == QString::fromLocal8Bit("root")
-        ? QString::fromLocal8Bit("/root")
-        : QString::fromLocal8Bit("/home/") + devConfig.uname;
-}
-
-const QStringList AbstractMaemoRunControl::options() const
-{
-    const bool usePassword
-        = devConfig.authentication == MaemoDeviceConfig::Password;
-    const QLatin1String opt("-o");
-    QStringList optionList;
-    if (!usePassword)
-        optionList << QLatin1String("-i") << devConfig.keyFile;
-    return optionList << opt
-        << QString::fromLatin1("PasswordAuthentication=%1").
-            arg(usePassword ? "yes" : "no") << opt
-        << QString::fromLatin1("PubkeyAuthentication=%1").
-            arg(usePassword ? "no" : "yes") << opt
-        << QString::fromLatin1("ConnectTimeout=%1").arg(devConfig.timeout)
-        << opt << QLatin1String("CheckHostIP=no")
-        << opt << QLatin1String("StrictHostKeyChecking=no");
-}
-
-const QString AbstractMaemoRunControl::executableOnTarget() const
-{
-    return QString::fromLocal8Bit("%1/%2").arg(remoteDir()).
-        arg(executableFileName());
-}
-
-const QString AbstractMaemoRunControl::targetCmdLinePrefix() const
-{
-    return QString::fromLocal8Bit("chmod u+x %1; source /etc/profile; ").
-        arg(executableOnTarget());
-}
-
-#ifndef USE_SSH_LIB
-bool AbstractMaemoRunControl::setProcessEnvironment(QProcess &process)
-{
-    QTC_ASSERT(runConfig, return false);
-    Qt4BuildConfiguration *qt4bc = qobject_cast<Qt4BuildConfiguration*>
-        (runConfig->project()->activeBuildConfiguration());
-    QTC_ASSERT(qt4bc, return false);
-    Environment env = Environment::systemEnvironment();
-    qt4bc->toolChain()->addToEnvironment(env);
-    process.setEnvironment(env.toStringList());
-
-    return true;
-}
-
-void AbstractMaemoRunControl::readStandardError()
-{
-    QProcess *process = static_cast<QProcess *>(sender());
-    const QByteArray &data = process->readAllStandardError();
-    emit addToOutputWindow(this, QString::fromLocal8Bit(data.constData(),
-        data.length()));
-}
-
-void AbstractMaemoRunControl::readStandardOutput()
-{
-    QProcess *process = static_cast<QProcess *>(sender());
-    const QByteArray &data = process->readAllStandardOutput();
-    emit addToOutputWindow(this, QString::fromLocal8Bit(data.constData(),
-        data.length()));
-}
-#endif // USE_SSH_LIB
-
-// #pragma mark -- MaemoRunControl
-
-
-MaemoRunControl::MaemoRunControl(RunConfiguration *runConfiguration)
-    : AbstractMaemoRunControl(runConfiguration)
-{
-#ifndef USE_SSH_LIB
-    setProcessEnvironment(sshProcess);
-    setProcessEnvironment(stopProcess);
-
-    connect(&sshProcess, SIGNAL(readyReadStandardError()), this,
-        SLOT(readStandardError()));
-    connect(&sshProcess, SIGNAL(readyReadStandardOutput()), this,
-        SLOT(readStandardOutput()));
-    connect(&sshProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this,
-        SLOT(executionFinished()));
-    connect(&sshProcess, SIGNAL(error(QProcess::ProcessError)), &dumper,
-        SLOT(printToStream(QProcess::ProcessError)));
-#endif // USE_SSH_LIB
-}
-
-MaemoRunControl::~MaemoRunControl()
-{
-    stop();
-#ifndef USE_SSH_LIB
-    stopProcess.waitForFinished(5000);
-#endif
-}
-
-void MaemoRunControl::start()
-{
-    stoppedByUser = false;
-    startDeployment(false);
-}
-
-void MaemoRunControl::handleDeploymentFinished(bool success)
-{
-    if (success)
-        startExecution();
-    else
-        emit finished();
-}
-
-void MaemoRunControl::startExecution()
-{
-#ifdef USE_SSH_LIB
-    const QString remoteCall = QString::fromLocal8Bit("%1 %2 %3")
-        .arg(targetCmdLinePrefix()).arg(executableOnTarget())
-        .arg(runConfig->arguments().join(" "));
-    sshRunner.reset(new MaemoSshRunner(devConfig, remoteCall));
-    connect(sshRunner.data(), SIGNAL(remoteOutput(QString)),
-            this, SLOT(handleRemoteOutput(QString)));
-    connect(sshRunner.data(), SIGNAL(finished()),
-            this, SLOT(executionFinished()));
-    emit addToOutputWindow(this, tr("Starting remote application."));
-    emit started();
-    sshRunner->start();
-#else
-    const QString remoteCall = QString::fromLocal8Bit("%1 %2 %3")
-        .arg(targetCmdLinePrefix()).arg(executableOnTarget())
-        .arg(runConfig->arguments().join(" "));
-
-    QStringList cmdArgs;
-    cmdArgs << "-n" << "-p" << port() << "-l" << devConfig.uname
-        << options() << devConfig.host << remoteCall;
-    sshProcess.start(runConfig->sshCmd(), cmdArgs);
-
-    sshProcess.start(runConfig->sshCmd(), cmdArgs);
-    emit addToOutputWindow(this, tr("Starting remote application."));
-    if (sshProcess.waitForStarted()) {
-        emit started();
-    } else {
-        emit error(this, tr("Could not start ssh!"));
-        sshProcess.kill();
-    }
-#endif // USE_SSH_LIB
-}
-
-void MaemoRunControl::executionFinished()
-{
-    if (stoppedByUser)
-        emit addToOutputWindow(this, tr("Remote process stopped by user."));
-#ifdef USE_SSH_LIB
-    else if (sshRunner->hasError())
-        emit addToOutputWindow(this, tr("Remote process exited with error: ")
-                               % sshRunner->error());
-#else
-    else if (sshProcess.exitCode() != 0)
-        emit addToOutputWindow(this, tr("Remote process exited with error."));
-#endif // USE_SSH_LIB
-    else
-        emit addToOutputWindow(this, tr("Remote process finished successfully."));
-    emit finished();
-}
-
-void MaemoRunControl::stop()
-{
-    if (!isRunning())
-        return;
-
-    stoppedByUser = true;
-    if (isDeploying()) {
-        stopDeployment();
-    } else {
-#ifdef USE_SSH_LIB
-        sshRunner->stop();
-        const QString remoteCall = QString::fromLocal8Bit("pkill -x %1; "
-            "sleep 1; pkill -x -9 %1").arg(executableFileName());
-        sshStopper.reset(new MaemoSshRunner(devConfig, remoteCall));
-        sshStopper->start();
-#else
-        stopProcess.kill();
-        QStringList cmdArgs;
-        const QString remoteCall = QString::fromLocal8Bit("pkill -x %1; "
-            "sleep 1; pkill -x -9 %1").arg(executableFileName());
-        cmdArgs << "-n" << "-p" << port() << "-l" << devConfig.uname
-            << options() << devConfig.host << remoteCall;
-        stopProcess.start(runConfig->sshCmd(), cmdArgs);
-#endif // USE_SSH_LIB
-    }
-}
-
-bool MaemoRunControl::isRunning() const
-{
-    return isDeploying()
-#ifdef USE_SSH_LIB
-        || (!sshRunner.isNull() && sshRunner->isRunning());
-#else
-        || sshProcess.state() != QProcess::NotRunning;
-#endif // USE_SSH_LIB
-}
-
-#ifdef USE_SSH_LIB
-void MaemoRunControl::handleRemoteOutput(const QString &output)
-{
-    emit addToOutputWindowInline(this, output);
-}
-
-#endif // USE_SSH_LIB
-
-// #pragma mark -- MaemoDebugRunControl
-
-
-MaemoDebugRunControl::MaemoDebugRunControl(RunConfiguration *runConfiguration)
-    : AbstractMaemoRunControl(runConfiguration)
-    , gdbServerPort("10000"), debuggerManager(0)
-    , startParams(new Debugger::DebuggerStartParameters)
-{
-#ifndef USE_SSH_LIB
-    setProcessEnvironment(gdbServer);
-    setProcessEnvironment(stopProcess);
-#endif // USE_SSH_LIB
-
-    debuggerManager = ExtensionSystem::PluginManager::instance()
-        ->getObject<Debugger::DebuggerManager>();
-
-    QTC_ASSERT(debuggerManager != 0, return);
-    startParams->startMode = Debugger::StartRemote;
-    startParams->executable = executableOnHost();
-    startParams->remoteChannel = devConfig.host + ":" + gdbServerPort;
-    startParams->remoteArchitecture = "arm";
-    startParams->sysRoot = runConfig->sysRoot();
-    startParams->toolChainType = ToolChain::GCC_MAEMO;
-    startParams->debuggerCommand = runConfig->gdbCmd();
-    startParams->dumperLibrary = runConfig->dumperLib();
-    startParams->remoteDumperLib = QString::fromLocal8Bit("%1/%2")
-        .arg(remoteDir()).arg(QFileInfo(runConfig->dumperLib()).fileName());
-
-    connect(this, SIGNAL(stopRequested()), debuggerManager, SLOT(exitDebugger()));
-    connect(debuggerManager, SIGNAL(debuggingFinished()), this,
-        SLOT(debuggingFinished()), Qt::QueuedConnection);
-    connect(debuggerManager, SIGNAL(applicationOutputAvailable(QString)),
-        this, SLOT(debuggerOutput(QString)), Qt::QueuedConnection);
-}
-
-MaemoDebugRunControl::~MaemoDebugRunControl()
-{
-    disconnect(SIGNAL(addToOutputWindow(RunControl*,QString)));
-    disconnect(SIGNAL(addToOutputWindowInline(RunControl*,QString)));
-    stop();
-    debuggingFinished();
-}
-
-void MaemoDebugRunControl::start()
-{
-    startDeployment(true);
-}
-
-void MaemoDebugRunControl::handleDeploymentFinished(bool success)
-{
-    if (success) {
-        startGdbServer();
-    } else {
-        emit finished();
-    }
-}
-
-void MaemoDebugRunControl::startGdbServer()
-{
-    const QString remoteCall(QString::fromLocal8Bit("%1 gdbserver :%2 %3 %4").
-        arg(targetCmdLinePrefix()).arg(gdbServerPort). arg(executableOnTarget())
-        .arg(runConfig->arguments().join(" ")));
-    inferiorPid = -1;
-#ifdef USE_SSH_LIB
-    sshRunner.reset(new MaemoSshRunner(devConfig, remoteCall));
-    connect(sshRunner.data(), SIGNAL(remoteOutput(QString)),
-            this, SLOT(gdbServerStarted(QString)));
-    sshRunner->start();
-#else
-    QStringList sshArgs;
-    sshArgs << "-t" << "-n" << "-l" << devConfig.uname << "-p"
-        << port() << options() << devConfig.host << remoteCall;
-    disconnect(&gdbServer, SIGNAL(readyReadStandardError()), 0, 0);
-    connect(&gdbServer, SIGNAL(readyReadStandardError()), this,
-        SLOT(gdbServerStarted()));
-    gdbServer.start(runConfig->sshCmd(), sshArgs);
-#endif // USE_SSH_LIB
-}
-
-void MaemoDebugRunControl::gdbServerStartFailed(const QString &reason)
-{
-    emit addToOutputWindow(this, tr("Debugging failed: %1").arg(reason));
-    emit stopRequested();
-    emit finished();
-}
-
-#ifdef USE_SSH_LIB
-void MaemoDebugRunControl::gdbServerStarted(const QString &output)
-{
-    qDebug("gdbserver's stderr output: %s", output.toLatin1().data());
-    if (inferiorPid != -1)
-        return;
-    const QString searchString("pid = ");
-    const int searchStringLength = searchString.length();
-    int pidStartPos = output.indexOf(searchString);
-    const int pidEndPos = output.indexOf("\n", pidStartPos + searchStringLength);
-    if (pidStartPos == -1 || pidEndPos == -1) {
-        gdbServerStartFailed(output);
-        return;
-    }
-    pidStartPos += searchStringLength;
-    QString pidString = output.mid(pidStartPos, pidEndPos - pidStartPos);
-    qDebug("pidString = %s", pidString.toLatin1().data());
-    bool ok;
-    const int pid = pidString.toInt(&ok);
-    if (!ok) {
-        gdbServerStartFailed(tr("Debugging failed, could not parse gdb "
-            "server pid!"));
-        return;
-    }
-    inferiorPid = pid;
-    qDebug("inferiorPid = %d", inferiorPid);
-
-    disconnect(sshRunner.data(), SIGNAL(remoteOutput(QString)), 0, 0);
-    startDebugging();
-}
-#else
-void MaemoDebugRunControl::gdbServerStarted()
-{
-    const QByteArray output = gdbServer.readAllStandardError();
-    qDebug("gdbserver's stderr output: %s", output.data());
-
-    const QByteArray searchString("pid = ");
-    const int searchStringLength = searchString.length();
-
-    int pidStartPos = output.indexOf(searchString);
-    const int pidEndPos = output.indexOf("\n", pidStartPos + searchStringLength);
-    if (pidStartPos == -1 || pidEndPos == -1) {
-        gdbServerStartFailed(output.data());
-        return;
-    }
-
-    pidStartPos += searchStringLength;
-    QByteArray pidString = output.mid(pidStartPos, pidEndPos - pidStartPos);
-    qDebug("pidString = %s", pidString.data());
-
-    bool ok;
-    const int pid = pidString.toInt(&ok);
-    if (!ok) {
-        gdbServerStartFailed(tr("Debugging failed, could not parse gdb "
-            "server pid!"));
-        return;
-    }
-
-    inferiorPid = pid;
-    qDebug("inferiorPid = %d", inferiorPid);
-
-    disconnect(&gdbServer, SIGNAL(readyReadStandardError()), 0, 0);
-    connect(&gdbServer, SIGNAL(readyReadStandardError()), this,
-        SLOT(readStandardError()));
-    startDebugging();
-}
-#endif // USE_SSH_LIB
-
-void MaemoDebugRunControl::startDebugging()
-{
-    debuggerManager->startNewDebugger(startParams);
-}
-
-void MaemoDebugRunControl::stop()
-{
-    if (!isRunning())
-        return;
-    emit addToOutputWindow(this, tr("Stopping debugging operation ..."));
-    if (isDeploying()) {
-        stopDeployment();
-    } else {
-        emit stopRequested();
-    }
-}
-
-bool MaemoDebugRunControl::isRunning() const
-{
-    return isDeploying()
-#ifdef USE_SSH_LIB
-        || (!sshRunner.isNull() && sshRunner->isRunning())
-#else
-        || gdbServer.state() != QProcess::NotRunning
-#endif // USE_SSH_LIB
-        || debuggerManager->state() != Debugger::DebuggerNotReady;
-}
-
-void MaemoDebugRunControl::debuggingFinished()
-{
-#ifdef USE_SSH_LIB
-    if (!sshRunner.isNull() && sshRunner->isRunning()) {
-        sshRunner->stop();
-        const QString remoteCall = QString::fromLocal8Bit("kill %1; sleep 1; "
-            "kill -9 %1; pkill -x -9 gdbserver").arg(inferiorPid);
-        sshStopper.reset(new MaemoSshRunner(devConfig, remoteCall));
-        sshStopper->start();
-    }
-#else
-    if (gdbServer.state() != QProcess::NotRunning) {
-        stopProcess.kill();
-        const QString remoteCall = QString::fromLocal8Bit("kill %1; sleep 1; "
-            "kill -9 %1; pkill -x -9 gdbserver").arg(inferiorPid);
-        QStringList sshArgs;
-        sshArgs << "-n" << "-l" << devConfig.uname << "-p" << port()
-            << options() << devConfig.host << remoteCall;
-        stopProcess.start(runConfig->sshCmd(), sshArgs);
-    }
-    qDebug("ssh return code is %d", gdbServer.exitCode());
-#endif // USE_SSH_LIB
-    emit addToOutputWindow(this, tr("Debugging finished."));
-    emit finished();
-}
-
-void MaemoDebugRunControl::debuggerOutput(const QString &output)
-{
-    emit addToOutputWindowInline(this, output);
-}
-
 #include "maemorunconfiguration.moc"
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f5a379744b07a387f00019b0d9e8af7881010310
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.cpp
@@ -0,0 +1,661 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Creator.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "maemoruncontrol.h"
+
+#include "maemorunconfiguration.h"
+
+#ifndef USE_SSH_LIB
+#include "qt4buildconfiguration.h"
+#include "qt4project.h"
+#endif // USE_SSH_LIB
+
+#include <coreplugin/icore.h>
+#include <coreplugin/progressmanager/progressmanager.h>
+#include <extensionsystem/pluginmanager.h>
+#include <debugger/debuggermanager.h>
+#include <utils/qtcassert.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QFuture>
+#include <QtCore/QStringBuilder>
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+AbstractMaemoRunControl::AbstractMaemoRunControl(RunConfiguration *rc)
+    : RunControl(rc)
+    , runConfig(qobject_cast<MaemoRunConfiguration *>(rc))
+    , devConfig(runConfig ? runConfig->deviceConfig() : MaemoDeviceConfig())
+{
+#ifndef USE_SSH_LIB
+    setProcessEnvironment(deployProcess);
+    connect(&deployProcess, SIGNAL(readyReadStandardError()), this,
+        SLOT(readStandardError()));
+    connect(&deployProcess, SIGNAL(readyReadStandardOutput()), this,
+        SLOT(readStandardOutput()));
+    connect(&deployProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this,
+        SLOT(deployProcessFinished()));
+#endif // USE_SSH_LIB
+}
+
+void AbstractMaemoRunControl::startDeployment(bool forDebugging)
+{
+    QTC_ASSERT(runConfig, return);
+
+#ifndef USE_SSH_LIB
+    Core::ICore::instance()->progressManager()->addTask(m_progress.future(),
+        tr("Deploying"), QLatin1String("Maemo.Deploy"));
+#endif // USE_SSH_LIB
+    if (devConfig.isValid()) {
+        deployables.clear();
+        if (runConfig->currentlyNeedsDeployment()) {
+            deployables.append(Deployable(executableFileName(),
+                QFileInfo(executableOnHost()).canonicalPath(),
+                &MaemoRunConfiguration::wasDeployed));
+        }
+        if (forDebugging && runConfig->debuggingHelpersNeedDeployment()) {
+            const QFileInfo &info(runConfig->dumperLib());
+            deployables.append(Deployable(info.fileName(), info.canonicalPath(),
+                &MaemoRunConfiguration::debuggingHelpersDeployed));
+        }
+
+#ifndef USE_SSH_LIB
+        m_progress.setProgressRange(0, deployables.count());
+        m_progress.setProgressValue(0);
+        m_progress.reportStarted();
+#endif // USE_SSH_LIB
+        deploy();
+    } else {
+#ifdef USE_SSH_LIB
+        handleDeploymentFinished(false);
+#else
+        deploymentFinished(false);
+#endif // USE_SSH_LIB
+    }
+}
+
+void AbstractMaemoRunControl::deploy()
+{
+#ifdef USE_SSH_LIB
+    if (!deployables.isEmpty()) {
+        QStringList files;
+        QStringList targetDirs;
+        foreach (const Deployable &deployable, deployables) {
+            files << deployable.dir + QDir::separator() + deployable.fileName;
+            targetDirs << remoteDir();
+        }
+        emit addToOutputWindow(this, tr("Files to deploy: %1.").arg(files.join(" ")));
+        sshDeployer.reset(new MaemoSshDeployer(devConfig, files, targetDirs));
+        connect(sshDeployer.data(), SIGNAL(finished()),
+                this, SLOT(deployProcessFinished()));
+        connect(sshDeployer.data(), SIGNAL(fileCopied(QString)),
+                this, SLOT(handleFileCopied()));
+        Core::ICore::instance()->progressManager()
+                ->addTask(m_progress.future(), tr("Deploying"),
+                          QLatin1String("Maemo.Deploy"));
+        m_progress.setProgressRange(0, deployables.count());
+        m_progress.setProgressValue(0);
+        m_progress.reportStarted();
+        emit started();
+        sshDeployer->start();
+    } else {
+        handleDeploymentFinished(true);
+    }
+#else
+    if (!deployables.isEmpty()) {
+        const Deployable &deployable = deployables.first();
+        emit addToOutputWindow(this, tr("File to deploy: %1.").arg(deployable.fileName));
+
+        QStringList cmdArgs;
+        cmdArgs << "-P" << port() << options() << deployable.fileName
+            << (devConfig.uname + "@" + devConfig.host + ":" + remoteDir());
+        deployProcess.setWorkingDirectory(deployable.dir);
+
+        deployProcess.start(runConfig->scpCmd(), cmdArgs);
+        if (!deployProcess.waitForStarted()) {
+            emit error(this, tr("Could not start scp. Deployment failed."));
+            deployProcess.kill();
+        } else {
+            emit started();
+        }
+    } else {
+        deploymentFinished(true);
+    }
+#endif // USE_SSH_LIB
+}
+
+#ifdef USE_SSH_LIB
+void AbstractMaemoRunControl::handleFileCopied()
+{
+    Deployable deployable = deployables.takeFirst();
+    (runConfig->*deployable.updateTimestamp)();
+    m_progress.setProgressValue(m_progress.progressValue() + 1);
+}
+#endif // USE_SSH_LIB
+
+void AbstractMaemoRunControl::stopDeployment()
+{
+#ifdef USE_SSH_LIB
+    sshDeployer->stop();
+#else
+    deployProcess.kill();
+#endif // USE_SSH_LIB
+}
+
+bool AbstractMaemoRunControl::isDeploying() const
+{
+#ifdef USE_SSH_LIB
+    return !sshDeployer.isNull() && sshDeployer->isRunning();
+#else
+    return deployProcess.state() != QProcess::NotRunning;
+#endif // USE_SSH_LIB
+}
+
+void AbstractMaemoRunControl::deployProcessFinished()
+{
+#if USE_SSH_LIB
+    const bool success = !sshDeployer->hasError();
+    if (success) {
+        emit addToOutputWindow(this, tr("Deployment finished."));
+    } else {
+        emit error(this, tr("Deployment failed: ") % sshDeployer->error());
+        m_progress.reportCanceled();
+    }
+    m_progress.reportFinished();
+    handleDeploymentFinished(success);
+#else
+    bool success;
+    if (deployProcess.exitCode() == 0) {
+        emit addToOutputWindow(this, tr("Target deployed."));
+        success = true;
+        Deployable deployable = deployables.takeFirst();
+        (runConfig->*deployable.updateTimestamp)();
+        m_progress.setProgressValue(m_progress.progressValue() + 1);
+    } else {
+        emit error(this, tr("Deployment failed."));
+        success = false;
+    }
+    if (deployables.isEmpty() || !success)
+        deploymentFinished(success);
+    else
+        deploy();
+#endif // USE_SSH_LIB
+}
+
+#ifndef USE_SSH_LIB
+void AbstractMaemoRunControl::deploymentFinished(bool success)
+{
+    m_progress.reportFinished();
+    handleDeploymentFinished(success);
+}
+#endif // USE_SSH_LIB
+
+const QString AbstractMaemoRunControl::executableOnHost() const
+{
+    return runConfig->executable();
+}
+
+const QString AbstractMaemoRunControl::port() const
+{
+    return QString::number(devConfig.port);
+}
+
+const QString AbstractMaemoRunControl::executableFileName() const
+{
+    return QFileInfo(executableOnHost()).fileName();
+}
+
+const QString AbstractMaemoRunControl::remoteDir() const
+{
+    return devConfig.uname == QString::fromLocal8Bit("root")
+        ? QString::fromLocal8Bit("/root")
+        : QString::fromLocal8Bit("/home/") + devConfig.uname;
+}
+
+const QStringList AbstractMaemoRunControl::options() const
+{
+    const bool usePassword
+        = devConfig.authentication == MaemoDeviceConfig::Password;
+    const QLatin1String opt("-o");
+    QStringList optionList;
+    if (!usePassword)
+        optionList << QLatin1String("-i") << devConfig.keyFile;
+    return optionList << opt
+        << QString::fromLatin1("PasswordAuthentication=%1").
+            arg(usePassword ? "yes" : "no") << opt
+        << QString::fromLatin1("PubkeyAuthentication=%1").
+            arg(usePassword ? "no" : "yes") << opt
+        << QString::fromLatin1("ConnectTimeout=%1").arg(devConfig.timeout)
+        << opt << QLatin1String("CheckHostIP=no")
+        << opt << QLatin1String("StrictHostKeyChecking=no");
+}
+
+const QString AbstractMaemoRunControl::executableOnTarget() const
+{
+    return QString::fromLocal8Bit("%1/%2").arg(remoteDir()).
+        arg(executableFileName());
+}
+
+const QString AbstractMaemoRunControl::targetCmdLinePrefix() const
+{
+    return QString::fromLocal8Bit("chmod u+x %1; source /etc/profile; ").
+        arg(executableOnTarget());
+}
+
+#ifndef USE_SSH_LIB
+bool AbstractMaemoRunControl::setProcessEnvironment(QProcess &process)
+{
+    QTC_ASSERT(runConfig, return false);
+    Qt4BuildConfiguration *qt4bc = qobject_cast<Qt4BuildConfiguration*>
+        (runConfig->project()->activeBuildConfiguration());
+    QTC_ASSERT(qt4bc, return false);
+    Environment env = Environment::systemEnvironment();
+    qt4bc->toolChain()->addToEnvironment(env);
+    process.setEnvironment(env.toStringList());
+
+    return true;
+}
+
+void AbstractMaemoRunControl::readStandardError()
+{
+    QProcess *process = static_cast<QProcess *>(sender());
+    const QByteArray &data = process->readAllStandardError();
+    emit addToOutputWindow(this, QString::fromLocal8Bit(data.constData(),
+        data.length()));
+}
+
+void AbstractMaemoRunControl::readStandardOutput()
+{
+    QProcess *process = static_cast<QProcess *>(sender());
+    const QByteArray &data = process->readAllStandardOutput();
+    emit addToOutputWindow(this, QString::fromLocal8Bit(data.constData(),
+        data.length()));
+}
+#endif // USE_SSH_LIB
+
+// #pragma mark -- MaemoRunControl
+
+
+MaemoRunControl::MaemoRunControl(RunConfiguration *runConfiguration)
+    : AbstractMaemoRunControl(runConfiguration)
+{
+#ifndef USE_SSH_LIB
+    setProcessEnvironment(sshProcess);
+    setProcessEnvironment(stopProcess);
+
+    connect(&sshProcess, SIGNAL(readyReadStandardError()), this,
+        SLOT(readStandardError()));
+    connect(&sshProcess, SIGNAL(readyReadStandardOutput()), this,
+        SLOT(readStandardOutput()));
+    connect(&sshProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this,
+        SLOT(executionFinished()));
+#endif // USE_SSH_LIB
+}
+
+MaemoRunControl::~MaemoRunControl()
+{
+    stop();
+#ifndef USE_SSH_LIB
+    stopProcess.waitForFinished(5000);
+#endif
+}
+
+void MaemoRunControl::start()
+{
+    stoppedByUser = false;
+    startDeployment(false);
+}
+
+void MaemoRunControl::handleDeploymentFinished(bool success)
+{
+    if (success)
+        startExecution();
+    else
+        emit finished();
+}
+
+void MaemoRunControl::startExecution()
+{
+#ifdef USE_SSH_LIB
+    const QString remoteCall = QString::fromLocal8Bit("%1 %2 %3")
+        .arg(targetCmdLinePrefix()).arg(executableOnTarget())
+        .arg(runConfig->arguments().join(" "));
+    sshRunner.reset(new MaemoSshRunner(devConfig, remoteCall));
+    connect(sshRunner.data(), SIGNAL(remoteOutput(QString)),
+            this, SLOT(handleRemoteOutput(QString)));
+    connect(sshRunner.data(), SIGNAL(finished()),
+            this, SLOT(executionFinished()));
+    emit addToOutputWindow(this, tr("Starting remote application."));
+    emit started();
+    sshRunner->start();
+#else
+    const QString remoteCall = QString::fromLocal8Bit("%1 %2 %3")
+        .arg(targetCmdLinePrefix()).arg(executableOnTarget())
+        .arg(runConfig->arguments().join(" "));
+
+    QStringList cmdArgs;
+    cmdArgs << "-n" << "-p" << port() << "-l" << devConfig.uname
+        << options() << devConfig.host << remoteCall;
+    sshProcess.start(runConfig->sshCmd(), cmdArgs);
+
+    sshProcess.start(runConfig->sshCmd(), cmdArgs);
+    emit addToOutputWindow(this, tr("Starting remote application."));
+    if (sshProcess.waitForStarted()) {
+        emit started();
+    } else {
+        emit error(this, tr("Could not start ssh!"));
+        sshProcess.kill();
+    }
+#endif // USE_SSH_LIB
+}
+
+void MaemoRunControl::executionFinished()
+{
+    if (stoppedByUser)
+        emit addToOutputWindow(this, tr("Remote process stopped by user."));
+#ifdef USE_SSH_LIB
+    else if (sshRunner->hasError())
+        emit addToOutputWindow(this, tr("Remote process exited with error: ")
+                               % sshRunner->error());
+#else
+    else if (sshProcess.exitCode() != 0)
+        emit addToOutputWindow(this, tr("Remote process exited with error."));
+#endif // USE_SSH_LIB
+    else
+        emit addToOutputWindow(this, tr("Remote process finished successfully."));
+    emit finished();
+}
+
+void MaemoRunControl::stop()
+{
+    if (!isRunning())
+        return;
+
+    stoppedByUser = true;
+    if (isDeploying()) {
+        stopDeployment();
+    } else {
+#ifdef USE_SSH_LIB
+        sshRunner->stop();
+        const QString remoteCall = QString::fromLocal8Bit("pkill -x %1; "
+            "sleep 1; pkill -x -9 %1").arg(executableFileName());
+        sshStopper.reset(new MaemoSshRunner(devConfig, remoteCall));
+        sshStopper->start();
+#else
+        stopProcess.kill();
+        QStringList cmdArgs;
+        const QString remoteCall = QString::fromLocal8Bit("pkill -x %1; "
+            "sleep 1; pkill -x -9 %1").arg(executableFileName());
+        cmdArgs << "-n" << "-p" << port() << "-l" << devConfig.uname
+            << options() << devConfig.host << remoteCall;
+        stopProcess.start(runConfig->sshCmd(), cmdArgs);
+#endif // USE_SSH_LIB
+    }
+}
+
+bool MaemoRunControl::isRunning() const
+{
+    return isDeploying()
+#ifdef USE_SSH_LIB
+        || (!sshRunner.isNull() && sshRunner->isRunning());
+#else
+        || sshProcess.state() != QProcess::NotRunning;
+#endif // USE_SSH_LIB
+}
+
+#ifdef USE_SSH_LIB
+void MaemoRunControl::handleRemoteOutput(const QString &output)
+{
+    emit addToOutputWindowInline(this, output);
+}
+
+#endif // USE_SSH_LIB
+
+// #pragma mark -- MaemoDebugRunControl
+
+
+MaemoDebugRunControl::MaemoDebugRunControl(RunConfiguration *runConfiguration)
+    : AbstractMaemoRunControl(runConfiguration)
+    , gdbServerPort("10000"), debuggerManager(0)
+    , startParams(new Debugger::DebuggerStartParameters)
+{
+#ifndef USE_SSH_LIB
+    setProcessEnvironment(gdbServer);
+    setProcessEnvironment(stopProcess);
+#endif // USE_SSH_LIB
+
+    debuggerManager = ExtensionSystem::PluginManager::instance()
+        ->getObject<Debugger::DebuggerManager>();
+
+    QTC_ASSERT(debuggerManager != 0, return);
+    startParams->startMode = Debugger::StartRemote;
+    startParams->executable = executableOnHost();
+    startParams->remoteChannel = devConfig.host + ":" + gdbServerPort;
+    startParams->remoteArchitecture = "arm";
+    startParams->sysRoot = runConfig->sysRoot();
+    startParams->toolChainType = ToolChain::GCC_MAEMO;
+    startParams->debuggerCommand = runConfig->gdbCmd();
+    startParams->dumperLibrary = runConfig->dumperLib();
+    startParams->remoteDumperLib = QString::fromLocal8Bit("%1/%2")
+        .arg(remoteDir()).arg(QFileInfo(runConfig->dumperLib()).fileName());
+
+    connect(this, SIGNAL(stopRequested()), debuggerManager, SLOT(exitDebugger()));
+    connect(debuggerManager, SIGNAL(debuggingFinished()), this,
+        SLOT(debuggingFinished()), Qt::QueuedConnection);
+    connect(debuggerManager, SIGNAL(applicationOutputAvailable(QString)),
+        this, SLOT(debuggerOutput(QString)), Qt::QueuedConnection);
+}
+
+MaemoDebugRunControl::~MaemoDebugRunControl()
+{
+    disconnect(SIGNAL(addToOutputWindow(RunControl*,QString)));
+    disconnect(SIGNAL(addToOutputWindowInline(RunControl*,QString)));
+    stop();
+    debuggingFinished();
+}
+
+void MaemoDebugRunControl::start()
+{
+    startDeployment(true);
+}
+
+void MaemoDebugRunControl::handleDeploymentFinished(bool success)
+{
+    if (success) {
+        startGdbServer();
+    } else {
+        emit finished();
+    }
+}
+
+void MaemoDebugRunControl::startGdbServer()
+{
+    const QString remoteCall(QString::fromLocal8Bit("%1 gdbserver :%2 %3 %4").
+        arg(targetCmdLinePrefix()).arg(gdbServerPort). arg(executableOnTarget())
+        .arg(runConfig->arguments().join(" ")));
+    inferiorPid = -1;
+#ifdef USE_SSH_LIB
+    sshRunner.reset(new MaemoSshRunner(devConfig, remoteCall));
+    connect(sshRunner.data(), SIGNAL(remoteOutput(QString)),
+            this, SLOT(gdbServerStarted(QString)));
+    sshRunner->start();
+#else
+    QStringList sshArgs;
+    sshArgs << "-t" << "-n" << "-l" << devConfig.uname << "-p"
+        << port() << options() << devConfig.host << remoteCall;
+    disconnect(&gdbServer, SIGNAL(readyReadStandardError()), 0, 0);
+    connect(&gdbServer, SIGNAL(readyReadStandardError()), this,
+        SLOT(gdbServerStarted()));
+    gdbServer.start(runConfig->sshCmd(), sshArgs);
+#endif // USE_SSH_LIB
+}
+
+void MaemoDebugRunControl::gdbServerStartFailed(const QString &reason)
+{
+    emit addToOutputWindow(this, tr("Debugging failed: %1").arg(reason));
+    emit stopRequested();
+    emit finished();
+}
+
+#ifdef USE_SSH_LIB
+void MaemoDebugRunControl::gdbServerStarted(const QString &output)
+{
+    qDebug("gdbserver's stderr output: %s", output.toLatin1().data());
+    if (inferiorPid != -1)
+        return;
+    const QString searchString("pid = ");
+    const int searchStringLength = searchString.length();
+    int pidStartPos = output.indexOf(searchString);
+    const int pidEndPos = output.indexOf("\n", pidStartPos + searchStringLength);
+    if (pidStartPos == -1 || pidEndPos == -1) {
+        gdbServerStartFailed(output);
+        return;
+    }
+    pidStartPos += searchStringLength;
+    QString pidString = output.mid(pidStartPos, pidEndPos - pidStartPos);
+    qDebug("pidString = %s", pidString.toLatin1().data());
+    bool ok;
+    const int pid = pidString.toInt(&ok);
+    if (!ok) {
+        gdbServerStartFailed(tr("Debugging failed, could not parse gdb "
+            "server pid!"));
+        return;
+    }
+    inferiorPid = pid;
+    qDebug("inferiorPid = %d", inferiorPid);
+
+    disconnect(sshRunner.data(), SIGNAL(remoteOutput(QString)), 0, 0);
+    startDebugging();
+}
+#else
+void MaemoDebugRunControl::gdbServerStarted()
+{
+    const QByteArray output = gdbServer.readAllStandardError();
+    qDebug("gdbserver's stderr output: %s", output.data());
+
+    const QByteArray searchString("pid = ");
+    const int searchStringLength = searchString.length();
+
+    int pidStartPos = output.indexOf(searchString);
+    const int pidEndPos = output.indexOf("\n", pidStartPos + searchStringLength);
+    if (pidStartPos == -1 || pidEndPos == -1) {
+        gdbServerStartFailed(output.data());
+        return;
+    }
+
+    pidStartPos += searchStringLength;
+    QByteArray pidString = output.mid(pidStartPos, pidEndPos - pidStartPos);
+    qDebug("pidString = %s", pidString.data());
+
+    bool ok;
+    const int pid = pidString.toInt(&ok);
+    if (!ok) {
+        gdbServerStartFailed(tr("Debugging failed, could not parse gdb "
+            "server pid!"));
+        return;
+    }
+
+    inferiorPid = pid;
+    qDebug("inferiorPid = %d", inferiorPid);
+
+    disconnect(&gdbServer, SIGNAL(readyReadStandardError()), 0, 0);
+    connect(&gdbServer, SIGNAL(readyReadStandardError()), this,
+        SLOT(readStandardError()));
+    startDebugging();
+}
+#endif // USE_SSH_LIB
+
+void MaemoDebugRunControl::startDebugging()
+{
+    debuggerManager->startNewDebugger(startParams);
+}
+
+void MaemoDebugRunControl::stop()
+{
+    if (!isRunning())
+        return;
+    emit addToOutputWindow(this, tr("Stopping debugging operation ..."));
+    if (isDeploying()) {
+        stopDeployment();
+    } else {
+        emit stopRequested();
+    }
+}
+
+bool MaemoDebugRunControl::isRunning() const
+{
+    return isDeploying()
+#ifdef USE_SSH_LIB
+        || (!sshRunner.isNull() && sshRunner->isRunning())
+#else
+        || gdbServer.state() != QProcess::NotRunning
+#endif // USE_SSH_LIB
+        || debuggerManager->state() != Debugger::DebuggerNotReady;
+}
+
+void MaemoDebugRunControl::debuggingFinished()
+{
+#ifdef USE_SSH_LIB
+    if (!sshRunner.isNull() && sshRunner->isRunning()) {
+        sshRunner->stop();
+        const QString remoteCall = QString::fromLocal8Bit("kill %1; sleep 1; "
+            "kill -9 %1; pkill -x -9 gdbserver").arg(inferiorPid);
+        sshStopper.reset(new MaemoSshRunner(devConfig, remoteCall));
+        sshStopper->start();
+    }
+#else
+    if (gdbServer.state() != QProcess::NotRunning) {
+        stopProcess.kill();
+        const QString remoteCall = QString::fromLocal8Bit("kill %1; sleep 1; "
+            "kill -9 %1; pkill -x -9 gdbserver").arg(inferiorPid);
+        QStringList sshArgs;
+        sshArgs << "-n" << "-l" << devConfig.uname << "-p" << port()
+            << options() << devConfig.host << remoteCall;
+        stopProcess.start(runConfig->sshCmd(), sshArgs);
+    }
+    qDebug("ssh return code is %d", gdbServer.exitCode());
+#endif // USE_SSH_LIB
+    emit addToOutputWindow(this, tr("Debugging finished."));
+    emit finished();
+}
+
+void MaemoDebugRunControl::debuggerOutput(const QString &output)
+{
+    emit addToOutputWindowInline(this, output);
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h
new file mode 100644
index 0000000000000000000000000000000000000000..b33cc849a6911d4911a4ed5c732a7ac760139652
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemoruncontrol.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Creator.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAEMORUNCONTROL_H
+#define MAEMORUNCONTROL_H
+
+#include "maemodeviceconfigurations.h"
+#include "maemosshthread.h"
+
+#include <projectexplorer/runconfiguration.h>
+
+#include <QtCore/QFutureInterface>
+#ifndef USE_SSH_LIB
+#include <QtCore/QProcess>
+#endif
+#include <QtCore/QScopedPointer>
+#include <QtCore/QString>
+
+namespace Debugger {
+    class DebuggerManager;
+    class DebuggerStartParameters;
+} // namespace Debugger
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+class MaemoRunConfiguration;
+
+class AbstractMaemoRunControl : public ProjectExplorer::RunControl
+{
+    Q_OBJECT
+
+public:
+    AbstractMaemoRunControl(ProjectExplorer::RunConfiguration *runConfig);
+    virtual ~AbstractMaemoRunControl() {}
+
+protected:
+    void startDeployment(bool forDebugging);
+    void deploy();
+    void stopDeployment();
+    bool isDeploying() const;
+    const QString executableOnHost() const;
+    const QString executableOnTarget() const;
+    const QString executableFileName() const;
+    const QString port() const;
+    const QString targetCmdLinePrefix() const;
+    const QString remoteDir() const;
+    const QStringList options() const;
+#ifndef USE_SSH_LIB
+    void deploymentFinished(bool success);
+    virtual bool setProcessEnvironment(QProcess &process);
+#endif // USE_SSH_LIB
+private slots:
+#ifndef USE_SSH_LIB
+    void readStandardError();
+    void readStandardOutput();
+#endif // USE_SSH_LIB
+    void deployProcessFinished();
+#ifdef USE_SSH_LIB
+    void handleFileCopied();
+#endif
+
+protected:
+    MaemoRunConfiguration *runConfig; // TODO this pointer can be invalid
+    const MaemoDeviceConfig devConfig;
+
+private:
+    virtual void handleDeploymentFinished(bool success)=0;
+
+    QFutureInterface<void> m_progress;
+#ifdef USE_SSH_LIB
+    QScopedPointer<MaemoSshDeployer> sshDeployer;
+#else
+    QProcess deployProcess;
+#endif // USE_SSH_LIB
+    struct Deployable
+    {
+        typedef void (MaemoRunConfiguration::*updateFunc)();
+        Deployable(const QString &f, const QString &d, updateFunc u)
+            : fileName(f), dir(d), updateTimestamp(u) {}
+        QString fileName;
+        QString dir;
+        updateFunc updateTimestamp;
+    };
+    QList<Deployable> deployables;
+};
+
+class MaemoRunControl : public AbstractMaemoRunControl
+{
+    Q_OBJECT
+public:
+    MaemoRunControl(ProjectExplorer::RunConfiguration *runConfiguration);
+    ~MaemoRunControl();
+    void start();
+    void stop();
+    bool isRunning() const;
+
+private slots:
+    void executionFinished();
+#ifdef USE_SSH_LIB
+    void handleRemoteOutput(const QString &output);
+#endif
+
+private:
+    virtual void handleDeploymentFinished(bool success);
+    void startExecution();
+
+#ifdef USE_SSH_LIB
+    QScopedPointer<MaemoSshRunner> sshRunner;
+    QScopedPointer<MaemoSshRunner> sshStopper;
+#else
+    QProcess sshProcess;
+    QProcess stopProcess;
+#endif // USE_SSH_LIB
+    bool stoppedByUser;
+};
+
+class MaemoDebugRunControl : public AbstractMaemoRunControl
+{
+    Q_OBJECT
+public:
+    MaemoDebugRunControl(ProjectExplorer::RunConfiguration *runConfiguration);
+    ~MaemoDebugRunControl();
+    void start();
+    void stop();
+    bool isRunning() const;
+    Q_SLOT void debuggingFinished();
+
+signals:
+    void stopRequested();
+
+private slots:
+#ifdef USE_SSH_LIB
+    void gdbServerStarted(const QString &output);
+#else
+    void gdbServerStarted();
+#endif // USE_SSH_LIB
+
+    void debuggerOutput(const QString &output);
+
+private:
+    virtual void handleDeploymentFinished(bool success);
+
+    void startGdbServer();
+    void gdbServerStartFailed(const QString &reason);
+    void startDebugging();
+
+#ifdef USE_SSH_LIB
+    QScopedPointer<MaemoSshRunner> sshRunner;
+    QScopedPointer<MaemoSshRunner> sshStopper;
+#else
+    QProcess gdbServer;
+    QProcess stopProcess;
+#endif // USE_SSH_LIB
+    const QString gdbServerPort;
+    Debugger::DebuggerManager *debuggerManager;
+    QSharedPointer<Debugger::DebuggerStartParameters> startParams;
+    int inferiorPid;
+};
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
+
+#endif // MAEMORUNCONTROL_H
diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri
index 49eda97133b84bbbf2faff5640940ad632cbbea6..b442f41cbf1435fe6a82fc5a5c042e817a5ac00c 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri
+++ b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri
@@ -3,21 +3,24 @@ SUPPORT_QT_MAEMO = $$(QTCREATOR_WITH_MAEMO)
     message("Adding experimental support for Qt/Maemo applications.")
     DEFINES += QTCREATOR_WITH_MAEMO
 #    DEFINES += USE_SSH_LIB
-#    LIBS += -L/opt/ne7ssh/lib/ -lnet7ssh
+#    LIBS += -L/opt/ne7sshModified/lib/ \
+#        -lnet7ssh
     HEADERS += $$PWD/maemorunconfiguration.h \
         $$PWD/maemomanager.h \
         $$PWD/maemotoolchain.h \
         $$PWD/maemodeviceconfigurations.h \
         $$PWD/maemosettingspage.h \
         $$PWD/maemosshconnection.h \
-        $$PWD/maemosshthread.h
+        $$PWD/maemosshthread.h \
+        $$PWD/maemoruncontrol.h
     SOURCES += $$PWD/maemorunconfiguration.cpp \
         $$PWD/maemomanager.cpp \
         $$PWD/maemotoolchain.cpp \
         $$PWD/maemodeviceconfigurations.cpp \
         $$PWD/maemosettingspage.cpp \
         $$PWD/maemosshconnection.cpp \
-        $$PWD/maemosshthread.cpp
+        $$PWD/maemosshthread.cpp \
+        $$PWD/maemoruncontrol.cpp
     FORMS += $$PWD/maemosettingswidget.ui
     RESOURCES += $$PWD/qt-maemo.qrc
 }