diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index 0543f9c54f7be241e5255986d18c98eeae55bebb..ba1feb77f96fb0be5e266e6496b5a167d4da246a 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -113,7 +113,9 @@ public:
     QString symbolFileName;
     QString serverStartScript;
     QString sysRoot;
+    QString debuggerCommand;
     int toolChainType;
+    QString remoteDumperLib;
 
     QString dumperLibrary;
     QStringList dumperLibraryLocations;
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index f9ae5cd24c1386c4c7397b6accc608e9f268122c..9ce3c0ef81a646866b1158f4e5a886c9407d8801 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -451,6 +451,7 @@ void DebuggerPlugin::shutdown()
     delete m_locationMark;
     m_locationMark = 0;
 
+    removeObject(m_manager);
     delete m_manager;
     m_manager = 0;
 }
@@ -545,6 +546,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
     }
 
     m_manager = new DebuggerManager;
+    ExtensionSystem::PluginManager::instance()->addObject(m_manager);
     const QList<Core::IOptionsPage *> engineOptionPages =
         m_manager->initializeEngines(m_cmdLineEnabledEngines);
 
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 874488e6e24593ef9372910d02d1173c9ec82c68..343066a71e772f962d9f58aa9f0bc400888d55cf 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -3796,47 +3796,56 @@ void GdbEngine::tryLoadDebuggingHelpers()
     }
 
     m_debuggingHelperState = DebuggingHelperLoadTried;
+    const QString dlopenLib =
+        (startParameters().startMode == StartRemote)
+            ? startParameters().remoteDumperLib : lib;
 #if defined(Q_OS_WIN)
     if (m_dumperInjectionLoad) {
         /// Launch asynchronous remote thread to load.
         SharedLibraryInjector injector(inferiorPid());
         QString errorMessage;
-        if (injector.remoteInject(lib, false, &errorMessage)) {
-            debugMessage(tr("Dumper injection loading triggered (%1)...").arg(lib));
+        if (injector.remoteInject(dlopenLib, false, &errorMessage)) {
+            debugMessage(tr("Dumper injection loading triggered (%1)...").
+                         arg(dlopenLib));
         } else {
-            debugMessage(tr("Dumper loading (%1) failed: %2").arg(lib, errorMessage));
+            debugMessage(tr("Dumper loading (%1) failed: %2").
+                         arg(dlopenLib, errorMessage));
             debugMessage(errorMessage);
             manager()->showQtDumperLibraryWarning(errorMessage);
             m_debuggingHelperState = DebuggingHelperUnavailable;
             return;
         }
     } else {
-        debugMessage(tr("Loading dumpers via debugger call (%1)...").arg(lib));
+        debugMessage(tr("Loading dumpers via debugger call (%1)...").
+                     arg(dlopenLib));
         postCommand(_("sharedlibrary .*")); // for LoadLibraryA
         //postCommand(_("handle SIGSEGV pass stop print"));
         //postCommand(_("set unwindonsignal off"));
-        postCommand(_("call LoadLibraryA(\"") + GdbMi::escapeCString(lib) + _("\")"),
+        postCommand(_("call LoadLibraryA(\"") + GdbMi::escapeCString(dlopenLib) + _("\")"),
                     CB(handleDebuggingHelperSetup));
-        postCommand(_("sharedlibrary ") + dotEscape(lib));
+        postCommand(_("sharedlibrary ") + dotEscape(dlopenLib));
     }
 #elif defined(Q_OS_MAC)
     //postCommand(_("sharedlibrary libc")); // for malloc
     //postCommand(_("sharedlibrary libdl")); // for dlopen
-    postCommand(_("call (void)dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"),
+    postCommand(_("call (void)dlopen(\"") + GdbMi::escapeCString(dlopenLib)
+                + _("\", " STRINGIFY(RTLD_NOW) ")"),
         CB(handleDebuggingHelperSetup));
-    //postCommand(_("sharedlibrary ") + dotEscape(lib));
+    //postCommand(_("sharedlibrary ") + dotEscape(dlopenLib));
     m_debuggingHelperState = DebuggingHelperLoadTried;
 #else
     //postCommand(_("p dlopen"));
     QString flag = QString::number(RTLD_NOW);
     postCommand(_("sharedlibrary libc")); // for malloc
     postCommand(_("sharedlibrary libdl")); // for dlopen
-    postCommand(_("call (void*)dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"),
+    postCommand(_("call (void*)dlopen(\"") + GdbMi::escapeCString(dlopenLib)
+                + _("\", " STRINGIFY(RTLD_NOW) ")"),
         CB(handleDebuggingHelperSetup));
     // some older systems like CentOS 4.6 prefer this:
-    postCommand(_("call (void*)__dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"),
+    postCommand(_("call (void*)__dlopen(\"") + GdbMi::escapeCString(dlopenLib)
+                + _("\", " STRINGIFY(RTLD_NOW) ")"),
         CB(handleDebuggingHelperSetup));
-    postCommand(_("sharedlibrary ") + dotEscape(lib));
+    postCommand(_("sharedlibrary ") + dotEscape(dlopenLib));
 #endif
     if (!m_dumperInjectionLoad)
         tryQueryDebuggingHelpers();
diff --git a/src/plugins/debugger/gdb/remotegdbadapter.cpp b/src/plugins/debugger/gdb/remotegdbadapter.cpp
index 0a32bfc28b2cbb6c7aa4c2ff75cf8c4eb2c7db37..a8347ac33909da4f4d3d1fc2f35d7381c49e075c 100644
--- a/src/plugins/debugger/gdb/remotegdbadapter.cpp
+++ b/src/plugins/debugger/gdb/remotegdbadapter.cpp
@@ -160,6 +160,8 @@ void RemoteGdbAdapter::startInferior()
     m_engine->postCommand(_("set architecture %1")
         .arg(startParameters().remoteArchitecture));
     m_engine->postCommand(_("set sysroot %1").arg(startParameters().sysRoot));
+    m_engine->postCommand(_("set solib-search-path %1").
+                          arg(QFileInfo(startParameters().dumperLibrary).path()));
 
     if (!startParameters().processArgs.isEmpty())
         m_engine->postCommand(_("-exec-arguments ")
diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp
index 7626445a8dedb678dc2f5f98fdfab13df7881b26..02608a6c2937c6ad9ce8606b38bc6a7933630e0e 100644
--- a/src/plugins/projectexplorer/toolchain.cpp
+++ b/src/plugins/projectexplorer/toolchain.cpp
@@ -127,6 +127,8 @@ QString ToolChain::toolChainName(ToolChainType tc)
         return QCoreApplication::translate("ToolChain", "RVCT (ARMV5)");
     case RVCT_ARMV6:
         return QCoreApplication::translate("ToolChain", "RVCT (ARMV6)");
+    case GCC_MAEMO:
+        return QCoreApplication::translate("ToolChain", "GCC for Maemo");
     case OTHER:
         return QCoreApplication::translate("ToolChain", "Other");
     case INVALID:
diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h
index b3a11cb7be28305f4bd3e2519503d9e192ee77a8..26863c0245e6ecaccd14a9ca559b4172b8ae2246 100644
--- a/src/plugins/projectexplorer/toolchain.h
+++ b/src/plugins/projectexplorer/toolchain.h
@@ -83,7 +83,8 @@ public:
         GCCE = 6,
         RVCT_ARMV5 = 7,
         RVCT_ARMV6 = 8,
-        LAST_VALID = 9,
+        GCC_MAEMO = 9,
+        LAST_VALID = 10,
         OTHER = 200,
         UNKNOWN = 201,
         INVALID = 202
diff --git a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec
index 0dc3a49bcb4069eaffc972c951df79465ad5ae5a..a39d5609fa6cc53b399d62069509a67f47043acf 100644
--- a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec
+++ b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec
@@ -25,5 +25,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license>
         <dependency name="CppEditor" version="1.3.80"/>
         <dependency name="Help" version="1.3.80"/>
         <dependency name="Designer" version="1.3.80"/>
+        <dependency name="Debugger" version="1.3.80"/>
     </dependencyList>
 </plugin>
diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp
index fc6296576ab00e3d25b14cdea7acfc8acbc3b174..84a1b5cf47327db0d61c597a85bb360919e3eb2d 100644
--- a/src/plugins/qt4projectmanager/qmakestep.cpp
+++ b/src/plugins/qt4projectmanager/qmakestep.cpp
@@ -68,6 +68,12 @@ QStringList QMakeStep::arguments(const QString &buildConfiguration)
 
     arguments << "-r";
 
+#ifdef Q_OS_WIN
+    ToolChain::ToolChainType type = m_pro->toolChainType(bc);
+    if (type == ToolChain::GCC_MAEMO)
+        arguments << QLatin1String("-unix");
+#endif
+
     if (bc->value("buildConfiguration").isValid()) {
         QStringList configarguments;
         QtVersion::QmakeBuildConfig defaultBuildConfiguration = m_pro->qtVersion(bc)->defaultBuildConfig();
diff --git a/src/plugins/qt4projectmanager/qt-maemo/images/qemu-run.png b/src/plugins/qt4projectmanager/qt-maemo/images/qemu-run.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc4f5190a23303d00a8ef896c8db32038a70a722
Binary files /dev/null and b/src/plugins/qt4projectmanager/qt-maemo/images/qemu-run.png differ
diff --git a/src/plugins/qt4projectmanager/qt-maemo/images/qemu-stop.png b/src/plugins/qt4projectmanager/qt-maemo/images/qemu-stop.png
new file mode 100644
index 0000000000000000000000000000000000000000..53d0663d6ef4964b979faebd7614a71fc58b22f8
Binary files /dev/null and b/src/plugins/qt4projectmanager/qt-maemo/images/qemu-stop.png differ
diff --git a/src/plugins/qt4projectmanager/qt-maemo/images/qemu.xcf b/src/plugins/qt4projectmanager/qt-maemo/images/qemu.xcf
new file mode 100644
index 0000000000000000000000000000000000000000..226dd2b30a66259e6259de72f25bdab958da43da
Binary files /dev/null and b/src/plugins/qt4projectmanager/qt-maemo/images/qemu.xcf differ
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemomanager.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2d1049ee5da8314b303870a20f01fc3087e9272b
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.cpp
@@ -0,0 +1,158 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#include "maemomanager.h"
+
+#include "maemotoolchain.h"
+#include "maemorunconfiguration.h"
+
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/coreconstants.h>
+#include <coreplugin/icore.h>
+#include <coreplugin/modemanager.h>
+#include <extensionsystem/pluginmanager.h>
+
+#include <QtCore/QList>
+#include <QtCore/QMutexLocker>
+
+#include <QtGui/QAction>
+
+namespace Qt4ProjectManager {
+    namespace Internal {
+
+
+QMutex MaemoManager::m_mutex;
+MaemoManager *MaemoManager::m_instance = 0;
+
+const QSize iconSize = QSize(24, 20);
+
+MaemoManager::MaemoManager()
+    : QObject(0)
+    , m_runControlFactory(new MaemoRunControlFactory(this))
+    , m_runConfigurationFactory(new MaemoRunConfigurationFactory(this))
+    , m_qemuCommand(0)
+{
+
+    icon.addFile(":/qt-maemo/images/qemu-run.png", iconSize);
+    icon.addFile(":/qt-maemo/images/qemu-stop.png", iconSize, QIcon::Normal,
+        QIcon::On);
+
+    ExtensionSystem::PluginManager::instance()->addObject(m_runControlFactory);
+    ExtensionSystem::PluginManager::instance()->addObject(m_runConfigurationFactory);
+}
+
+MaemoManager::~MaemoManager()
+{
+    ExtensionSystem::PluginManager::instance()->removeObject(m_runControlFactory);
+    ExtensionSystem::PluginManager::instance()->removeObject(m_runConfigurationFactory);
+}
+
+MaemoManager *MaemoManager::instance()
+{
+    if (!m_instance) {
+        QMutexLocker _(&m_mutex);
+        if (!m_instance)
+            m_instance = new MaemoManager;
+    }
+    return m_instance;
+}
+
+ProjectExplorer::ToolChain*
+MaemoManager::maemoToolChain(const QtVersion *version) const
+{
+    return new MaemoToolChain(version);
+}
+
+void
+MaemoManager::addQemuSimulatorStarter(Project *project)
+{
+    projects.insert(project);
+
+    if (m_qemuCommand) {
+        m_qemuCommand->action()->setVisible(true);
+        return;
+    }
+
+    Core::ICore *core = Core::ICore::instance();
+    Core::ModeManager *modeManager = core->modeManager();
+    Core::ActionManager *actionManager = core->actionManager();
+
+    QAction *action = new QAction("Qemu", this);
+    action->setIcon(icon.pixmap(iconSize));
+    action->setToolTip(tr("Start Qemu"));
+    m_qemuCommand = actionManager->registerAction(action, "qemu",
+        QList<int>() << Core::Constants::C_GLOBAL_ID);
+    modeManager->addAction(m_qemuCommand, 1);
+    m_qemuCommand->action()->setEnabled(true);
+    m_qemuCommand->setAttribute(Core::Command::CA_UpdateText);
+    m_qemuCommand->setAttribute(Core::Command::CA_UpdateIcon);
+
+    connect(m_qemuCommand->action(), SIGNAL(triggered()), this, SLOT(triggered()));
+}
+
+void
+MaemoManager::removeQemuSimulatorStarter(Project *project)
+{
+    projects.remove(project);
+    if (projects.isEmpty() && m_qemuCommand)
+        m_qemuCommand->action()->setVisible(false);
+}
+
+void
+MaemoManager::setQemuSimulatorStarterEnabled(bool enable)
+{
+    if (m_qemuCommand)
+        m_qemuCommand->action()->setEnabled(enable);
+}
+
+void
+MaemoManager::triggered()
+{
+    emit startStopQemu();
+}
+
+void
+MaemoManager::updateQemuSimulatorStarter(bool running)
+{
+    if (m_qemuCommand) {
+        QIcon::State state = QIcon::Off;
+        QString toolTip(tr("Start Qemu"));
+        if (running) {
+            state = QIcon::On;
+            toolTip = tr("Stop Qemu");
+        }
+
+        QAction *action = m_qemuCommand->action();
+        action->setToolTip(toolTip);
+        action->setIcon(icon.pixmap(iconSize, QIcon::Normal, state));
+    }
+}
+
+    } // namespace Internal
+} // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemomanager.h b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.h
new file mode 100644
index 0000000000000000000000000000000000000000..f76c83346ab4e0238ec82931d8d4c33b8cc9df0a
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.h
@@ -0,0 +1,103 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#ifndef MAEMOMANAGER_H
+#define MAEMOMANAGER_H
+
+#include "qtversionmanager.h"
+
+#include <coreplugin/actionmanager/command.h>
+
+#include <QtCore/QMutex>
+#include <QtCore/QObject>
+#include <QtCore/QSet>
+
+#include <QtGui/QIcon>
+
+QT_BEGIN_NAMESPACE
+class QAction;
+QT_END_NAMESPACE
+
+namespace ProjectExplorer {
+    class Project;
+    class ToolChain;
+}
+using ProjectExplorer::Project;
+using ProjectExplorer::ToolChain;
+
+namespace Qt4ProjectManager {
+    class QtVersion;
+    namespace Internal {
+
+class MaemoRunControlFactory;
+class MaemoRunConfigurationFactory;
+
+class MaemoManager : public QObject
+{
+    Q_OBJECT
+
+public:
+    static MaemoManager *instance();
+
+    void addVersion(const Qt4ProjectManager::QtVersion *version) { Q_UNUSED(version); }
+    ToolChain *maemoToolChain(const Qt4ProjectManager::QtVersion *version) const;
+
+    void addQemuSimulatorStarter(Project *project);
+    void removeQemuSimulatorStarter(Project *project);
+
+    void setQemuSimulatorStarterEnabled(bool state);
+
+public slots:
+    void triggered();
+    void updateQemuSimulatorStarter(bool running);
+
+signals:
+    void startStopQemu();
+
+private:
+    MaemoManager();
+    ~MaemoManager();
+
+private:
+    static QMutex m_mutex;
+    static MaemoManager *m_instance;
+
+    MaemoRunControlFactory *m_runControlFactory;
+    MaemoRunConfigurationFactory *m_runConfigurationFactory;
+
+    QIcon icon;
+    int m_runCount;
+    QSet<Project*> projects;
+    Core::Command *m_qemuCommand;
+};
+
+    } // namespace Internal
+} // namespace Qt4ProjectManager
+
+#endif // MAEMOMANAGER_H
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c5a46a1d9414b5fc64ecaced3069bd5491a9920f
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
@@ -0,0 +1,1497 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "maemorunconfiguration.h"
+
+#include "maemomanager.h"
+#include "maemotoolchain.h"
+#include "profilereader.h"
+#include "qt4project.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>
+#include <projectexplorer/persistentsettings.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/session.h>
+
+#include <QtCore/QDebug>
+#include <QtCore/QProcess>
+#include <QtCore/QSharedPointer>
+
+#include <QtGui/QCheckBox>
+#include <QtGui/QFormLayout>
+#include <QtGui/QFrame>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QRadioButton>
+
+using namespace ProjectExplorer;
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+class MaemoRunConfigurationWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    MaemoRunConfigurationWidget(
+        MaemoRunConfiguration *runConfiguration, QWidget *parent = 0);
+
+private slots:
+    void configNameEdited(const QString &text);
+    void argumentsEdited(const QString &args);
+    void hostNameEdited(const QString &name);
+    void userNameEdited(const QString &name);
+    void portEdited(const QString &port);
+    void hostTypeChanged();
+
+#if USE_SSL_PASSWORD
+    void passwordUseChanged();
+    void passwordEdited(const QString &password);
+#endif
+
+    void updateTargetInformation();
+    void updateVisibleSimulatorParameter();
+
+private:
+    QLineEdit *m_configNameLineEdit;
+    QLineEdit *m_argsLineEdit;
+    QLineEdit *m_hostNameLineEdit;
+    QLineEdit *m_userLineEdit;
+    QLineEdit *m_passwordLineEdit;
+    QLineEdit *m_portLineEdit;
+    QLabel *m_executableLabel;
+    QLabel *m_debuggerLabel;
+    QLabel *m_simParamsValueLabel;
+    QLabel *m_chooseSimPathLabel;
+    QLabel *m_simParamsNameLabel;
+    QCheckBox *m_passwordCheckBox;
+    QRadioButton *m_hwButton;
+    QRadioButton *m_simButton;
+    Utils::PathChooser *m_simPathChooser;
+    MaemoRunConfiguration *m_runConfiguration;
+};
+
+class AbstractMaemoRunControl : public ProjectExplorer::RunControl
+{
+    Q_OBJECT
+
+public:
+    AbstractMaemoRunControl(RunConfig runConfig);
+    virtual ~AbstractMaemoRunControl() {}
+
+protected:
+    void startDeployment(bool forDebugging);
+    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;
+    virtual void deploymentFinished(bool success)=0;
+    virtual bool setProcessEnvironment(QProcess &process);
+
+private slots:
+    void readStandardError();
+    void readStandardOutput();
+    void deployProcessFinished();
+
+protected:
+    ErrorDumper dumper;
+    const QSharedPointer<MaemoRunConfiguration> runConfig;
+
+private:
+    QProcess deployProcess;
+    bool deployingExecutable;
+    bool deployingDumperLib;
+};
+
+class MaemoRunControl : public AbstractMaemoRunControl
+{
+    Q_OBJECT
+public:
+    MaemoRunControl(RunConfig runConfiguration);
+    ~MaemoRunControl();
+    void start();
+    void stop();
+    bool isRunning() const;
+
+private slots:
+    void executionFinished();
+
+private:
+    void deploymentFinished(bool success);
+    void startExecution();
+
+    QProcess sshProcess;
+    QProcess stopProcess;
+    bool stoppedByUser;
+};
+
+class MaemoDebugRunControl : public AbstractMaemoRunControl
+{
+    Q_OBJECT
+public:
+    MaemoDebugRunControl(RunConfig runConfiguration);
+    ~MaemoDebugRunControl();
+    void start();
+    void stop();
+    bool isRunning() const;
+    Q_SLOT void debuggingFinished();
+
+signals:
+    void stopRequested();
+
+private slots:
+    void gdbServerStarted();
+    void debuggerOutput(const QString &output);
+
+private:
+    void deploymentFinished(bool success);
+
+    void startGdbServer();
+    void gdbServerStartFailed(const QString &reason);
+    void startDebugging();
+
+    QProcess gdbServer;
+    QProcess stopProcess;
+    const QString gdbServerPort;
+    Debugger::DebuggerManager *debuggerManager;
+    QSharedPointer<Debugger::DebuggerStartParameters> startParams;
+    int inferiorPid;
+};
+
+void ErrorDumper::printToStream(QProcess::ProcessError error)
+{
+    QString reason;
+    switch (error) {
+        case QProcess::FailedToStart:
+            reason = "The process failed to start. Either the invoked program is"
+                " missing, or you may have insufficient permissions to invoke "
+                "the program.";
+            break;
+
+        case QProcess::Crashed:
+            reason = "The process crashed some time after starting successfully.";
+            break;
+
+        case QProcess::Timedout:
+            reason = "The last waitFor...() function timed out. The state of "
+                "QProcess is unchanged, and you can try calling waitFor...() "
+                "again.";
+            break;
+
+        case QProcess::WriteError:
+            reason = "An error occurred when attempting to write to the process."
+                " For example, the process may not be running, or it may have "
+                "closed its input channel.";
+            break;
+
+        case QProcess::ReadError:
+            reason = "An error occurred when attempting to read from the process."
+                " For example, the process may not be running.";
+            break;
+
+        default:
+            reason = "QProcess::UnknownError";
+            break;
+    }
+    qWarning() << "Failed to run emulator. Reason:" << reason;
+}
+
+
+// #pragma mark -- MaemoRunConfiguration
+
+
+const QString MaemoRunConfiguration::ArgumentsKey("Arguments");
+const QString MaemoRunConfiguration::RemoteHostIsSimulatorKey =
+    "RemoteHostIsSimulator";
+const QString MaemoRunConfiguration::RemoteHostNameKey =
+    "RemoteHostName";
+const QString MaemoRunConfiguration::RemoteUserNameKey =
+    "RemoteUserName";
+const QString MaemoRunConfiguration::RemotePortKey("RemotePort");
+const QString MaemoRunConfiguration::LastDeployedKey("LastDeployed");
+const QString MaemoRunConfiguration::DebuggingHelpersLastDeployedKey =
+    "DebuggingHelpersLastDeployed";
+
+#if USE_SSL_PASSWORD
+const QString MaemoRunConfiguration::RemoteUserPasswordKey =
+        "RemoteUserPassword";
+const QString MaemoRunConfiguration::RemoteHostRequiresPasswordKey =
+        "RemoteHostRequiresPassword";
+#endif
+
+MaemoRunConfiguration::MaemoRunConfiguration(Project *project,
+        const QString &proFilePath)
+    : RunConfiguration(project)
+    , m_proFilePath(proFilePath)
+    , m_cachedTargetInformationValid(false)
+    , m_cachedSimulatorInformationValid(false)
+    , qemu(0)
+{
+    if (!m_proFilePath.isEmpty()) {
+        setName(tr("%1 on Maemo device").arg(QFileInfo(m_proFilePath)
+            .completeBaseName()));
+    } else {
+        setName(tr("MaemoRunConfiguration"));
+    }
+
+    connect(project, SIGNAL(targetInformationChanged()), this,
+        SLOT(invalidateCachedTargetInformation()));
+    connect(project, SIGNAL(activeBuildConfigurationChanged()), this,
+        SLOT(invalidateCachedTargetInformation()));
+
+    connect(project, SIGNAL(targetInformationChanged()), this,
+        SLOT(invalidateCachedSimulatorInformation()));
+    connect(project, SIGNAL(activeBuildConfigurationChanged()), this,
+        SLOT(invalidateCachedSimulatorInformation()));
+
+    qemu = new QProcess(this);
+    connect(qemu, SIGNAL(error(QProcess::ProcessError)), &dumper,
+        SLOT(printToStream(QProcess::ProcessError)));
+    connect(qemu, SIGNAL(finished(int, QProcess::ExitStatus)), this,
+        SLOT(qemuProcessFinished()));
+}
+
+MaemoRunConfiguration::~MaemoRunConfiguration()
+{
+    if (qemu && qemu->state() != QProcess::NotRunning) {
+        qemu->terminate();
+        qemu->kill();
+    }
+    delete qemu;
+    qemu = NULL;
+}
+
+QString MaemoRunConfiguration::type() const
+{
+    return QLatin1String("Qt4ProjectManager.MaemoRunConfiguration");
+}
+
+Qt4Project *MaemoRunConfiguration::project() const
+{
+    Qt4Project *pro = qobject_cast<Qt4Project *>(RunConfiguration::project());
+    Q_ASSERT(pro != 0);
+    return pro;
+}
+
+bool MaemoRunConfiguration::isEnabled() const
+{
+    Qt4Project *qt4Project = qobject_cast<Qt4Project*>(project());
+    QTC_ASSERT(qt4Project, return false);
+    ToolChain::ToolChainType type =
+        qt4Project->toolChainType(qt4Project->activeBuildConfiguration());
+    return type == ToolChain::GCC_MAEMO;
+}
+
+QWidget *MaemoRunConfiguration::configurationWidget()
+{
+    return new MaemoRunConfigurationWidget(this);
+}
+
+void MaemoRunConfiguration::save(PersistentSettingsWriter &writer) const
+{
+    writer.saveValue("Runtime", m_simulatorPath);
+    writer.saveValue(ArgumentsKey, m_arguments);
+    writer.saveValue(RemoteHostIsSimulatorKey, m_remoteHostIsSimulator);
+    writer.saveValue(RemoteHostNameKey, m_remoteHostName);
+    writer.saveValue(RemoteUserNameKey, m_remoteUserName);
+#if USE_SSL_PASSWORD
+    writer.saveValue(RemoteUserPasswordKey, m_remoteUserPassword);
+    writer.saveValue(RemoteHostRequiresPasswordKey, m_remoteHostRequiresPassword);
+#endif
+    writer.saveValue(RemotePortKey, m_remotePort);
+    writer.saveValue(LastDeployedKey, m_lastDeployed);
+    writer.saveValue(DebuggingHelpersLastDeployedKey,
+        m_debuggingHelpersLastDeployed);
+
+    const QDir &dir = QFileInfo(project()->file()->fileName()).absoluteDir();
+    writer.saveValue("ProFile", dir.relativeFilePath(m_proFilePath));
+
+    RunConfiguration::save(writer);
+}
+
+void MaemoRunConfiguration::restore(const PersistentSettingsReader &reader)
+{
+    RunConfiguration::restore(reader);
+
+    m_simulatorPath = reader.restoreValue("Runtime").toString();
+    m_arguments = reader.restoreValue(ArgumentsKey).toStringList();
+    m_remoteHostIsSimulator =
+        reader.restoreValue(RemoteHostIsSimulatorKey).toBool();
+    m_remoteHostName = reader.restoreValue(RemoteHostNameKey).toString();
+    m_remoteUserName = reader.restoreValue(RemoteUserNameKey).toString();
+#if USE_SSL_PASSWORD
+    m_remoteUserPassword = reader.restoreValue(RemoteUserPasswordKey).toString();
+    m_remoteHostRequiresPassword =
+        reader.restoreValue(RemoteHostRequiresPasswordKey).toBool();
+#endif
+    m_remotePort = reader.restoreValue(RemotePortKey).toInt();
+    m_lastDeployed = reader.restoreValue(LastDeployedKey).toDateTime();
+    m_debuggingHelpersLastDeployed =
+        reader.restoreValue(DebuggingHelpersLastDeployedKey).toDateTime();
+
+    const QDir &dir = QFileInfo(project()->file()->fileName()).absoluteDir();
+    m_proFilePath = dir.filePath(reader.restoreValue("ProFile").toString());
+}
+
+bool MaemoRunConfiguration::currentlyNeedsDeployment() const
+{
+    return fileNeedsDeployment(executable(), m_lastDeployed);
+}
+
+void MaemoRunConfiguration::wasDeployed()
+{
+    m_lastDeployed = QDateTime::currentDateTime();
+}
+
+bool MaemoRunConfiguration::hasDebuggingHelpers() const
+{
+    return project()->qtVersion(project()->activeBuildConfiguration())
+        ->hasDebuggingHelper();
+}
+
+bool MaemoRunConfiguration::debuggingHelpersNeedDeployment() const
+{
+    if (hasDebuggingHelpers())
+        return fileNeedsDeployment(dumperLib(), m_debuggingHelpersLastDeployed);
+    return false;
+}
+
+void MaemoRunConfiguration::debuggingHelpersDeployed()
+{
+    m_debuggingHelpersLastDeployed = QDateTime::currentDateTime();
+}
+
+bool MaemoRunConfiguration::fileNeedsDeployment(const QString &path,
+    const QDateTime &lastDeployed) const
+{
+    return !lastDeployed.isValid()
+        || QFileInfo(path).lastModified() > lastDeployed;
+}
+
+const QString MaemoRunConfiguration::remoteDir() const
+{
+    return remoteUserName() == QString::fromLocal8Bit("root")
+        ? QString::fromLocal8Bit("/root")
+        : QString::fromLocal8Bit("/home/") + remoteUserName();
+}
+
+const QString MaemoRunConfiguration::sshCmd() const
+{
+    return cmd(QString::fromLocal8Bit("ssh"));
+}
+
+const QString MaemoRunConfiguration::scpCmd() const
+{
+    return cmd(QString::fromLocal8Bit("scp"));
+}
+
+const QString MaemoRunConfiguration::cmd(const QString &cmdName) const
+{
+    QString command(cmdName);
+#ifdef Q_OS_WIN
+    command = maddeRoot() + QLatin1String("/bin/") + command
+          + QLatin1String(".exe");
+#endif
+    return command;
+}
+
+const MaemoToolChain *MaemoRunConfiguration::toolchain() const
+{
+    Qt4Project *qt4Project = qobject_cast<Qt4Project *>(project());
+    QTC_ASSERT(qt4Project != 0, return 0);
+    MaemoToolChain *tc = dynamic_cast<MaemoToolChain *>(
+        qt4Project->toolChain(qt4Project->activeBuildConfiguration()) );
+    QTC_ASSERT(tc != 0, return 0);
+    return tc;
+}
+
+const QString MaemoRunConfiguration::gdbCmd() const
+{
+    return toolchain() != 0
+            ? toolchain()->targetRoot() + "/bin/gdb"
+            : QString();
+}
+
+QString MaemoRunConfiguration::maddeRoot() const
+{
+    return toolchain() != 0 ? toolchain()->maddeRoot() : QString();
+}
+
+const QString MaemoRunConfiguration::sysRoot() const
+{
+    return toolchain() != 0 ? toolchain()->sysrootRoot() : QString();
+}
+
+const QString MaemoRunConfiguration::dumperLib() const
+{
+    return project()->qtVersion(project()->activeBuildConfiguration())->
+        debuggingHelperLibrary();
+}
+
+QString MaemoRunConfiguration::executable() const
+{
+    const_cast<MaemoRunConfiguration*> (this)->updateTarget();
+    return m_executable;
+}
+
+QString MaemoRunConfiguration::simulatorPath() const
+{
+    qDebug("MaemoRunConfiguration::simulatorPath() called, %s",
+        qPrintable(m_simulatorPath));
+
+    const_cast<MaemoRunConfiguration*> (this)->updateSimulatorInformation();
+    return m_simulatorPath;
+}
+
+QString MaemoRunConfiguration::visibleSimulatorParameter() const
+{
+    qDebug("MaemoRunConfiguration::visibleSimulatorParameter() called");
+
+    const_cast<MaemoRunConfiguration*> (this)->updateSimulatorInformation();
+    return m_visibleSimulatorParameter;
+}
+
+QString MaemoRunConfiguration::simulator() const
+{
+    const_cast<MaemoRunConfiguration*> (this)->updateSimulatorInformation();
+    return m_simulator;
+}
+
+QString MaemoRunConfiguration::simulatorArgs() const
+{
+    const_cast<MaemoRunConfiguration*> (this)->updateSimulatorInformation();
+    return m_simulatorArgs;
+}
+
+void MaemoRunConfiguration::setArguments(const QStringList &args)
+{
+    m_arguments = args;
+}
+
+void MaemoRunConfiguration::setRemoteHostIsSimulator(bool isSimulator)
+{
+    m_remoteHostIsSimulator = isSimulator;
+}
+
+void MaemoRunConfiguration::setRemoteHostName(const QString &hostName)
+{
+    m_lastDeployed = QDateTime();
+    m_debuggingHelpersLastDeployed = QDateTime();
+    m_remoteHostName = hostName;
+}
+
+void MaemoRunConfiguration::setRemoteUserName(const QString &userName)
+{
+    m_lastDeployed = QDateTime();
+    m_debuggingHelpersLastDeployed = QDateTime();
+    m_remoteUserName = userName;
+}
+
+void MaemoRunConfiguration::setRemotePort(int port)
+{
+    m_lastDeployed = QDateTime();
+    m_debuggingHelpersLastDeployed = QDateTime();
+    m_remotePort = port;
+}
+
+#if USE_SSL_PASSWORD
+void MaemoRunConfiguration::setRemotePassword(const QString &password)
+{
+    Q_ASSERT(remoteHostRequiresPassword());
+    m_remoteUserPassword = password;
+}
+
+void MaemoRunConfiguration::setRemoteHostRequiresPassword(bool requiresPassword)
+{
+    m_remoteHostRequiresPassword = requiresPassword;
+}
+#endif
+
+bool MaemoRunConfiguration::isQemuRunning() const
+{
+    return (qemu && qemu->state() != QProcess::NotRunning);
+}
+
+void MaemoRunConfiguration::invalidateCachedTargetInformation()
+{
+    m_cachedTargetInformationValid = false;
+    emit targetInformationChanged();
+}
+
+void MaemoRunConfiguration::setSimulatorPath(const QString &path)
+{
+    qDebug("MaemoRunConfiguration::setSimulatorPath() called, "
+        "m_simulatorPath: %s, new path: %s", qPrintable(m_simulatorPath),
+        qPrintable(path));
+
+    if (m_simulatorPath != path)
+        m_cachedSimulatorInformationValid = false;
+
+    m_simulatorPath = path;
+    emit cachedSimulatorInformationChanged();
+}
+
+void MaemoRunConfiguration::invalidateCachedSimulatorInformation()
+{
+    qDebug("MaemoRunConfiguration::invalidateCachedSimulatorInformation() "
+        "called");
+
+    m_cachedSimulatorInformationValid = false;
+    emit cachedSimulatorInformationChanged();
+}
+
+void MaemoRunConfiguration::updateTarget()
+{
+    if (m_cachedTargetInformationValid)
+        return;
+
+    m_executable = QString::null;
+    m_cachedTargetInformationValid = true;
+
+    if (Qt4Project *qt4Project = static_cast<Qt4Project *>(project())) {
+        Qt4PriFileNode * priFileNode = qt4Project->rootProjectNode()
+            ->findProFileFor(m_proFilePath);
+        if (!priFileNode) {
+            emit targetInformationChanged();
+            return;
+        }
+
+        QtVersion *qtVersion =
+            qt4Project->qtVersion(qt4Project->activeBuildConfiguration());
+        ProFileReader *reader = priFileNode->createProFileReader();
+        reader->setCumulative(false);
+        reader->setQtVersion(qtVersion);
+
+        // Find out what flags we pass on to qmake, this code is duplicated in
+        // the qmake step
+        QtVersion::QmakeBuildConfig defaultBuildConfiguration =
+            qtVersion->defaultBuildConfig();
+        QtVersion::QmakeBuildConfig projectBuildConfiguration =
+            QtVersion::QmakeBuildConfig(qt4Project->activeBuildConfiguration()
+                ->value("buildConfiguration").toInt());
+
+        QStringList addedUserConfigArguments;
+        QStringList removedUserConfigArguments;
+        if ((defaultBuildConfiguration & QtVersion::BuildAll)
+            && !(projectBuildConfiguration & QtVersion::BuildAll))
+            removedUserConfigArguments << "debug_and_release";
+
+        if (!(defaultBuildConfiguration & QtVersion::BuildAll)
+            && (projectBuildConfiguration & QtVersion::BuildAll))
+            addedUserConfigArguments << "debug_and_release";
+
+        if ((defaultBuildConfiguration & QtVersion::DebugBuild)
+            && !(projectBuildConfiguration & QtVersion::DebugBuild))
+            addedUserConfigArguments << "release";
+
+        if (!(defaultBuildConfiguration & QtVersion::DebugBuild)
+            && (projectBuildConfiguration & QtVersion::DebugBuild))
+            addedUserConfigArguments << "debug";
+
+        reader->setUserConfigCmdArgs(addedUserConfigArguments,
+            removedUserConfigArguments);
+
+        if (!reader->readProFile(m_proFilePath)) {
+            delete reader;
+            Core::ICore::instance()->messageManager()->printToOutputPane(tr(
+                "Could not parse %1. The Maemo run configuration %2 "
+                "can not be started.").arg(m_proFilePath).arg(name()));
+            emit targetInformationChanged();
+            return;
+        }
+
+        // Extract data
+        QDir baseProjectDirectory =
+            QFileInfo(project()->file()->fileName()).absoluteDir();
+        QString relSubDir =
+            baseProjectDirectory.relativeFilePath(QFileInfo(m_proFilePath).path());
+        QDir baseBuildDirectory =
+            project()->buildDirectory(project()->activeBuildConfiguration());
+        QString baseDir = baseBuildDirectory.absoluteFilePath(relSubDir);
+
+        if (!reader->contains("DESTDIR")) {
+#if 0   // TODO: fix this, seems to be wrong on windows
+            if (reader->values("CONFIG").contains("debug_and_release_target")) {
+                QString qmakeBuildConfig = "release";
+                if (projectBuildConfiguration & QtVersion::DebugBuild)
+                    qmakeBuildConfig = "debug";
+                baseDir += QLatin1Char('/') + qmakeBuildConfig;
+            }
+#endif
+        } else {
+            const QString &destDir = reader->value("DESTDIR");
+            if (QDir::isRelativePath(destDir))
+                baseDir += QLatin1Char('/') + destDir;
+            else
+                baseDir = destDir;
+        }
+
+        QString target = reader->value("TARGET");
+        if (target.isEmpty())
+            target = QFileInfo(m_proFilePath).baseName();
+
+        m_executable = QDir::cleanPath(baseDir + QLatin1Char('/') + target);
+        delete reader;
+    }
+
+    emit targetInformationChanged();
+}
+
+void MaemoRunConfiguration::updateSimulatorInformation()
+{
+    qDebug("MaemoRunConfiguration::updateSimulatorInformation() called");
+
+    if (m_cachedSimulatorInformationValid)
+        return;
+
+    m_simulator = QString::null;
+    m_simulatorArgs == QString::null;
+    m_cachedSimulatorInformationValid = true;
+    m_visibleSimulatorParameter = tr("Please select a Maemo simulator.");
+
+    if (!m_simulatorPath.isEmpty()) {
+        m_visibleSimulatorParameter = tr("'%1' is not a valid Maemo simulator.")
+            .arg(m_simulatorPath);
+    }
+
+    const QStringList &files = QDir(m_simulatorPath).entryList(QDir::Files
+        | QDir::NoSymLinks | QDir::NoDotAndDotDot);
+    if (files.count() >= 2) {
+        const QLatin1String info("information");
+        if (files.contains(info)) {
+            QFile file(m_simulatorPath + QLatin1Char('/') + info);
+            if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                QMap<QString, QString> map;
+                QTextStream stream(&file);
+                while (!stream.atEnd()) {
+                    const QString &line = stream.readLine().trimmed();
+                    const int index = line.indexOf(QLatin1Char('='));
+                    map.insert(line.mid(0, index).remove(QLatin1Char('\'')),
+                        line.mid(index + 1).remove(QLatin1Char('\'')));
+                }
+
+                m_simulator = map.value(QLatin1String("runcommand"));
+                m_simulatorArgs = map.value(QLatin1String("runcommand_args"));
+
+                m_visibleSimulatorParameter = m_simulator
+#ifdef Q_OS_WIN
+                    + QLatin1String(".exe")
+#endif
+                    + QLatin1Char(' ') + m_simulatorArgs;
+            }
+        }
+    }
+
+    emit cachedSimulatorInformationChanged();
+}
+
+void MaemoRunConfiguration::startStopQemu()
+{
+    if (qemu->state() != QProcess::NotRunning) {
+        if (qemu->state() == QProcess::Running) {
+            qemu->terminate();
+            qemu->kill();
+            emit qemuProcessStatus(false);
+        }
+        return;
+    }
+
+    QString root = maddeRoot();
+    if (root.isEmpty() || simulator().isEmpty())
+        return;
+
+    const QLatin1Char colon(';');
+    const QString path = QDir::toNativeSeparators(root + QLatin1Char('/'));
+
+    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+    env.insert("PATH", env.value("Path") + colon + path + QLatin1String("bin"));
+    env.insert("PATH", env.value("Path") + colon + path + QLatin1String("madlib"));
+
+    qemu->setProcessEnvironment(env);
+    qemu->setWorkingDirectory(simulatorPath());
+
+    QString app = root + QLatin1String("/madlib/") + simulator()
+#ifdef Q_OS_WIN
+        + QLatin1String(".exe")
+#endif
+    ;   // keep
+
+    qemu->start(app + QLatin1Char(' ') + simulatorArgs(), QIODevice::ReadWrite);
+    emit qemuProcessStatus(qemu->waitForStarted());
+}
+
+void MaemoRunConfiguration::qemuProcessFinished()
+{
+    emit qemuProcessStatus(false);
+}
+
+void MaemoRunConfiguration::enabledStateChanged()
+{
+    MaemoManager::instance()->setQemuSimulatorStarterEnabled(isEnabled());
+}
+
+
+// #pragma mark -- MaemoRunConfigurationWidget
+
+
+MaemoRunConfigurationWidget::MaemoRunConfigurationWidget(
+        MaemoRunConfiguration *runConfiguration, QWidget *parent)
+    : QWidget(parent)
+    , m_runConfiguration(runConfiguration)
+{
+    QFormLayout *mainLayout = new QFormLayout;
+    setLayout(mainLayout);
+    mainLayout->setFormAlignment(Qt::AlignLeft | Qt::AlignVCenter);
+    m_configNameLineEdit = new QLineEdit(m_runConfiguration->name());
+    mainLayout->addRow(tr("Run configuration name:"), m_configNameLineEdit);
+    m_executableLabel = new QLabel(m_runConfiguration->executable());
+    mainLayout->addRow(tr("Executable:"), m_executableLabel);
+    m_argsLineEdit = new QLineEdit(m_runConfiguration->arguments().join(" "));
+    mainLayout->addRow(tr("Arguments:"), m_argsLineEdit);
+    m_debuggerLabel = new QLabel(m_runConfiguration->gdbCmd());
+    mainLayout->addRow(tr("Debugger:"), m_debuggerLabel);
+
+    QWidget *hostTypeWidget = new QWidget;
+    QHBoxLayout *hostTypeLayout = new QHBoxLayout;
+    hostTypeLayout->setContentsMargins(0, 0, 0, 0);
+    hostTypeWidget->setLayout(hostTypeLayout);
+    m_hwButton = new QRadioButton(tr("Physical device"));
+    m_simButton = new QRadioButton(tr("Simulator"));
+    hostTypeLayout->addWidget(m_hwButton);
+    hostTypeLayout->addWidget(m_simButton);
+    hostTypeLayout->addStretch(1);
+    mainLayout->addRow(tr("Remote host type:"), hostTypeWidget);
+    m_chooseSimPathLabel = new QLabel(tr("Choose simulator:"));
+    m_simPathChooser = new Utils::PathChooser;
+    m_simPathChooser->setPath(m_runConfiguration->simulatorPath());
+    mainLayout->addRow(m_chooseSimPathLabel, m_simPathChooser);
+    m_simParamsNameLabel = new QLabel(tr("Simulator command line:"));
+    m_simParamsValueLabel= new QLabel(m_runConfiguration->visibleSimulatorParameter());
+    mainLayout->addRow(m_simParamsNameLabel, m_simParamsValueLabel);
+
+    m_hostNameLineEdit = new QLineEdit(m_runConfiguration->remoteHostName());
+    mainLayout->addRow(tr("Remote host name:"), m_hostNameLineEdit);
+    m_userLineEdit = new QLineEdit(m_runConfiguration->remoteUserName());
+    mainLayout->addRow(tr("Remote user name:"), m_userLineEdit);
+
+    // Unlikely to ever work: ssh uses /dev/tty directly instead of stdin/out
+#if USE_SSL_PASSWORD
+    m_passwordCheckBox = new QCheckBox(tr("Remote password:"));
+    m_passwordCheckBox->setToolTip(tr("Uncheck for passwordless login"));
+    m_passwordCheckBox->setChecked(m_runConfiguration
+        ->remoteHostRequiresPassword());
+    m_passwordLineEdit = new QLineEdit(m_runConfiguration->remoteUserPassword());
+    m_passwordLineEdit->setEchoMode(QLineEdit::Password);
+    m_passwordLineEdit->setEnabled(m_passwordCheckBox->isChecked());
+    mainLayout->addRow(m_passwordCheckBox, m_passwordLineEdit);
+#endif
+
+    m_portLineEdit = new QLineEdit(QString::number(m_runConfiguration->remotePort()));
+    mainLayout->addRow(tr("Remote SSH port:"), m_portLineEdit);
+
+    connect(m_configNameLineEdit, SIGNAL(textEdited(QString)), this,
+        SLOT(configNameEdited(QString)));
+    connect(m_argsLineEdit, SIGNAL(textEdited(QString)), this,
+        SLOT(argumentsEdited(QString)));
+    connect(m_runConfiguration, SIGNAL(targetInformationChanged()), this,
+        SLOT(updateTargetInformation()));
+    connect(m_hwButton, SIGNAL(toggled(bool)), this, SLOT(hostTypeChanged()));
+    connect(m_simButton, SIGNAL(toggled(bool)), this, SLOT(hostTypeChanged()));
+    connect(m_hostNameLineEdit, SIGNAL(textEdited(QString)), this,
+        SLOT(hostNameEdited(QString)));
+    connect(m_userLineEdit, SIGNAL(textEdited(QString)), this,
+        SLOT(userNameEdited(QString)));
+#if USE_SSL_PASSWORD
+    connect(m_passwordCheckBox, SIGNAL(stateChanged(int)), this,
+        SLOT(passwordUseChanged()));
+    connect(m_passwordLineEdit, SIGNAL(textEdited(QString)), this,
+        SLOT(passwordEdited(QString)));
+#endif
+    connect(m_portLineEdit, SIGNAL(textEdited(QString)), this,
+        SLOT(portEdited(QString)));
+    connect(m_simPathChooser, SIGNAL(changed(QString)), m_runConfiguration,
+        SLOT(setSimulatorPath(QString)));
+    connect(m_runConfiguration, SIGNAL(cachedSimulatorInformationChanged()),
+        this, SLOT(updateVisibleSimulatorParameter()));
+    if (m_runConfiguration->remoteHostIsSimulator())
+        m_simButton->setChecked(true);
+    else
+        m_hwButton->setChecked(true);
+}
+
+void MaemoRunConfigurationWidget::configNameEdited(const QString &text)
+{
+    m_runConfiguration->setName(text);
+}
+
+void MaemoRunConfigurationWidget::argumentsEdited(const QString &text)
+{
+    m_runConfiguration->setArguments(text.split(' ', QString::SkipEmptyParts));
+}
+
+void MaemoRunConfigurationWidget::updateTargetInformation()
+{
+    m_executableLabel->setText(m_runConfiguration->executable());
+}
+
+void MaemoRunConfigurationWidget::updateVisibleSimulatorParameter()
+{
+    m_simParamsValueLabel->setText(m_runConfiguration->visibleSimulatorParameter());
+}
+
+void MaemoRunConfigurationWidget::hostTypeChanged()
+{
+    Q_ASSERT(m_hwButton->isChecked() != m_simButton->isChecked());
+    const bool isSimulator = m_simButton->isChecked();
+    m_chooseSimPathLabel->setVisible(isSimulator);
+    m_simPathChooser->setVisible(isSimulator);
+    m_simParamsNameLabel->setVisible(isSimulator);
+    m_simParamsValueLabel->setVisible(isSimulator);
+    m_runConfiguration->setRemoteHostIsSimulator(isSimulator);
+}
+
+void MaemoRunConfigurationWidget::hostNameEdited(const QString &hostName)
+{
+    m_runConfiguration->setRemoteHostName(hostName);
+}
+
+void MaemoRunConfigurationWidget::userNameEdited(const QString &userName)
+{
+    m_runConfiguration->setRemoteUserName(userName);
+}
+
+#if USE_SSL_PASSWORD
+void MaemoRunConfigurationWidget::passwordUseChanged()
+{
+    const bool usePassword = m_passwordCheckBox->checkState() == Qt::Checked;
+    m_passwordLineEdit->setEnabled(usePassword);
+    m_runConfiguration->setRemoteHostRequiresPassword(usePassword);
+}
+
+void MaemoRunConfigurationWidget::passwordEdited(const QString &password)
+{
+    m_runConfiguration->setRemotePassword(password);
+}
+#endif
+
+void MaemoRunConfigurationWidget::portEdited(const QString &portString)
+{
+    bool isValidString;
+    int port = portString.toInt(&isValidString);
+    if (isValidString)
+        m_runConfiguration->setRemotePort(port);
+    else
+        m_portLineEdit->setText(QString::number(m_runConfiguration->remotePort()));
+}
+
+
+// #pragma mark -- MaemoRunConfigurationFactory
+
+
+MaemoRunConfigurationFactory::MaemoRunConfigurationFactory(QObject* parent)
+    : IRunConfigurationFactory(parent)
+{
+}
+
+MaemoRunConfigurationFactory::~MaemoRunConfigurationFactory()
+{
+}
+
+bool MaemoRunConfigurationFactory::canRestore(const QString &type) const
+{
+    return type == "Qt4ProjectManager.MaemoRunConfiguration";
+}
+
+QStringList MaemoRunConfigurationFactory::availableCreationTypes(
+    Project *pro) const
+{
+    Qt4Project *qt4project = qobject_cast<Qt4Project *>(pro);
+    if (qt4project) {
+        QStringList applicationProFiles;
+        QList<Qt4ProFileNode *> list = qt4project->applicationProFiles();
+        foreach (Qt4ProFileNode * node, list) {
+            applicationProFiles.append("MaemoRunConfiguration." + node->path());
+        }
+        return applicationProFiles;
+    }
+    return QStringList();
+}
+
+QString MaemoRunConfigurationFactory::displayNameForType(
+    const QString &type) const
+{
+    const int size = QString::fromLocal8Bit("MaemoRunConfiguration.").size();
+    return tr("%1 on Maemo device").arg(QFileInfo(type.mid(size))
+        .completeBaseName());
+}
+
+RunConfig MaemoRunConfigurationFactory::create(Project *project,
+    const QString &type)
+{
+    Qt4Project *qt4project = qobject_cast<Qt4Project *>(project);
+    Q_ASSERT(qt4project);
+
+    connect(project, SIGNAL(addedRunConfiguration(ProjectExplorer::Project*,
+        QString)), this, SLOT(addedRunConfiguration(ProjectExplorer::Project*)));
+    connect(project, SIGNAL(removedRunConfiguration(ProjectExplorer::Project*,
+        QString)), this, SLOT(removedRunConfiguration(ProjectExplorer::Project*)));
+
+    RunConfig rc;
+    const QLatin1String prefix("MaemoRunConfiguration.");
+    if (type.startsWith(prefix)) {
+        rc = RunConfig(new MaemoRunConfiguration(qt4project,
+            type.mid(QString(prefix).size())));
+    } else {
+        Q_ASSERT(type == "Qt4ProjectManager.MaemoRunConfiguration");
+        rc = RunConfig(new MaemoRunConfiguration(qt4project,
+            QString::null));
+    }
+
+    if (rc.data()) {
+        connect(project, SIGNAL(runConfigurationsEnabledStateChanged()),
+            rc.data(), SLOT(enabledStateChanged()));
+        connect(MaemoManager::instance(), SIGNAL(startStopQemu()), rc.data(),
+            SLOT(startStopQemu()));
+        connect(rc.data(), SIGNAL(qemuProcessStatus(bool)),
+            MaemoManager::instance(), SLOT(updateQemuSimulatorStarter(bool)));
+    }
+
+    ProjectExplorerPlugin *explorer = ProjectExplorerPlugin::instance();
+    connect(explorer->session(), SIGNAL(projectAdded(ProjectExplorer::Project*)),
+        this, SLOT(projectAdded(ProjectExplorer::Project*)));
+    connect(explorer->session(), SIGNAL(projectRemoved(ProjectExplorer::Project*)),
+        this, SLOT(projectRemoved(ProjectExplorer::Project*)));
+    connect(explorer, SIGNAL(currentProjectChanged(ProjectExplorer::Project*)),
+        this, SLOT(currentProjectChanged(ProjectExplorer::Project*)));
+
+    return rc;
+}
+
+bool hasMaemoRunConfig(ProjectExplorer::Project* project)
+{
+    if (Qt4Project *qt4Project = qobject_cast<Qt4Project *>(project)) {
+        QList<RunConfig> list = qt4Project->runConfigurations();
+        foreach (const RunConfig &rc, list) {
+            if (!rc.dynamicCast<MaemoRunConfiguration>().isNull())
+                return true;
+        }
+    }
+    return false;
+}
+
+void MaemoRunConfigurationFactory::addedRunConfiguration(
+    ProjectExplorer::Project* project)
+{
+    if (hasMaemoRunConfig(project))
+        MaemoManager::instance()->addQemuSimulatorStarter(project);
+}
+
+void MaemoRunConfigurationFactory::removedRunConfiguration(
+    ProjectExplorer::Project* project)
+{
+    if (!hasMaemoRunConfig(project))
+        MaemoManager::instance()->removeQemuSimulatorStarter(project);
+}
+
+void MaemoRunConfigurationFactory::projectAdded(
+    ProjectExplorer::Project* project)
+{
+    if (hasMaemoRunConfig(project))
+        MaemoManager::instance()->addQemuSimulatorStarter(project);
+}
+
+void MaemoRunConfigurationFactory::projectRemoved(
+    ProjectExplorer::Project* project)
+{
+    if (hasMaemoRunConfig(project))
+        MaemoManager::instance()->removeQemuSimulatorStarter(project);
+}
+
+void MaemoRunConfigurationFactory::currentProjectChanged(
+    ProjectExplorer::Project* project)
+{
+    bool hasRunConfig = hasMaemoRunConfig(project);
+    MaemoManager::instance()->setQemuSimulatorStarterEnabled(hasRunConfig);
+
+    bool isRunning = false;
+    if (Qt4Project *qt4Project = qobject_cast<Qt4Project *>(project)) {
+        const RunConfig &rc = qt4Project->activeRunConfiguration();
+        if (!rc.dynamicCast<MaemoRunConfiguration>().isNull())
+            isRunning = rc.dynamicCast<MaemoRunConfiguration>()->isQemuRunning();
+    }
+    MaemoManager::instance()->updateQemuSimulatorStarter(isRunning);
+}
+
+
+// #pragma mark -- MaemoRunControlFactory
+
+
+MaemoRunControlFactory::MaemoRunControlFactory(QObject *parent)
+    : IRunControlFactory(parent)
+{
+}
+
+bool MaemoRunControlFactory::canRun(const RunConfig &runConfiguration,
+    const QString &mode) const
+{
+    return !runConfiguration.dynamicCast<MaemoRunConfiguration>().isNull()
+        && (mode == ProjectExplorer::Constants::RUNMODE
+        || mode == ProjectExplorer::Constants::DEBUGMODE);
+}
+
+RunControl* MaemoRunControlFactory::create(const RunConfig &runConfig,
+    const QString &mode)
+{
+    QSharedPointer<MaemoRunConfiguration> rc = runConfig
+        .dynamicCast<MaemoRunConfiguration>();
+    Q_ASSERT(!rc.isNull());
+    Q_ASSERT(mode == ProjectExplorer::Constants::RUNMODE
+        || mode == ProjectExplorer::Constants::DEBUGMODE);
+    if (mode == ProjectExplorer::Constants::RUNMODE)
+        return new MaemoRunControl(rc);
+    return new MaemoDebugRunControl(rc);
+}
+
+QString MaemoRunControlFactory::displayName() const
+{
+    return tr("Run on device");
+}
+
+QWidget* MaemoRunControlFactory::configurationWidget(const RunConfig &config)
+{
+    Q_UNUSED(config)
+    return 0;
+}
+
+
+// #pragma mark -- AbstractMaemoRunControl
+
+
+AbstractMaemoRunControl::AbstractMaemoRunControl(RunConfig rc)
+    : RunControl(rc)
+    , runConfig(rc.objectCast<MaemoRunConfiguration>())
+{
+    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()));
+}
+
+void AbstractMaemoRunControl::startDeployment(bool forDebugging)
+{
+    QTC_ASSERT(!runConfig.isNull(), return);
+    QStringList deployables;
+    if (runConfig->currentlyNeedsDeployment()) {
+        deployingExecutable = true;
+        deployables << executableFileName();
+    } else {
+        deployingExecutable = false;
+    }
+    if (forDebugging && runConfig->debuggingHelpersNeedDeployment()) {
+        deployables << runConfig->dumperLib();
+        deployingDumperLib = true;
+    } else {
+        deployingDumperLib = false;
+    }
+    if (!deployables.isEmpty()) {
+        emit addToOutputWindow(this, tr("Files to deploy: %1.")
+            .arg(deployables.join(" ")));
+        QStringList cmdArgs;
+        cmdArgs << "-P" << port() << deployables << (runConfig->remoteUserName()
+            + "@" + runConfig->remoteHostName() + ":" + runConfig->remoteDir());
+        deployProcess.setWorkingDirectory(QFileInfo(executableOnHost()).absolutePath());
+        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);
+    }
+}
+
+void AbstractMaemoRunControl::stopDeployment()
+{
+    deployProcess.kill();
+}
+
+bool AbstractMaemoRunControl::isDeploying() const
+{
+    return deployProcess.state() != QProcess::NotRunning;
+}
+
+void AbstractMaemoRunControl::deployProcessFinished()
+{
+    bool success;
+    if (deployProcess.exitCode() == 0) {
+        emit addToOutputWindow(this, tr("Target deployed."));
+        success = true;
+        if (deployingExecutable)
+            runConfig->wasDeployed();
+        if (deployingDumperLib)
+            runConfig->debuggingHelpersDeployed();
+    } else {
+        emit error(this, tr("Deployment failed."));
+        success = false;
+    }
+    deploymentFinished(success);
+}
+
+const QString AbstractMaemoRunControl::executableOnHost() const
+{
+    return runConfig->executable();
+}
+
+const QString AbstractMaemoRunControl::port() const
+{
+    return QString::number(runConfig->remotePort());
+}
+
+const QString AbstractMaemoRunControl::executableFileName() const
+{
+    return QFileInfo(executableOnHost()).fileName();
+}
+
+const QString AbstractMaemoRunControl::executableOnTarget() const
+{
+    return QString::fromLocal8Bit("%1/%2").arg(runConfig->remoteDir()).
+        arg(executableFileName());
+}
+
+const QString AbstractMaemoRunControl::targetCmdLinePrefix() const
+{
+    return QString::fromLocal8Bit("chmod u+x %1; source /etc/profile; ").
+        arg(executableOnTarget());
+}
+
+bool AbstractMaemoRunControl::setProcessEnvironment(QProcess &process)
+{
+    QTC_ASSERT(!runConfig.isNull(), return false);
+    Qt4Project *qt4Project = qobject_cast<Qt4Project *>(runConfig->project());
+    QTC_ASSERT(runConfig, return false);
+    Environment env = Environment::systemEnvironment();
+    qt4Project->toolChain(qt4Project->activeBuildConfiguration())
+        ->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()));
+}
+
+
+// #pragma mark -- MaemoRunControl
+
+
+MaemoRunControl::MaemoRunControl(RunConfig runConfiguration)
+    : AbstractMaemoRunControl(runConfiguration)
+{
+    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)));
+}
+
+MaemoRunControl::~MaemoRunControl()
+{
+    stop();
+    stopProcess.waitForFinished(5000);
+}
+
+void MaemoRunControl::start()
+{
+    stoppedByUser = false;
+    startDeployment(false);
+}
+
+void MaemoRunControl::deploymentFinished(bool success)
+{
+    if (success)
+        startExecution();
+    else
+        emit finished();
+}
+
+void MaemoRunControl::startExecution()
+{
+    const QString remoteCall = QString::fromLocal8Bit("%1 %2 %3")
+        .arg(targetCmdLinePrefix()).arg(executableOnTarget())
+        .arg(runConfig->arguments().join(" "));
+
+    QStringList cmdArgs;
+    cmdArgs << "-n" << "-p" << port() << "-l" << runConfig->remoteUserName()
+        << runConfig->remoteHostName() << 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();
+    }
+}
+
+void MaemoRunControl::executionFinished()
+{
+    if (stoppedByUser)
+        emit addToOutputWindow(this, tr("Remote process stopped by user."));
+    else if (sshProcess.exitCode() != 0)
+        emit addToOutputWindow(this, tr("Remote process exited with error."));
+    else
+        emit addToOutputWindow(this, tr("Remote process finished successfully."));
+    emit finished();
+}
+
+void MaemoRunControl::stop()
+{
+    stoppedByUser = true;
+    if (isDeploying()) {
+        stopDeployment();
+    } else {
+        stopProcess.kill();
+        QStringList cmdArgs;
+        const QString remoteCall = QString::fromLocal8Bit("pkill -f %1; "
+            "sleep 1; pkill -9 -f %1").arg(executableFileName());
+        cmdArgs << "-n" << "-p" << port() << "-l" << runConfig->remoteUserName()
+            << runConfig->remoteHostName() << remoteCall;
+        stopProcess.start(runConfig->sshCmd(), cmdArgs);
+    }
+}
+
+bool MaemoRunControl::isRunning() const
+{
+    return isDeploying() || sshProcess.state() != QProcess::NotRunning;
+}
+
+
+// #pragma mark -- MaemoDebugRunControl
+
+
+MaemoDebugRunControl::MaemoDebugRunControl(RunConfig runConfiguration)
+    : AbstractMaemoRunControl(runConfiguration)
+    , gdbServerPort("10000"), debuggerManager(0)
+    , startParams(new Debugger::DebuggerStartParameters)
+{
+    setProcessEnvironment(gdbServer);
+    setProcessEnvironment(stopProcess);
+
+    qDebug("Maemo Debug run controls started");
+    debuggerManager = ExtensionSystem::PluginManager::instance()
+        ->getObject<Debugger::DebuggerManager>();
+
+    QTC_ASSERT(debuggerManager != 0, return);
+    startParams->startMode = Debugger::StartRemote;
+    startParams->executable = executableOnHost();
+    startParams->remoteChannel = runConfig->remoteHostName() + ":"
+        + 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(runConfig->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::deploymentFinished(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(" ")));
+    QStringList sshArgs;
+    sshArgs << "-t" << "-n" << "-l" << runConfig->remoteUserName() << "-p"
+        << port() << runConfig->remoteHostName() << remoteCall;
+    inferiorPid = -1;
+    disconnect(&gdbServer, SIGNAL(readyReadStandardError()), 0, 0);
+    connect(&gdbServer, SIGNAL(readyReadStandardError()), this,
+        SLOT(gdbServerStarted()));
+    gdbServer.start(runConfig->sshCmd(), sshArgs);
+    qDebug("Maemo: started gdb server, ssh arguments were %s", qPrintable(sshArgs.join(" ")));
+}
+
+void MaemoDebugRunControl::gdbServerStartFailed(const QString &reason)
+{
+    emit addToOutputWindow(this, tr("Debugging failed: %1").arg(reason));
+    emit stopRequested();
+    emit finished();
+}
+
+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();
+}
+
+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() || gdbServer.state() != QProcess::NotRunning
+        || debuggerManager->state() != Debugger::DebuggerNotReady;
+}
+
+void MaemoDebugRunControl::debuggingFinished()
+{
+    if (gdbServer.state() != QProcess::NotRunning) {
+        stopProcess.kill();
+        const QString remoteCall = QString::fromLocal8Bit("kill %1; sleep 1; "
+            "kill -9 %1; pkill -9 -f gdbserver").arg(inferiorPid);
+        QStringList sshArgs;
+        sshArgs << "-n" << "-l" << runConfig->remoteUserName() << "-p" << port()
+            << runConfig->remoteHostName() << remoteCall;
+        stopProcess.start(runConfig->sshCmd(), sshArgs);
+    }
+    qDebug("ssh return code is %d", gdbServer.exitCode());
+    emit addToOutputWindow(this, tr("Debugging finished."));
+    emit finished();
+}
+
+void MaemoDebugRunControl::debuggerOutput(const QString &output)
+{
+    emit addToOutputWindowInline(this, output);
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
+
+#include "maemorunconfiguration.moc"
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h
new file mode 100644
index 0000000000000000000000000000000000000000..e03dc263caa100ffa1c178911bfba3dddc09ebd4
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h
@@ -0,0 +1,228 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MAEMORUNCONFIGURATION_H
+#define MAEMORUNCONFIGURATION_H
+
+#include <QtCore/QDateTime>
+#include <QtGui/QWidget>
+
+#include <debugger/debuggermanager.h>
+#include <projectexplorer/runconfiguration.h>
+#include <projectexplorer/applicationlauncher.h>
+
+namespace Qt4ProjectManager {
+class Qt4Project;
+
+namespace Internal {
+
+class MaemoManager;
+class MaemoToolChain;
+using namespace ProjectExplorer;
+typedef QSharedPointer<RunConfiguration> RunConfig;
+
+#define USE_SSL_PASSWORD 0
+
+class ErrorDumper : public QObject
+{
+    Q_OBJECT
+public:
+    ErrorDumper(QObject *parent = 0)
+        : QObject(parent) {}
+
+public slots:
+    void printToStream(QProcess::ProcessError error);
+};
+
+
+class MaemoRunConfiguration : public RunConfiguration
+{
+    Q_OBJECT
+public:
+    MaemoRunConfiguration(Project *project, const QString &proFilePath);
+    ~MaemoRunConfiguration();
+
+    QString type() const;
+    bool isEnabled() const;
+    QWidget *configurationWidget();
+    Qt4Project *project() const;
+
+    void save(ProjectExplorer::PersistentSettingsWriter &writer) const;
+    void restore(const ProjectExplorer::PersistentSettingsReader &reader);
+
+    bool currentlyNeedsDeployment() const;
+    void wasDeployed();
+
+    bool hasDebuggingHelpers() const;
+    bool debuggingHelpersNeedDeployment() const;
+    void debuggingHelpersDeployed();
+
+    QString maddeRoot() const;
+    QString executable() const;
+    const QString sysRoot() const;
+    const QStringList arguments() const { return m_arguments; }
+    void setArguments(const QStringList &args);
+
+    QString simulator() const;
+    QString simulatorArgs() const;
+    QString simulatorPath() const;
+    QString visibleSimulatorParameter() const;
+
+    bool remoteHostIsSimulator() const { return m_remoteHostIsSimulator; }
+    const QString remoteHostName() const { return m_remoteHostName; }
+    const QString remoteUserName() const { return m_remoteUserName; }
+    int remotePort() const { return m_remotePort > 0 ? m_remotePort : 22; }
+
+    const QString remoteDir() const;
+    const QString sshCmd() const;
+    const QString scpCmd() const;
+    const QString gdbCmd() const;
+    const QString dumperLib() const;
+
+    void setRemoteHostIsSimulator(bool isSimulator);
+    void setRemoteHostName(const QString &hostName);
+    void setRemoteUserName(const QString &userName);
+    void setRemotePort(int port);
+
+    bool isQemuRunning() const;
+
+#if USE_SSL_PASSWORD
+    // Only valid if remoteHostRequiresPassword() == true.
+    void setRemotePassword(const QString &password);
+    const QString remoteUserPassword() const { return m_remoteUserPassword; }
+
+        void setRemoteHostRequiresPassword(bool requiresPassword);
+    bool remoteHostRequiresPassword() const { return m_remoteHostRequiresPassword; }
+#endif
+
+signals:
+    void targetInformationChanged();
+    void cachedSimulatorInformationChanged();
+    void qemuProcessStatus(bool running);
+
+private slots:
+    void invalidateCachedTargetInformation();
+
+    void setSimulatorPath(const QString &path);
+    void invalidateCachedSimulatorInformation();
+
+    void startStopQemu();
+    void qemuProcessFinished();
+
+    void enabledStateChanged();
+
+private:
+    void updateTarget();
+    void updateSimulatorInformation();
+    const QString cmd(const QString &cmdName) const;
+    const MaemoToolChain *toolchain() const;
+    bool fileNeedsDeployment(const QString &path, const QDateTime &lastDeployed) const;
+
+private:
+    // Keys for saving/loading attributes.
+    static const QString ArgumentsKey;
+    static const QString RemoteHostIsSimulatorKey;
+    static const QString RemoteHostRequiresPasswordKey;
+    static const QString RemoteHostNameKey;
+    static const QString RemoteUserNameKey;
+    static const QString RemoteUserPasswordKey;
+    static const QString RemotePortKey;
+    static const QString LastDeployedKey;
+    static const QString DebuggingHelpersLastDeployedKey;
+
+    QString m_executable;
+    QString m_proFilePath;
+    bool m_cachedTargetInformationValid;
+
+    QStringList m_arguments;
+    QString m_simulator;
+    QString m_simulatorArgs;
+    QString m_simulatorPath;
+    QString m_visibleSimulatorParameter;
+    bool m_cachedSimulatorInformationValid;
+
+    QString m_gdbPath;
+
+    // Information about the remote host.
+    bool m_remoteHostIsSimulator;
+    QString m_remoteHostName;
+    QString m_remoteUserName;
+    int m_remotePort;
+
+    QDateTime m_lastDeployed;
+    QDateTime m_debuggingHelpersLastDeployed;
+
+    QProcess *qemu;
+    ErrorDumper dumper;
+
+#if USE_SSL_PASSWORD
+    QString m_remoteUserPassword;
+    bool m_remoteHostRequiresPassword;
+#endif
+};
+
+
+class MaemoRunConfigurationFactory : public IRunConfigurationFactory
+{
+    Q_OBJECT
+public:
+    MaemoRunConfigurationFactory(QObject *parent);
+    ~MaemoRunConfigurationFactory();
+
+    bool canRestore(const QString &type) const;
+    QStringList availableCreationTypes(Project *project) const;
+    QString displayNameForType(const QString &type) const;
+    RunConfig create(Project *project, const QString &type);
+
+private slots:
+    void addedRunConfiguration(ProjectExplorer::Project* project);
+    void removedRunConfiguration(ProjectExplorer::Project* project);
+
+    void projectAdded(ProjectExplorer::Project* project);
+    void projectRemoved(ProjectExplorer::Project* project);
+    void currentProjectChanged(ProjectExplorer::Project* project);
+};
+
+
+class MaemoRunControlFactory : public IRunControlFactory
+{
+    Q_OBJECT
+public:
+    MaemoRunControlFactory(QObject *parent = 0);
+    bool canRun(const RunConfig &runConfiguration, const QString &mode) const;
+    RunControl* create(const RunConfig &runConfiguration, const QString &mode);
+    QString displayName() const;
+    QWidget *configurationWidget(const RunConfig &runConfiguration);
+};
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
+
+
+#endif // MAEMORUNCONFIGURATION_H
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6c029e5b0d33dc1750f2d0b607ee88d6e5d4c0ba
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.cpp
@@ -0,0 +1,220 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "maemotoolchain.h"
+#include "qtversionmanager.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QtDebug>
+
+using namespace ProjectExplorer;
+using namespace Qt4ProjectManager::Internal;
+
+#ifdef Q_OS_WIN32
+#define EXEC_SUFFIX ".exe"
+#else
+#define EXEC_SUFFIX ""
+#endif
+
+namespace {
+    const char *GCC_MAEMO_COMMAND = "arm-none-linux-gnueabi-gcc" EXEC_SUFFIX;
+}
+
+MaemoToolChain::MaemoToolChain(const Qt4ProjectManager::QtVersion *version)
+    : GccToolChain(QLatin1String(GCC_MAEMO_COMMAND))
+    , m_maddeInitialized(false)
+    , m_sysrootInitialized(false)
+    , m_simulatorInitialized(false)
+    , m_targetInitialized(false)
+    , m_toolchainInitialized(false)
+    , m_version(version)
+{
+}
+
+MaemoToolChain::~MaemoToolChain()
+{
+}
+
+ToolChain::ToolChainType MaemoToolChain::type() const
+{
+    return ToolChain::GCC_MAEMO;
+}
+
+QList<HeaderPath> MaemoToolChain::systemHeaderPaths()
+{
+    if (m_systemHeaderPaths.isEmpty()) {
+        GccToolChain::systemHeaderPaths();
+        m_systemHeaderPaths
+            .append(HeaderPath(QString("%1/usr/include").arg(sysrootRoot()),
+                HeaderPath::GlobalHeaderPath));
+    }
+    return m_systemHeaderPaths;
+}
+
+void MaemoToolChain::addToEnvironment(ProjectExplorer::Environment &env)
+{
+    if (m_version) {
+        env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin")
+            .arg(maddeRoot())));
+        env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin")
+            .arg(targetRoot())));
+        env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin")
+            .arg(toolchainRoot())));
+#ifdef Q_OS_WIN
+        env.set("HOME", QDir::toNativeSeparators(maddeRoot()
+            + QLatin1String("/home/") + QDir::home().dirName()));
+#endif
+    }
+}
+
+QString MaemoToolChain::makeCommand() const
+{
+    return QLatin1String("make" EXEC_SUFFIX);
+}
+
+bool MaemoToolChain::equals(ToolChain *other) const
+{
+    MaemoToolChain *toolChain = static_cast<MaemoToolChain*> (other);
+    return (other->type() == type()
+        && toolChain->sysrootRoot() == sysrootRoot()
+        && toolChain->simulatorRoot() == simulatorRoot()
+        && toolChain->targetRoot() == targetRoot()
+        && toolChain->toolchainRoot() == toolchainRoot());
+}
+
+QString MaemoToolChain::maddeRoot() const
+{
+    if (!m_maddeInitialized)
+        (const_cast<MaemoToolChain*> (this))->setMaddeRoot();
+    return m_maddeRoot;
+}
+
+QString MaemoToolChain::targetRoot() const
+{
+    if (!m_targetInitialized)
+        (const_cast<MaemoToolChain*> (this))->setTargetRoot();
+    return m_targetRoot;
+}
+
+QString MaemoToolChain::sysrootRoot() const
+{
+    if (!m_sysrootInitialized)
+        (const_cast<MaemoToolChain*> (this))->setSysrootAndToolchain();
+    return m_sysrootRoot;
+}
+
+QString MaemoToolChain::simulatorRoot() const
+{
+    if (!m_simulatorInitialized)
+        (const_cast<MaemoToolChain*> (this))->setSimulatorRoot();
+    return m_simulatorRoot;
+}
+
+QString MaemoToolChain::toolchainRoot() const
+{
+    if (!m_toolchainInitialized)
+        (const_cast<MaemoToolChain*> (this))->setSysrootAndToolchain();
+    return m_toolchainRoot;
+}
+
+void MaemoToolChain::setTargetRoot()
+{
+    m_targetInitialized = true;
+    QString qmake = QDir::cleanPath(m_version->qmakeCommand());
+    m_targetRoot = qmake.remove(QLatin1String("/bin/qmake" EXEC_SUFFIX));
+}
+
+void MaemoToolChain::setMaddeRoot()
+{
+    QDir dir(targetRoot());
+    dir.cdUp(); dir.cdUp();
+
+    m_maddeInitialized = true;
+    m_maddeRoot = dir.absolutePath();
+}
+
+void MaemoToolChain::setSimulatorRoot()
+{
+    QString target = QDir::cleanPath(targetRoot());
+    target = target.mid(target.lastIndexOf(QLatin1Char('/')) + 1);
+
+    QFile file(maddeRoot() + QLatin1String("/cache/madde.conf"));
+    if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+        QTextStream stream(&file);
+        while (!stream.atEnd()) {
+            QString line = stream.readLine().trimmed();
+            if (!line.startsWith(QLatin1String("target")))
+                continue;
+
+            const QStringList &list = line.split(QLatin1Char(' '));
+            if (list.count() <= 1 || list.at(1) != target)
+                continue;
+
+            line = stream.readLine().trimmed();
+            while (!stream.atEnd() && line != QLatin1String("end")) {
+                if (line.startsWith(QLatin1String("runtime"))) {
+                    const QStringList &list = line.split(QLatin1Char(' '));
+                    if (list.count() > 1) {
+                        m_simulatorRoot = maddeRoot()
+                            + QLatin1String("/runtimes/") + list.at(1).trimmed();
+                    }
+                    break;
+                }
+                line = stream.readLine().trimmed();
+            }
+        }
+    }
+
+    m_simulatorInitialized = true;
+}
+
+void MaemoToolChain::setSysrootAndToolchain()
+{
+    QFile file(QDir::cleanPath(targetRoot()) + QLatin1String("/information"));
+    if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+        QTextStream stream(&file);
+        while (!stream.atEnd()) {
+            const QString &line = stream.readLine().trimmed();
+            const QStringList &list = line.split(QLatin1Char(' '));
+            if (list.count() <= 1)
+                continue;
+            if (list.at(0) == QLatin1String("sysroot")) {
+                m_sysrootRoot = maddeRoot() + QLatin1String("/sysroots/")
+                    + list.at(1);
+            }
+            if (list.at(0) == QLatin1String("toolchain")) {
+                m_toolchainRoot = maddeRoot() + QLatin1String("/toolchains/")
+                    + list.at(1);
+            }
+        }
+    }
+
+    m_sysrootInitialized = true;
+    m_toolchainInitialized = true;
+}
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.h b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.h
new file mode 100644
index 0000000000000000000000000000000000000000..1ed3d52af224dab3c08109638021a117ecd738c0
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.h
@@ -0,0 +1,87 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MAEMOTOOLCHAIN_H
+#define MAEMOTOOLCHAIN_H
+
+#include <projectexplorer/toolchain.h>
+
+namespace Qt4ProjectManager {
+    class QtVersion;
+    namespace Internal {
+
+class MaemoToolChain : public ProjectExplorer::GccToolChain
+{
+public:
+    MaemoToolChain(const Qt4ProjectManager::QtVersion *version);
+    virtual ~MaemoToolChain();
+
+    QList<ProjectExplorer::HeaderPath> systemHeaderPaths();
+    void addToEnvironment(ProjectExplorer::Environment &env);
+    ProjectExplorer::ToolChain::ToolChainType type() const;
+    QString makeCommand() const;
+
+    QString maddeRoot() const;
+    QString targetRoot() const;
+    QString sysrootRoot() const;
+    QString simulatorRoot() const;
+    QString toolchainRoot() const;
+
+protected:
+    bool equals(ToolChain *other) const;
+
+private:
+    void setMaddeRoot();
+    void setTargetRoot();
+    void setSimulatorRoot();
+    void setSysrootAndToolchain();
+
+private:
+    QString m_maddeRoot;
+    bool m_maddeInitialized;
+
+    QString m_sysrootRoot;
+    bool m_sysrootInitialized;
+
+    QString m_simulatorRoot;
+    bool m_simulatorInitialized;
+
+    QString m_targetRoot;
+    bool m_targetInitialized;
+
+    QString m_toolchainRoot;
+    bool m_toolchainInitialized;
+
+    const Qt4ProjectManager::QtVersion *m_version;
+};
+
+    } // namespace Internal
+} // namespace Qt4ProjectManager
+
+#endif // MAEMOTOOLCHAIN_H
diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri
new file mode 100644
index 0000000000000000000000000000000000000000..31d800c74a4ff3311aa3232d305dad8e5082cc5c
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.pri
@@ -0,0 +1,14 @@
+SUPPORT_QT_MAEMO = $$(QTCREATOR_WITH_MAEMO)
+!isEmpty(SUPPORT_QT_MAEMO) {
+    message("Adding experimental support for Qt/Maemo applications.")
+    DEFINES += QTCREATOR_WITH_MAEMO
+    HEADERS += \
+        $$PWD/maemorunconfiguration.h \
+        $$PWD/maemomanager.h \
+        $$PWD/maemotoolchain.h
+    SOURCES += \
+        $$PWD/maemorunconfiguration.cpp \
+        $$PWD/maemomanager.cpp \
+        $$PWD/maemotoolchain.cpp
+    RESOURCES += $$PWD/qt-maemo.qrc
+}
diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.qrc b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..354fe64d1be9a16a17ec3a1d86223c8db39ffd9c
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-maemo/qt-maemo.qrc
@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/qt-maemo">
+        <file>images/qemu-run.png</file>
+        <file>images/qemu-stop.png</file>
+    </qresource>
+</RCC>
diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.pro b/src/plugins/qt4projectmanager/qt4projectmanager.pro
index a85ffcef011e6fdc409e650dc4f098070f9b18e6..de942dadbee0e3bd0ec59e1cc8a1ab28f48a14e4 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanager.pro
+++ b/src/plugins/qt4projectmanager/qt4projectmanager.pro
@@ -88,6 +88,7 @@ RESOURCES += qt4projectmanager.qrc \
     wizards/wizards.qrc
 include(../../shared/proparser/proparser.pri)
 include(qt-s60/qt-s60.pri)
+include(qt-maemo/qt-maemo.pri)
 include(customwidgetwizard/customwidgetwizard.pri)
 DEFINES += QT_NO_CAST_TO_ASCII
 OTHER_FILES += Qt4ProjectManager.pluginspec
diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp
index 468e9a260a2b7f035020d8d5b6b3a936e094f176..9471e3d1f30c8a8ce4dffd830d56b7fe2b4a8dd2 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp
+++ b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp
@@ -51,6 +51,10 @@
 #include "qt-s60/s60manager.h"
 #endif
 
+#ifdef QTCREATOR_WITH_MAEMO
+#include "qt-maemo/maemomanager.h"
+#endif
+
 #include <coreplugin/icore.h>
 #include <extensionsystem/pluginmanager.h>
 #include <projectexplorer/buildmanager.h>
@@ -160,6 +164,10 @@ bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString *
     addAutoReleasedObject(new S60Manager);
 #endif
 
+#ifdef QTCREATOR_WITH_MAEMO
+    addAutoReleasedObject(MaemoManager::instance());
+#endif
+
     // TODO reenable
     //m_embeddedPropertiesPage = new EmbeddedPropertiesPage;
     //addObject(m_embeddedPropertiesPage);
diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
index ac35590a6b476afb0828d04ee67e1ee105ccc6eb..a17b7e7092e37ac0f62a82c1d9b9201ca5294e5e 100644
--- a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp
@@ -95,15 +95,21 @@ QString Qt4RunConfiguration::type() const
 
 bool Qt4RunConfiguration::isEnabled() const
 {
-#ifdef QTCREATOR_WITH_S60
+#if defined(QTCREATOR_WITH_S60) || defined(QTCREATOR_WITH_MAEMO)
     Qt4Project *pro = qobject_cast<Qt4Project*>(project());
     QTC_ASSERT(pro, return false);
     ProjectExplorer::ToolChain::ToolChainType type = pro->toolChainType(pro->activeBuildConfiguration());
+#ifdef QTCREATOR_WITH_S60
     if (type == ProjectExplorer::ToolChain::WINSCW
         || type == ProjectExplorer::ToolChain::GCCE
         || type == ProjectExplorer::ToolChain::RVCT_ARMV5
         || type == ProjectExplorer::ToolChain::RVCT_ARMV6)
         return false;
+#endif
+#ifdef QTCREATOR_WITH_MAEMO
+    if (type == ProjectExplorer::ToolChain::GCC_MAEMO)
+        return false;
+#endif
 #endif
     return true;
 }
diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp
index d7a1dc3843c59bbcb6c06478b9789404111c2fb0..3125fccddd2d6af4357078766dd48d86583bae51 100644
--- a/src/plugins/qt4projectmanager/qtversionmanager.cpp
+++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp
@@ -35,6 +35,9 @@
 #ifdef QTCREATOR_WITH_S60
 #include "qt-s60/s60manager.h"
 #endif
+#ifdef QTCREATOR_WITH_MAEMO
+#include "qt-maemo/maemomanager.h"
+#endif
 
 #include <projectexplorer/debugginghelper.h>
 #include <projectexplorer/projectexplorer.h>
@@ -1055,6 +1058,10 @@ ProjectExplorer::ToolChain *QtVersion::createToolChain(ProjectExplorer::ToolChai
     } else if (type == ProjectExplorer::ToolChain::RVCT_ARMV5
                || type == ProjectExplorer::ToolChain::RVCT_ARMV6) {
         tempToolchain = S60Manager::instance()->createRVCTToolChain(this, type);
+#endif
+#ifdef QTCREATOR_WITH_MAEMO
+    } else if (type == ProjectExplorer::ToolChain::GCC_MAEMO) {
+        tempToolchain = MaemoManager::instance()->maemoToolChain(this);
 #endif
     } else {
         qDebug()<<"Could not create ToolChain for"<<mkspec();
@@ -1150,6 +1157,25 @@ QList<ProjectExplorer::ToolChain::ToolChainType> QtVersion::possibleToolChainTyp
                 << ProjectExplorer::ToolChain::RVCT_ARMV5
                 << ProjectExplorer::ToolChain::RVCT_ARMV6
                 << ProjectExplorer::ToolChain::WINSCW;
+#endif
+#ifdef QTCREATOR_WITH_MAEMO
+    } else if (spec.contains("linux-g++-opengl")) {
+        bool maemo = false;
+        const QString baseDir = m_versionInfo.contains("QT_INSTALL_DATA") ?
+            m_versionInfo.value("QT_INSTALL_DATA") : QLatin1String("");
+        QFile qconfigpri(baseDir + QLatin1String("/mkspecs/qconfig.pri"));
+        if (qconfigpri.exists()) {
+            qconfigpri.open(QIODevice::ReadOnly | QIODevice::Text);
+            QTextStream stream(&qconfigpri);
+            while (!stream.atEnd()) {
+                QString line = stream.readLine().trimmed();
+                if (line.startsWith(QLatin1String("QT_ARCH"))
+                    && line.endsWith(QLatin1String("arm")))
+                    maemo = true;
+            }
+        }
+        toolChains << (maemo ? ProjectExplorer::ToolChain::GCC_MAEMO
+                       : ProjectExplorer::ToolChain::GCC);
 #endif
     } else {
         toolChains << ProjectExplorer::ToolChain::GCC;