diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp
index a5b91c006bf0113af2a233dd262997c179de278f..d70bdcd2481761ec3e739e28a0e9eeb03e671797 100644
--- a/src/plugins/projectexplorer/toolchain.cpp
+++ b/src/plugins/projectexplorer/toolchain.cpp
@@ -123,6 +123,10 @@ QString ToolChain::toolChainName(ToolChainType tc)
         return QCoreApplication::translate("ToolChain", "WINSCW");
     case GCCE:
         return QCoreApplication::translate("ToolChain", "GCCE");
+    case GCCE_GNUPOC:
+        return QCoreApplication::translate("ToolChain", "GCCE/GnuPoc");
+    case RVCT_ARMV6_GNUPOC:
+        return QCoreApplication::translate("ToolChain", "RVCT (ARMV6)/GnuPoc");
     case RVCT_ARMV5:
         return QCoreApplication::translate("ToolChain", "RVCT (ARMV5)");
     case RVCT_ARMV6:
diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h
index 2492b5a417e919b65212d0797dffd1e2b97c8717..7af97d36cf18e0100629cf7d930f7b75c21abbf9 100644
--- a/src/plugins/projectexplorer/toolchain.h
+++ b/src/plugins/projectexplorer/toolchain.h
@@ -83,8 +83,10 @@ public:
         GCCE = 6,
         RVCT_ARMV5 = 7,
         RVCT_ARMV6 = 8,
-        GCC_MAEMO = 9,
-        LAST_VALID = 10,
+        GCC_MAEMO = 9,        
+        GCCE_GNUPOC = 10,
+        RVCT_ARMV6_GNUPOC = 11,
+        LAST_VALID = 11,
         OTHER = 200,
         UNKNOWN = 201,
         INVALID = 202
diff --git a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp
index ab4bb0df8df73aeb0bdfde09cb9ff6d1f5623895..e665beed1c066925eae8ede165cb3abd8d0736fe 100644
--- a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp
@@ -30,25 +30,32 @@
 #include "gccetoolchain.h"
 #include "qt4project.h"
 
+#include <utils/qtcassert.h>
+
 #include <QtCore/QDir>
-#include <QtDebug>
+#include <QtCore/QtDebug>
+
+enum { debug = 0 };
 
 using namespace ProjectExplorer;
 using namespace Qt4ProjectManager::Internal;
 
-GCCEToolChain::GCCEToolChain(S60Devices::Device device, const QString &gcceCommand)
-    : GccToolChain(gcceCommand),
-    m_deviceId(device.id),
-    m_deviceName(device.name),
-    m_deviceRoot(device.epocRoot),
+GCCEToolChain::GCCEToolChain(const S60Devices::Device &device,
+                             const QString &gcceCommand,
+                             ProjectExplorer::ToolChain::ToolChainType type) :
+    GccToolChain(gcceCommand),
+    m_mixin(device),
+    m_type(type),
     m_gcceCommand(gcceCommand)
 {
-
+    QTC_ASSERT(m_type == ProjectExplorer::ToolChain::GCCE || m_type == ProjectExplorer::ToolChain::GCCE_GNUPOC, return)
+    if (debug)
+        qDebug() << "GCCEToolChain on" << m_type << m_mixin.device();
 }
 
 ToolChain::ToolChainType GCCEToolChain::type() const
 {
-    return ToolChain::GCCE;
+    return m_type;
 }
 
 QByteArray GCCEToolChain::predefinedMacros()
@@ -66,34 +73,44 @@ QList<HeaderPath> GCCEToolChain::systemHeaderPaths()
 {
     if (m_systemHeaderPaths.isEmpty()) {
         GccToolChain::systemHeaderPaths();
-        m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath));
-        m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\stdapis").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath));
-        m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\stdapis\\sys").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath));
-        m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\variant").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath));
+        switch (m_type) {
+        case ProjectExplorer::ToolChain::GCCE:
+            m_systemHeaderPaths += m_mixin.epocHeaderPaths();
+            break;
+        case ProjectExplorer::ToolChain::GCCE_GNUPOC:
+            m_systemHeaderPaths += m_mixin.gnuPocHeaderPaths();
+            break;
+        default:
+            break;
+        }
     }
     return m_systemHeaderPaths;
 }
 
 void GCCEToolChain::addToEnvironment(ProjectExplorer::Environment &env)
 {
-    env.prependOrSetPath(QString("%1\\epoc32\\tools").arg(m_deviceRoot)); // e.g. make.exe
-    env.prependOrSetPath(QString("%1\\epoc32\\gcc\\bin").arg(m_deviceRoot)); // e.g. gcc.exe
-    env.prependOrSetPath(QFileInfo(m_gcceCommand).absolutePath());
-    env.set("EPOCDEVICE", QString("%1:%2").arg(m_deviceId, m_deviceName));
-    env.set("EPOCROOT", S60Devices::cleanedRootPath(m_deviceRoot));
+    switch (m_type) {
+    case ProjectExplorer::ToolChain::GCCE:
+        m_mixin.addEpocToEnvironment(&env);
+        env.prependOrSetPath(QFileInfo(m_gcceCommand).absolutePath());
+    case ProjectExplorer::ToolChain::GCCE_GNUPOC:
+        break;
+    default:
+        m_mixin.addGnuPocToEnvironment(&env);
+        break;
+    }
 }
 
 QString GCCEToolChain::makeCommand() const
 {
-    return "make";
+    return QLatin1String("make");
 }
 
-bool GCCEToolChain::equals(ToolChain *other) const
+bool GCCEToolChain::equals(ToolChain *otherIn) const
 {
-    GCCEToolChain *otherGCCE = static_cast<GCCEToolChain *>(other);
-    return (other->type() == type()
-            && m_deviceId == otherGCCE->m_deviceId
-            && m_deviceName == otherGCCE->m_deviceName
-            && m_deviceRoot == otherGCCE->m_deviceRoot
-            && m_gcceCommand == otherGCCE->m_gcceCommand);
+    if (otherIn->type() != type())
+                return false;
+    const GCCEToolChain *other = static_cast<const GCCEToolChain *>(otherIn);
+    return m_mixin == other->m_mixin
+           && m_gcceCommand == other->m_gcceCommand;
 }
diff --git a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h
index 84d30909dc2f4ef39cbbf78f94ef9ca5a3550f1b..3ce865890a8793d76ce1ec040b48a1b0b4a092d1 100644
--- a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h
+++ b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h
@@ -40,20 +40,23 @@ namespace Internal {
 class GCCEToolChain : public ProjectExplorer::GccToolChain
 {
 public:
-    GCCEToolChain(S60Devices::Device device, const QString &gcceCommand);
+    explicit GCCEToolChain(const S60Devices::Device &device,
+                           const QString &gcceCommand,
+                           ProjectExplorer::ToolChain::ToolChainType type);
+
     QByteArray predefinedMacros();
-    QList<ProjectExplorer::HeaderPath> systemHeaderPaths();
-    void addToEnvironment(ProjectExplorer::Environment &env);
-    ProjectExplorer::ToolChain::ToolChainType type() const;
-    QString makeCommand() const;
+    virtual QList<ProjectExplorer::HeaderPath> systemHeaderPaths();
+    virtual void addToEnvironment(ProjectExplorer::Environment &env);
+    virtual ProjectExplorer::ToolChain::ToolChainType type() const;
+    virtual QString makeCommand() const;
+
 protected:
-    bool equals(ToolChain *other) const;
+    virtual bool equals(ToolChain *other) const;
 
-private:
-    QString m_deviceId;
-    QString m_deviceName;
-    QString m_deviceRoot;
-    QString m_gcceCommand;
+private:    
+    const S60ToolChainMixin m_mixin;
+    const ProjectExplorer::ToolChain::ToolChainType m_type;
+    const QString m_gcceCommand;
 };
 
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp
index 46524f72d3079881a2aedbf9c7da95ecd62433a3..efa54dfb858edb38cfe27e5831eb98778ed79196 100644
--- a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp
@@ -33,12 +33,13 @@
 using namespace ProjectExplorer;
 using namespace Qt4ProjectManager::Internal;
 
-RVCTToolChain::RVCTToolChain(S60Devices::Device device, ToolChain::ToolChainType type)
-    : m_versionUpToDate(false),
-    m_deviceId(device.id),
-    m_deviceName(device.name),
-    m_deviceRoot(device.epocRoot),
-    m_type(type)
+RVCTToolChain::RVCTToolChain(const S60Devices::Device &device, ToolChain::ToolChainType type) :
+    m_mixin(device),
+    m_type(type),
+    m_versionUpToDate(false),
+    m_major(0),
+    m_minor(0),
+    m_build(0)
 {
 }
 
@@ -109,31 +110,40 @@ QList<HeaderPath> RVCTToolChain::systemHeaderPaths()
         QString rvctInclude = env.value(QString::fromLatin1("RVCT%1%2INC").arg(m_major).arg(m_minor));
         if (!rvctInclude.isEmpty())
             m_systemHeaderPaths.append(HeaderPath(rvctInclude, HeaderPath::GlobalHeaderPath));
-        m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath));
-        m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\stdapis").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath));
-        m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\stdapis\\sys").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath));
-        m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\variant").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath));
+        switch (m_type) {
+        case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
+            m_systemHeaderPaths += m_mixin.gnuPocHeaderPaths();
+            break;
+        default:
+            m_systemHeaderPaths += m_mixin.epocHeaderPaths();
+            break;
+        }
     }
     return m_systemHeaderPaths;
 }
 
 void RVCTToolChain::addToEnvironment(ProjectExplorer::Environment &env)
 {
-    env.prependOrSetPath(QString("%1\\epoc32\\tools").arg(m_deviceRoot)); // e.g. make.exe
-    env.prependOrSetPath(QString("%1\\epoc32\\gcc\\bin").arg(m_deviceRoot)); // e.g. gcc.exe
-    env.set("EPOCDEVICE", QString("%1:%2").arg(m_deviceId, m_deviceName));
-    env.set("EPOCROOT", S60Devices::cleanedRootPath(m_deviceRoot));
+    switch (m_type) {
+    case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
+        m_mixin.addGnuPocToEnvironment(&env);
+        break;
+    default:
+        m_mixin.addEpocToEnvironment(&env);
+        break;
+    }
 }
 
 QString RVCTToolChain::makeCommand() const
 {
-    return "make";
+    return QLatin1String("make");
 }
 
-bool RVCTToolChain::equals(ToolChain *other) const
+bool RVCTToolChain::equals(ToolChain *otherIn) const
 {
-    return (other->type() == type()
-            && m_deviceId == static_cast<RVCTToolChain *>(other)->m_deviceId
-            && m_deviceName == static_cast<RVCTToolChain *>(other)->m_deviceName);
+    if (otherIn->type() != type())
+        return false;
+    const RVCTToolChain *other = static_cast<const RVCTToolChain *>(otherIn);
+    return other->m_mixin == m_mixin;
 }
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h
index 2759cee45e027eaab6aebaa7c0e62907dd8163e2..93cf80235ff25da0d0b8ea5dc13fdb96ac48031d 100644
--- a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h
+++ b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h
@@ -40,7 +40,8 @@ namespace Internal {
 class RVCTToolChain : public ProjectExplorer::ToolChain
 {
 public:
-    RVCTToolChain(S60Devices::Device device, ProjectExplorer::ToolChain::ToolChainType type);
+    explicit RVCTToolChain(const S60Devices::Device &device,
+                           ProjectExplorer::ToolChain::ToolChainType type);
     virtual QByteArray predefinedMacros();
     QList<ProjectExplorer::HeaderPath> systemHeaderPaths();
     void addToEnvironment(ProjectExplorer::Environment &env);
@@ -52,14 +53,13 @@ protected:
 private:
     void updateVersion();
 
+    const S60ToolChainMixin m_mixin;
+    const ProjectExplorer::ToolChain::ToolChainType m_type;
     bool m_versionUpToDate;
     int m_major;
     int m_minor;
     int m_build;
-    QString m_deviceId;
-    QString m_deviceName;
-    QString m_deviceRoot;
-    ProjectExplorer::ToolChain::ToolChainType m_type;
+
     QByteArray m_predefinedMacros;
     QList<ProjectExplorer::HeaderPath> m_systemHeaderPaths;
 };
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
index 94dfb99aec6c85530336162c0a7df0bd8924e4ef..ee8904aad8fa8e04bad8dd0dbc0e21ab1816d22b 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -56,6 +56,8 @@
 using namespace ProjectExplorer;
 using namespace Qt4ProjectManager::Internal;
 
+enum { debug = 0 };
+
 // Format information about a file
 static QString lsFile(const QString &f)
 {
@@ -317,13 +319,18 @@ void S60DeviceRunConfiguration::updateTarget()
     m_packageTemplateFileName = QDir::cleanPath(
             m_workingDir + QLatin1Char('/') + m_targetName + QLatin1String("_template.pkg"));
 
-    ToolChain::ToolChainType toolchain = pro->toolChainType(pro->activeBuildConfiguration());
-    if (toolchain == ToolChain::GCCE)
+    switch (pro->toolChainType(pro->activeBuildConfiguration())) {
+    case ToolChain::GCCE:
+    case ToolChain::GCCE_GNUPOC:
         m_platform = QLatin1String("gcce");
-    else if (toolchain == ToolChain::RVCT_ARMV5)
+        break;
+    case ToolChain::RVCT_ARMV5:
         m_platform = QLatin1String("armv5");
-    else
+        break;
+    default: // including ToolChain::RVCT_ARMV6_GNUPOC:
         m_platform = QLatin1String("armv6");
+        break;
+    }
     if (projectBuildConfiguration & QtVersion::DebugBuild)
         m_target = QLatin1String("udeb");
     else
@@ -396,8 +403,9 @@ QSharedPointer<RunConfiguration> S60DeviceRunConfigurationFactory::create(Projec
 
 S60DeviceRunControlBase::S60DeviceRunControlBase(const QSharedPointer<RunConfiguration> &runConfiguration) :
     RunControl(runConfiguration),    
+    m_toolChain(ProjectExplorer::ToolChain::INVALID),
     m_makesis(new QProcess(this)),
-    m_signsis(new QProcess(this)),
+    m_signsis(0),
     m_launcher(0)
 {    
     connect(m_makesis, SIGNAL(readyReadStandardError()),
@@ -409,21 +417,12 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(const QSharedPointer<RunConfigu
     connect(m_makesis, SIGNAL(finished(int,QProcess::ExitStatus)),
             this, SLOT(makesisProcessFinished()));
 
-    connect(m_signsis, SIGNAL(readyReadStandardError()),
-            this, SLOT(readStandardError()));
-    connect(m_signsis, SIGNAL(readyReadStandardOutput()),
-            this, SLOT(readStandardOutput()));
-    connect(m_signsis, SIGNAL(error(QProcess::ProcessError)),
-            this, SLOT(signsisProcessFailed()));
-    connect(m_signsis, SIGNAL(finished(int,QProcess::ExitStatus)),
-            this, SLOT(signsisProcessFinished()));
-
     Qt4Project *project = qobject_cast<Qt4Project *>(runConfiguration->project());
     QTC_ASSERT(project, return);
 
     QSharedPointer<S60DeviceRunConfiguration> s60runConfig = runConfiguration.objectCast<S60DeviceRunConfiguration>();
     QTC_ASSERT(s60runConfig, return);
-
+    m_toolChain = s60runConfig->toolChainType();
     m_serialPortName = s60runConfig->serialPortName();
     m_serialPortFriendlyName = S60Manager::instance()->serialDeviceLister()->friendlyNameForPort(m_serialPortName);
     m_communicationType = s60runConfig->communicationType();
@@ -437,13 +436,42 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(const QSharedPointer<RunConfigu
     m_useCustomSignature = (s60runConfig->signingMode() == S60DeviceRunConfiguration::SignCustom);
     m_customSignaturePath = s60runConfig->customSignaturePath();
     m_customKeyPath = s60runConfig->customKeyPath();
-    m_toolsDirectory = S60Manager::instance()->deviceForQtVersion(
-            project->qtVersion(project->activeBuildConfiguration())).toolsRoot
-            + "/epoc32/tools";
-    m_executableFileName = lsFile(s60runConfig->localExecutableFileName());
-    m_makesisTool = m_toolsDirectory + "/makesis.exe";
+
+    ProjectExplorer::BuildConfiguration *const activeBuildConf = project->activeBuildConfiguration();
+    const S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(project->qtVersion(activeBuildConf));
+    switch (m_toolChain) {
+    case ProjectExplorer::ToolChain::GCCE_GNUPOC:
+    case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC: {
+            // 'sis' is a make target here. Set up with correct environment
+            ProjectExplorer::ToolChain *toolchain = project->toolChain(activeBuildConf);
+            m_makesisTool = toolchain->makeCommand();
+            m_toolsDirectory = device.epocRoot + QLatin1String("/epoc32/tools");
+            ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
+            toolchain->addToEnvironment(env);
+            m_makesis->setEnvironment(env.toStringList());
+        }
+        break;
+    default:        
+        m_toolsDirectory = device.toolsRoot + QLatin1String("/epoc32/tools");        
+        m_makesisTool = m_toolsDirectory + "/makesis.exe";
+        // Set up signing packages
+        m_signsis = new QProcess(this);
+        connect(m_signsis, SIGNAL(readyReadStandardError()),
+                this, SLOT(readStandardError()));
+        connect(m_signsis, SIGNAL(readyReadStandardOutput()),
+                this, SLOT(readStandardOutput()));
+        connect(m_signsis, SIGNAL(error(QProcess::ProcessError)),
+                this, SLOT(signsisProcessFailed()));
+        connect(m_signsis, SIGNAL(finished(int,QProcess::ExitStatus)),
+                this, SLOT(signsisProcessFinished()));
+        break;
+    }
+    m_executableFileName = s60runConfig->localExecutableFileName();
     m_packageFilePath = s60runConfig->packageFileName();
     m_packageFile = QFileInfo(m_packageFilePath).fileName();
+    if (debug)
+        qDebug() << "S60DeviceRunControlBase" << m_targetName << ProjectExplorer::ToolChain::toolChainName(m_toolChain)
+                 << m_serialPortName << m_communicationType << m_workingDirectory;
 }
 
 S60DeviceRunControlBase::~S60DeviceRunControlBase()
@@ -464,7 +492,7 @@ void S60DeviceRunControlBase::start()
     }
 
     emit addToOutputWindow(this, tr("Creating %1.sisx ...").arg(QDir::toNativeSeparators(m_baseFileName)));
-    emit addToOutputWindow(this, tr("Executable file: %1").arg(m_executableFileName));
+    emit addToOutputWindow(this, tr("Executable file: %1").arg(lsFile(m_executableFileName)));
 
     QString errorMessage;
     QString settingsCategory;
@@ -478,14 +506,27 @@ void S60DeviceRunControlBase::start()
         return;
     }
 
-    if (!createPackageFileFromTemplate(&errorMessage)) {
-        error(this, errorMessage);
-        emit finished();
-        return;
+    QStringList makeSisArgs;
+    switch (m_toolChain) {
+    case ProjectExplorer::ToolChain::GCCE_GNUPOC:
+    case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
+        makeSisArgs.push_back(QLatin1String("sis"));
+        break;
+    default:
+        makeSisArgs.push_back(m_packageFile);
+        if (!createPackageFileFromTemplate(&errorMessage)) {
+            error(this, errorMessage);
+            emit finished();
+            return;
+        }
+        break;
     }
+
     m_makesis->setWorkingDirectory(m_workingDirectory);
-    emit addToOutputWindow(this, tr("%1 %2").arg(QDir::toNativeSeparators(m_makesisTool), m_packageFile));
-    m_makesis->start(m_makesisTool, QStringList(m_packageFile), QIODevice::ReadOnly);
+    emit addToOutputWindow(this, tr("%1 %2").arg(QDir::toNativeSeparators(m_makesisTool), m_packageFile));    
+    if (debug)
+        qDebug() << m_makesisTool <<  makeSisArgs << m_workingDirectory;
+    m_makesis->start(m_makesisTool, makeSisArgs, QIODevice::ReadOnly);
 }
 
 static inline void stopProcess(QProcess *p)
@@ -551,7 +592,7 @@ bool S60DeviceRunControlBase::createPackageFileFromTemplate(QString *errorMessag
 
 void S60DeviceRunControlBase::makesisProcessFailed()
 {
-    processFailed("makesis.exe", m_makesis->error());
+    processFailed(m_makesisTool, m_makesis->error());
 }
 
 void S60DeviceRunControlBase::makesisProcessFinished()
@@ -562,6 +603,19 @@ void S60DeviceRunControlBase::makesisProcessFinished()
         emit finished();
         return;
     }
+    switch (m_toolChain) {
+    case ProjectExplorer::ToolChain::GCCE_GNUPOC:
+    case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
+        startDeployment();
+        break;
+    default:
+        startSigning();
+        break;
+    }
+}
+
+void S60DeviceRunControlBase::startSigning()
+{
     QString signsisTool = m_toolsDirectory + QLatin1String("/signsis.exe");
     QString sisFile = QFileInfo(m_baseFileName + QLatin1String(".sis")).fileName();
     QString sisxFile = QFileInfo(m_baseFileName + QLatin1String(".sisx")).fileName();
@@ -589,8 +643,13 @@ void S60DeviceRunControlBase::signsisProcessFinished()
         error(this, tr("An error occurred while creating the package."));
         stop();
         emit finished();
-        return;
+    } else {
+        startDeployment();
     }
+}
+
+void S60DeviceRunControlBase::startDeployment()
+{
     m_launcher = new trk::Launcher();
     connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
     connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(printConnectFailed(QString)));
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
index 04616bf109a8a499a5ab5be574266a5bbba4048e..bdde0ac2574db33f8aac97a827f4115fa7f8b170 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -127,8 +127,11 @@ public:
     QSharedPointer<ProjectExplorer::RunConfiguration> create(ProjectExplorer::Project *project, const QString &type);
 };
 
-/* S60DeviceRunControlBase: Builds and signs package and starts launcher
- * to deploy. Subclasses can configure the launcher to run or start a debugger. */
+/* S60DeviceRunControlBase: Builds the package and starts launcher
+ * to deploy. Subclasses can configure the launcher to run or start a debugger.
+ * Building the  package comprises for:
+ * GnuPoc: run 'make sis'
+ * Other:  run the makesis.exe tool, run signsis */
 
 class S60DeviceRunControlBase : public ProjectExplorer::RunControl
 {
@@ -175,7 +178,10 @@ private slots:
 
 private:        
     bool createPackageFileFromTemplate(QString *errorMessage);
+    void startSigning();
+    void startDeployment();
 
+    ProjectExplorer::ToolChain::ToolChainType m_toolChain;
     QString m_serialPortName;
     QString m_serialPortFriendlyName;
     int     m_communicationType;
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp
index a9bcc354e0f5c7b9606912b573c068bf1f8d76b4..8eb68d9d9aadad7784cecb7fcdfd92b78d2209cf 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp
@@ -28,6 +28,9 @@
 **************************************************************************/
 
 #include "s60devices.h"
+#include "gccetoolchain.h"
+
+#include <projectexplorer/environment.h>
 
 #include <QtCore/QSettings>
 #include <QtCore/QXmlStreamReader>
@@ -81,10 +84,47 @@ S60Devices::S60Devices(QObject *parent)
 {
 }
 
+// GNU-Poc stuff
+static const char *gnuPocRootC = "GNUPOC_ROOT";
+
+static inline QString msgEnvVarNotSet(const char *var)
+{
+    return QString::fromLatin1("The environment variable %1 is not set.").arg(QLatin1String(var));
+}
+
+static inline QString msgEnvVarDirNotExist(const QString &dir, const char *var)
+{
+    return QString::fromLatin1("The directory %1 pointed to by the environment variable %2 is not set.").arg(dir, QLatin1String(var));
+}
+
 bool S60Devices::readLinux()
 {
-    m_errorString = QLatin1String("not implemented.");
-    return false;
+    // Detect GNUPOC_ROOT/EPOC ROOT
+    const QByteArray gnuPocRootA = qgetenv(gnuPocRootC);
+    if (gnuPocRootA.isEmpty()) {
+        m_errorString = msgEnvVarNotSet(gnuPocRootC);
+        return false;
+    }
+
+    const QDir gnuPocRootDir(QString::fromLocal8Bit(gnuPocRootA));
+    if (!gnuPocRootDir.exists()) {
+        m_errorString = msgEnvVarDirNotExist(gnuPocRootDir.absolutePath(), gnuPocRootC);
+        return false;
+    }
+
+    const QDir epocDir(gnuPocRootDir.absolutePath() + QLatin1String("/symbian-sdks/5.0"));
+    if (!epocDir.exists()) {
+        m_errorString = QString::fromLatin1("EPOC could not be found at %1.").arg(epocDir.absolutePath());
+        return false;
+    }
+    // Check Qt
+    Device device;
+    device.id = device.name = QLatin1String("GnuPoc");
+    device.epocRoot = epocDir.absolutePath();
+    device.toolsRoot = gnuPocRootDir.absolutePath();
+    device.isDefault = true;
+    m_devices.push_back(device);
+    return true;
 }
 
 bool S60Devices::read()
@@ -162,6 +202,8 @@ bool S60Devices::readWin()
 bool S60Devices::detectQtForDevices()
 {
     for (int i = 0; i < m_devices.size(); ++i) {
+        if (!m_devices[i].qt.isEmpty())
+            continue;
         QFile qtDll(QString("%1/epoc32/release/winscw/udeb/QtCore.dll").arg(m_devices[i].epocRoot));
         if (!qtDll.exists() || !qtDll.open(QIODevice::ReadOnly)) {
             m_devices[i].qt = QString();
@@ -237,6 +279,57 @@ QString S60Devices::cleanedRootPath(const QString &deviceRoot)
     return path;
 }
 
+// S60ToolChainMixin
+S60ToolChainMixin::S60ToolChainMixin(const S60Devices::Device &d) :
+    m_device(d)
+{
+}
+
+const S60Devices::Device & S60ToolChainMixin::device() const
+{
+    return m_device;
+}
+
+bool S60ToolChainMixin::equals(const  S60ToolChainMixin &rhs) const
+{
+    return m_device.id == rhs.m_device.id
+           && m_device.name == rhs.m_device.name;
+}
+
+QList<ProjectExplorer::HeaderPath> S60ToolChainMixin::epocHeaderPaths() const
+{
+    QList<ProjectExplorer::HeaderPath> rc;
+    rc << ProjectExplorer::HeaderPath(m_device.epocRoot + QLatin1String("\\epoc32\\include"),
+                     ProjectExplorer::HeaderPath::GlobalHeaderPath)
+       << ProjectExplorer::HeaderPath(m_device.epocRoot + QLatin1String("\\epoc32\\include\\stdapis"),
+                     ProjectExplorer::HeaderPath::GlobalHeaderPath)
+       << ProjectExplorer::HeaderPath(m_device.epocRoot + QLatin1String("\\epoc32\\include\\stdapis\\sys"),
+                     ProjectExplorer::HeaderPath::GlobalHeaderPath)
+       << ProjectExplorer::HeaderPath(m_device.epocRoot + QLatin1String("\\epoc32\\include\\variant"),
+                     ProjectExplorer::HeaderPath::GlobalHeaderPath);
+    return rc;
+}
+
+void S60ToolChainMixin::addEpocToEnvironment(ProjectExplorer::Environment *env) const
+{
+    env->prependOrSetPath(m_device.epocRoot + QLatin1String("\\epoc32\\tools")); // e.g. make.exe
+    env->prependOrSetPath(m_device.epocRoot + QLatin1String("\\epoc32\\gcc\\bin")); // e.g. gcc.exe
+    env->set(QLatin1String("EPOCDEVICE"), m_device.id + QLatin1Char(':') + m_device.name);
+    env->set(QLatin1String("EPOCROOT"), S60Devices::cleanedRootPath(m_device.epocRoot));
+}
+
+QList<ProjectExplorer::HeaderPath> S60ToolChainMixin::gnuPocHeaderPaths() const
+{
+    return QList<ProjectExplorer::HeaderPath>(); // TODO:
+}
+
+void S60ToolChainMixin::addGnuPocToEnvironment(ProjectExplorer::Environment *env) const
+{
+    env->prependOrSetPath(m_device.toolsRoot + QLatin1String("/bin"));
+    //  # trailing "/" is required!
+    env->set(QLatin1String("EPOCROOT"),  m_device.epocRoot + QLatin1Char('/'));
+}
+
 QDebug operator<<(QDebug db, const S60Devices::Device &d)
 {
     QDebug nospace = db.nospace();
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devices.h b/src/plugins/qt4projectmanager/qt-s60/s60devices.h
index 01173d979af3e7ce131b14002b618642fc4f0e56..895b89ce7b7b98aff2bfe359e58448c50f77caa9 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devices.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devices.h
@@ -30,6 +30,8 @@
 #ifndef S60DEVICES_H
 #define S60DEVICES_H
 
+#include <projectexplorer/toolchain.h>
+
 #include <QtCore/QObject>
 #include <QtCore/QString>
 #include <QtCore/QList>
@@ -76,6 +78,35 @@ private:
     QList<Device> m_devices;
 };
 
+/* Mixin for the toolchains with convenience functions for EPOC
+ * (Windows) and GnuPoc (Linux). */
+
+class S60ToolChainMixin {
+    Q_DISABLE_COPY(S60ToolChainMixin)
+public:
+    explicit S60ToolChainMixin(const S60Devices::Device &device);
+
+    const S60Devices::Device &device() const;
+
+    // Epoc
+    QList<ProjectExplorer::HeaderPath> epocHeaderPaths() const;
+    void addEpocToEnvironment(ProjectExplorer::Environment *env) const;
+
+    // GnuPoc
+    QList<ProjectExplorer::HeaderPath> gnuPocHeaderPaths() const;
+    void addGnuPocToEnvironment(ProjectExplorer::Environment *env) const;
+
+    bool equals(const S60ToolChainMixin &rhs) const;
+
+private:
+    const S60Devices::Device m_device;
+};
+
+inline bool operator==(const S60ToolChainMixin &s1, const S60ToolChainMixin &s2)
+{ return s1.equals(s2); }
+inline bool operator!=(const S60ToolChainMixin &s1, const S60ToolChainMixin &s2)
+{ return !s1.equals(s2); }
+
 QDebug operator<<(QDebug dbg, const S60Devices::Device &d);
 QDebug operator<<(QDebug dbg, const S60Devices &d);
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
index fece8f8237cadf58407c0923262b57e65a6cc133..c123826404a669955b947998b7014b024ee734e0 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
@@ -155,6 +155,15 @@ QString S60Manager::deviceIdFromDetectionSource(const QString &autoDetectionSour
     return QString();
 }
 
+static inline QString qmakeFromQtDir(const QString &qtDir)
+{
+    QString qmake = qtDir + QLatin1String("/bin/qmake");
+#ifdef Q_OS_WIN
+    qmake += QLatin1String(".exe");
+#endif
+    return qmake;
+}
+
 void S60Manager::updateQtVersions()
 {
     // This assumes that the QtVersionManager has already read
@@ -176,11 +185,11 @@ void S60Manager::updateQtVersions()
             }
         }
         if (deviceVersion) {
-            deviceVersion->setQMakeCommand(device.qt+"/bin/qmake.exe");
+            deviceVersion->setQMakeCommand(qmakeFromQtDir(device.qt));
             deviceVersion->setName(QString("%1 (Qt %2)").arg(device.id, deviceVersion->qtVersionString()));
             handledVersions.append(deviceVersion);
         } else {
-            deviceVersion = new QtVersion(QString("%1 (Qt %2)").arg(device.id), device.qt+"/bin/qmake.exe",
+            deviceVersion = new QtVersion(QString("%1 (Qt %2)").arg(device.id), qmakeFromQtDir(device.qt),
                                           true, QString("%1.%2").arg(S60_AUTODETECTION_SOURCE, device.id));
             deviceVersion->setName(deviceVersion->name().arg(deviceVersion->qtVersionString()));
             versionsToAdd.append(deviceVersion);
@@ -211,7 +220,12 @@ ProjectExplorer::ToolChain *S60Manager::createGCCEToolChain(const Qt4ProjectMana
     ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
     env.prependOrSetPath(version->gcceDirectory()+"/bin");
     QString gcceCommandPath= env.searchInPath(GCCE_COMMAND);
-    return new GCCEToolChain(deviceForQtVersion(version), gcceCommandPath);
+    return new GCCEToolChain(deviceForQtVersion(version), gcceCommandPath, ProjectExplorer::ToolChain::GCCE);
+}
+
+ProjectExplorer::ToolChain *S60Manager::createGCCE_GnuPocToolChain(const Qt4ProjectManager::QtVersion *version) const
+{
+    return new GCCEToolChain(deviceForQtVersion(version), QLatin1String("arm-none-symbianelf-g++"), ProjectExplorer::ToolChain::GCCE_GNUPOC);
 }
 
 ProjectExplorer::ToolChain *S60Manager::createRVCTToolChain(
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.h b/src/plugins/qt4projectmanager/qt-s60/s60manager.h
index 77e93be3a93dbffce8ef41a51fdff3664912f173..1633b1bb9c9aabbb7b0591467c63cb1bca260bde 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60manager.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.h
@@ -54,6 +54,7 @@ public:
 
     ProjectExplorer::ToolChain *createWINSCWToolChain(const Qt4ProjectManager::QtVersion *version) const;
     ProjectExplorer::ToolChain *createGCCEToolChain(const Qt4ProjectManager::QtVersion *version) const;
+    ProjectExplorer::ToolChain *createGCCE_GnuPocToolChain(const Qt4ProjectManager::QtVersion *version) const;
     ProjectExplorer::ToolChain *createRVCTToolChain(const Qt4ProjectManager::QtVersion *version,
                                                     ProjectExplorer::ToolChain::ToolChainType type) const;
 
diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
index 658dc00425eabf1bf127bdee6d3ba2fd9a8cc594..efeaa228b55aef419804fa6c491688442913b77d 100644
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ b/src/plugins/qt4projectmanager/qt4project.cpp
@@ -505,24 +505,37 @@ QString Qt4Project::makeCommand(BuildConfiguration *configuration) const
     return tc ? tc->makeCommand() : "make";
 }
 
+#ifdef QTCREATOR_WITH_S60
+static inline QString symbianMakeTarget(QtVersion::QmakeBuildConfig buildConfig,
+                                        const QString &type)
+{
+    QString rc = (buildConfig & QtVersion::DebugBuild) ?
+                 QLatin1String("debug-") : QLatin1String("release-");
+    rc += type;
+    return rc;
+}
+#endif
+
 QString Qt4Project::defaultMakeTarget(BuildConfiguration *configuration) const
 {
 #ifdef QTCREATOR_WITH_S60
     ToolChain *tc = toolChain(configuration);
     if (!tc)
         return QString::null;
-    QtVersion::QmakeBuildConfig buildConfig
+    const QtVersion::QmakeBuildConfig buildConfig
             = QtVersion::QmakeBuildConfig(activeBuildConfiguration()->value("buildConfiguration").toInt());
 
-    if (tc->type() == ToolChain::GCCE) {
-        if (!(buildConfig & QtVersion::DebugBuild)) {
-            return "release-gcce";
-        }
-        return "debug-gcce";
-    } else if (tc->type() == ToolChain::RVCT_ARMV5) {
-        return (buildConfig & QtVersion::DebugBuild ? "debug-" : "release-") + QLatin1String("armv5");
-    } else if (tc->type() == ToolChain::RVCT_ARMV6) {
-        return (buildConfig & QtVersion::DebugBuild ? "debug-" : "release-") + QLatin1String("armv6");
+    switch (tc->type()) {
+    case ToolChain::GCCE:
+    case ToolChain::GCCE_GNUPOC:
+        return symbianMakeTarget(buildConfig, QLatin1String("gcce"));
+    case ToolChain::RVCT_ARMV5:
+        return symbianMakeTarget(buildConfig, QLatin1String("armv5"));
+    case ToolChain::RVCT_ARMV6:
+    case ToolChain::RVCT_ARMV6_GNUPOC:
+        return symbianMakeTarget(buildConfig, QLatin1String("armv6"));
+    default:
+        break;
     }
 #else
     Q_UNUSED(configuration);
diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp
index e9b824922936ecb695c14bf0746af8d0307007c9..c3fa345b6d290c69af59610fc7d71c29f1efbb2e 100644
--- a/src/plugins/qt4projectmanager/qtversionmanager.cpp
+++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp
@@ -1049,6 +1049,7 @@ ProjectExplorer::ToolChain::ToolChainType QtVersion::defaultToolchainType() cons
 // if none, then it's INVALID everywhere this function is called
 void QtVersion::updateToolChainAndMkspec() const
 {
+    typedef QSharedPointer<ProjectExplorer::ToolChain> ToolChainPtr;
     if (m_toolChainUpToDate)
         return;
 
@@ -1156,35 +1157,36 @@ void QtVersion::updateToolChainAndMkspec() const
     QString ce_arch = reader->value("CE_ARCH");
     QString qt_arch = reader->value("QT_ARCH");
     if (!ce_sdk.isEmpty() && !ce_arch.isEmpty()) {
-        QString wincePlatformName = ce_sdk + " (" + ce_arch + ")";
-        m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>(
-                ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatformName));
+        QString wincePlatformName = ce_sdk + " (" + ce_arch + QLatin1Char(')');
+        m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatformName));
     } else if (makefileGenerator == "SYMBIAN_ABLD") {
 #ifdef QTCREATOR_WITH_S60
-        m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>(
-                S60Manager::instance()->createGCCEToolChain(this));
-        m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>(
-                S60Manager::instance()->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5));
-        m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>(
-                S60Manager::instance()->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6));
-        m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>(
-                S60Manager::instance()->createWINSCWToolChain(this));
+        if (S60Manager *s60mgr = S60Manager::instance()) {            
+#    ifdef Q_OS_WIN
+            m_toolChains << ToolChainPtr(s60mgr->createGCCEToolChain(this))
+                         << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5))
+                         << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6))
+                         << ToolChainPtr(s60mgr->createWINSCWToolChain(this));
+#    else
+            m_toolChains << ToolChainPtr(s60mgr->createGCCE_GnuPocToolChain(this))
+                         << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC));
+#    endif
+        }
 #endif
     } else if (qt_arch == "arm") {
 #ifdef QTCREATOR_WITH_MAEMO
-        m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>(
-                MaemoManager::instance()->maemoToolChain(this));
+        m_toolChains << ToolChainPtr(MaemoManager::instance()->maemoToolChain(this));
 #endif
     } else if (qmakeCXX == "cl" || qmakeCXX == "icl") {
         // TODO proper support for intel cl
-        m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>(
+        m_toolChains << ToolChainPtr(
                 ProjectExplorer::ToolChain::createMSVCToolChain(msvcVersion(), isQt64Bit()));
     } else if (qmakeCXX == "g++" && makefileGenerator == "MINGW") {
         ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
         //addToEnvironment(env);
         env.prependOrSetPath(mingwDirectory() + "/bin");
         qmakeCXX = env.searchInPath(qmakeCXX);
-        m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>(
+        m_toolChains << ToolChainPtr(
                 ProjectExplorer::ToolChain::createMinGWToolChain(qmakeCXX, mingwDirectory()));
     } else if (qmakeCXX == "g++" || qmakeCXX == "icc") {
         ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
@@ -1195,8 +1197,7 @@ void QtVersion::updateToolChainAndMkspec() const
             // Unfortunately, we need a valid QMAKE_CXX to configure the parser.
             qmakeCXX = QLatin1String("cc");
         }
-        m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>(
-                ProjectExplorer::ToolChain::createGccToolChain(qmakeCXX));
+        m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createGccToolChain(qmakeCXX));
     }
 
     if (m_toolChains.isEmpty()) {