diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
index e6b6bd98a0c56d3849c0226da50d2af047e81a5d..3f952ed74c005325f27734d0c626c2160ae2e7bd 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
@@ -38,7 +38,7 @@
 #include "cmaketarget.h"
 
 #include <projectexplorer/projectexplorerconstants.h>
-#include <projectexplorer/toolchain.h>
+#include <projectexplorer/toolchainmanager.h>
 #include <projectexplorer/buildsteplist.h>
 #include <utils/qtcassert.h>
 
@@ -50,7 +50,7 @@ using namespace Internal;
 namespace {
 const char * const CMAKE_BC_ID("CMakeProjectManager.CMakeBuildConfiguration");
 
-const char * const MSVC_VERSION_KEY("CMakeProjectManager.CMakeBuildConfiguration.MsvcVersion");
+const char * const TOOLCHAIN_KEY("CMakeProjectManager.CMakeBuildConfiguration.ToolChain");
 const char * const BUILD_DIRECTORY_KEY("CMakeProjectManager.CMakeBuildConfiguration.BuildDirectory");
 } // namespace
 
@@ -74,7 +74,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(CMakeTarget *parent, CMakeBuild
 QVariantMap CMakeBuildConfiguration::toMap() const
 {
     QVariantMap map(ProjectExplorer::BuildConfiguration::toMap());
-    map.insert(QLatin1String(MSVC_VERSION_KEY), m_msvcVersion);
+    map.insert(QLatin1String(TOOLCHAIN_KEY), m_toolChain ? m_toolChain->id() : QString());
     map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory);
     return map;
 }
@@ -84,7 +84,8 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
     if (!BuildConfiguration::fromMap(map))
         return false;
 
-    m_msvcVersion = map.value(QLatin1String(MSVC_VERSION_KEY)).toString();
+    m_toolChain = ProjectExplorer::ToolChainManager::instance()->
+            findToolChain(map.value(QLatin1String(TOOLCHAIN_KEY)).toString());
     m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), cmakeTarget()->defaultBuildDirectory()).toString();
 
     return true;
@@ -105,41 +106,6 @@ QString CMakeBuildConfiguration::buildDirectory() const
     return m_buildDirectory;
 }
 
-ProjectExplorer::ToolChainType CMakeBuildConfiguration::toolChainType() const
-{
-    if (m_toolChain)
-        return m_toolChain->type();
-    return ProjectExplorer::ToolChain_UNKNOWN;
-}
-
-ProjectExplorer::ToolChain *CMakeBuildConfiguration::toolChain() const
-{
-    updateToolChain();
-    return m_toolChain;
-}
-
-void CMakeBuildConfiguration::updateToolChain() const
-{
-    ProjectExplorer::ToolChain *newToolChain = 0;
-    if (msvcVersion().isEmpty()) {
-#ifdef Q_OS_WIN
-        newToolChain = ProjectExplorer::ToolChain::createMinGWToolChain("gcc", QString());
-#else
-        newToolChain = ProjectExplorer::ToolChain::createGccToolChain("gcc");
-#endif
-    } else { // msvc
-        newToolChain = ProjectExplorer::ToolChain::createMSVCToolChain(m_msvcVersion, false);
-    }
-
-    if (ProjectExplorer::ToolChain::equals(newToolChain, m_toolChain)) {
-        delete newToolChain;
-        newToolChain = 0;
-    } else {
-        delete m_toolChain;
-        m_toolChain = newToolChain;
-    }
-}
-
 void CMakeBuildConfiguration::setBuildDirectory(const QString &buildDirectory)
 {
     if (m_buildDirectory == buildDirectory)
@@ -149,21 +115,6 @@ void CMakeBuildConfiguration::setBuildDirectory(const QString &buildDirectory)
     emit environmentChanged();
 }
 
-QString CMakeBuildConfiguration::msvcVersion() const
-{
-    return m_msvcVersion;
-}
-
-void CMakeBuildConfiguration::setMsvcVersion(const QString &msvcVersion)
-{
-    if (m_msvcVersion == msvcVersion)
-        return;
-    m_msvcVersion = msvcVersion;
-    updateToolChain();
-
-    emit msvcVersionChanged();
-}
-
 ProjectExplorer::IOutputParser *CMakeBuildConfiguration::createOutputParser() const
 {
     if (m_toolChain)
@@ -255,10 +206,10 @@ CMakeBuildConfiguration *CMakeBuildConfigurationFactory::create(ProjectExplorer:
         delete bc;
         return 0;
     }
+    bc->setToolChain(copw.toolChain());
     cmtarget->addBuildConfiguration(bc); // this also makes the name unique
 
     bc->setBuildDirectory(copw.buildDirectory());
-    bc->setMsvcVersion(copw.msvcVersion());
     cmtarget->cmakeProject()->parseCMakeLists();
 
     // Default to all
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
index 808dbe9426e331e59b23e588f52ad00a4652d867..c26dcf542e625054fd8ccb8923aae930b3e4a1fa 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
@@ -35,7 +35,7 @@
 #define CMAKEBUILDCONFIGURATION_H
 
 #include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/toolchaintype.h>
+#include <projectexplorer/abi.h>
 
 namespace ProjectExplorer {
 class ToolChain;
@@ -60,23 +60,14 @@ public:
 
     virtual QString buildDirectory() const;
 
-    ProjectExplorer::ToolChainType toolChainType() const;
-    ProjectExplorer::ToolChain *toolChain() const;
-
     void setBuildDirectory(const QString &buildDirectory);
 
-    QString msvcVersion() const;
-    void setMsvcVersion(const QString &msvcVersion);
-
     QVariantMap toMap() const;
 
     ProjectExplorer::IOutputParser *createOutputParser() const;
 
     Utils::Environment baseEnvironment() const;
 
-signals:
-    void msvcVersionChanged();
-
 protected:
     CMakeBuildConfiguration(CMakeTarget *parent, CMakeBuildConfiguration *source);
     virtual bool fromMap(const QVariantMap &map);
diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp
index d1416661346c53fe33d71efb575a4658958f27db..39e74a76db13c4542ae77175b2186ee7c1ec8bdd 100644
--- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp
@@ -44,7 +44,7 @@
 #include "cmakeprojectmanager.h"
 
 #include <utils/pathchooser.h>
-#include <projectexplorer/toolchain.h>
+#include <projectexplorer/toolchainmanager.h>
 
 #include <QtGui/QVBoxLayout>
 #include <QtGui/QFormLayout>
@@ -72,7 +72,8 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const
     : m_cmakeManager(cmakeManager),
       m_sourceDirectory(sourceDirectory),
       m_creatingCbpFiles(false),
-      m_environment(env)
+      m_environment(env),
+      m_toolChain(0)
 {
     int startid;
     if (hasInSourceBuild()) {
@@ -106,7 +107,8 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const
     : m_cmakeManager(cmakeManager),
       m_sourceDirectory(sourceDirectory),
       m_creatingCbpFiles(true),
-      m_environment(env)
+      m_environment(env),
+      m_toolChain(0)
 {
 
     CMakeRunPage::Mode rmode;
@@ -126,7 +128,8 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const
     : m_cmakeManager(cmakeManager),
       m_sourceDirectory(sourceDirectory),
       m_creatingCbpFiles(true),
-      m_environment(env)
+      m_environment(env),
+      m_toolChain(0)
 {
     m_buildDirectory = oldBuildDirectory;
     addPage(new ShadowBuildPage(this, true));
@@ -196,26 +199,27 @@ void CMakeOpenProjectWizard::setBuildDirectory(const QString &directory)
     m_buildDirectory = directory;
 }
 
-QString CMakeOpenProjectWizard::msvcVersion() const
+QString CMakeOpenProjectWizard::arguments() const
 {
-    return m_msvcVersion;
+    return m_arguments;
 }
 
-void CMakeOpenProjectWizard::setMsvcVersion(const QString &version)
+void CMakeOpenProjectWizard::setArguments(const QString &args)
 {
-    m_msvcVersion = version;
+    m_arguments = args;
 }
 
-QString CMakeOpenProjectWizard::arguments() const
+ProjectExplorer::ToolChain *CMakeOpenProjectWizard::toolChain() const
 {
-    return m_arguments;
+    return m_toolChain;
 }
 
-void CMakeOpenProjectWizard::setArguments(const QString &args)
+void CMakeOpenProjectWizard::setToolChain(ProjectExplorer::ToolChain *tc)
 {
-    m_arguments = args;
+    m_toolChain = tc;
 }
 
+
 Utils::Environment CMakeOpenProjectWizard::environment() const
 {
     return m_environment;
@@ -236,7 +240,6 @@ InSourceBuildPage::InSourceBuildPage(CMakeOpenProjectWizard *cmakeWizard)
     setTitle(tr("Build Location"));
 }
 
-
 ShadowBuildPage::ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard, bool change)
     : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard)
 {
@@ -378,9 +381,8 @@ void CMakeRunPage::initializePage()
         m_descriptionLabel->setText(tr("Refreshing cbp file in %1.").arg(m_buildDirectory));
     }
     if (m_cmakeWizard->cmakeManager()->hasCodeBlocksMsvcGenerator()) {
-        m_generatorComboBox->setVisible(true);
+        // Try to find out generator from CMakeCache file, if it exists
         QString cachedGenerator;
-        // Try to find out generator from CMakeCachhe file, if it exists
 
         QFile fi(m_buildDirectory + "/CMakeCache.txt");
         if (fi.exists()) {
@@ -398,67 +400,66 @@ void CMakeRunPage::initializePage()
                 }
             }
         }
-        m_generatorComboBox->clear();
-        // Find out whether we have multiple msvc versions
-        QStringList msvcVersions = ProjectExplorer::ToolChain::availableMSVCVersions();
-        if (msvcVersions.isEmpty()) {
-
-        } else if (msvcVersions.count() == 1) {
-            m_generatorComboBox->addItem(tr("NMake Generator"), msvcVersions.first());
-        } else {
-            foreach (const QString &msvcVersion, msvcVersions)
-                m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(msvcVersion), msvcVersion);
-        }
-
-        if (cachedGenerator == "NMake Makefiles" && !msvcVersions.isEmpty()) {
-            m_generatorComboBox->setCurrentIndex(0);
-            m_cmakeWizard->setMsvcVersion(msvcVersions.first());
-        }
 
-        m_generatorComboBox->addItem(tr("MinGW Generator"), "mingw");
-        if (cachedGenerator == "MinGW Makefiles") {
-            m_generatorComboBox->setCurrentIndex(m_generatorComboBox->count() - 1);
-            m_cmakeWizard->setMsvcVersion("");
+        m_generatorComboBox->setVisible(true);
+        m_generatorComboBox->clear();
+        QList<ProjectExplorer::ToolChain *> tcs =
+                ProjectExplorer::ToolChainManager::instance()->findToolChains(ProjectExplorer::Abi::hostAbi());
+        foreach (ProjectExplorer::ToolChain *tc, tcs) {
+            ProjectExplorer::Abi targetAbi = tc->targetAbi();
+            QVariant tcVariant = qVariantFromValue(static_cast<void *>(tc));
+            if (targetAbi.os() == ProjectExplorer::Abi::Windows) {
+                if (targetAbi.osFlavor() == ProjectExplorer::Abi::Windows_msvc)
+                    m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(tc->displayName()), tcVariant);
+                else if (targetAbi.osFlavor() == ProjectExplorer::Abi::Windows_msys)
+                    m_generatorComboBox->addItem(tr("MinGW Generator (%1)").arg(tc->displayName()), tcVariant);
+                else
+                    continue;
+            }
         }
     } else {
         // No new enough cmake, simply hide the combo box
         m_generatorComboBox->setVisible(false);
+        QList<ProjectExplorer::ToolChain *> tcs =
+                ProjectExplorer::ToolChainManager::instance()->findToolChains(ProjectExplorer::Abi::hostAbi());
+        if (tcs.isEmpty())
+            return;
+        m_cmakeWizard->setToolChain(tcs.at(0));
     }
 }
 
 void CMakeRunPage::runCMake()
 {
+    int index = m_generatorComboBox->currentIndex();
+
+    ProjectExplorer::ToolChain *tc = 0;
+    if (index >= 0) {
+        tc = static_cast<ProjectExplorer::ToolChain *>(m_generatorComboBox->itemData(index).value<void *>());
+        if (!tc)
+            return;
+        m_cmakeWizard->setToolChain(tc);
+    } else {
+        tc = m_cmakeWizard->toolChain();
+    }
+    Q_ASSERT(tc);
+
     m_runCMake->setEnabled(false);
     m_argumentsLineEdit->setEnabled(false);
+    m_generatorComboBox->setEnabled(false);
     CMakeManager *cmakeManager = m_cmakeWizard->cmakeManager();
 
-#ifdef Q_OS_WIN
-    m_cmakeWizard->setMsvcVersion(QString());
-    QString generator = QLatin1String("-GCodeBlocks - MinGW Makefiles");
-    if (m_generatorComboBox->isVisible()) {
-         // the combobox is shown, check which generator is selected
-        int index = m_generatorComboBox->currentIndex();
-        if (index != -1) {
-            QString version = m_generatorComboBox->itemData(index).toString();
-            if (version != "mingw") {
-                generator = "-GCodeBlocks - NMake Makefiles";
-                m_cmakeWizard->setMsvcVersion(version);
-            } else {
-                m_cmakeWizard->setMsvcVersion("");
-            }
-        }
-    }
-#else // Q_OS_WIN
     QString generator = QLatin1String("-GCodeBlocks - Unix Makefiles");
-#endif
-    Utils::Environment env = m_cmakeWizard->environment();
-    if (!m_cmakeWizard->msvcVersion().isEmpty()) {
-        // Add the environment of that msvc version to environment
-        ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChain::createMSVCToolChain(m_cmakeWizard->msvcVersion(), false);
-        tc->addToEnvironment(env);
-        delete tc;
+    if (tc->targetAbi().os() == ProjectExplorer::Abi::Windows) {
+        if (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::Windows_msvc)
+            generator = QLatin1String("-GCodeBlocks - NMake Makefiles");
+        else
+            generator = QLatin1String("-GCodeBlocks - MinGW Makefiles");
     }
 
+
+    Utils::Environment env = m_cmakeWizard->environment();
+    tc->addToEnvironment(env);
+
     if (m_cmakeExecutable) {
         // We asked the user for the cmake executable
         m_cmakeWizard->cmakeManager()->setCMakeExecutable(m_cmakeExecutable->path());
@@ -475,6 +476,7 @@ void CMakeRunPage::runCMake()
     } else {
         m_runCMake->setEnabled(true);
         m_argumentsLineEdit->setEnabled(true);
+        m_generatorComboBox->setEnabled(true);
         m_output->appendPlainText(tr("No valid CMake executable specified."));
     }
 }
@@ -515,6 +517,8 @@ void CMakeRunPage::cmakeFinished()
 {
     m_runCMake->setEnabled(true);
     m_argumentsLineEdit->setEnabled(true);
+    m_generatorComboBox->setEnabled(true);
+
     if (m_cmakeProcess->exitCode() != 0) {
         m_exitCodeLabel->setVisible(true);
         m_exitCodeLabel->setText(tr("CMake exited with errors. Please check cmake output."));
@@ -542,4 +546,3 @@ bool CMakeRunPage::isComplete() const
 {
     return m_complete;
 }
-
diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h
index 88715540f2f728e15a3b871bb9822b2e1ba2e972..af6e575a365162fc134c1d0f992e622a054606dd 100644
--- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h
+++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h
@@ -48,6 +48,10 @@ namespace Utils {
     class PathChooser;
 }
 
+namespace ProjectExplorer {
+class ToolChain;
+}
+
 namespace CMakeProjectManager {
 namespace Internal {
 
@@ -87,10 +91,11 @@ public:
     CMakeManager *cmakeManager() const;
     QString arguments() const;
     void setArguments(const QString &args);
+    ProjectExplorer::ToolChain *toolChain() const;
+    void setToolChain(ProjectExplorer::ToolChain *);
     Utils::Environment environment() const;
-    QString msvcVersion() const;
-    void setMsvcVersion(const QString &version);
     bool existsUpToDateXmlFile() const;
+
 private:
     void init();
     bool hasInSourceBuild() const;
@@ -98,9 +103,9 @@ private:
     QString m_buildDirectory;
     QString m_sourceDirectory;
     QString m_arguments;
-    QString m_msvcVersion;
     bool m_creatingCbpFiles;
     Utils::Environment m_environment;
+    ProjectExplorer::ToolChain *m_toolChain;
 };
 
 class InSourceBuildPage : public QWizardPage
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index 014cd526329f139b23e8fc166e71d12ce6ee4af7..a7f5ceff4ee0731445dbb8d399835522f8928b1e 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -169,7 +169,6 @@ void CMakeProject::changeActiveBuildConfiguration(ProjectExplorer::BuildConfigur
                                     mode,
                                     cmakebc->environment());
         copw.exec();
-        cmakebc->setMsvcVersion(copw.msvcVersion());
     }
     // reparse
     parseCMakeLists();
@@ -282,6 +281,9 @@ bool CMakeProject::parseCMakeLists()
     //qDebug()<<"Updating CodeModel";
     createUiCodeModelSupport();
 
+    if (!activeBC->toolChain())
+        return true;
+
     QStringList allIncludePaths;
     QStringList allFrameworkPaths;
     QList<ProjectExplorer::HeaderPath> allHeaderPaths = activeBC->toolChain()->systemHeaderPaths();
@@ -527,9 +529,9 @@ bool CMakeProject::fromMap(const QVariantMap &map)
 
         CMakeBuildConfiguration *bc =
                 static_cast<CMakeBuildConfiguration *>(t->buildConfigurations().at(0));
-        bc->setMsvcVersion(copw.msvcVersion());
         if (!copw.buildDirectory().isEmpty())
             bc->setBuildDirectory(copw.buildDirectory());
+        bc->setToolChain(copw.toolChain());
 
         addTarget(t);
     } else {
@@ -554,7 +556,7 @@ bool CMakeProject::fromMap(const QVariantMap &map)
                                         activeBC->environment());
             if (copw.exec() != QDialog::Accepted)
                 return false;
-            activeBC->setMsvcVersion(copw.msvcVersion());
+            activeBC->setToolChain(copw.toolChain());
         }
     }
 
diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp
index 79976c9f55e1ee37fdaeb6c97e4ef39503012093..0cea71779d9c9f6056fdf1b40968465ed7679f48 100644
--- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp
@@ -299,14 +299,6 @@ void CMakeRunConfiguration::setUserEnvironmentChanges(const QList<Utils::Environ
     }
 }
 
-ProjectExplorer::ToolChainType CMakeRunConfiguration::toolChainType() const
-{
-    CMakeBuildConfiguration *bc = activeBuildConfiguration();
-    if (!bc)
-        return ProjectExplorer::ToolChain_UNKNOWN;
-    return bc->toolChainType();
-}
-
 void CMakeRunConfiguration::setEnabled(bool b)
 {
     if (m_enabled == b)
diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h
index fc8b3b39a5ced6b13c8a59ae593fd7ff181c2834..1e3df0de11ad05a864913bc19520ea4e37200e9c 100644
--- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h
+++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h
@@ -37,6 +37,7 @@
 #include <projectexplorer/applicationrunconfiguration.h>
 #include <projectexplorer/persistentsettings.h>
 #include <projectexplorer/environmentwidget.h>
+#include <projectexplorer/toolchain.h>
 #include <utils/environment.h>
 #include <utils/pathchooser.h>
 #include <utils/detailswidget.h>
@@ -83,7 +84,6 @@ public:
 
     QString dumperLibrary() const;
     QStringList dumperLibraryLocations() const;
-    ProjectExplorer::ToolChainType toolChainType() const;
 
     QVariantMap toMap() const;
 
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index 86a11b6290865a8bd17c8e7422453942f4e7bbf9..8dfd96709a688fcf4c8175c360d83e724de57dc7 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -309,10 +309,10 @@ static inline bool validMode(DebuggerStartMode sm)
     return true;
 }
 
-static inline QString msgCdbDisabled(ToolChainType tc)
+static inline QString msgCdbDisabled(const ProjectExplorer::Abi &abi)
 {
     return CdbEngine::tr("The CDB debug engine required for %1 is currently disabled.").
-                      arg(ToolChain::toolChainName(tc));
+            arg(abi.toString());
 }
 
 // Accessed by RunControlFactory
@@ -322,7 +322,7 @@ DebuggerEngine *createCdbEngine(const DebuggerStartParameters &sp,
 #ifdef Q_OS_WIN
     CdbOptionsPage *op = CdbOptionsPage::instance();
     if (!op || !op->options()->isValid()) {
-        *errorMessage = msgCdbDisabled(sp.toolChainType);
+        *errorMessage = msgCdbDisabled(sp.toolChainAbi);
         return 0;
     }
     if (!validMode(sp.startMode)) {
@@ -347,25 +347,18 @@ bool isCdbEngineEnabled()
 #endif
 }
 
-ConfigurationCheck checkCdbConfiguration(ToolChainType toolChain)
+ConfigurationCheck checkCdbConfiguration(const ProjectExplorer::Abi &abi)
 {
     ConfigurationCheck check;
-    switch (toolChain) {
-    case ToolChain_MinGW: // Do our best
-    case ToolChain_MSVC:
-    case ToolChain_WINCE:
-    case ToolChain_OTHER:
-    case ToolChain_UNKNOWN:
-    case ToolChain_INVALID:
+    if (abi.binaryFormat() == ProjectExplorer::Abi::Format_PE
+            && abi.osFlavor() != ProjectExplorer::Abi::Windows_msys) {
         if (!isCdbEngineEnabled()) {
-            check.errorMessage = msgCdbDisabled(toolChain);
+            check.errorMessage = msgCdbDisabled(abi);
             check.settingsPage = CdbOptionsPage::settingsId();
         }
-        break;
-    default:
-        //: %1 is something like "GCCE" or "Intel C++ Compiler (Linux)" (see ToolChain context)
-        check.errorMessage = CdbEngine::tr("The CDB debug engine does not support the %1 toolchain.").
-                    arg(ToolChain::toolChainName(toolChain));
+    } else {
+        check.errorMessage = CdbEngine::tr("The CDB debug engine does not support the %1 ABI.").
+                    arg(abi.toString());
         check.settingsPage = CdbOptionsPage::settingsId();
     }
     return check;
diff --git a/src/plugins/debugger/debuggercore.h b/src/plugins/debugger/debuggercore.h
index da85e4c4d8a06c2c18844bbd736662c5e5ebbe12..f86d5122c3877614f94195473d4c20156de3077a 100644
--- a/src/plugins/debugger/debuggercore.h
+++ b/src/plugins/debugger/debuggercore.h
@@ -36,6 +36,8 @@
 
 #include "debuggerconstants.h"
 
+#include <projectexplorer/abi.h>
+
 #include <QtCore/QObject>
 
 QT_BEGIN_NAMESPACE
@@ -101,7 +103,7 @@ public:
     virtual bool initialize(const QStringList &arguments, QString *errorMessage) = 0;
     virtual QWidget *mainWindow() const = 0;
     virtual bool isDockVisible(const QString &objectName) const = 0;
-    virtual QString gdbBinaryForToolChain(int toolChain) const = 0;
+    virtual QString gdbBinaryForAbi(const ProjectExplorer::Abi &abi) const = 0;
     virtual void showModuleSymbols(const QString &moduleName,
         const QVector<Symbol> &symbols) = 0;
     virtual void openMemoryEditor() = 0;
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index 7b82b9a4a7761712492fc25b42e7d785fd04b84c..5b1030651cac7e072de42b6ee6578125e9dd5412 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -57,9 +57,6 @@
 #include <coreplugin/progressmanager/progressmanager.h>
 #include <coreplugin/progressmanager/futureprogress.h>
 
-#include <projectexplorer/toolchain.h>
-#include <projectexplorer/toolchaintype.h>
-
 #include <texteditor/itexteditor.h>
 #include <texteditor/basetextmark.h>
 
@@ -123,7 +120,7 @@ QDebug operator<<(QDebug str, const DebuggerStartParameters &sp)
             << " symbolFileName=" << sp.symbolFileName
             << " useServerStartScript=" << sp.useServerStartScript
             << " serverStartScript=" << sp.serverStartScript
-            << " toolchain=" << sp.toolChainType << '\n';
+            << " abi=" << sp.toolChainAbi.toString() << '\n';
     return str;
 }
 
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index caaa78a2dfaeaadb8ca25d24ca1d107b858fe0b6..af0ef86b091f860ea5435a62b7165d097ff22f29 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -97,8 +97,6 @@
 #include <projectexplorer/projectexplorerconstants.h>
 #include <projectexplorer/session.h>
 #include <projectexplorer/target.h>
-#include <projectexplorer/toolchain.h>
-#include <projectexplorer/toolchaintype.h>
 
 #include <qt4projectmanager/qt4projectmanagerconstants.h>
 
@@ -904,7 +902,7 @@ public slots:
     void runControlStarted(DebuggerEngine *engine);
     void runControlFinished(DebuggerEngine *engine);
     DebuggerLanguages activeLanguages() const;
-    QString gdbBinaryForToolChain(int toolChain) const;
+    QString gdbBinaryForAbi(const ProjectExplorer::Abi &abi) const;
     void remoteCommand(const QStringList &options, const QStringList &);
 
     bool isReverseDebugging() const;
@@ -1536,7 +1534,8 @@ void DebuggerPluginPrivate::startExternalApplication()
         sp.processArgs = dlg.executableArguments();
     // Fixme: 1 of 3 testing hacks.
     if (sp.processArgs.startsWith(__("@tcf@ ")) || sp.processArgs.startsWith(__("@sym@ ")))
-        sp.toolChainType = ToolChain_RVCT2_ARMV5;
+        // Set up an ARM Symbian Abi
+        sp.toolChainAbi = Abi(Abi::ARM, Abi::Symbian, Abi::Symbian_device, Abi::Format_ELF, false);
 
     if (dlg.breakAtMain()) {
 #ifdef Q_OS_WIN
@@ -1615,7 +1614,12 @@ void DebuggerPluginPrivate::startRemoteCdbSession()
 {
     const QString connectionKey = _("CdbRemoteConnection");
     DebuggerStartParameters sp;
-    sp.toolChainType = ToolChain_MSVC;
+    Abi hostAbi = Abi::hostAbi();
+    sp.toolChainAbi = ProjectExplorer::Abi(hostAbi.architecture(),
+                                           ProjectExplorer::Abi::Windows,
+                                           ProjectExplorer::Abi::Windows_msvc,
+                                           ProjectExplorer::Abi::Format_PE,
+                                           true);
     sp.startMode = AttachToRemote;
     StartRemoteCdbDialog dlg(mainWindow());
     QString previousConnection = configValue(connectionKey).toString();
@@ -1681,7 +1685,7 @@ void DebuggerPluginPrivate::startRemoteApplication()
     sp.displayName = dlg.localExecutable();
     sp.debuggerCommand = dlg.debugger(); // Override toolchain-detection.
     if (!sp.debuggerCommand.isEmpty())
-        sp.toolChainType = ToolChain_INVALID;
+        sp.toolChainAbi = ProjectExplorer::Abi();
     sp.startMode = AttachToRemote;
     sp.useServerStartScript = dlg.useServerStartScript();
     sp.serverStartScript = dlg.serverStartScript();
@@ -2494,10 +2498,9 @@ void DebuggerPluginPrivate::createNewDock(QWidget *widget)
 void DebuggerPluginPrivate::runControlStarted(DebuggerEngine *engine)
 {
     activateDebugMode();
-    QString toolChainName =
-        ToolChain::toolChainName(engine->startParameters().toolChainType);
-    const QString message = tr("Starting debugger '%1' for tool chain '%2'...")
-            .arg(engine->objectName()).arg(toolChainName);
+    const QString message = tr("Starting debugger '%1' for ABI '%2'...")
+            .arg(engine->objectName())
+            .arg(engine->startParameters().toolChainAbi.toString());
     showMessage(message, StatusBar);
     showMessage(m_debuggerSettings->dump(), LogDebug);
     m_snapshotHandler->appendSnapshot(engine);
@@ -2534,9 +2537,9 @@ void DebuggerPluginPrivate::remoteCommand(const QStringList &options,
     runScheduled();
 }
 
-QString DebuggerPluginPrivate::gdbBinaryForToolChain(int toolChain) const
+QString DebuggerPluginPrivate::gdbBinaryForAbi(const ProjectExplorer::Abi &abi) const
 {
-    return GdbOptionsPage::gdbBinaryToolChainMap.key(toolChain);
+    return GdbOptionsPage::abiToGdbMap.value(abi.toString());
 }
 
 DebuggerLanguages DebuggerPluginPrivate::activeLanguages() const
@@ -2757,7 +2760,7 @@ void DebuggerPluginPrivate::extensionsInitialized()
     dock->setProperty(DOCKWIDGET_DEFAULT_AREA, Qt::RightDockWidgetArea);
 
     m_debuggerSettings->readSettings();
-    GdbOptionsPage::readGdbBinarySettings();
+    GdbOptionsPage::readGdbSettings();
 
     // Register factory of DebuggerRunControl.
     m_debuggerRunControlFactory = new DebuggerRunControlFactory
@@ -3158,8 +3161,7 @@ void DebuggerPluginPrivate::aboutToShutdown()
         this, 0);
     m_debuggerSettings->writeSettings();
     m_mainWindow->writeSettings();
-    if (GdbOptionsPage::gdbBinariesChanged)
-        GdbOptionsPage::writeGdbBinarySettings();
+    GdbOptionsPage::writeGdbSettings();
 }
 
 } // namespace Internal
diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp
index 6ad856cff50449d2d282e7ab37412c9753b30862..512ffb3534cdf3d5492b0ca48c350a7d0d3cca27 100644
--- a/src/plugins/debugger/debuggerrunner.cpp
+++ b/src/plugins/debugger/debuggerrunner.cpp
@@ -49,9 +49,9 @@
 #  include "peutils.h"
 #endif
 
+#include <projectexplorer/abi.h>
 #include <projectexplorer/debugginghelper.h>
 #include <projectexplorer/project.h>
-#include <projectexplorer/toolchain.h>
 #include <projectexplorer/projectexplorerconstants.h>
 #include <projectexplorer/target.h>
 #include <projectexplorer/buildconfiguration.h>
@@ -74,7 +74,7 @@ namespace Debugger {
 namespace Internal {
 
 bool isCdbEngineEnabled(); // Check the configuration page
-ConfigurationCheck checkCdbConfiguration(ToolChainType toolChain);
+ConfigurationCheck checkCdbConfiguration(const ProjectExplorer::Abi &);
 
 DebuggerEngine *createCdbEngine(const DebuggerStartParameters &,
     DebuggerEngine *masterEngine, QString *error);
@@ -88,7 +88,7 @@ DebuggerEngine *createQmlEngine(const DebuggerStartParameters &,
 DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &);
 DebuggerEngine *createLldbEngine(const DebuggerStartParameters &);
 
-extern QString msgNoBinaryForToolChain(int tc);
+extern QString msgNoBinaryForToolChain(const ProjectExplorer::Abi &abi);
 
 static QString msgEngineNotAvailable(const char *engine)
 {
@@ -165,8 +165,13 @@ DebuggerEngineType DebuggerRunControlPrivate::engineForExecutable
 
     // We need the CDB debugger in order to be able to debug VS
     // executables.
-   ConfigurationCheck check = checkDebugConfiguration(ToolChain_MSVC);
-   if (!check) {
+    Abi hostAbi = Abi::hostAbi();
+    ConfigurationCheck check = checkDebugConfiguration(Abi(hostAbi.architecture(),
+                                                           Abi::Windows,
+                                                           hostAbi.osFlavor(),
+                                                           Abi::Format_PE,
+                                                           hostAbi.wordWidth()));
+    if (!check) {
         m_errorMessage = check.errorMessage;
         m_settingsIdHint = check.settingsPage;
         if (enabledEngineTypes & CdbEngineType)
@@ -216,38 +221,18 @@ DebuggerEngineType DebuggerRunControlPrivate::engineForMode
 //
 ////////////////////////////////////////////////////////////////////////
 
-static DebuggerEngineType engineForToolChain(ToolChainType toolChainType)
+static DebuggerEngineType engineForToolChain(const Abi &toolChain)
 {
-    switch (toolChainType) {
-        case ToolChain_LINUX_ICC:
-        case ToolChain_MinGW:
-        case ToolChain_GCC:
-        case ToolChain_WINSCW: // S60
-        case ToolChain_GCCE:
-        case ToolChain_RVCT2_ARMV5:
-        case ToolChain_RVCT2_ARMV6:
-        case ToolChain_RVCT_ARMV5_GNUPOC:
-        case ToolChain_GCCE_GNUPOC:
-        case ToolChain_GCC_MAEMO5:
-        case ToolChain_GCC_HARMATTAN:
-        case ToolChain_GCC_MEEGO:
+    if (toolChain.binaryFormat() == Abi::Format_ELF || toolChain.binaryFormat() == Abi::Format_Mach_O
+            || (toolChain.binaryFormat() == Abi::Format_PE && toolChain.osFlavor() == Abi::Windows_msys)) {
 #ifdef WITH_LLDB
             // lldb override
             if (Core::ICore::instance()->settings()->value("LLDB/enabled").toBool())
                 return LldbEngineType;
 #endif
             return GdbEngineType;
-
-
-        case ToolChain_MSVC:
-        case ToolChain_WINCE:
+    } else if (toolChain.binaryFormat() == Abi::Format_PE && toolChain.osFlavor() != Abi::Windows_msys) {
             return CdbEngineType;
-
-        case ToolChain_OTHER:
-        case ToolChain_UNKNOWN:
-        case ToolChain_INVALID:
-        default:
-            break;
     }
     return NoEngineType;
 }
@@ -280,7 +265,7 @@ DebuggerRunControl::DebuggerRunControl(RunConfiguration *runConfiguration,
     else if (sp.executable.endsWith(_(".py")))
         engineType = PdbEngineType;
     else {
-        engineType = engineForToolChain(sp.toolChainType);
+        engineType = engineForToolChain(sp.toolChainAbi);
         if (engineType == CdbEngineType && !(enabledEngineTypes & CdbEngineType)) {
             d->m_errorMessage = msgEngineNotAvailable("Cdb Engine");
             engineType = NoEngineType;
@@ -351,9 +336,8 @@ DebuggerRunControl::DebuggerRunControl(RunConfiguration *runConfiguration,
         // Could not find anything suitable.
         debuggingFinished();
         // Create Message box with possibility to go to settings.
-        QString toolChainName = ToolChain::toolChainName(sp.toolChainType);
-        const QString msg = tr("Cannot debug '%1' (tool chain: '%2'): %3")
-            .arg(sp.executable, toolChainName, d->m_errorMessage);
+        const QString msg = tr("Cannot debug '%1' (binary format: '%2'): %3")
+            .arg(sp.executable, sp.toolChainAbi.toString(), d->m_errorMessage);
         Core::ICore::instance()->showWarningWithOptions(tr("Warning"),
             msg, QString(), QLatin1String(Constants::DEBUGGER_SETTINGS_CATEGORY),
             d->m_settingsIdHint);
@@ -388,37 +372,27 @@ void DebuggerRunControl::setCustomEnvironment(Utils::Environment env)
     d->m_engine->startParameters().environment = env;
 }
 
-DEBUGGER_EXPORT ConfigurationCheck checkDebugConfiguration(ToolChainType toolChain)
+ConfigurationCheck checkDebugConfiguration(const ProjectExplorer::Abi &abi)
 {
     ConfigurationCheck result;
 
     if (!(debuggerCore()->activeLanguages() & CppLanguage))
         return result;
 
-    switch(toolChain) {
-    case ToolChain_GCC:
-    case ToolChain_LINUX_ICC:
-    case ToolChain_MinGW:
-    case ToolChain_WINCE: // S60
-    case ToolChain_WINSCW:
-    case ToolChain_GCCE:
-    case ToolChain_RVCT2_ARMV5:
-    case ToolChain_RVCT2_ARMV6:
-        if (debuggerCore()->gdbBinaryForToolChain(toolChain).isEmpty()) {
-            result.errorMessage = msgNoBinaryForToolChain(toolChain);
+    if (abi.binaryFormat() == Abi::Format_ELF ||
+            abi.binaryFormat() == Abi::Format_Mach_O ||
+            (abi.binaryFormat() == Abi::Format_PE && abi.osFlavor() == Abi::Windows_msys)) {
+        if (debuggerCore()->gdbBinaryForAbi(abi).isEmpty()) {
+            result.errorMessage = msgNoBinaryForToolChain(abi);
             result.errorMessage += QLatin1Char(' ') + msgEngineNotAvailable("Gdb");
             result.settingsPage = GdbOptionsPage::settingsId();
         }
-        break;
-    case ToolChain_MSVC:
-        result = checkCdbConfiguration(toolChain);
+    } else if (abi.binaryFormat() == Abi::Format_PE && abi.osFlavor() != Abi::Windows_msys) {
+        result = checkCdbConfiguration(abi);
         if (!result) {
             result.errorMessage += msgEngineNotAvailable("Cdb");
             result.settingsPage = QLatin1String("Cdb");
         }
-        break;
-    default:
-        break;
     }
 
     if (!result && !result.settingsPage.isEmpty())
@@ -586,7 +560,7 @@ static DebuggerStartParameters localStartParameters(RunConfiguration *runConfigu
     sp.workingDirectory = rc->workingDirectory();
     sp.executable = rc->executable();
     sp.processArgs = rc->commandLineArguments();
-    sp.toolChainType = rc->toolChainType();
+    sp.toolChainAbi = rc->abi();
     sp.useTerminal = rc->runMode() == LocalApplicationRunConfiguration::Console;
     sp.dumperLibrary = rc->dumperLibrary();
     sp.dumperLibraryLocations = rc->dumperLibraryLocations();
@@ -644,7 +618,7 @@ DebuggerRunControl *DebuggerRunControlFactory::create
 {
     DebuggerStartParameters sp = sp0;
     sp.enabledEngines = m_enabledEngines;
-    ConfigurationCheck check = checkDebugConfiguration(sp.toolChainType);
+    ConfigurationCheck check = checkDebugConfiguration(sp.toolChainAbi);
 
     if (!check) {
         //appendMessage(errorMessage, true);
diff --git a/src/plugins/debugger/debuggerrunner.h b/src/plugins/debugger/debuggerrunner.h
index 76e1b5cae5ef4e66e1af18eaafa63935c66591d4..1da943d02a241ee0b48acf0c550cdb296ec24100 100644
--- a/src/plugins/debugger/debuggerrunner.h
+++ b/src/plugins/debugger/debuggerrunner.h
@@ -36,8 +36,8 @@
 
 #include "debugger_global.h"
 
+#include <projectexplorer/abi.h>
 #include <projectexplorer/runconfiguration.h>
-#include <projectexplorer/toolchaintype.h>
 
 #include <QtCore/QScopedPointer>
 
@@ -68,7 +68,7 @@ public:
     QString settingsPage;
 };
 
-DEBUGGER_EXPORT ConfigurationCheck checkDebugConfiguration(ProjectExplorer::ToolChainType toolChain);
+DEBUGGER_EXPORT ConfigurationCheck checkDebugConfiguration(const ProjectExplorer::Abi &abi);
 
 // This is a job description containing all data "local" to the jobs, including
 // the models of the individual debugger views.
diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h
index 2fe82d4bc0d138a3e734b9f92d3fa6194d6e338a..011042d7342f2bf4ece757978d93d0b8e70b6abd 100644
--- a/src/plugins/debugger/debuggerstartparameters.h
+++ b/src/plugins/debugger/debuggerstartparameters.h
@@ -39,7 +39,7 @@
 
 #include <utils/ssh/sshconnection.h>
 #include <utils/environment.h>
-#include <projectexplorer/toolchaintype.h>
+#include <projectexplorer/abi.h>
 
 #include <QtCore/QMetaType>
 
@@ -70,7 +70,6 @@ public:
         qmlServerPort(0),
         useServerStartScript(false),
         connParams(Utils::SshConnectionParameters::NoProxy),
-        toolChainType(ProjectExplorer::ToolChain_UNKNOWN),
         startMode(NoStartMode),
         executableUid(0),
         communicationChannel(CommunicationChannelUsb),
@@ -117,7 +116,7 @@ public:
     Utils::SshConnectionParameters connParams;
 
     QString debuggerCommand;
-    ProjectExplorer::ToolChainType toolChainType;
+    ProjectExplorer::Abi toolChainAbi;
     QString qtInstallPath;
 
     QString dumperLibrary;
diff --git a/src/plugins/debugger/gdb/gdbchooserwidget.cpp b/src/plugins/debugger/gdb/gdbchooserwidget.cpp
index 50d84ba036f72991ca60b44ed11b697b2a09b279..283f29722290c70f9689fe72235866ea92a40b6e 100644
--- a/src/plugins/debugger/gdb/gdbchooserwidget.cpp
+++ b/src/plugins/debugger/gdb/gdbchooserwidget.cpp
@@ -52,51 +52,15 @@
 #include <QtGui/QIcon>
 #include <QtGui/QGroupBox>
 #include <QtGui/QCheckBox>
-#include <QtCore/QDebug>
 #include <QtCore/QSet>
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
 #include <QtCore/QProcess>
 
-enum { binaryRole = Qt::UserRole + 1, toolChainRole = Qt::UserRole + 2 };
-enum Columns { binaryColumn, toolChainColumn, ColumnCount };
+enum Columns { abiColumn, binaryColumn, ColumnCount };
 
 typedef QList<QStandardItem *> StandardItemList;
 
-Q_DECLARE_METATYPE(QList<int>)
-
-static QList<int> allGdbToolChains()
-{
-    QList<int> rc;
-    rc
-#ifdef Q_OS_UNIX
-       << ProjectExplorer::ToolChain_GCC
-       << ProjectExplorer::ToolChain_LINUX_ICC
-#endif
-#ifdef Q_OS_WIN
-       << ProjectExplorer::ToolChain_MinGW
-       << ProjectExplorer::ToolChain_WINSCW
-       << ProjectExplorer::ToolChain_GCCE
-       << ProjectExplorer::ToolChain_RVCT2_ARMV5
-       << ProjectExplorer::ToolChain_RVCT2_ARMV6
-#endif
-       << ProjectExplorer::ToolChain_GCC_MAEMO5
-       << ProjectExplorer::ToolChain_GCC_HARMATTAN
-       << ProjectExplorer::ToolChain_GCC_MEEGO
-#ifdef Q_OS_UNIX
-       << ProjectExplorer::ToolChain_GCCE_GNUPOC
-       << ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC
-#endif
-       << ProjectExplorer::ToolChain_OTHER
-       << ProjectExplorer::ToolChain_UNKNOWN;
-    return rc;
-}
-
-static inline QString toolChainName(int tc)
-{
-    return ProjectExplorer::ToolChain::toolChainName(static_cast<ProjectExplorer::ToolChainType>(tc));
-}
-
 namespace Debugger {
 namespace Internal {
 
@@ -105,6 +69,10 @@ namespace Internal {
 // Obtain a tooltip for a gdb binary by running --version
 static inline QString gdbToolTip(const QString &binary)
 {
+    if (binary.isEmpty())
+        return QString();
+    if (!QFileInfo(binary).exists())
+        return GdbChooserWidget::tr("File not found.");
     QProcess process;
     process.start(binary, QStringList(QLatin1String("--version")));
     process.closeWriteChannel();
@@ -122,37 +90,32 @@ static inline QString gdbToolTip(const QString &binary)
 // Provides a delayed tooltip listing the gdb version as
 // obtained by running it. Provides conveniences for getting/setting the maps and
 // for listing the toolchains used and the ones still available.
-
 class GdbBinaryModel : public QStandardItemModel {
 public:
-    typedef GdbChooserWidget::BinaryToolChainMap BinaryToolChainMap;
-
     explicit GdbBinaryModel(QObject * parent = 0);
-    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+    bool setData(const QModelIndex &index, const QVariant &value, int role);
 
     // get / set data as map.
-    BinaryToolChainMap gdbBinaries() const;
-    void setGdbBinaries(const BinaryToolChainMap &m);
+    QMap<QString, QString> gdbMapping() const;
+    void setGdbMapping(const QMap<QString, QString> &m);
 
     QString binary(int row) const;
-    QList<int> toolChains(int row) const;
+    QString abi(int row) const;
 
-    QStringList binaries() const;
-    QList<int> usedToolChains() const;
-    QSet<int> unusedToolChainSet() const;
-    QList<int> unusedToolChains() const;
+    void append(const QString &abi, const QString &binary);
 
-    void append(const QString &binary, const QList<int> &toolChains);
+    bool isDirty() const;
 
+    static void setAbiItem(QStandardItem *item, const QString &abi);
     static void setBinaryItem(QStandardItem *item, const QString &binary);
-    static void setToolChainItem(QStandardItem *item, const QList<int> &toolChain);
 };
 
 GdbBinaryModel::GdbBinaryModel(QObject *parent) :
     QStandardItemModel(0, ColumnCount, parent)
 {
     QStringList headers;
-    headers << GdbChooserWidget::tr("Binary") << GdbChooserWidget::tr("Toolchains");
+    headers << GdbChooserWidget::tr("ABI") << GdbChooserWidget::tr("Debugger");
     setHorizontalHeaderLabels(headers);
 }
 
@@ -166,455 +129,119 @@ QVariant GdbBinaryModel::data(const QModelIndex &index, int role) const
         // Run the gdb and obtain the tooltip
         const QString tooltip = gdbToolTip(binary(index.row()));
         // Set on the whole row
+        item(index.row(), abiColumn)->setToolTip(tooltip);
         item(index.row(), binaryColumn)->setToolTip(tooltip);
-        item(index.row(), toolChainColumn)->setToolTip(tooltip);
         return QVariant(tooltip);
     }
     return QStandardItemModel::data(index, role);
 }
 
-QStringList GdbBinaryModel::binaries() const
-{
-    QStringList rc;
-    const int binaryCount = rowCount();
-    for (int b = 0; b < binaryCount; b++)
-        rc.push_back(binary(b));
-    return rc;
-}
-
-QList<int> GdbBinaryModel::usedToolChains() const
-{
-    // Loop over model and collect all toolchains.
-    QList<int> rc;
-    const int binaryCount = rowCount();
-    for (int b = 0; b < binaryCount; b++)
-        foreach(int tc, toolChains(b))
-            rc.push_back(tc);
-    return rc;
-}
-
-QSet<int> GdbBinaryModel::unusedToolChainSet() const
+bool GdbBinaryModel::setData(const QModelIndex &index, const QVariant &value, int role)
 {
-    const QSet<int> used = usedToolChains().toSet();
-    QSet<int> all = allGdbToolChains().toSet();
-    return all.subtract(used);
-}
-
-QList<int> GdbBinaryModel::unusedToolChains() const
-{
-    QList<int> unused = unusedToolChainSet().toList();
-    qSort(unused);
-    return unused;
+    if (index.isValid() && role == Qt::EditRole) {
+        Q_ASSERT(index.column() == binaryColumn);
+        item(index.row(), abiColumn)->setToolTip(QString());
+        item(index.row(), binaryColumn)->setToolTip(QString());
+        item(index.row(), binaryColumn)->setData(true);
+        QFont f(item(index.row(), binaryColumn)->font());
+        f.setBold(true);
+        item(index.row(), binaryColumn)->setFont(f);
+    }
+    return QStandardItemModel::setData(index, value, role);
 }
 
-GdbBinaryModel::BinaryToolChainMap GdbBinaryModel::gdbBinaries() const
+QMap<QString, QString> GdbBinaryModel::gdbMapping() const
 {
-    BinaryToolChainMap rc;
+    QMap<QString, QString> rc;
     const int binaryCount = rowCount();
-    for (int r = 0; r < binaryCount; r++) {
-        const QString bin = binary(r);
-        foreach(int tc, toolChains(r))
-            rc.insert(bin, tc);
-    }
+    for (int r = 0; r < binaryCount; ++r)
+        rc.insert(abi(r), binary(r));
     return rc;
 }
 
-void GdbBinaryModel::setGdbBinaries(const BinaryToolChainMap &m)
+void GdbBinaryModel::setGdbMapping(const QMap<QString, QString> &m)
 {
     removeRows(0, rowCount());
-    foreach(const QString &binary, m.uniqueKeys())
-        append(binary, m.values(binary));
+    for (QMap<QString, QString>::const_iterator i = m.constBegin(); i != m.constEnd(); ++i)
+        append(i.key(), i.value());
 }
 
 QString GdbBinaryModel::binary(int row) const
 {
-    return item(row, binaryColumn)->data(binaryRole).toString();
+    return QDir::fromNativeSeparators(item(row, binaryColumn)->data(Qt::DisplayRole).toString());
 }
 
-QList<int> GdbBinaryModel::toolChains(int row) const
+QString GdbBinaryModel::abi(int row) const
 {
-    const QVariant data = item(row, toolChainColumn)->data(toolChainRole);
-    return qVariantValue<QList<int> >(data);
+    return item(row, abiColumn)->data(Qt::DisplayRole).toString();
 }
 
 void GdbBinaryModel::setBinaryItem(QStandardItem *item, const QString &binary)
 {
-    const QFileInfo fi(binary);
-    item->setText(fi.isAbsolute() ? fi.fileName() : QDir::toNativeSeparators(binary));
+    item->setText(binary.isEmpty() ? QString() : QDir::toNativeSeparators(binary));
     item->setToolTip(QString());; // clean out delayed tooltip
-    item->setData(QVariant(binary), binaryRole);
-    item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable);
+    item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable|Qt::ItemIsEditable);
+    item->setData(false);
 }
 
-void GdbBinaryModel::setToolChainItem(QStandardItem *item, const QList<int> &toolChains)
+void GdbBinaryModel::setAbiItem(QStandardItem *item, const QString &abi)
 {
-    // Format comma-separated list
-    const QString toolChainSeparator = QLatin1String(", ");
-    QString toolChainDesc;
-    const int count = toolChains.size();
-    for (int i = 0; i < count; i++) {
-        if (i)
-            toolChainDesc += toolChainSeparator;
-        toolChainDesc += toolChainName(toolChains.at(i));
-    }
-
-    item->setText(toolChainDesc);
-    item->setToolTip(QString());; // clean out delayed tooltip
-    item->setData(qVariantFromValue(toolChains), toolChainRole);
+    item->setText(abi);
+    item->setToolTip(QString()); // clean out delayed tooltip
     item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable);
 }
 
-void GdbBinaryModel::append(const QString &binary, const QList<int> &toolChains)
+void GdbBinaryModel::append(const QString &abi, const QString &binary)
 {
     QStandardItem *binaryItem = new QStandardItem;
-    QStandardItem *toolChainItem = new QStandardItem;
+    QStandardItem *abiItem = new QStandardItem;
+    GdbBinaryModel::setAbiItem(abiItem, abi);
     GdbBinaryModel::setBinaryItem(binaryItem, binary);
-    GdbBinaryModel::setToolChainItem(toolChainItem, toolChains);
+
     StandardItemList row;
-    row << binaryItem << toolChainItem;
+    row << abiItem << binaryItem;
     appendRow(row);
 }
 
+bool GdbBinaryModel::isDirty() const
+{
+    for (int i = 0; i < rowCount(); ++i) {
+        if (item(i, binaryColumn)->data().toBool())
+            return true;
+    }
+    return false;
+}
+
 // ----------- GdbChooserWidget
 GdbChooserWidget::GdbChooserWidget(QWidget *parent) :
     QWidget(parent),
     m_treeView(new QTreeView),
-    m_model(new GdbBinaryModel(m_treeView)),
-    m_addButton(new QToolButton),
-    m_deleteButton(new QToolButton),
-    m_dirty(false)
+    m_model(new GdbBinaryModel(m_treeView))
 {
-    QHBoxLayout *mainHLayout = new QHBoxLayout;
-
+    QVBoxLayout *layout = new QVBoxLayout(this);
     m_treeView->setRootIsDecorated(false);
     m_treeView->setModel(m_model);
     m_treeView->setUniformRowHeights(true);
     m_treeView->setAllColumnsShowFocus(true);
     m_treeView->setSelectionMode(QAbstractItemView::SingleSelection);
-    connect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
-            this, SLOT(slotCurrentChanged(QModelIndex,QModelIndex)));
-    connect(m_treeView, SIGNAL(doubleClicked(QModelIndex)),
-            this, SLOT(slotDoubleClicked(QModelIndex)));
-    mainHLayout->addWidget(m_treeView);
-
-    m_addButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_PLUS)));
-    connect(m_addButton, SIGNAL(clicked()), this, SLOT(slotAdd()));
-
-    m_deleteButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_MINUS)));
-    m_deleteButton->setEnabled(false);
-    connect(m_deleteButton, SIGNAL(clicked()), this, SLOT(slotRemove()));
-
-    QVBoxLayout *vButtonLayout = new QVBoxLayout;
-    vButtonLayout->addWidget(m_addButton);
-    vButtonLayout->addWidget(m_deleteButton);
-    vButtonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
-
-    mainHLayout->addLayout(vButtonLayout);
-    setLayout(mainHLayout);
-}
-
-QStandardItem *GdbChooserWidget::currentItem() const
-{
-    // Return the column-0-item
-    QModelIndex currentIndex = m_treeView->currentIndex();
-    if (!currentIndex.isValid())
-        return 0;
-    if (currentIndex.column() != binaryColumn)
-        currentIndex = currentIndex.sibling(currentIndex.row(), binaryColumn);
-    return m_model->itemFromIndex(currentIndex);
-}
-
-void GdbChooserWidget::slotAdd()
-{
-    // Any toolchains left?
-    const QList<int> unusedToolChains = m_model->unusedToolChains();
-    if (unusedToolChains.isEmpty())
-        return;
-
-    // On a binary or no current item: Add binary + toolchain
-    BinaryToolChainDialog binaryDialog(this);
-    binaryDialog.setToolChainChoices(unusedToolChains);
-    if (binaryDialog.exec() != QDialog::Accepted)
-        return;
-    // Refuse binaries that already exist
-    const QString path = binaryDialog.path();
-    if (m_model->binaries().contains(path)) {
-        QMessageBox::warning(this, tr("Duplicate binary"),
-                             tr("The binary '%1' already exists.").arg(path));
-        return;
-    }
-    // Add binary + toolchain to model
-    m_model->append(path, binaryDialog.toolChains());
-    m_dirty = true;
-}
-
-void GdbChooserWidget::slotRemove()
-{
-    if (QStandardItem *item = currentItem())
-        removeItem(item);
-}
-
-void GdbChooserWidget::removeItem(QStandardItem *item)
-{
-    m_model->removeRow(item->row());
-    m_dirty = true;
-}
-
-void GdbChooserWidget::slotCurrentChanged(const QModelIndex &current, const QModelIndex &)
-{
-    const bool hasItem = current.isValid() && m_model->itemFromIndex(current);
-    m_deleteButton->setEnabled(hasItem);
-}
-
-void GdbChooserWidget::slotDoubleClicked(const QModelIndex &current)
-{
-    QTC_ASSERT(current.isValid(), return)
-    // Show dialog to edit. Make all unused toolchains including the ones
-    // previously assigned to that binary available.
-    const int row = current.row();
-    const QString oldBinary = m_model->binary(row);
-    const QList<int> oldToolChains = m_model->toolChains(row);
-    const QSet<int> toolChainChoices = m_model->unusedToolChainSet().unite(oldToolChains.toSet());
-
-    BinaryToolChainDialog dialog(this);
-    dialog.setPath(oldBinary);
-    const BinaryToolChainMap map = gdbBinaries();
-    dialog.setToolChainChoices(toolChainChoices.toList(), &map);
-    dialog.setToolChains(oldToolChains);
-    if (dialog.exec() != QDialog::Accepted)
-        return;
-    // Check if anything changed.
-    const QString newBinary = dialog.path();
-    const QList<int> newToolChains = dialog.toolChains();
-    if (newBinary == oldBinary && newToolChains == oldToolChains)
-        return;
-
-    GdbBinaryModel::setBinaryItem(m_model->item(row, binaryColumn), newBinary);
-    GdbBinaryModel::setToolChainItem(m_model->item(row, toolChainColumn), newToolChains);
-    m_dirty = true;
+    layout->addWidget(m_treeView);
 }
 
-GdbChooserWidget::BinaryToolChainMap GdbChooserWidget::gdbBinaries() const
+QMap<QString, QString> GdbChooserWidget::gdbMapping() const
 {
-    return m_model->gdbBinaries();
+    return m_model->gdbMapping();
 }
 
-void GdbChooserWidget::setGdbBinaries(const BinaryToolChainMap &m)
+void GdbChooserWidget::setGdbMapping(const QMap<QString, QString> &m)
 {
-    m_model->setGdbBinaries(m);
+    m_model->setGdbMapping(m);
     for (int c = 0; c < ColumnCount; c++)
         m_treeView->resizeColumnToContents(c);
-    m_dirty = false;
 }
 
 bool GdbChooserWidget::isDirty() const
 {
-    return m_dirty;
-}
-
-void GdbChooserWidget::clearDirty()
-{
-    m_dirty = false;
-}
-
-// -------------- ToolChainSelectorWidget
-static const char *toolChainPropertyC = "toolChain";
-
-static inline int toolChainOfCheckBox(const QCheckBox *c)
-{
-    return c->property(toolChainPropertyC).toInt();
-}
-
-static inline QVBoxLayout *createGroupBox(const QString &title, QVBoxLayout *lt)
-{
-    QGroupBox *gb = new QGroupBox(title);
-    QVBoxLayout *gbLayout = new QVBoxLayout;
-    gb->setLayout(gbLayout);
-    lt->addWidget(gb);
-    return gbLayout;
-}
-
-ToolChainSelectorWidget::ToolChainSelectorWidget(QWidget *parent) :
-    QWidget(parent), m_valid(false)
-{
-    QVBoxLayout *mainLayout = new QVBoxLayout;
-    QVBoxLayout *desktopLayout = createGroupBox(tr("Desktop/General"), mainLayout);
-    QVBoxLayout *symbianLayout = createGroupBox(tr("Symbian"), mainLayout);
-    QVBoxLayout *maemoLayout = createGroupBox(tr("Maemo"), mainLayout);
-
-    // Group checkboxes into categories
-    foreach(int tc, allGdbToolChains()) {
-        switch (tc) {
-        case ProjectExplorer::ToolChain_GCC:
-        case ProjectExplorer::ToolChain_LINUX_ICC:
-        case ProjectExplorer::ToolChain_MinGW:
-        case ProjectExplorer::ToolChain_OTHER:
-        case ProjectExplorer::ToolChain_UNKNOWN:
-            desktopLayout->addWidget(createToolChainCheckBox(tc));
-            break;
-        case ProjectExplorer::ToolChain_MSVC:
-        case ProjectExplorer::ToolChain_WINCE:
-            break;
-        case ProjectExplorer::ToolChain_WINSCW:
-        case ProjectExplorer::ToolChain_GCCE:
-        case ProjectExplorer::ToolChain_RVCT2_ARMV5:
-        case ProjectExplorer::ToolChain_RVCT2_ARMV6:
-        case ProjectExplorer::ToolChain_GCCE_GNUPOC:
-        case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC:
-            symbianLayout->addWidget(createToolChainCheckBox(tc));
-            break;
-        case ProjectExplorer::ToolChain_GCC_MAEMO5:
-        case ProjectExplorer::ToolChain_GCC_HARMATTAN:
-        case ProjectExplorer::ToolChain_GCC_MEEGO:
-            maemoLayout->addWidget(createToolChainCheckBox(tc));
-            break;
-        case ProjectExplorer::ToolChain_INVALID:
-            break;
-        }
-    }
-    setLayout(mainLayout);
-}
-
-QCheckBox *ToolChainSelectorWidget::createToolChainCheckBox(int tc)
-{
-    // Add checkbox
-    QCheckBox *cb = new QCheckBox(toolChainName(tc));
-    cb->setProperty(toolChainPropertyC, QVariant(tc));
-    connect(cb, SIGNAL(stateChanged(int)), this, SLOT(slotCheckStateChanged(int)));
-    m_checkBoxes.push_back(cb);
-    return cb;
-}
-
-static inline QString msgDisabledToolChainToolTip(const QString &binary, int toolChain)
-{
-    return ToolChainSelectorWidget::tr(
-    "<html><head/><body><p>Another gdb binary (<i>%1</i>) is currently configured "
-    "to handle the toolchain <i>%2</i>.</p></body></html>").
-    arg(QFileInfo(binary).fileName(), toolChainName(toolChain));
-}
-
-void ToolChainSelectorWidget::setEnabledToolChains(const QList<int> &enabled,
-                                                   const BinaryToolChainMap *binaryToolChainMap)
-{
-    foreach(QCheckBox *cb, m_checkBoxes) {
-        const int toolChain = toolChainOfCheckBox(cb);
-        if (enabled.contains(toolChain)) {
-            cb->setToolTip(QString());
-        } else {
-            // Toolchain is handled by a different binary, hint to user.
-            cb->setEnabled(false);
-            const QString binary = binaryToolChainMap ?  binaryToolChainMap->key(toolChain) : QString();
-            if (!binary.isEmpty())
-                cb->setToolTip(msgDisabledToolChainToolTip(binary, toolChain));
-        }
-    }
-}
-
-void ToolChainSelectorWidget::setCheckedToolChains(const QList<int> &checked)
-{
-    foreach(QCheckBox *cb, m_checkBoxes)
-        if (checked.contains(toolChainOfCheckBox(cb)))
-            cb->setChecked(true);
-    // Trigger 'valid changed'
-    slotCheckStateChanged(checked.isEmpty() ? Qt::Unchecked : Qt::Checked);
-}
-
-QList<int> ToolChainSelectorWidget::checkedToolChains() const
-{
-    QList<int> rc;
-    foreach(const QCheckBox *cb, m_checkBoxes)
-        if (cb->isChecked())
-            rc.push_back(toolChainOfCheckBox(cb));
-    return rc;
-}
-
-bool ToolChainSelectorWidget::isValid() const
-{
-    return m_valid;
-}
-
-void ToolChainSelectorWidget::slotCheckStateChanged(int state)
-{
-    // Emit signal if valid state changed
-    const bool newValid = state == Qt::Checked || hasCheckedToolChain();
-    if (newValid != m_valid) {
-        m_valid = newValid;
-        emit validChanged(m_valid);
-    }
-}
-
-bool ToolChainSelectorWidget::hasCheckedToolChain() const
-{
-    foreach(const QCheckBox *cb, m_checkBoxes)
-        if (cb->isChecked())
-            return true;
-    return false;
-}
-
-// -------------- ToolChainDialog
-BinaryToolChainDialog::BinaryToolChainDialog(QWidget *parent) :
-    QDialog(parent),
-    m_toolChainSelector(new ToolChainSelectorWidget),
-    m_mainLayout(new QFormLayout),
-    m_buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel)),
-    m_pathChooser(new Utils::PathChooser)
-{
-
-    setModal(true);
-    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
-    setWindowTitle(tr("Select binary and toolchains"));
-
-    m_pathChooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
-    m_pathChooser->setPromptDialogTitle(tr("Gdb binary"));
-    connect(m_pathChooser, SIGNAL(validChanged()), this, SLOT(slotValidChanged()));
-    m_mainLayout->addRow(tr("Path:"), m_pathChooser);
-
-    connect(m_toolChainSelector, SIGNAL(validChanged(bool)), this, SLOT(slotValidChanged()));
-    m_mainLayout->addRow(m_toolChainSelector);
-
-    connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
-    connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
-    m_mainLayout->addRow(m_buttonBox);
-    setLayout(m_mainLayout);
-
-    setOkButtonEnabled(false);
-    m_pathChooser->setFocus();
-}
-
-void BinaryToolChainDialog::setToolChainChoices(const QList<int> &tcs,
-                                                const BinaryToolChainMap *binaryToolChainMap)
-{
-    m_toolChainSelector->setEnabledToolChains(tcs, binaryToolChainMap);
-}
-
-void BinaryToolChainDialog::setToolChains(const QList<int> &tcs)
-{
-    m_toolChainSelector->setCheckedToolChains(tcs);
-}
-
-QList<int> BinaryToolChainDialog::toolChains() const
-{
-    return m_toolChainSelector->checkedToolChains();
-}
-
-void BinaryToolChainDialog::setOkButtonEnabled(bool v)
-{
-    m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(v);
-}
-
-void BinaryToolChainDialog::setPath(const QString &p)
-{
-    m_pathChooser->setPath(p);
-}
-
-QString BinaryToolChainDialog::path() const
-{
-    return m_pathChooser->rawPath();
-}
-
-void BinaryToolChainDialog::slotValidChanged()
-{
-    setOkButtonEnabled(m_pathChooser->isValid() && m_toolChainSelector->isValid());
+    return m_model->isDirty();
 }
 
 } // namespace Internal
diff --git a/src/plugins/debugger/gdb/gdbchooserwidget.h b/src/plugins/debugger/gdb/gdbchooserwidget.h
index da62e60ddac0670f0dc91c5cb159fc7e0d3d14d7..45f20eacb5181cdb0aa06169d22bca059b0586ae 100644
--- a/src/plugins/debugger/gdb/gdbchooserwidget.h
+++ b/src/plugins/debugger/gdb/gdbchooserwidget.h
@@ -67,96 +67,17 @@ class GdbChooserWidget : public QWidget
 public:
     explicit GdbChooserWidget(QWidget *parent = 0);
 
-    typedef QMultiMap<QString, int> BinaryToolChainMap;
-
-    BinaryToolChainMap gdbBinaries() const;
-    void setGdbBinaries(const BinaryToolChainMap &m);
+    QMap<QString, QString> gdbMapping() const;
+    void setGdbMapping(const QMap<QString, QString> &m);
 
     bool isDirty() const;
 
-public slots:
-    void clearDirty();
-
-private slots:
-    void slotAdd();
-    void slotRemove();
-    void slotCurrentChanged(const QModelIndex &current, const QModelIndex & previous);
-    void slotDoubleClicked(const QModelIndex &current);
-
 private:
     void removeItem(QStandardItem *item);
     QToolButton *createAddToolMenuButton();
-    QStandardItem *currentItem() const;
 
     QTreeView *m_treeView;
     GdbBinaryModel *m_model;
-    QToolButton *m_addButton;
-    QToolButton *m_deleteButton;
-    bool m_dirty;
-};
-
-// Present toolchains with checkboxes grouped in QGroupBox panes
-// and provide valid-handling. Unavailabe toolchains can be grayed
-// out using setEnabledToolChains().
-class ToolChainSelectorWidget : public QWidget {
-    Q_OBJECT
-public:
-    typedef GdbChooserWidget::BinaryToolChainMap BinaryToolChainMap;
-
-    explicit ToolChainSelectorWidget(QWidget *parent = 0);
-
-    void setEnabledToolChains(const QList<int> &enabled,
-                              // Optionally used for generating a tooltip for the disabled check boxes
-                              const BinaryToolChainMap *binaryToolChainMap = 0);
-
-    void setCheckedToolChains(const QList<int> &);
-    QList<int> checkedToolChains() const;
-
-    bool isValid() const;
-
-signals:
-    void validChanged(bool);
-
-private slots:
-    void slotCheckStateChanged(int);
-
-private:
-    bool hasCheckedToolChain() const;
-    QCheckBox *createToolChainCheckBox(int tc);
-
-    QList<QCheckBox*> m_checkBoxes;
-    bool m_valid;
-};
-
-// Internal helper dialog for selecting a binary and its
-// associated toolchains.
-class BinaryToolChainDialog : public QDialog {
-    Q_OBJECT
-public:
-    typedef GdbChooserWidget::BinaryToolChainMap BinaryToolChainMap;
-
-    explicit BinaryToolChainDialog(QWidget *parent);
-
-    void setToolChainChoices(const QList<int> &,
-                             // Optionally used for generating a tooltip for the disabled check boxes
-                             const BinaryToolChainMap *binaryToolChainMap = 0);
-
-    void setToolChains(const QList<int> &);
-    QList<int> toolChains() const;
-
-    void setPath(const QString &);
-    QString path() const;
-
-private slots:
-    void slotValidChanged();
-
-private:
-    void setOkButtonEnabled(bool e);
-
-    ToolChainSelectorWidget *m_toolChainSelector;
-    QFormLayout *m_mainLayout;
-    QDialogButtonBox *m_buttonBox;
-    Utils::PathChooser *m_pathChooser;
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index dce1d60f1bc27f391295131c560f4f0ef91e53a9..c9030ece6357b471c4333b2cf449bbdc4990affd 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -1795,36 +1795,29 @@ int GdbEngine::currentFrame() const
     return stackHandler()->currentIndex();
 }
 
-QString msgNoBinaryForToolChain(int tc)
+QString msgNoBinaryForToolChain(const ProjectExplorer::Abi &tc)
 {
     using namespace ProjectExplorer;
-    return GdbEngine::tr("There is no gdb binary available for '%1'.")
-        .arg(ToolChain::toolChainName(ToolChainType(tc)));
+    return GdbEngine::tr("There is no gdb binary available for binaries in format '%1'")
+        .arg(tc.toString());
 }
 
 AbstractGdbAdapter *GdbEngine::createAdapter()
 {
     const DebuggerStartParameters &sp = startParameters();
-    switch (sp.toolChainType) {
-    case ProjectExplorer::ToolChain_WINSCW: // S60
-    case ProjectExplorer::ToolChain_GCCE:
-    case ProjectExplorer::ToolChain_RVCT2_ARMV5:
-    case ProjectExplorer::ToolChain_RVCT2_ARMV6:
-    case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC:
-    case ProjectExplorer::ToolChain_GCCE_GNUPOC:
+    if (sp.toolChainAbi.os() == ProjectExplorer::Abi::Symbian) {
+        // FIXME: 1 of 3 testing hacks.
         if (sp.debugClient == DebuggerStartParameters::DebugClientCoda)
             return new CodaGdbAdapter(this);
         else
             return new TrkGdbAdapter(this);
-    default:
-        break;
     }
 
     switch (sp.startMode) {
     case AttachCore:
         return new CoreGdbAdapter(this);
     case AttachToRemote:
-        return new RemoteGdbServerAdapter(this, sp.toolChainType);
+        return new RemoteGdbServerAdapter(this, sp.toolChainAbi);
     case StartRemoteGdb:
         return new RemotePlainGdbAdapter(this);
     case AttachExternal:
@@ -4220,12 +4213,12 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb,
     const DebuggerStartParameters &sp = startParameters();
     m_gdb = QString::fromLocal8Bit(qgetenv("QTC_DEBUGGER_PATH"));
     if (m_gdb.isEmpty() && sp.startMode != StartRemoteGdb)
-        m_gdb = debuggerCore()->gdbBinaryForToolChain(sp.toolChainType);
+        m_gdb = debuggerCore()->gdbBinaryForAbi(startParameters().toolChainAbi);
     if (m_gdb.isEmpty())
         m_gdb = gdb;
     if (m_gdb.isEmpty()) {
         handleAdapterStartFailed(
-            msgNoBinaryForToolChain(sp.toolChainType),
+            msgNoBinaryForToolChain(sp.toolChainAbi),
             GdbOptionsPage::settingsId());
         return false;
     }
diff --git a/src/plugins/debugger/gdb/gdboptionspage.cpp b/src/plugins/debugger/gdb/gdboptionspage.cpp
index 46f69c72f89a39c4d2a02a303c9487add89e7098..8f64c46f9f7480a5b14fe8281d2797b60e546db5 100644
--- a/src/plugins/debugger/gdb/gdboptionspage.cpp
+++ b/src/plugins/debugger/gdb/gdboptionspage.cpp
@@ -37,8 +37,8 @@
 
 #include <coreplugin/icore.h>
 #include <projectexplorer/projectexplorer.h>
-#include <projectexplorer/toolchain.h>
-#include <projectexplorer/toolchaintype.h>
+#include <projectexplorer/toolchainmanager.h>
+#include <projectexplorer/abi.h>
 
 #include <QtCore/QCoreApplication>
 #include <QtCore/QTextStream>
@@ -47,22 +47,37 @@
 namespace Debugger {
 namespace Internal {
 
-const char gdbBinariesSettingsGroupC[] = "GdbBinaries";
-const char debugModeGdbBinaryKeyC[] = "GdbBinary";
+static const char *GDB_MAPPING_ARRAY = "GdbMapping";
+static const char *GDB_ABI_KEY = "Abi";
+static const char *GDB_BINARY_KEY = "Binary";
 
-GdbOptionsPage::GdbBinaryToolChainMap GdbOptionsPage::gdbBinaryToolChainMap;
-bool GdbOptionsPage::gdbBinariesChanged = true;
+GdbOptionsPage::GdbBinaryToolChainMap GdbOptionsPage::abiToGdbMap;
+bool GdbOptionsPage::gdbMappingChanged = true;
 
-void GdbOptionsPage::readGdbBinarySettings() /* static */
+void GdbOptionsPage::readGdbSettings() /* static */
 {
+    // FIXME: Convert old settings!
     using namespace ProjectExplorer;
     QSettings *settings = Core::ICore::instance()->settings();
-    // Convert gdb binaries from flat settings list (see writeSettings)
-    // into map ("binary1=gdb,1,2", "binary2=symbian_gdb,3,4").
-    gdbBinaryToolChainMap.clear();
+
+    abiToGdbMap.clear();
+
+    int size = settings->beginReadArray(GDB_MAPPING_ARRAY);
+    for (int i = 0; i < size; ++i) {
+        settings->setArrayIndex(i);
+        ProjectExplorer::Abi abi(settings->value(GDB_ABI_KEY).toString());
+        if (!abi.isValid())
+            continue;
+        QString binary = settings->value(GDB_BINARY_KEY).toString();
+        if (binary.isEmpty())
+            continue;
+        abiToGdbMap.insert(abi.toString(), binary);
+    }
+    settings->endArray();
+
+    // Map old settings (pre 2.2):
     const QChar separator = QLatin1Char(',');
-    const QString keyRoot = QLatin1String(gdbBinariesSettingsGroupC) + QLatin1Char('/') +
-                            QLatin1String(debugModeGdbBinaryKeyC);
+    const QString keyRoot = QLatin1String("GdbBinaries/GdbBinaries");
     for (int i = 1; ; i++) {
         const QString value = settings->value(keyRoot + QString::number(i)).toString();
         if (value.isEmpty())
@@ -71,81 +86,116 @@ void GdbOptionsPage::readGdbBinarySettings() /* static */
         QStringList tokens = value.split(separator);
         if (tokens.size() < 2)
             break;
+
         const QString binary = tokens.front();
         // Skip non-existent absolute binaries allowing for upgrades by the installer.
         // Force a rewrite of the settings file.
         const QFileInfo binaryInfo(binary);
         if (binaryInfo.isAbsolute() && !binaryInfo.isExecutable()) {
-            gdbBinariesChanged = true;
             const QString msg = QString::fromLatin1("Warning: The gdb binary '%1' does not exist, skipping.\n").arg(binary);
             qWarning("%s", qPrintable(msg));
             continue;
         }
+
         // Create entries for all toolchains.
         tokens.pop_front();
         foreach (const QString &t, tokens) {
             // Paranoia: Check if the there is already a binary configured for the toolchain.
-            const int toolChain = t.toInt();
-            const QString predefinedGdb = gdbBinaryToolChainMap.key(toolChain);
-            if (predefinedGdb.isEmpty()) {
-                gdbBinaryToolChainMap.insert(binary, toolChain);
-            } else {
-                const QString toolChainName =
-                    ProjectExplorer::ToolChain::toolChainName(ToolChainType(toolChain));
-                const QString msg =
-                        QString::fromLatin1("An inconsistency has been encountered in the Ini-file '%1':\n"
-                                            "Skipping gdb binary '%2' for toolchain '%3' as '%4' is already configured for it.").
-                        arg(settings->fileName(), binary, toolChainName, predefinedGdb);
-                qWarning("%s", qPrintable(msg));
+            QString abi;
+            switch (t.toInt())
+            {
+            case 0: // GCC
+            case 1: // Linux ICC
+#ifndef Q_OS_WIN
+                abi = ProjectExplorer::Abi::hostAbi().toString();
+#endif
+                break;
+            case 2: // MinGW
+            case 3: // MSVC
+            case 4: // WINCE
+#ifdef Q_OS_WIN
+                abi = ProjectExplorer::Abi::hostAbi().toString();
+#endif
+                break;
+            case 5: // WINSCW
+                abi = ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Symbian,
+                                           ProjectExplorer::Abi::Symbian_emulator,
+                                           ProjectExplorer::Abi::Format_ELF,
+                                           32).toString();
+                break;
+            case 6: // GCCE
+            case 7: // RVCT 2, ARM v5
+            case 8: // RVCT 2, ARM v6
+            case 11: // RVCT GNUPOC
+            case 12: // RVCT 4, ARM v5
+            case 13: // RVCT 4, ARM v6
+                abi = ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Symbian,
+                                           ProjectExplorer::Abi::Symbian_device,
+                                           ProjectExplorer::Abi::Format_ELF,
+                                           32).toString();
+                break;
+            case 9: // GCC Maemo5
+                abi = ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Linux,
+                                           ProjectExplorer::Abi::Linux_maemo,
+                                           ProjectExplorer::Abi::Format_ELF,
+                                           32).toString();
+
+                break;
+            case 14: // GCC Harmattan
+                abi = ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Linux,
+                                           ProjectExplorer::Abi::Linux_harmattan,
+                                           ProjectExplorer::Abi::Format_ELF,
+                                           32).toString();
+                break;
+            case 15: // GCC Meego
+                abi = ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Linux,
+                                           ProjectExplorer::Abi::Linux_meego,
+                                           ProjectExplorer::Abi::Format_ELF,
+                                           32).toString();
+                break;
+            default:
+                break;
             }
+            if (abi.isEmpty() || abiToGdbMap.contains(abi))
+                continue;
+
+            abiToGdbMap.insert(abi, binary);
         }
     }
-    // Linux defaults
-#ifdef Q_OS_UNIX
-    if (gdbBinaryToolChainMap.isEmpty()) {
-        const QString gdb = QLatin1String("gdb");
-        gdbBinaryToolChainMap.insert(gdb, ToolChain_GCC);
-        gdbBinaryToolChainMap.insert(gdb, ToolChain_LINUX_ICC);
-        gdbBinaryToolChainMap.insert(gdb, ToolChain_OTHER);
-        gdbBinaryToolChainMap.insert(gdb, ToolChain_UNKNOWN);
-    }
-#endif
+
+    gdbMappingChanged = false;
 }
 
-void GdbOptionsPage::writeGdbBinarySettings() /* static */
+void GdbOptionsPage::writeGdbSettings() /* static */
 {
+    // FIXME: This should actually get called in response to ICore::saveSettingsRequested()
+    if (!gdbMappingChanged)
+        return;
+
     QSettings *settings = Core::ICore::instance()->settings();
-    // Convert gdb binaries map into a flat settings list of
-    // ("binary1=gdb,1,2", "binary2=symbian_gdb,3,4"). It needs to be ASCII for installers
-    QString lastBinary;
-    QStringList settingsList;
-    const QChar separator = QLatin1Char(',');
-    const GdbBinaryToolChainMap::const_iterator cend = gdbBinaryToolChainMap.constEnd();
-    for (GdbBinaryToolChainMap::const_iterator it = gdbBinaryToolChainMap.constBegin(); it != cend; ++it) {
-        if (it.key() != lastBinary) {
-            lastBinary = it.key(); // Start new entry with first toolchain
-            settingsList.push_back(lastBinary);
-        }
-        settingsList.back().append(separator); // Append toolchain to last binary
-        settingsList.back().append(QString::number(it.value()));
+
+    settings->beginWriteArray(GDB_MAPPING_ARRAY);
+
+    int index = 0;
+    for (QMap<QString, QString>::const_iterator i = abiToGdbMap.constBegin();
+         i != abiToGdbMap.constEnd(); ++i) {
+        if (i.value().isEmpty())
+            continue;
+
+        settings->setArrayIndex(index);
+        ++index;
+
+        settings->setValue(GDB_ABI_KEY, i.key());
+        settings->setValue(GDB_BINARY_KEY, i.value());
     }
-    // Terminate settings list by an empty element such that consecutive keys resulting
-    // from ini-file merging are suppressed while reading.
-    settingsList.push_back(QString());
-    // Write out list
-    settings->beginGroup(QLatin1String(gdbBinariesSettingsGroupC));
-    settings->remove(QString()); // remove all keys in group.
-    const int count = settingsList.size();
-    const QString keyRoot = QLatin1String(debugModeGdbBinaryKeyC);
-    for (int i = 0; i < count; i++)
-        settings->setValue(keyRoot + QString::number(i + 1), settingsList.at(i));
-    settings->endGroup();
+    settings->endArray();
+
+    gdbMappingChanged = false;
 }
 
 GdbOptionsPage::GdbOptionsPage()
     : m_ui(0)
-{
-}
+{ }
 
 QString GdbOptionsPage::settingsId()
 {
@@ -174,10 +224,41 @@ QIcon GdbOptionsPage::categoryIcon() const
 
 QWidget *GdbOptionsPage::createPage(QWidget *parent)
 {
+    // Fix up abi mapping now that the ToolChainManager is available:
+    connect(ProjectExplorer::ToolChainManager::instance(), SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)),
+            this, SLOT(handleToolChainAdditions(ProjectExplorer::ToolChain*)));
+    connect(ProjectExplorer::ToolChainManager::instance(), SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
+            this, SLOT(handleToolChainRemovals(ProjectExplorer::ToolChain*)));
+
+    // Update mapping now that toolchains are available
+    QList<ProjectExplorer::ToolChain *> tcs =
+            ProjectExplorer::ToolChainManager::instance()->toolChains();
+
+    QStringList abiList;
+    foreach (ProjectExplorer::ToolChain *tc, tcs) {
+        const QString abi = tc->targetAbi().toString();
+        if (!abiList.contains(abi))
+            abiList.append(abi);
+        if (!abiToGdbMap.contains(abi))
+            handleToolChainAdditions(tc);
+    }
+
+    QStringList toRemove;
+    for (QMap<QString, QString>::const_iterator i = abiToGdbMap.constBegin();
+         i != abiToGdbMap.constEnd(); ++i) {
+        if (!abiList.contains(i.key()))
+            toRemove.append(i.key());
+    }
+
+    foreach (const QString &key, toRemove)
+        abiToGdbMap.remove(key);
+
+    // Actual page setup:
     QWidget *w = new QWidget(parent);
     m_ui = new Ui::GdbOptionsPage;
     m_ui->setupUi(w);
-    m_ui->gdbChooserWidget->setGdbBinaries(gdbBinaryToolChainMap);
+    m_ui->gdbChooserWidget->setGdbMapping(abiToGdbMap);
+
     m_ui->scriptFileChooser->setExpectedKind(Utils::PathChooser::File);
     m_ui->scriptFileChooser->setPromptDialogTitle(tr("Choose Location of Startup Script File"));
 
@@ -201,18 +282,7 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent)
         m_ui->checkBoxEnableReverseDebugging);
     m_group.insert(debuggerCore()->action(GdbWatchdogTimeout), 0);
 
-#if 1
     m_ui->groupBoxPluginDebugging->hide();
-#else // The related code (handleAqcuiredInferior()) is disabled as well.
-    m_group.insert(debuggerCore()->action(AllPluginBreakpoints),
-        m_ui->radioButtonAllPluginBreakpoints);
-    m_group.insert(debuggerCore()->action(SelectedPluginBreakpoints),
-        m_ui->radioButtonSelectedPluginBreakpoints);
-    m_group.insert(debuggerCore()->action(NoPluginBreakpoints),
-        m_ui->radioButtonNoPluginBreakpoints);
-    m_group.insert(debuggerCore()->action(SelectedPluginBreakpointsPattern),
-        m_ui->lineEditSelectedPluginBreakpointsPattern);
-#endif
 
     m_ui->lineEditSelectedPluginBreakpointsPattern->
         setEnabled(debuggerCore()->action(SelectedPluginBreakpoints)->value().toBool());
@@ -246,11 +316,12 @@ void GdbOptionsPage::apply()
 {
     if (!m_ui) // page never shown
         return;
+
     m_group.apply(Core::ICore::instance()->settings());
     if (m_ui->gdbChooserWidget->isDirty()) {
-        gdbBinariesChanged = true;
-        gdbBinaryToolChainMap = m_ui->gdbChooserWidget->gdbBinaries();
-        m_ui->gdbChooserWidget->clearDirty();
+        abiToGdbMap = m_ui->gdbChooserWidget->gdbMapping();
+        m_ui->gdbChooserWidget->setGdbMapping(abiToGdbMap);
+        gdbMappingChanged = true;
     }
 }
 
@@ -268,5 +339,37 @@ bool GdbOptionsPage::matches(const QString &s) const
     return m_searchKeywords.contains(s, Qt::CaseInsensitive);
 }
 
+void GdbOptionsPage::handleToolChainAdditions(ProjectExplorer::ToolChain *tc)
+{
+    ProjectExplorer::Abi tcAbi = tc->targetAbi();
+
+    if (tcAbi.binaryFormat() != ProjectExplorer::Abi::Format_ELF
+            && tcAbi.binaryFormat() != ProjectExplorer::Abi::Format_Mach_O
+            && !( tcAbi.os() == ProjectExplorer::Abi::Windows
+                  && tcAbi.osFlavor() == ProjectExplorer::Abi::Windows_msys ))
+        return;
+    if (abiToGdbMap.contains(tcAbi.toString()))
+        return;
+
+    QString binary;
+#ifdef Q_OS_UNIX
+    ProjectExplorer::Abi hostAbi = ProjectExplorer::Abi::hostAbi();
+    if (hostAbi == tcAbi)
+        binary = QLatin1String("gdb");
+#endif
+    abiToGdbMap.insert(tc->targetAbi().toString(), binary);
+}
+
+void GdbOptionsPage::handleToolChainRemovals(ProjectExplorer::ToolChain *tc)
+{
+    QList<ProjectExplorer::ToolChain *> tcs = ProjectExplorer::ToolChainManager::instance()->toolChains();
+    foreach (ProjectExplorer::ToolChain *current, tcs) {
+        if (current->targetAbi() == tc->targetAbi())
+            return;
+    }
+
+    abiToGdbMap.remove(tc->targetAbi().toString());
+}
+
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/gdb/gdboptionspage.h b/src/plugins/debugger/gdb/gdboptionspage.h
index faf28cdcc362f6ebe55c5dcb63bbdb224b616d4c..3a7c9a2c741b33fea4ea48af9cefbc6914d673c7 100644
--- a/src/plugins/debugger/gdb/gdboptionspage.h
+++ b/src/plugins/debugger/gdb/gdboptionspage.h
@@ -39,6 +39,10 @@
 #include <coreplugin/dialogs/ioptionspage.h>
 #include <utils/savedaction.h>
 
+namespace ProjectExplorer {
+class ToolChain;
+} // namespace ProjectExplorer
+
 namespace Debugger {
 namespace Internal {
 
@@ -61,11 +65,15 @@ public:
 
     static QString settingsId();
 
-    typedef QMultiMap<QString, int> GdbBinaryToolChainMap;
-    static GdbBinaryToolChainMap gdbBinaryToolChainMap;
-    static bool gdbBinariesChanged;
-    static void readGdbBinarySettings();
-    static void writeGdbBinarySettings();
+    typedef QMap<QString, QString> GdbBinaryToolChainMap;
+    static GdbBinaryToolChainMap abiToGdbMap;
+    static bool gdbMappingChanged;
+    static void readGdbSettings();
+    static void writeGdbSettings();
+
+private slots:
+    static void handleToolChainAdditions(ProjectExplorer::ToolChain *);
+    static void handleToolChainRemovals(ProjectExplorer::ToolChain *);
 
 private:
     Ui::GdbOptionsPage *m_ui;
diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
index 13b8a208f57be3066471c3182d4c47481519c87b..fcef41aca1e290c485ff92db192f6f34b5deeb40 100644
--- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
+++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
@@ -41,7 +41,7 @@
 
 #include <utils/qtcassert.h>
 #include <utils/fancymainwindow.h>
-#include <projectexplorer/toolchaintype.h>
+#include <projectexplorer/abi.h>
 
 #include <QtCore/QFileInfo>
 #include <QtGui/QMessageBox>
@@ -59,9 +59,11 @@ namespace Internal {
 //
 ///////////////////////////////////////////////////////////////////////
 
-RemoteGdbServerAdapter::RemoteGdbServerAdapter(GdbEngine *engine, int toolChainType, QObject *parent) :
+RemoteGdbServerAdapter::RemoteGdbServerAdapter(GdbEngine *engine,
+                                               const ProjectExplorer::Abi &abi,
+                                               QObject *parent) :
     AbstractGdbAdapter(engine, parent),
-    m_toolChainType(toolChainType)
+    m_abi(abi)
 {
     connect(&m_uploadProc, SIGNAL(error(QProcess::ProcessError)),
         SLOT(uploadProcError(QProcess::ProcessError)));
@@ -75,21 +77,10 @@ RemoteGdbServerAdapter::RemoteGdbServerAdapter(GdbEngine *engine, int toolChainT
 
 AbstractGdbAdapter::DumperHandling RemoteGdbServerAdapter::dumperHandling() const
 {
-    switch (m_toolChainType) {
-    case ProjectExplorer::ToolChain_MinGW:
-    case ProjectExplorer::ToolChain_MSVC:
-    case ProjectExplorer::ToolChain_WINCE:
-    case ProjectExplorer::ToolChain_WINSCW:
-    case ProjectExplorer::ToolChain_GCCE:
-    case ProjectExplorer::ToolChain_RVCT2_ARMV5:
-    case ProjectExplorer::ToolChain_RVCT2_ARMV6:
-    case ProjectExplorer::ToolChain_GCC_MAEMO5:
-    case ProjectExplorer::ToolChain_GCC_HARMATTAN:
-    case ProjectExplorer::ToolChain_GCC_MEEGO:
+    if (m_abi.os() == ProjectExplorer::Abi::Symbian
+            || m_abi.os() == ProjectExplorer::Abi::Windows
+            || m_abi.binaryFormat() == ProjectExplorer::Abi::Format_ELF)
         return DumperLoadedByGdb;
-    default:
-        break;
-    }
     return DumperLoadedByGdbPreload;
 }
 
diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.h b/src/plugins/debugger/gdb/remotegdbserveradapter.h
index 342def5eb551e65ebb468e8aaf07094451012aaf..9c27b2ec44b4af548429ac1728547f8a2284e7ec 100644
--- a/src/plugins/debugger/gdb/remotegdbserveradapter.h
+++ b/src/plugins/debugger/gdb/remotegdbserveradapter.h
@@ -37,6 +37,8 @@
 #include "abstractgdbadapter.h"
 #include "localgdbprocess.h"
 
+#include <projectexplorer/abi.h>
+
 namespace Debugger {
 namespace Internal {
 
@@ -51,7 +53,7 @@ class RemoteGdbServerAdapter : public AbstractGdbAdapter
     Q_OBJECT
 
 public:
-    RemoteGdbServerAdapter(GdbEngine *engine, int toolChainType, QObject *parent = 0);
+    RemoteGdbServerAdapter(GdbEngine *engine, const ProjectExplorer::Abi &abi, QObject *parent = 0);
 
 private:
     DumperHandling dumperHandling() const;
@@ -93,7 +95,7 @@ private:
     void handleTargetRemote(const GdbResponse &response);
     void handleInterruptInferior(const GdbResponse &response);
 
-    const int m_toolChainType;
+    const ProjectExplorer::Abi m_abi;
 
     QProcess m_uploadProc;
     LocalGdbProcess m_gdbProc;
diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp
index 5e99e170f4b0ccdf5907699cf21f173da89afb4e..77fc23dcb982b68dcf15448a601b2ebd2e67ad7c 100644
--- a/src/plugins/genericprojectmanager/genericproject.cpp
+++ b/src/plugins/genericprojectmanager/genericproject.cpp
@@ -39,7 +39,7 @@
 
 #include <projectexplorer/buildenvironmentwidget.h>
 #include <projectexplorer/customexecutablerunconfiguration.h>
-#include <projectexplorer/toolchain.h>
+#include <projectexplorer/toolchainmanager.h>
 #include <projectexplorer/projectexplorerconstants.h>
 #include <cplusplus/ModelManagerInterface.h>
 #include <extensionsystem/pluginmanager.h>
@@ -90,7 +90,7 @@ GenericProject::~GenericProject()
     m_manager->unregisterProject(this);
 
     delete m_rootNode;
-    delete m_toolChain;
+    // do not delete m_toolChain
 }
 
 GenericTarget *GenericProject::activeTarget() const
@@ -217,8 +217,8 @@ void GenericProject::refresh(RefreshOptions options)
         QStringList allIncludePaths;
         QStringList allFrameworkPaths;
 
-        foreach (const ProjectExplorer::HeaderPath &headerPath, m_toolChain->systemHeaderPaths()) {
-            if (headerPath.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath)
+        foreach (const HeaderPath &headerPath, m_toolChain->systemHeaderPaths()) {
+            if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
                 allFrameworkPaths.append(headerPath.path());
             else
                 allIncludePaths.append(headerPath.path());
@@ -328,44 +328,20 @@ void GenericProject::setIncludePaths(const QStringList &includePaths)
 QByteArray GenericProject::defines() const
 { return m_defines; }
 
-void GenericProject::setToolChainType(ProjectExplorer::ToolChainType type)
+void GenericProject::setToolChain(ToolChain *tc)
 {
-    using namespace ProjectExplorer;
-
-    m_toolChainType = type;
-
-    delete m_toolChain;
-    m_toolChain = 0;
-
-    if (type == ToolChain_MinGW) {
-        const QLatin1String qmake_cxx("g++"); // ### FIXME
-        const QString mingwDirectory; // ### FIXME
-
-        m_toolChain = ToolChain::createMinGWToolChain(qmake_cxx, mingwDirectory);
-
-    } else if (type == ToolChain_MSVC) {
-        const QString msvcVersion; // ### FIXME
-        m_toolChain = ToolChain::createMSVCToolChain(msvcVersion, false);
+    if (m_toolChain == tc)
+        return;
 
-    } else if (type == ToolChain_WINCE) {
-        const QString msvcVersion, wincePlatform; // ### FIXME
-        m_toolChain = ToolChain::createWinCEToolChain(msvcVersion, wincePlatform);
-    } else if (type == ToolChain_GCC) {
-        const QLatin1String qmake_cxx("g++"); // ### FIXME
-        m_toolChain = ToolChain::createGccToolChain(qmake_cxx);
-    } else if (type == ToolChain_LINUX_ICC) {
-        m_toolChain = ToolChain::createLinuxIccToolChain();
-    }
+    m_toolChain = tc;
+    emit toolChainChanged(m_toolChain);
 }
 
-ProjectExplorer::ToolChain *GenericProject::toolChain() const
+ToolChain *GenericProject::toolChain() const
 {
     return m_toolChain;
 }
 
-ProjectExplorer::ToolChainType GenericProject::toolChainType() const
-{ return m_toolChainType; }
-
 QString GenericProject::displayName() const
 {
     return m_projectName;
@@ -381,19 +357,19 @@ Core::IFile *GenericProject::file() const
     return m_file;
 }
 
-ProjectExplorer::IProjectManager *GenericProject::projectManager() const
+IProjectManager *GenericProject::projectManager() const
 {
     return m_manager;
 }
 
-QList<ProjectExplorer::Project *> GenericProject::dependsOn()
+QList<Project *> GenericProject::dependsOn()
 {
     return QList<Project *>();
 }
 
-QList<ProjectExplorer::BuildConfigWidget*> GenericProject::subConfigWidgets()
+QList<BuildConfigWidget*> GenericProject::subConfigWidgets()
 {
-    QList<ProjectExplorer::BuildConfigWidget*> list;
+    QList<BuildConfigWidget*> list;
     list << new BuildEnvironmentWidget;
     return list;
 }
@@ -420,7 +396,7 @@ QStringList GenericProject::buildTargets() const
 QVariantMap GenericProject::toMap() const
 {
     QVariantMap map(Project::toMap());
-    map.insert(QLatin1String(TOOLCHAIN_KEY), static_cast<int>(m_toolChainType));
+    map.insert(QLatin1String(TOOLCHAIN_KEY), m_toolChain ? m_toolChain->id() : QString());
     return map;
 }
 
@@ -438,7 +414,7 @@ bool GenericProject::fromMap(const QVariantMap &map)
             continue;
         }
         if (!t->activeRunConfiguration())
-            t->addRunConfiguration(new ProjectExplorer::CustomExecutableRunConfiguration(t));
+            t->addRunConfiguration(new CustomExecutableRunConfiguration(t));
     }
 
     // Add default setup:
@@ -448,11 +424,17 @@ bool GenericProject::fromMap(const QVariantMap &map)
         addTarget(factory->create(this, QLatin1String(GENERIC_DESKTOP_TARGET_ID)));
     }
 
-    ToolChainType type =
-            static_cast<ProjectExplorer::ToolChainType>
-            (map.value(QLatin1String(TOOLCHAIN_KEY), 0).toInt());
-
-    setToolChainType(type);
+    QString id = map.value(QLatin1String(TOOLCHAIN_KEY)).toString();
+    if (!id.isNull()) {
+        setToolChain(ToolChainManager::instance()->findToolChain(id));
+    } else {
+        QList<ToolChain *> tcs =
+                ToolChainManager::instance()->findToolChains(Abi::hostAbi());
+        if (tcs.isEmpty())
+            tcs = ToolChainManager::instance()->toolChains();
+        if (!tcs.isEmpty())
+            setToolChain(tcs.at(0));
+    }
 
     setIncludePaths(allIncludePaths());
 
@@ -465,7 +447,7 @@ bool GenericProject::fromMap(const QVariantMap &map)
 ////////////////////////////////////////////////////////////////////////////////////
 
 GenericBuildSettingsWidget::GenericBuildSettingsWidget(GenericTarget *target)
-    : m_target(target), m_buildConfiguration(0)
+    : m_target(target), m_toolChainChooser(0), m_buildConfiguration(0)
 {
     QFormLayout *fl = new QFormLayout(this);
     fl->setContentsMargins(0, -1, 0, -1);
@@ -479,21 +461,18 @@ GenericBuildSettingsWidget::GenericBuildSettingsWidget(GenericTarget *target)
     connect(m_pathChooser, SIGNAL(changed(QString)), this, SLOT(buildDirectoryChanged()));
 
     // tool chain
-    QComboBox *toolChainChooser = new QComboBox;
-    toolChainChooser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
-    using namespace ProjectExplorer;
-    int index = 0;
-    int selectedIndex = -1;
-    foreach (ToolChainType tc, ToolChain::supportedToolChains()) {
-        toolChainChooser->addItem(ToolChain::toolChainName(tc), QVariant::fromValue<ToolChainType>(tc));
-        if (m_target->genericProject()->toolChainType() == tc)
-            selectedIndex = index;
-        ++index;
-    }
+    m_toolChainChooser = new QComboBox;
+    m_toolChainChooser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+    updateToolChainList();
 
-    toolChainChooser->setCurrentIndex(selectedIndex);
-    fl->addRow(tr("Tool chain:"), toolChainChooser);
-    connect(toolChainChooser, SIGNAL(activated(int)), this, SLOT(toolChainSelected(int)));
+    fl->addRow(tr("Tool chain:"), m_toolChainChooser);
+    connect(m_toolChainChooser, SIGNAL(activated(int)), this, SLOT(toolChainSelected(int)));
+    connect(m_target->genericProject(), SIGNAL(toolChainChanged(ProjectExplorer::ToolChain*)),
+            this, SLOT(toolChainChanged(ProjectExplorer::ToolChain*)));
+    connect(ProjectExplorer::ToolChainManager::instance(), SIGNAL(toolChainAdded(ToolChain*)),
+            this, SLOT(updateToolChainList()));
+    connect(ProjectExplorer::ToolChainManager::instance(), SIGNAL(toolChainRemoved(ToolChain*)),
+            this, SLOT(updateToolChainList()));
 }
 
 GenericBuildSettingsWidget::~GenericBuildSettingsWidget()
@@ -517,9 +496,36 @@ void GenericBuildSettingsWidget::toolChainSelected(int index)
 {
     using namespace ProjectExplorer;
 
-    QComboBox *toolChainChooser = qobject_cast<QComboBox*>(sender());
-    ToolChainType type = toolChainChooser->itemData(index).value<ToolChainType>();
-    m_target->genericProject()->setToolChainType(type);
+    ToolChain *tc = static_cast<ToolChain *>(m_toolChainChooser->itemData(index).value<void *>());
+    m_target->genericProject()->setToolChain(tc);
+}
+
+void GenericBuildSettingsWidget::toolChainChanged(ProjectExplorer::ToolChain *tc)
+{
+    for (int i = 0; i < m_toolChainChooser->count(); ++i) {
+        ToolChain * currentTc = static_cast<ToolChain *>(m_toolChainChooser->itemData(i).value<void *>());
+        if (currentTc != tc)
+            continue;
+        m_toolChainChooser->setCurrentIndex(i);
+        return;
+    }
+}
+
+void GenericBuildSettingsWidget::updateToolChainList()
+{
+    m_toolChainChooser->clear();
+
+    QList<ToolChain *> tcs = ToolChainManager::instance()->toolChains();
+    if (!m_target->genericProject()->toolChain()) {
+        m_toolChainChooser->addItem(tr("<Invalid Toolchain>"), qVariantFromValue(static_cast<void *>(0)));
+        m_toolChainChooser->setCurrentIndex(0);
+    }
+    foreach (ToolChain *tc, tcs) {
+        m_toolChainChooser->addItem(tc->displayName(), qVariantFromValue(static_cast<void *>(tc)));
+        if (m_target->genericProject()->toolChain()
+                && m_target->genericProject()->toolChain()->id() == tc->id())
+            m_toolChainChooser->setCurrentIndex(m_toolChainChooser->count() - 1);
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/plugins/genericprojectmanager/genericproject.h b/src/plugins/genericprojectmanager/genericproject.h
index 6997c8696c6b5058def9d13b2acba729f8c3ad21..9c95a25ea1afd190f5efdb07e1117a76876d5767 100644
--- a/src/plugins/genericprojectmanager/genericproject.h
+++ b/src/plugins/genericprojectmanager/genericproject.h
@@ -41,13 +41,17 @@
 #include <projectexplorer/project.h>
 #include <projectexplorer/projectnodes.h>
 #include <projectexplorer/target.h>
+#include <projectexplorer/toolchain.h>
 #include <projectexplorer/buildstep.h>
-#include <projectexplorer/toolchaintype.h>
 #include <projectexplorer/buildconfiguration.h>
 #include <coreplugin/ifile.h>
 
 #include <QtCore/QFuture>
 
+QT_BEGIN_NAMESPACE
+class QComboBox;
+QT_END_NAMESPACE
+
 namespace Utils {
 class PathChooser;
 }
@@ -90,7 +94,6 @@ public:
     QStringList files(FilesMode fileMode) const;
 
     QStringList buildTargets() const;
-    ProjectExplorer::ToolChain *toolChain() const;
 
     bool addFiles(const QStringList &filePaths);
     bool removeFiles(const QStringList &filePaths);
@@ -111,11 +114,14 @@ public:
     QStringList projectIncludePaths() const;
     QStringList files() const;
     QStringList generated() const;
-    ProjectExplorer::ToolChainType toolChainType() const;
-    void setToolChainType(ProjectExplorer::ToolChainType type);
+    ProjectExplorer::ToolChain *toolChain() const;
+    void setToolChain(ProjectExplorer::ToolChain *tc);
 
     QVariantMap toMap() const;
 
+signals:
+    void toolChainChanged(ProjectExplorer::ToolChain *);
+
 protected:
     virtual bool fromMap(const QVariantMap &map);
 
@@ -143,7 +149,6 @@ private:
 
     GenericProjectNode *m_rootNode;
     ProjectExplorer::ToolChain *m_toolChain;
-    ProjectExplorer::ToolChainType m_toolChainType;
     QFuture<void> m_codeModelFuture;
 };
 
@@ -190,10 +195,13 @@ public:
 private Q_SLOTS:
     void buildDirectoryChanged();
     void toolChainSelected(int index);
+    void toolChainChanged(ProjectExplorer::ToolChain *);
+    void updateToolChainList();
 
 private:
     GenericTarget *m_target;
     Utils::PathChooser *m_pathChooser;
+    QComboBox *m_toolChainChooser;
     GenericBuildConfiguration *m_buildConfiguration;
 };
 
diff --git a/src/plugins/projectexplorer/abi.cpp b/src/plugins/projectexplorer/abi.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3a02abfc390f42a8ec1324308de0141999b2bf12
--- /dev/null
+++ b/src/plugins/projectexplorer/abi.cpp
@@ -0,0 +1,429 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "abi.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFile>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QSysInfo>
+
+namespace ProjectExplorer {
+
+Abi::Abi(const Architecture &a, const OS &o,
+         const OSFlavour &of, const BinaryFormat &f, unsigned char w) :
+    m_architecture(a), m_os(o), m_osFlavor(of), m_binaryFormat(f), m_wordWidth(w)
+{
+    switch (m_os) {
+    case ProjectExplorer::Abi::UNKNOWN_OS:
+        m_osFlavor = UNKNOWN_OSFLAVOUR;
+        break;
+    case ProjectExplorer::Abi::Linux:
+        if (m_osFlavor < Linux_generic || m_osFlavor > Linux_meego)
+            m_osFlavor = UNKNOWN_OSFLAVOUR;
+        break;
+    case ProjectExplorer::Abi::Mac:
+        if (m_osFlavor < Mac_generic || m_osFlavor > Mac_generic)
+            m_osFlavor = UNKNOWN_OSFLAVOUR;
+        break;
+    case ProjectExplorer::Abi::Symbian:
+        if (m_osFlavor < Symbian_device || m_osFlavor > Symbian_emulator)
+            m_osFlavor = UNKNOWN_OSFLAVOUR;
+        break;
+    case ProjectExplorer::Abi::UNIX:
+        if (m_osFlavor < Unix_generic || m_osFlavor > Unix_generic)
+            m_osFlavor = UNKNOWN_OSFLAVOUR;
+        break;
+    case ProjectExplorer::Abi::Windows:
+        if (m_osFlavor < Windows_msvc || m_osFlavor > Windows_ce)
+            m_osFlavor = UNKNOWN_OSFLAVOUR;
+        break;
+    }
+}
+
+Abi::Abi(const QString &abiString) :
+    m_architecture(UNKNOWN_ARCHITECTURE), m_os(UNKNOWN_OS),
+    m_osFlavor(UNKNOWN_OSFLAVOUR), m_binaryFormat(UNKNOWN_FORMAT), m_wordWidth(0)
+{
+    QStringList abiParts = abiString.split(QLatin1Char('-'));
+    if (abiParts.count() >= 1) {
+        if (abiParts.at(0) == QLatin1String("unknown"))
+            m_architecture = UNKNOWN_ARCHITECTURE;
+        else if (abiParts.at(0) == QLatin1String("arm"))
+            m_architecture = ARM;
+        else if (abiParts.at(0) == QLatin1String("x86"))
+            m_architecture = x86;
+        else if (abiParts.at(0) == QLatin1String("mips"))
+            m_architecture = Mips;
+        else if (abiParts.at(0) == QLatin1String("ppc"))
+            m_architecture = PowerPC;
+        else if (abiParts.at(0) == QLatin1String("itanium"))
+            m_architecture = Itanium;
+        else
+            return;
+    }
+
+    if (abiParts.count() >= 2) {
+        if (abiParts.at(1) == QLatin1String("unknown"))
+            m_os = UNKNOWN_OS;
+        else if (abiParts.at(1) == QLatin1String("linux"))
+            m_os = Linux;
+        else if (abiParts.at(1) == QLatin1String("macos"))
+            m_os = Mac;
+        else if (abiParts.at(1) == QLatin1String("symbian"))
+            m_os = Symbian;
+        else if (abiParts.at(1) == QLatin1String("unix"))
+            m_os = UNIX;
+        else if (abiParts.at(1) == QLatin1String("windows"))
+            m_os = Windows;
+        else
+            return;
+    }
+
+    if (abiParts.count() >= 3) {
+        if (abiParts.at(2) == QLatin1String("unknown"))
+            m_osFlavor = UNKNOWN_OSFLAVOUR;
+        else if (abiParts.at(2) == QLatin1String("generic") && m_os == Linux)
+            m_osFlavor = Linux_generic;
+        else if (abiParts.at(2) == QLatin1String("maemo") && m_os == Linux)
+            m_osFlavor = Linux_maemo;
+        else if (abiParts.at(2) == QLatin1String("meego") && m_os == Linux)
+            m_osFlavor = Linux_meego;
+        else if (abiParts.at(2) == QLatin1String("generic") && m_os == Mac)
+            m_osFlavor = Mac_generic;
+        else if (abiParts.at(2) == QLatin1String("device") && m_os == Symbian)
+            m_osFlavor = Symbian_device;
+        else if (abiParts.at(2) == QLatin1String("emulator") && m_os == Symbian)
+            m_osFlavor = Symbian_emulator;
+        else if (abiParts.at(2) == QLatin1String("generic") && m_os == UNIX)
+            m_osFlavor = Unix_generic;
+        else if (abiParts.at(2) == QLatin1String("msvc") && m_os == Windows)
+            m_osFlavor = Windows_msvc;
+        else if (abiParts.at(2) == QLatin1String("msys") && m_os == Windows)
+            m_osFlavor = Windows_msys;
+        else if (abiParts.at(2) == QLatin1String("ce") && m_os == Windows)
+            m_osFlavor = Windows_ce;
+        else
+            return;
+    }
+
+    if (abiParts.count() >= 4) {
+        if (abiParts.at(3) == QLatin1String("unknown"))
+            m_binaryFormat = UNKNOWN_FORMAT;
+        else if (abiParts.at(3) == QLatin1String("elf"))
+            m_binaryFormat = Format_ELF;
+        else if (abiParts.at(3) == QLatin1String("pe"))
+            m_binaryFormat = Format_PE;
+        else if (abiParts.at(3) == QLatin1String("mach_o"))
+            m_binaryFormat = Format_Mach_O;
+        else if (abiParts.at(3) == QLatin1String("qml_rt"))
+            m_binaryFormat = Format_Runtime_QML;
+        else
+            return;
+    }
+
+    if (abiParts.count() >= 5) {
+        const QString &bits = abiParts.at(4);
+        if (!bits.endsWith(QLatin1String("bit")))
+            return;
+
+        bool ok = false;
+        int bitCount = bits.left(bits.count() - 3).toInt(&ok);
+        if (!ok)
+            return;
+        if (bitCount != 8 && bitCount != 16 && bitCount != 32 && bitCount != 64)
+            return;
+        m_wordWidth = bitCount;
+    }
+}
+
+QString Abi::toString() const
+{
+    QStringList dn;
+    dn << toString(m_architecture);
+    dn << toString(m_os);
+    dn << toString(m_osFlavor);
+    dn << toString(m_binaryFormat);
+    dn << toString(m_wordWidth);
+
+    return dn.join(QLatin1String("-"));
+}
+
+bool Abi::operator == (const Abi &other) const
+{
+    return m_architecture == other.m_architecture
+            && m_os == other.m_os
+            && m_osFlavor == other.m_osFlavor
+            && m_binaryFormat == other.m_binaryFormat
+            && m_wordWidth == other.m_wordWidth;
+}
+
+bool Abi::isCompatibleWith(const Abi &other) const
+{
+    return (architecture() == other.architecture() || other.architecture() == Abi::UNKNOWN_ARCHITECTURE)
+            && (os() == other.os() || other.os() == Abi::UNKNOWN_OS)
+            && (osFlavor() == other.osFlavor() || other.osFlavor() == Abi::UNKNOWN_OSFLAVOUR)
+            && (binaryFormat() == other.binaryFormat() || other.binaryFormat() == Abi::UNKNOWN_FORMAT)
+            && ((wordWidth() == other.wordWidth() && wordWidth() != 0) || other.wordWidth() == 0);
+}
+
+bool Abi::isValid() const
+{
+    return m_architecture != UNKNOWN_ARCHITECTURE
+            && m_os != UNKNOWN_OS
+            && m_osFlavor != UNKNOWN_OSFLAVOUR
+            && m_binaryFormat != UNKNOWN_FORMAT
+            && m_wordWidth != 0;
+}
+
+QString Abi::toString(const Architecture &a)
+{
+    switch (a) {
+    case ARM:
+        return QLatin1String("arm");
+    case x86:
+        return QLatin1String("x86");
+    case Mips:
+        return QLatin1String("mips");
+    case PowerPC:
+        return QLatin1String("ppc");
+    case Itanium:
+        return QLatin1String("itanium");
+    case UNKNOWN_ARCHITECTURE: // fall through!
+    default:
+        return QLatin1String("unknown");
+    }
+}
+
+QString Abi::toString(const OS &o)
+{
+    switch (o) {
+    case Linux:
+        return QLatin1String("linux");
+    case Mac:
+        return QLatin1String("macos");
+    case Symbian:
+        return QLatin1String("symbian");
+    case UNIX:
+        return QLatin1String("unix");
+    case Windows:
+        return QLatin1String("windows");
+    case UNKNOWN_OS: // fall through!
+    default:
+        return QLatin1String("unknown");
+    };
+}
+
+QString Abi::toString(const OSFlavour &of)
+{
+    switch (of) {
+    case ProjectExplorer::Abi::Linux_generic:
+        return QLatin1String("generic");
+    case ProjectExplorer::Abi::Linux_maemo:
+        return QLatin1String("maemo");
+    case ProjectExplorer::Abi::Linux_harmattan:
+        return QLatin1String("harmattan");
+    case ProjectExplorer::Abi::Linux_meego:
+        return QLatin1String("meego");
+    case ProjectExplorer::Abi::Mac_generic:
+        return QLatin1String("generic");
+    case ProjectExplorer::Abi::Symbian_device:
+        return QLatin1String("device");
+    case ProjectExplorer::Abi::Symbian_emulator:
+        return QLatin1String("emulator");
+    case ProjectExplorer::Abi::Unix_generic:
+        return QLatin1String("generic");
+    case ProjectExplorer::Abi::Windows_msvc:
+        return QLatin1String("msvc");
+    case ProjectExplorer::Abi::Windows_msys:
+        return QLatin1String("msys");
+    case ProjectExplorer::Abi::Windows_ce:
+        return QLatin1String("ce");
+    case ProjectExplorer::Abi::UNKNOWN_OSFLAVOUR: // fall throught!
+    default:
+        return QLatin1String("unknown");
+    }
+}
+
+QString Abi::toString(const BinaryFormat &bf)
+{
+    switch (bf) {
+    case Format_ELF:
+        return QLatin1String("elf");
+    case Format_PE:
+        return QLatin1String("pe");
+    case Format_Mach_O:
+        return QLatin1String("mach_o");
+    case Format_Runtime_QML:
+        return QLatin1String("qml_rt");
+    case UNKNOWN_FORMAT: // fall through!
+    default:
+        return QLatin1String("unknown");
+    }
+}
+
+QString Abi::toString(int w)
+{
+    if (w == 0)
+        return QLatin1String("unknown");
+    return QString::fromLatin1("%1bit").arg(w);
+}
+
+
+Abi Abi::hostAbi()
+{
+    Architecture arch = QTC_CPU; // define set by qmake
+    OS os = UNKNOWN_OS;
+    OSFlavour subos = UNKNOWN_OSFLAVOUR;
+    BinaryFormat format = UNKNOWN_FORMAT;
+
+#if defined (Q_OS_WIN)
+    os = Windows;
+    subos = Windows_msvc;
+    format = Format_PE;
+#elif defined (Q_OS_LINUX)
+    os = Linux;
+    subos = Linux_generic;
+    format = Format_ELF;
+#elif defined (Q_OS_MAC)
+    os = Mac;
+    subos = Mac_generic;
+    format = Format_Mach_O;
+#endif
+
+    return Abi(arch, os, subos, format, QSysInfo::WordSize);
+}
+
+static Abi macAbiForCpu(quint32 type) {
+    switch (type) {
+    case 7: // CPU_TYPE_X86, CPU_TYPE_I386
+        return Abi(Abi::x86, Abi::Mac, Abi::Mac_generic, Abi::Format_Mach_O, 32);
+    case 0x01000000 +  7: // CPU_TYPE_X86_64
+        return Abi(Abi::x86, Abi::Mac, Abi::Mac_generic, Abi::Format_Mach_O, 64);
+    case 18: // CPU_TYPE_POWERPC
+        return Abi(Abi::PowerPC, Abi::Mac, Abi::Mac_generic, Abi::Format_Mach_O, 32);
+    case 0x01000000 + 18: // CPU_TYPE_POWERPC64
+        return Abi(Abi::PowerPC, Abi::Mac, Abi::Mac_generic, Abi::Format_Mach_O, 32);
+    case 12: // CPU_TYPE_ARM
+        return Abi(Abi::ARM, Abi::Mac, Abi::Mac_generic, Abi::Format_Mach_O, 32);
+    default:
+        return Abi();
+    }
+}
+
+QList<Abi> Abi::abisOfBinary(const QString &path)
+{
+    QList<Abi> result;
+    if (path.isEmpty())
+        return result;
+
+    QFile f(path);
+    if (!f.exists())
+        return result;
+
+    f.open(QFile::ReadOnly);
+    QByteArray data = f.read(1024);
+    f.close();
+
+    if (data.size() >= 20
+            && static_cast<unsigned char>(data.at(0)) == 0x7f && static_cast<unsigned char>(data.at(1)) == 'E'
+            && static_cast<unsigned char>(data.at(2)) == 'L' && static_cast<unsigned char>(data.at(3)) == 'F') {
+        // ELF format:
+        quint16 machine = (data.at(19) << 8) + data.at(18);
+        switch (machine) {
+        case 3: // EM_386
+            result.append(Abi(Abi::x86, Abi::Linux, Abi::Linux_generic, Abi::Format_ELF, 32));
+            break;
+        case 8: // EM_MIPS
+            result.append(Abi(Abi::Mips, Abi::Linux, Abi::Linux_generic, Abi::Format_ELF, 32));
+            break;
+        case 20: // EM_PPC
+            result.append(Abi(Abi::PowerPC, Abi::Linux, Abi::Linux_generic, Abi::Format_ELF, 32));
+            break;
+        case 21: // EM_PPC64
+            result.append(Abi(Abi::PowerPC, Abi::Linux, Abi::Linux_generic, Abi::Format_ELF, 64));
+            break;
+        case 62: // EM_X86_64
+            result.append(Abi(Abi::x86, Abi::Linux, Abi::Linux_generic, Abi::Format_ELF, 64));
+            break;
+        case 50: // EM_IA_64
+            result.append(Abi(Abi::Itanium, Abi::Linux, Abi::Linux_generic, Abi::Format_ELF, 64));
+            break;
+        default:
+            ;;
+        }
+    } else if (data.size() >= 8
+               && (static_cast<unsigned char>(data.at(0)) == 0xce || static_cast<unsigned char>(data.at(0)) == 0xcf)
+               && static_cast<unsigned char>(data.at(1)) == 0xfa
+               && static_cast<unsigned char>(data.at(2)) == 0xed && static_cast<unsigned char>(data.at(3)) == 0xfe) {
+        // Mach-O format (Mac non-fat binary, 32 and 64bit magic)
+        quint32 type = (data.at(7) << 24) + (data.at(6) << 16) + (data.at(5) << 8) + data.at(4);
+        result.append(macAbiForCpu(type));
+    } else if (data.size() >= 8
+               && static_cast<unsigned char>(data.at(0)) == 0xca && static_cast<unsigned char>(data.at(1)) == 0xfe
+               && static_cast<unsigned char>(data.at(2)) == 0xba && static_cast<unsigned char>(data.at(3)) == 0xbe) {
+        // Mac fat binary:
+        quint32 count = (data.at(4) << 24) + (data.at(5) << 16) + (data.at(6) << 8) + data.at(7);
+        int pos = 8;
+        for (quint32 i = 0; i < count; ++i) {
+            if (data.size() <= pos + 4)
+                break;
+
+            quint32 type = (data.at(pos) << 24) + (data.at(pos + 1) << 16) + (data.at(pos + 2) << 8) + data.at(pos + 3);
+            result.append(macAbiForCpu(type));
+            pos += 20;
+        }
+    } else {
+        // Windows PE
+        // Windows can have its magic bytes everywhere...
+        int pePos = data.indexOf("PE\0\0");
+        if (pePos >= 0 && pePos + 5 < data.size()) {
+            quint16 machine = (data.at(pePos + 5) << 8) + data.at(pePos + 4);
+            switch (machine) {
+            case 0x8664: // x86_64
+                result.append(Abi(Abi::x86, Abi::Windows, Abi::Windows_msvc, Abi::Format_PE, 64));
+                break;
+            case 0x014c: // i386
+                result.append(Abi(Abi::x86, Abi::Windows, Abi::Windows_msvc, Abi::Format_PE, 32));
+                break;
+            case 0x0200: // ia64
+                result.append(Abi(Abi::Itanium, Abi::Windows, Abi::Windows_msvc, Abi::Format_PE, 64));
+                break;
+            }
+        }
+    }
+    return result;
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/abi.h b/src/plugins/projectexplorer/abi.h
new file mode 100644
index 0000000000000000000000000000000000000000..069eec4f32742e6dfa6e2e85eefd1ecdc0902559
--- /dev/null
+++ b/src/plugins/projectexplorer/abi.h
@@ -0,0 +1,142 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef PROJECTEXPLORER_ABI_H
+#define PROJECTEXPLORER_ABI_H
+
+#include "projectexplorer_export.h"
+
+#include <QtCore/QList>
+
+namespace ProjectExplorer {
+
+// --------------------------------------------------------------------------
+// ABI
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT Abi
+{
+public:
+    enum Architecture {
+        UNKNOWN_ARCHITECTURE,
+        ARM,
+        x86,
+        Itanium,
+        Mips,
+        PowerPC
+    };
+
+    enum OS {
+        UNKNOWN_OS,
+        Linux,
+        Mac,
+        Symbian,
+        UNIX,
+        Windows
+    };
+
+    enum OSFlavour {
+        UNKNOWN_OSFLAVOUR,
+
+        // Linux
+        Linux_generic,
+        Linux_harmattan,
+        Linux_maemo,
+        Linux_meego,
+
+        // Mac
+        Mac_generic,
+
+        // Symbian
+        Symbian_device,
+        Symbian_emulator,
+
+        // Unix
+        Unix_generic,
+
+        // Windows
+        Windows_msvc,
+        Windows_msys,
+        Windows_ce
+    };
+
+    enum BinaryFormat {
+        UNKNOWN_FORMAT,
+        Format_ELF,
+        Format_Mach_O,
+        Format_PE,
+        Format_Runtime_QML
+    };
+
+    Abi() :
+        m_architecture(UNKNOWN_ARCHITECTURE), m_os(UNKNOWN_OS),
+        m_osFlavor(UNKNOWN_OSFLAVOUR), m_binaryFormat(UNKNOWN_FORMAT), m_wordWidth(0)
+    { }
+
+    Abi(const Architecture &a, const OS &o,
+        const OSFlavour &so, const BinaryFormat &f, unsigned char w);
+    Abi(const QString &abiString);
+
+    bool operator == (const Abi &other) const;
+    bool isCompatibleWith(const Abi &other) const;
+
+    bool isValid() const;
+
+    Architecture architecture() const { return m_architecture; }
+    OS os() const { return m_os; }
+    OSFlavour osFlavor() const { return m_osFlavor; }
+    BinaryFormat binaryFormat() const { return m_binaryFormat; }
+    unsigned char wordWidth() const { return m_wordWidth; }
+
+    QString toString() const;
+
+    static QString toString(const Architecture &a);
+    static QString toString(const OS &o);
+    static QString toString(const OSFlavour &of);
+    static QString toString(const BinaryFormat &bf);
+    static QString toString(int w);
+
+    static Abi hostAbi();
+    static QList<Abi> abisOfBinary(const QString &path);
+
+private:
+    Architecture m_architecture;
+    OS m_os;
+    OSFlavour m_osFlavor;
+    BinaryFormat m_binaryFormat;
+    unsigned char m_wordWidth;
+};
+
+} // namespace ProjectExplorer
+
+#endif // PROJECTEXPLORER_ABI_H
diff --git a/src/plugins/projectexplorer/applicationrunconfiguration.h b/src/plugins/projectexplorer/applicationrunconfiguration.h
index d6441dbcf45bd7dd59d286771b115ed9054ece78..4faadd19c444f6a83d1f77d0283d4ae26ee6ec2b 100644
--- a/src/plugins/projectexplorer/applicationrunconfiguration.h
+++ b/src/plugins/projectexplorer/applicationrunconfiguration.h
@@ -34,11 +34,11 @@
 #ifndef APPLICATIONRUNCONFIGURATION_H
 #define APPLICATIONRUNCONFIGURATION_H
 
-#include <projectexplorer/toolchaintype.h>
-
 #include "runconfiguration.h"
 #include "applicationlauncher.h"
 
+#include "abi.h"
+
 namespace Utils {
 class AbstractMacroExpander;
 class Environment;
@@ -63,7 +63,6 @@ public:
     virtual Utils::Environment environment() const = 0;
     virtual QString dumperLibrary() const = 0;
     virtual QStringList dumperLibraryLocations() const = 0;
-    virtual ProjectExplorer::ToolChainType toolChainType() const = 0;
 
 protected:
     explicit LocalApplicationRunConfiguration(Target *target, const QString &id);
diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp
index a6735d81283b073c1c003e474ddd04f6597020f6..40e81d3c91df6fcf7e0aa8a400f280adaaf3cb04 100644
--- a/src/plugins/projectexplorer/buildconfiguration.cpp
+++ b/src/plugins/projectexplorer/buildconfiguration.cpp
@@ -38,6 +38,7 @@
 #include "projectexplorer.h"
 #include "projectexplorerconstants.h"
 #include "target.h"
+#include "toolchainmanager.h"
 #include "project.h"
 
 #include <coreplugin/variablemanager.h>
@@ -52,13 +53,15 @@ const char * const BUILD_STEP_LIST_COUNT("ProjectExplorer.BuildConfiguration.Bui
 const char * const BUILD_STEP_LIST_PREFIX("ProjectExplorer.BuildConfiguration.BuildStepList.");
 const char * const CLEAR_SYSTEM_ENVIRONMENT_KEY("ProjectExplorer.BuildConfiguration.ClearSystemEnvironment");
 const char * const USER_ENVIRONMENT_CHANGES_KEY("ProjectExplorer.BuildConfiguration.UserEnvironmentChanges");
+const char * const TOOLCHAIN_KEY("ProjectExplorer.BuildCOnfiguration.ToolChain");
 
 } // namespace
 
 BuildConfiguration::BuildConfiguration(Target *target, const QString &id) :
     ProjectConfiguration(target, id),
     m_clearSystemEnvironment(false),
-    m_macroExpander(this)
+    m_macroExpander(this),
+    m_toolChain(0)
 {
     Q_ASSERT(target);
     BuildStepList *bsl = new BuildStepList(this, QLatin1String(Constants::BUILDSTEPS_BUILD));
@@ -75,7 +78,8 @@ BuildConfiguration::BuildConfiguration(Target *target, BuildConfiguration *sourc
     ProjectConfiguration(target, source),
     m_clearSystemEnvironment(source->m_clearSystemEnvironment),
     m_userEnvironmentChanges(source->m_userEnvironmentChanges),
-    m_macroExpander(this)
+    m_macroExpander(this),
+    m_toolChain(source->m_toolChain)
 {
     Q_ASSERT(target);
     // Do not clone stepLists here, do that in the derived constructor instead
@@ -112,6 +116,8 @@ QVariantMap BuildConfiguration::toMap() const
     for (int i = 0; i < m_stepLists.count(); ++i)
         map.insert(QLatin1String(BUILD_STEP_LIST_PREFIX) + QString::number(i), m_stepLists.at(i)->toMap());
 
+    map.insert(QLatin1String(TOOLCHAIN_KEY), m_toolChain ? m_toolChain->id() : QLatin1String("INVALID"));
+
     return map;
 }
 
@@ -139,6 +145,9 @@ bool BuildConfiguration::fromMap(const QVariantMap &map)
         m_stepLists.append(list);
     }
 
+    QString id = map.value(QLatin1String(TOOLCHAIN_KEY)).toString();
+    m_toolChain = ToolChainManager::instance()->findToolChain(id);
+
     // TODO: We currently assume there to be at least a clean and build list!
     Q_ASSERT(knownStepLists().contains(QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_BUILD)));
     Q_ASSERT(knownStepLists().contains(QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_CLEAN)));
@@ -151,6 +160,19 @@ Target *BuildConfiguration::target() const
     return static_cast<Target *>(parent());
 }
 
+ProjectExplorer::ToolChain *BuildConfiguration::toolChain() const
+{
+    return m_toolChain;
+}
+
+void BuildConfiguration::setToolChain(ProjectExplorer::ToolChain *tc)
+{
+    if (m_toolChain == tc)
+        return;
+    m_toolChain = tc;
+    emit toolChainChanged();
+}
+
 Utils::Environment BuildConfiguration::baseEnvironment() const
 {
     Utils::Environment result;
diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h
index 780304cc56c6932327ee76e75d3dc362c3079741..f60597bcad47fdb821f2546808a492ce02864728 100644
--- a/src/plugins/projectexplorer/buildconfiguration.h
+++ b/src/plugins/projectexplorer/buildconfiguration.h
@@ -43,13 +43,12 @@
 #include <QtCore/QString>
 #include <QtCore/QStringList>
 
-
-
 namespace ProjectExplorer {
 
 class BuildConfiguration;
 class BuildStepList;
 class Target;
+class ToolChain;
 class IOutputParser;
 
 class BuildConfigMacroExpander : public Utils::AbstractQtcMacroExpander {
@@ -97,10 +96,14 @@ public:
 
     Utils::AbstractMacroExpander *macroExpander() { return &m_macroExpander; }
 
+    virtual ProjectExplorer::ToolChain *toolChain() const;
+    virtual void setToolChain(ProjectExplorer::ToolChain *tc);
+
 signals:
     void environmentChanged();
     void buildDirectoryChanged();
     void enabledChanged();
+    void toolChainChanged();
 
 protected:
     BuildConfiguration(Target *target, const QString &id);
@@ -115,6 +118,7 @@ private:
     QList<Utils::EnvironmentItem> m_userEnvironmentChanges;
     QList<BuildStepList *> m_stepLists;
     BuildConfigMacroExpander m_macroExpander;
+    ToolChain *m_toolChain;
 };
 
 class PROJECTEXPLORER_EXPORT IBuildConfigurationFactory :
diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
index dcfc7c9cf98823b80ecc8cc3e6fee03be9c9ca0e..fdf4e0dd62539cbd683c5f2f66e8c9235730a30a 100644
--- a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
+++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
@@ -33,11 +33,11 @@
 
 #include "customexecutablerunconfiguration.h"
 #include "customexecutableconfigurationwidget.h"
-#include "toolchaintype.h"
+
 #include "buildconfiguration.h"
 #include "debugginghelper.h"
-#include "target.h"
 #include "projectexplorerconstants.h"
+#include "target.h"
 
 #include <coreplugin/icore.h>
 
@@ -334,9 +334,9 @@ QStringList CustomExecutableRunConfiguration::dumperLibraryLocations() const
     return ProjectExplorer::DebuggingHelperLibrary::locationsByInstallData(qtInstallData);
 }
 
-ProjectExplorer::ToolChainType CustomExecutableRunConfiguration::toolChainType() const
+ProjectExplorer::Abi CustomExecutableRunConfiguration::abi() const
 {
-    return ProjectExplorer::ToolChain_UNKNOWN;
+    return ProjectExplorer::Abi::hostAbi();
 }
 
 // Factory
diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.h b/src/plugins/projectexplorer/customexecutablerunconfiguration.h
index 99dcf9c8b328dba24d5aa3196c0ba8912137191f..76c10c11405a093dee0d456936c46f79515bbd0b 100644
--- a/src/plugins/projectexplorer/customexecutablerunconfiguration.h
+++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.h
@@ -79,7 +79,7 @@ public:
     QString dumperLibrary() const;
     QStringList dumperLibraryLocations() const;
 
-    ProjectExplorer::ToolChainType toolChainType() const;
+    ProjectExplorer::Abi abi() const;
 
     QVariantMap toMap() const;
 
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a7323ceb2e71971e9cb47a23bbf61e62f68f2ea7
--- /dev/null
+++ b/src/plugins/projectexplorer/gcctoolchain.cpp
@@ -0,0 +1,786 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "gcctoolchain.h"
+#include "gccparser.h"
+#include "linuxiccparser.h"
+#include "projectexplorerconstants.h"
+
+#include <utils/environment.h>
+#include <utils/synchronousprocess.h>
+
+#include <QtCore/QBuffer>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFileInfo>
+#include <QtCore/QProcess>
+
+#include <QtGui/QGridLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QCheckBox>
+
+namespace ProjectExplorer {
+
+// --------------------------------------------------------------------------
+// Helpers:
+// --------------------------------------------------------------------------
+
+static const char *const COMPILER_PATH_KEY = "ProjectExplorer.GccToolChain.Path";
+static const char *const FORCE_32BIT_KEY = "ProjectExplorer.GccToolChain.Force32Bit";
+
+static QByteArray runGcc(const QString &gcc, const QStringList &arguments, const QStringList &env)
+{
+    if (gcc.isEmpty())
+        return QByteArray();
+
+    QProcess cpp;
+    cpp.setEnvironment(env);
+    cpp.start(gcc, arguments);
+    if (!cpp.waitForStarted()) {
+        qWarning("%s: Cannot start '%s': %s", Q_FUNC_INFO, qPrintable(gcc),
+            qPrintable(cpp.errorString()));
+        return QByteArray();
+    }
+    cpp.closeWriteChannel();
+    if (!cpp.waitForFinished()) {
+        Utils::SynchronousProcess::stopProcess(cpp);
+        qWarning("%s: Timeout running '%s'.", Q_FUNC_INFO, qPrintable(gcc));
+        return QByteArray();
+    }
+    if (cpp.exitStatus() != QProcess::NormalExit) {
+        qWarning("%s: '%s' crashed.", Q_FUNC_INFO, qPrintable(gcc));
+        return QByteArray();
+    }
+    return cpp.readAllStandardOutput();
+}
+
+static QByteArray gccPredefinedMacros(const QString &gcc, const QStringList &env)
+{
+    QStringList arguments;
+    arguments << QLatin1String("-xc++")
+              << QLatin1String("-E")
+              << QLatin1String("-dM")
+              << QLatin1String("-");
+
+    QByteArray predefinedMacros = runGcc(gcc, arguments, env);
+#ifdef Q_OS_MAC
+    // Turn off flag indicating Apple's blocks support
+    const QByteArray blocksDefine("#define __BLOCKS__ 1");
+    const QByteArray blocksUndefine("#undef __BLOCKS__");
+    const int idx = predefinedMacros.indexOf(blocksDefine);
+    if (idx != -1) {
+        predefinedMacros.replace(idx, blocksDefine.length(), blocksUndefine);
+    }
+
+    // Define __strong and __weak (used for Apple's GC extension of C) to be empty
+    predefinedMacros.append("#define __strong\n");
+    predefinedMacros.append("#define __weak\n");
+#endif // Q_OS_MAC
+    return predefinedMacros;
+}
+
+static QList<HeaderPath> gccHeaderPathes(const QString &gcc, const QStringList &env)
+{
+    QList<HeaderPath> systemHeaderPaths;
+    QStringList arguments;
+    arguments << QLatin1String("-xc++")
+              << QLatin1String("-E")
+              << QLatin1String("-v")
+              << QLatin1String("-");
+
+    QByteArray line;
+    QByteArray data = runGcc(gcc, arguments, env);
+    QBuffer cpp(&data);
+    while (cpp.canReadLine()) {
+        line = cpp.readLine();
+        if (line.startsWith("#include"))
+            break;
+    }
+
+    if (!line.isEmpty() && line.startsWith("#include")) {
+        HeaderPath::Kind kind = HeaderPath::UserHeaderPath;
+        while (cpp.canReadLine()) {
+            line = cpp.readLine();
+            if (line.startsWith("#include")) {
+                kind = HeaderPath::GlobalHeaderPath;
+            } else if (! line.isEmpty() && QChar(line.at(0)).isSpace()) {
+                HeaderPath::Kind thisHeaderKind = kind;
+
+                line = line.trimmed();
+
+                const int index = line.indexOf(" (framework directory)");
+                if (index != -1) {
+                    line.truncate(index);
+                    thisHeaderKind = HeaderPath::FrameworkHeaderPath;
+                }
+
+                systemHeaderPaths.append(HeaderPath(QFile::decodeName(line), thisHeaderKind));
+            } else if (line.startsWith("End of search list.")) {
+                break;
+            } else {
+                qWarning() << "ignore line:" << line;
+            }
+        }
+    }
+    return systemHeaderPaths;
+}
+
+static ProjectExplorer::Abi guessGccAbi(const QString &m)
+{
+    QString machine = m.toLower();
+    if (machine.isEmpty())
+        return ProjectExplorer::Abi();
+
+    QStringList parts = machine.split(QRegExp("[ /-]"));
+
+    ProjectExplorer::Abi host = ProjectExplorer::Abi::hostAbi();
+
+    ProjectExplorer::Abi::Architecture arch = ProjectExplorer::Abi::UNKNOWN_ARCHITECTURE;
+    ProjectExplorer::Abi::OS os = ProjectExplorer::Abi::UNKNOWN_OS;
+    ProjectExplorer::Abi::OSFlavour flavor = ProjectExplorer::Abi::UNKNOWN_OSFLAVOUR;
+    ProjectExplorer::Abi::BinaryFormat format = ProjectExplorer::Abi::UNKNOWN_FORMAT;
+    int width = 32;
+    int unknownCount = 0;
+
+    foreach (const QString &p, parts) {
+        if (p == QLatin1String("unknown") || p == QLatin1String("pc") || p == QLatin1String("none")
+            || p == QLatin1String("gnu") || p == QLatin1String("86_64")) {
+            continue;
+        } else if (p == QLatin1String("i386") || p == QLatin1String("i486") || p == QLatin1String("i586")
+                   || p == QLatin1String("i686") || p == QLatin1String("x86")) {
+            arch = ProjectExplorer::Abi::x86;
+        } else if (p == QLatin1String("arm")) {
+            arch = ProjectExplorer::Abi::ARM;
+            width = 32;
+        } else if (p == QLatin1String("x86_64")) {
+            arch = ProjectExplorer::Abi::x86;
+            width = 64;
+        } else if (p == QLatin1String("w64")) {
+            width = 64;
+        } else if (p == QLatin1String("linux")) {
+            os = ProjectExplorer::Abi::Linux;
+            flavor = ProjectExplorer::Abi::Linux_generic;
+            format = ProjectExplorer::Abi::Format_ELF;
+        } else if (p == QLatin1String("symbianelf")) {
+            os = ProjectExplorer::Abi::Symbian;
+            flavor = ProjectExplorer::Abi::Symbian_device;
+            format = ProjectExplorer::Abi::Format_ELF;
+        } else if (p == QLatin1String("mingw32")) {
+            arch = ProjectExplorer::Abi::x86;
+            os = ProjectExplorer::Abi::Windows;
+            flavor = ProjectExplorer::Abi::Windows_msys;
+            format = ProjectExplorer::Abi::Format_PE;
+        } else if (p == QLatin1String("apple")) {
+            os = ProjectExplorer::Abi::Mac;
+            flavor = ProjectExplorer::Abi::Mac_generic;
+            format = ProjectExplorer::Abi::Format_Mach_O;
+        } else if (p == QLatin1String("darwin10")) {
+            width = 64;
+        } else if (p == QLatin1String("gnueabi")) {
+            format = ProjectExplorer::Abi::Format_ELF;
+        } else {
+            ++unknownCount;
+        }
+    }
+
+    if (unknownCount == parts.count())
+        return ProjectExplorer::Abi();
+    return ProjectExplorer::Abi(arch, os, flavor, format, width);
+}
+
+static ProjectExplorer::Abi guessGccAbi(const QString &path, const QStringList &env)
+{
+    QStringList arguments(QLatin1String("-dumpmachine"));
+    QString machine = QString::fromLocal8Bit(runGcc(path, arguments, env)).trimmed();
+    return guessGccAbi(machine);
+}
+
+// --------------------------------------------------------------------------
+// GccToolChain
+// --------------------------------------------------------------------------
+
+GccToolChain::GccToolChain(bool autodetect) :
+    ToolChain(QLatin1String(Constants::GCC_TOOLCHAIN_ID), autodetect),
+    m_forcedTo32Bit(false),
+    m_supports64Bit(false)
+{ }
+
+GccToolChain::GccToolChain(const QString &id, bool autodetect) :
+    ToolChain(id, autodetect),
+    m_forcedTo32Bit(false),
+    m_supports64Bit(false)
+{ }
+
+GccToolChain::GccToolChain(const GccToolChain &tc) :
+    ToolChain(tc),
+    m_compilerPath(tc.compilerPath()),
+    m_forcedTo32Bit(tc.m_forcedTo32Bit),
+    m_supports64Bit(tc.m_supports64Bit),
+    m_targetAbi(tc.m_targetAbi)
+{
+    setCompilerPath(tc.m_compilerPath);
+}
+
+QString GccToolChain::defaultDisplayName() const
+{
+    if (!m_targetAbi.isValid())
+        return typeName();
+    return QString::fromLatin1("%1 (%2 %3)").arg(typeName(),
+                                                 ProjectExplorer::Abi::toString(m_targetAbi.architecture()),
+                                                 ProjectExplorer::Abi::toString(m_targetAbi.wordWidth()));
+}
+
+void GccToolChain::updateId()
+{
+    QString i = id();
+    i = i.left(i.indexOf(QLatin1Char(':')));
+    setId(QString::fromLatin1("%1:%2.%3").arg(i).arg(m_compilerPath).arg(m_forcedTo32Bit));
+}
+
+QString GccToolChain::typeName() const
+{
+    return Internal::GccToolChainFactory::tr("GCC");
+}
+
+Abi GccToolChain::targetAbi() const
+{
+    if (!m_targetAbi.isValid()) {
+        Utils::Environment env = Utils::Environment::systemEnvironment();
+        addToEnvironment(env);
+        m_targetAbi = guessGccAbi(m_compilerPath, env.toStringList());
+        m_supports64Bit = (m_targetAbi.wordWidth() == 64);
+        if (m_targetAbi.wordWidth() == 64 && m_forcedTo32Bit)
+            m_targetAbi = Abi(m_targetAbi.architecture(), m_targetAbi.os(), m_targetAbi.osFlavor(),
+                              m_targetAbi.binaryFormat(), 32);
+
+        if (displayName() == typeName())
+            setDisplayName(defaultDisplayName());
+    }
+    return m_targetAbi;
+}
+
+bool GccToolChain::isValid() const
+{
+    return !m_compilerPath.isNull();
+}
+
+QByteArray GccToolChain::predefinedMacros() const
+{
+    if (m_predefinedMacros.isEmpty()) {
+        // Using a clean environment breaks ccache/distcc/etc.
+        Utils::Environment env = Utils::Environment::systemEnvironment();
+        addToEnvironment(env);
+        m_predefinedMacros = gccPredefinedMacros(m_compilerPath, env.toStringList());
+    }
+    return m_predefinedMacros;
+}
+
+QList<HeaderPath> GccToolChain::systemHeaderPaths() const
+{
+    if (m_headerPathes.isEmpty()) {
+        // Using a clean environment breaks ccache/distcc/etc.
+        Utils::Environment env = Utils::Environment::systemEnvironment();
+        addToEnvironment(env);
+        m_headerPathes = gccHeaderPathes(m_compilerPath, env.toStringList());
+    }
+    return m_headerPathes;
+}
+
+void GccToolChain::addToEnvironment(Utils::Environment &env) const
+{
+    if (!m_compilerPath.isEmpty())
+        env.prependOrSetPath(QFileInfo(m_compilerPath).absolutePath());
+}
+
+QString GccToolChain::makeCommand() const
+{
+    return QLatin1String("make");
+}
+
+IOutputParser *GccToolChain::outputParser() const
+{
+    return new GccParser;
+}
+
+void GccToolChain::setCompilerPath(const QString &path)
+{
+    if (path == m_compilerPath)
+        return;
+
+    if (displayName() == defaultDisplayName())
+        setDisplayName(typeName());
+    m_compilerPath = path;
+    m_targetAbi = Abi();
+    updateId();
+
+    if (m_compilerPath.isEmpty())
+        return;
+
+    targetAbi(); // update ABI information (and default display name)
+}
+
+QString GccToolChain::compilerPath() const
+{
+    return m_compilerPath;
+}
+
+bool GccToolChain::isForcedTo32Bit() const
+{
+    return m_forcedTo32Bit;
+}
+void GccToolChain::forceTo32Bit(bool f)
+{
+    if (f == m_forcedTo32Bit)
+        return;
+
+    if (displayName() == defaultDisplayName())
+        setDisplayName(typeName());
+
+    m_forcedTo32Bit = f;
+    m_targetAbi = Abi(); // Invalidate ABI.
+    updateId();
+
+    targetAbi();
+}
+
+bool GccToolChain::supports64Bit() const
+{
+    return m_supports64Bit;
+}
+
+ToolChain *GccToolChain::clone() const
+{
+    return new GccToolChain(*this);
+}
+
+QVariantMap GccToolChain::toMap() const
+{
+    QVariantMap data = ToolChain::toMap();
+    data.insert(QLatin1String(COMPILER_PATH_KEY), m_compilerPath);
+    data.insert(QLatin1String(FORCE_32BIT_KEY), m_forcedTo32Bit);
+    return data;
+}
+
+bool GccToolChain::fromMap(const QVariantMap &data)
+{
+    if (!ToolChain::fromMap(data))
+        return false;
+
+    m_compilerPath = data.value(QLatin1String(COMPILER_PATH_KEY)).toString();
+    m_forcedTo32Bit = data.value(QLatin1String(FORCE_32BIT_KEY)).toBool();
+    return true;
+}
+
+bool GccToolChain::operator ==(const ToolChain &other) const
+{
+    if (!ToolChain::operator ==(other))
+        return false;
+
+    const GccToolChain *gccTc = static_cast<const GccToolChain *>(&other);
+    return m_compilerPath == gccTc->m_compilerPath && m_forcedTo32Bit == gccTc->m_forcedTo32Bit;
+}
+
+ToolChainConfigWidget *GccToolChain::configurationWidget()
+{
+    return new Internal::GccToolChainConfigWidget(this);
+}
+
+// --------------------------------------------------------------------------
+// GccToolChainFactory
+// --------------------------------------------------------------------------
+
+QString Internal::GccToolChainFactory::displayName() const
+{
+    return tr("GCC");
+}
+
+QString Internal::GccToolChainFactory::id() const
+{
+    return QLatin1String(Constants::GCC_TOOLCHAIN_ID);
+}
+
+bool Internal::GccToolChainFactory::canCreate()
+{
+    return true;
+}
+
+ToolChain *Internal::GccToolChainFactory::create()
+{
+    return createToolChain(false);
+}
+
+QList<ToolChain *> Internal::GccToolChainFactory::autoDetect()
+{
+    return autoDetectCompiler(QLatin1String("gcc"));
+}
+
+// Used by the ToolChainManager to restore user-generated ToolChains
+bool Internal::GccToolChainFactory::canRestore(const QVariantMap &data)
+{
+    return idFromMap(data).startsWith(QLatin1String(Constants::GCC_TOOLCHAIN_ID) + QLatin1Char(':'));
+}
+
+ToolChain *Internal::GccToolChainFactory::restore(const QVariantMap &data)
+{
+    GccToolChain *tc = new GccToolChain(false);
+    if (tc->fromMap(data))
+        return tc;
+
+    delete tc;
+    return 0;
+}
+
+GccToolChain *Internal::GccToolChainFactory::createToolChain(bool autoDetect)
+{
+    return new GccToolChain(autoDetect);
+}
+
+QList<ToolChain *> Internal::GccToolChainFactory::autoDetectCompiler(const QString &cc)
+{
+    QList<ToolChain *> result;
+
+    QString path = Utils::Environment::systemEnvironment().searchInPath(cc);
+    if (path.isEmpty())
+        return result;
+
+    GccToolChain *tc = createToolChain(true);
+    if (!tc)
+        return result;
+
+    tc->setCompilerPath(path);
+    ProjectExplorer::Abi abi = tc->targetAbi();
+    if (abi.isValid())
+        result.append(tc);
+    else
+        delete tc;
+
+    if (abi.wordWidth() != 64)
+        return result;
+
+    tc = createToolChain(true);
+    Q_ASSERT(tc); // worked once, so should work again:-)
+    tc->forceTo32Bit(true);
+    tc->setCompilerPath(path);
+    if (tc->targetAbi().isValid())
+        result.append(tc);
+    else
+        delete tc;
+
+    return result;
+}
+
+// --------------------------------------------------------------------------
+// GccToolChainConfigWidget
+// --------------------------------------------------------------------------
+
+Internal::GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) :
+    ToolChainConfigWidget(tc)
+{
+    Q_ASSERT(tc);
+
+    QGridLayout *layout = new QGridLayout(this);
+    QLabel *label = new QLabel(this);
+    label->setText(tr("Compiler path:"));
+    layout->addWidget(label, 0, 0);
+
+    m_compilerPath = new Utils::PathChooser(this);
+    m_compilerPath->setExpectedKind(Utils::PathChooser::ExistingCommand);
+    layout->addWidget(m_compilerPath, 0, 1);
+    connect(m_compilerPath, SIGNAL(changed(QString)), this, SLOT(handlePathChange()));
+
+    label = new QLabel(this);
+    label->setText(tr("Force 32bit compilation:"));
+    layout->addWidget(label, 1, 0);
+
+    m_force32BitCheckBox = new QCheckBox(this);
+    layout->addWidget(m_force32BitCheckBox, 1, 1);
+    connect(m_force32BitCheckBox, SIGNAL(toggled(bool)), this, SLOT(handle32BitChange()));
+
+    discard();
+}
+
+void Internal::GccToolChainConfigWidget::apply()
+{
+    if (toolChain()->isAutoDetected())
+        return;
+
+    GccToolChain *tc = static_cast<GccToolChain *>(toolChain());
+    Q_ASSERT(tc);
+    QString displayName = tc->displayName();
+    QString path = m_compilerPath->path();
+    if (path.isEmpty())
+        path = m_compilerPath->rawPath();
+    tc->forceTo32Bit(m_force32BitCheckBox->isChecked());
+    tc->setCompilerPath(path);
+    tc->setDisplayName(displayName); // reset display name
+}
+
+void Internal::GccToolChainConfigWidget::discard()
+{
+    GccToolChain *tc = static_cast<GccToolChain *>(toolChain());
+    Q_ASSERT(tc);
+    m_compilerPath->setPath(tc->compilerPath());
+    m_force32BitCheckBox->setChecked(tc->isForcedTo32Bit());
+    m_force32BitCheckBox->setEnabled(tc->supports64Bit());
+}
+
+bool Internal::GccToolChainConfigWidget::isDirty() const
+{
+    GccToolChain *tc = static_cast<GccToolChain *>(toolChain());
+    Q_ASSERT(tc);
+    return m_compilerPath->path() != tc->compilerPath()
+            || m_force32BitCheckBox->isChecked() != tc->isForcedTo32Bit();
+}
+
+void Internal::GccToolChainConfigWidget::handlePathChange()
+{
+    QString path = m_compilerPath->path();
+    if (!QFileInfo(path).isExecutable()) {
+        m_force32BitCheckBox->setEnabled(false);
+        m_force32BitCheckBox->setChecked(true);
+    } else {
+        ProjectExplorer::Abi abi = guessGccAbi(path, Utils::Environment::systemEnvironment().toStringList());
+        m_force32BitCheckBox->setEnabled(abi.wordWidth() == 64);
+        m_force32BitCheckBox->setChecked(abi.wordWidth() == 32);
+    }
+    emit dirty(toolChain());
+}
+
+void Internal::GccToolChainConfigWidget::handle32BitChange()
+{
+    emit dirty(toolChain());
+}
+
+// --------------------------------------------------------------------------
+// MingwToolChain
+// --------------------------------------------------------------------------
+
+MingwToolChain::MingwToolChain(bool autodetect) :
+    GccToolChain(QLatin1String(Constants::MINGW_TOOLCHAIN_ID), autodetect)
+{ }
+
+QString MingwToolChain::typeName() const
+{
+    return Internal::MingwToolChainFactory::tr("MinGW");
+}
+
+QString MingwToolChain::makeCommand() const
+{
+    return QLatin1String("mingw32-make.exe");
+}
+
+ToolChain *MingwToolChain::clone() const
+{
+    return new MingwToolChain(*this);
+}
+
+// --------------------------------------------------------------------------
+// MingwToolChainFactory
+// --------------------------------------------------------------------------
+
+QString Internal::MingwToolChainFactory::displayName() const
+{
+    return tr("MinGW");
+}
+
+QString Internal::MingwToolChainFactory::id() const
+{
+    return QLatin1String(Constants::MINGW_TOOLCHAIN_ID);
+}
+
+QList<ToolChain *> Internal::MingwToolChainFactory::autoDetect()
+{
+    return autoDetectCompiler(QLatin1String("gcc"));
+}
+
+bool Internal::MingwToolChainFactory::canCreate()
+{
+    return true;
+}
+
+ToolChain *Internal::MingwToolChainFactory::create()
+{
+    return createToolChain(false);
+}
+
+bool Internal::MingwToolChainFactory::canRestore(const QVariantMap &data)
+{
+    return idFromMap(data).startsWith(QLatin1String(Constants::MINGW_TOOLCHAIN_ID) + QLatin1Char(':'));
+}
+
+ToolChain *Internal::MingwToolChainFactory::restore(const QVariantMap &data)
+{
+    MingwToolChain *tc = new MingwToolChain(false);
+    if (tc->fromMap(data))
+        return tc;
+
+    delete tc;
+    return 0;
+}
+
+GccToolChain *Internal::MingwToolChainFactory::createToolChain(bool autoDetect)
+{
+    return new MingwToolChain(autoDetect);
+}
+
+// --------------------------------------------------------------------------
+// LinuxIccToolChain
+// --------------------------------------------------------------------------
+
+LinuxIccToolChain::LinuxIccToolChain(bool autodetect) :
+    GccToolChain(QLatin1String(Constants::LINUXICC_TOOLCHAIN_ID), autodetect)
+{ }
+
+QString LinuxIccToolChain::typeName() const
+{
+    return Internal::LinuxIccToolChainFactory::tr("Linux ICC");
+}
+
+IOutputParser *LinuxIccToolChain::outputParser() const
+{
+    return new LinuxIccParser;
+}
+
+ToolChain *LinuxIccToolChain::clone() const
+{
+    return new LinuxIccToolChain(*this);
+}
+
+// --------------------------------------------------------------------------
+// LinuxIccToolChainFactory
+// --------------------------------------------------------------------------
+
+QString Internal::LinuxIccToolChainFactory::displayName() const
+{
+    return tr("Linux ICC");
+}
+
+QString Internal::LinuxIccToolChainFactory::id() const
+{
+    return QLatin1String(Constants::LINUXICC_TOOLCHAIN_ID);
+}
+
+QList<ToolChain *> Internal::LinuxIccToolChainFactory::autoDetect()
+{
+    return autoDetectCompiler(QLatin1String("icpc"));
+}
+
+ToolChain *Internal::LinuxIccToolChainFactory::create()
+{
+    return createToolChain(false);
+}
+
+bool Internal::LinuxIccToolChainFactory::canRestore(const QVariantMap &data)
+{
+    return idFromMap(data).startsWith(QLatin1String(Constants::LINUXICC_TOOLCHAIN_ID) + QLatin1Char(':'));
+}
+
+ToolChain *Internal::LinuxIccToolChainFactory::restore(const QVariantMap &data)
+{
+    LinuxIccToolChain *tc = new LinuxIccToolChain(false);
+    if (tc->fromMap(data))
+        return tc;
+
+    delete tc;
+    return 0;
+}
+
+GccToolChain *Internal::LinuxIccToolChainFactory::createToolChain(bool autoDetect)
+{
+    return new LinuxIccToolChain(autoDetect);
+}
+
+} // namespace ProjectExplorer
+
+// Unit tests:
+
+#ifdef WITH_TESTS
+#   include "projectexplorer.h"
+
+#   include <QTest>
+#   include <QtCore/QUrl>
+
+namespace ProjectExplorer {
+
+void ProjectExplorerPlugin::testGccAbiGuessing_data()
+{
+    QTest::addColumn<QString>("input");
+    QTest::addColumn<QString>("abi");
+
+    QTest::newRow("invalid input")
+            << QString::fromLatin1("Some text")
+            << QString::fromLatin1("unknown-unknown-unknown-unknown-unknown");
+    QTest::newRow("empty input")
+            << QString::fromLatin1("")
+            << QString::fromLatin1("unknown-unknown-unknown-unknown-unknown");
+    QTest::newRow("broken input")
+            << QString::fromLatin1("arm-none-foo-gnueabi")
+            << QString::fromLatin1("arm-unknown-unknown-elf-32bit");
+
+    QTest::newRow("Maemo 1")
+            << QString::fromLatin1("arm-none-linux-gnueabi")
+            << QString::fromLatin1("arm-linux-generic-elf-32bit");
+    QTest::newRow("Linux 1")
+            << QString::fromLatin1("i686-linux-gnu")
+            << QString::fromLatin1("x86-linux-generic-elf-32bit");
+    QTest::newRow("Linux 2")
+            << QString::fromLatin1("i486-linux-gnu")
+            << QString::fromLatin1("x86-linux-generic-elf-32bit");
+    QTest::newRow("Linux 3")
+            << QString::fromLatin1("x86_64-linux-gnu")
+            << QString::fromLatin1("x86-linux-generic-elf-64bit");
+    QTest::newRow("Mingw 1")
+            << QString::fromLatin1("i686-w64-mingw32")
+            << QString::fromLatin1("x86-windows-msys-pe-64bit");
+    QTest::newRow("Mingw 2")
+            << QString::fromLatin1("mingw32")
+            << QString::fromLatin1("x86-windows-msys-pe-32bit");
+    QTest::newRow("Mac 1")
+            << QString::fromLatin1("i686-apple-darwin10")
+            << QString::fromLatin1("x86-macos-generic-mach_o-64bit");
+    QTest::newRow("Intel 1")
+            << QString::fromLatin1("86_64 x86_64 GNU/Linux")
+            << QString::fromLatin1("x86-linux-generic-elf-64bit");
+}
+
+void ProjectExplorerPlugin::testGccAbiGuessing()
+{
+    QFETCH(QString, input);
+    QFETCH(QString, abi);
+
+    ProjectExplorer::Abi a = guessGccAbi(input);
+    QCOMPARE(a.toString(), abi);
+}
+
+} // namespace ProjectExplorer
+
+#endif
diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h
new file mode 100644
index 0000000000000000000000000000000000000000..90cd0d05354bb9362628d94015752b228442927a
--- /dev/null
+++ b/src/plugins/projectexplorer/gcctoolchain.h
@@ -0,0 +1,275 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef GCCTOOLCHAIN_H
+#define GCCTOOLCHAIN_H
+
+#include "projectexplorer_export.h"
+
+#include "toolchain.h"
+
+#include "toolchainconfigwidget.h"
+
+#include <utils/pathchooser.h>
+
+QT_BEGIN_NAMESPACE
+class QCheckBox;
+QT_END_NAMESPACE
+
+namespace ProjectExplorer {
+
+namespace Internal {
+class GccToolChainFactory;
+class MingwToolChainFactory;
+class LinuxIccToolChainFactory;
+}
+
+// --------------------------------------------------------------------------
+// GccToolChain
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT GccToolChain : public ToolChain
+{
+public:
+    QString typeName() const;
+    Abi targetAbi() const;
+
+    bool isValid() const;
+
+    QByteArray predefinedMacros() const;
+    QList<HeaderPath> systemHeaderPaths() const;
+    void addToEnvironment(Utils::Environment &env) const;
+    QString makeCommand() const;
+    IOutputParser *outputParser() const;
+
+    QVariantMap toMap() const;
+    bool fromMap(const QVariantMap &data);
+
+    ToolChainConfigWidget *configurationWidget();
+
+    bool operator ==(const ToolChain &) const;
+
+    void setCompilerPath(const QString &);
+    QString compilerPath() const;
+
+    bool isForcedTo32Bit() const;
+    void forceTo32Bit(bool);
+
+    bool supports64Bit() const;
+
+    ToolChain *clone() const;
+
+protected:
+    GccToolChain(const QString &id, bool autodetect);
+    GccToolChain(const GccToolChain &);
+
+    QString defaultDisplayName() const;
+
+    void updateId();
+
+    mutable QByteArray m_predefinedMacros;
+
+private:
+    GccToolChain(bool autodetect);
+
+    QString m_compilerPath;
+    bool m_forcedTo32Bit;
+    mutable bool m_supports64Bit;
+
+    mutable Abi m_targetAbi;
+    mutable QList<HeaderPath> m_headerPathes;
+
+    friend class Internal::GccToolChainFactory;
+    friend class ToolChainFactory;
+};
+
+
+// --------------------------------------------------------------------------
+// GccToolChainFactory
+// --------------------------------------------------------------------------
+
+namespace Internal {
+
+class GccToolChainFactory : public ToolChainFactory
+{
+    Q_OBJECT
+
+public:
+    // Name used to display the name of the toolchain that will be created.
+    QString displayName() const;
+    QString id() const;
+
+    QList<ToolChain *> autoDetect();
+
+    bool canCreate();
+    ToolChain *create();
+
+    // Used by the ToolChainManager to restore user-generated ToolChains
+    bool canRestore(const QVariantMap &data);
+    ToolChain *restore(const QVariantMap &data);
+
+protected:
+    virtual GccToolChain *createToolChain(bool autoDetect);
+    QList<ToolChain *> autoDetectCompiler(const QString &path);
+};
+
+} // namespace Internal
+
+// --------------------------------------------------------------------------
+// GccToolChainConfigWidget
+// --------------------------------------------------------------------------
+
+namespace Internal {
+
+class GccToolChainConfigWidget : public ToolChainConfigWidget
+{
+    Q_OBJECT
+
+public:
+    GccToolChainConfigWidget(GccToolChain *);
+    void apply();
+    void discard();
+    bool isDirty() const;
+
+private slots:
+    void handlePathChange();
+    void handle32BitChange();
+
+private:
+    Utils::PathChooser *m_compilerPath;
+    QCheckBox *m_force32BitCheckBox;
+};
+
+} // namespace Internal
+
+// --------------------------------------------------------------------------
+// MingwToolChain
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT MingwToolChain : public GccToolChain
+{
+public:
+    QString typeName() const;
+    QString makeCommand() const;
+
+    ToolChain *clone() const;
+
+private:
+    MingwToolChain(bool autodetect);
+
+    friend class Internal::MingwToolChainFactory;
+    friend class ToolChainFactory;
+};
+
+// --------------------------------------------------------------------------
+// MingwToolChainFactory
+// --------------------------------------------------------------------------
+
+namespace Internal {
+
+class MingwToolChainFactory : public GccToolChainFactory
+{
+    Q_OBJECT
+
+public:
+    // Name used to display the name of the toolchain that will be created.
+    QString displayName() const;
+    QString id() const;
+
+    QList<ToolChain *> autoDetect();
+
+    bool canCreate();
+    ToolChain *create();
+
+    // Used by the ToolChainManager to restore user-generated ToolChains
+    bool canRestore(const QVariantMap &data);
+    ToolChain *restore(const QVariantMap &data);
+
+protected:
+    GccToolChain *createToolChain(bool autoDetect);
+};
+
+} // namespace Internal
+
+// --------------------------------------------------------------------------
+// LinuxIccToolChain
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT LinuxIccToolChain : public GccToolChain
+{
+public:
+
+    QString typeName() const;
+
+    IOutputParser *outputParser() const;
+
+    ToolChain *clone() const;
+
+private:
+    LinuxIccToolChain(bool autodetect);
+
+    friend class Internal::LinuxIccToolChainFactory;
+    friend class ToolChainFactory;
+};
+
+// --------------------------------------------------------------------------
+// LinuxIccToolChainFactory
+// --------------------------------------------------------------------------
+
+namespace Internal {
+
+class LinuxIccToolChainFactory : public GccToolChainFactory
+{
+    Q_OBJECT
+
+public:
+    // Name used to display the name of the toolchain that will be created.
+    QString displayName() const;
+    QString id() const;
+
+    QList<ToolChain *> autoDetect();
+
+    ToolChain *create();
+
+    // Used by the ToolChainManager to restore user-generated ToolChains
+    bool canRestore(const QVariantMap &data);
+    ToolChain *restore(const QVariantMap &data);
+
+protected:
+    GccToolChain *createToolChain(bool autoDetect);
+};
+
+} // namespace Internal
+} // namespace ProjectExplorer
+
+#endif // GCCTOOLCHAIN_H
diff --git a/src/plugins/projectexplorer/msvcparser.cpp b/src/plugins/projectexplorer/msvcparser.cpp
index 3ba3f76ec035861d1d121320010c0f6418d9c914..5c582ad9405d41e4bbbba2b85ec00212554743ee 100644
--- a/src/plugins/projectexplorer/msvcparser.cpp
+++ b/src/plugins/projectexplorer/msvcparser.cpp
@@ -269,7 +269,6 @@ void ProjectExplorerPlugin::testMsvcOutputParsers_data()
                         QLatin1String("debug\\Experimentation.exe"), -1,
                         QLatin1String(ProjectExplorer::Constants::TASK_CATEGORY_COMPILE)))
             << QString();
-
 }
 
 void ProjectExplorerPlugin::testMsvcOutputParsers()
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aac1b5f370fbd794d07a4e47b2c196a12de8d754
--- /dev/null
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -0,0 +1,525 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "msvctoolchain.h"
+#include "msvcparser.h"
+#include "projectexplorerconstants.h"
+
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/projectexplorersettings.h>
+
+#include <utils/qtcprocess.h>
+#include <utils/synchronousprocess.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QSettings>
+#include <QtCore/QTemporaryFile>
+#include <QtGui/QLabel>
+#include <QtGui/QVBoxLayout>
+
+namespace ProjectExplorer {
+namespace Internal {
+
+// --------------------------------------------------------------------------
+// Helpers:
+// --------------------------------------------------------------------------
+
+static QString platformName(MsvcToolChain::Platform t)
+{
+    switch (t) {
+    case MsvcToolChain::s32:
+        return QLatin1String(" (x86)");
+    case MsvcToolChain::s64:
+        return QLatin1String(" (x64)");
+    case MsvcToolChain::ia64:
+        return QLatin1String(" (ia64)");
+    case MsvcToolChain::amd64:
+        return QLatin1String(" (amd64)");
+    }
+    return QString();
+}
+
+static QString generateDisplayName(const QString &name,
+                                   MsvcToolChain::Type t,
+                                   MsvcToolChain::Platform p)
+{
+    if (t == MsvcToolChain::WindowsSDK) {
+        QString sdkName = name;
+        sdkName += platformName(p);
+        return sdkName;
+    }
+    // Comes as "9.0" from the registry
+    QString vcName = QLatin1String("Microsoft Visual C++ Compiler ");
+    vcName += name;
+    vcName += platformName(p);
+    return vcName;
+}
+
+static QByteArray msvcCompilationFile()
+{
+    static const char* macros[] = {"_ATL_VER", "_CHAR_UNSIGNED", "__CLR_VER",
+                                   "__cplusplus_cli", "__COUNTER__", "__cplusplus",
+                                   "_CPPLIB_VER", "_CPPRTTI", "_CPPUNWIND",
+                                   "_DEBUG", "_DLL", "__FUNCDNAME__",
+                                   "__FUNCSIG__","__FUNCTION__","_INTEGRAL_MAX_BITS",
+                                   "_M_ALPHA","_M_CEE","_M_CEE_PURE",
+                                   "_M_CEE_SAFE","_M_IX86","_M_IA64",
+                                   "_M_IX86_FP","_M_MPPC","_M_MRX000",
+                                   "_M_PPC","_M_X64","_MANAGED",
+                                   "_MFC_VER","_MSC_BUILD", /* "_MSC_EXTENSIONS", */
+                                   "_MSC_FULL_VER","_MSC_VER","__MSVC_RUNTIME_CHECKS",
+                                   "_MT", "_NATIVE_WCHAR_T_DEFINED", "_OPENMP",
+                                   "_VC_NODEFAULTLIB", "_WCHAR_T_DEFINED", "_WIN32",
+                                   "_WIN32_WCE", "_WIN64", "_Wp64", "__DATE__",
+                                   "__DATE__", "__TIME__", "__TIMESTAMP__",
+                                   0};
+    QByteArray file = "#define __PPOUT__(x) V##x=x\n\n";
+    for (int i = 0; macros[i] != 0; ++i) {
+        const QByteArray macro(macros[i]);
+        file += "#if defined(" + macro + ")\n__PPOUT__("
+                + macro + ")\n#endif\n";
+    }
+    file += "\nvoid main(){}\n\n";
+    return file;
+}
+
+// Run MSVC 'cl' compiler to obtain #defines.
+static QByteArray msvcPredefinedMacros(const QStringList &env)
+{
+    QByteArray predefinedMacros = "#define __MSVCRT__\n"
+                      "#define __w64\n"
+                      "#define __int64 long long\n"
+                      "#define __int32 long\n"
+                      "#define __int16 short\n"
+                      "#define __int8 char\n"
+                      "#define __ptr32\n"
+                      "#define __ptr64\n";
+
+    QString tmpFilePath;
+    {
+        // QTemporaryFile is buggy and will not unlock the file for cl.exe
+        QTemporaryFile tmpFile(QDir::tempPath()+"/envtestXXXXXX.cpp");
+        tmpFile.setAutoRemove(false);
+        if (!tmpFile.open())
+            return predefinedMacros;
+        tmpFilePath = QFileInfo(tmpFile).canonicalFilePath();
+        tmpFile.write(msvcCompilationFile());
+        tmpFile.close();
+    }
+    QProcess cpp;
+    cpp.setEnvironment(env);
+    cpp.setWorkingDirectory(QDir::tempPath());
+    QStringList arguments;
+    const QString binary = QLatin1String("cl.exe");
+    arguments << QLatin1String("/EP") << QDir::toNativeSeparators(tmpFilePath);
+    cpp.start(QLatin1String("cl.exe"), arguments);
+    if (!cpp.waitForStarted()) {
+        qWarning("%s: Cannot start '%s': %s", Q_FUNC_INFO, qPrintable(binary),
+            qPrintable(cpp.errorString()));
+        return predefinedMacros;
+    }
+    cpp.closeWriteChannel();
+    if (!cpp.waitForFinished()) {
+        Utils::SynchronousProcess::stopProcess(cpp);
+        qWarning("%s: Timeout running '%s'.", Q_FUNC_INFO, qPrintable(binary));
+        return predefinedMacros;
+    }
+    if (cpp.exitStatus() != QProcess::NormalExit) {
+        qWarning("%s: '%s' crashed.", Q_FUNC_INFO, qPrintable(binary));
+        return predefinedMacros;
+    }
+
+    const QList<QByteArray> output = cpp.readAllStandardOutput().split('\n');
+    foreach (const QByteArray& line, output) {
+        if (line.startsWith('V')) {
+            QList<QByteArray> split = line.split('=');
+            const QByteArray key = split.at(0).mid(1);
+            QByteArray value = split.at(1);
+            if (!value.isEmpty()) {
+                value.chop(1); //remove '\n'
+            }
+            predefinedMacros += "#define ";
+            predefinedMacros += key;
+            predefinedMacros += ' ';
+            predefinedMacros += value;
+            predefinedMacros += '\n';
+        }
+    }
+    QFile::remove(tmpFilePath);
+    return predefinedMacros;
+}
+
+static QString winExpandDelayedEnvReferences(QString in, const Utils::Environment &env)
+{
+    const QChar exclamationMark = QLatin1Char('!');
+    for (int pos = 0; pos < in.size(); ) {
+        // Replace "!REF!" by its value in process environment
+        pos = in.indexOf(exclamationMark, pos);
+        if (pos == -1)
+            break;
+        const int nextPos = in.indexOf(exclamationMark, pos + 1);
+        if (nextPos == -1)
+            break;
+        const QString var = in.mid(pos + 1, nextPos - pos - 1);
+        const QString replacement = env.value(var.toUpper());
+        in.replace(pos, nextPos + 1 - pos, replacement);
+        pos += replacement.size();
+    }
+    return in;
+}
+
+static Utils::Environment msvcReadEnvironmentSetting(const QString &varsBat,
+                                                     const QString &args,
+                                                     Utils::Environment &env)
+{
+    // Run the setup script and extract the variables
+    if (!QFileInfo(varsBat).exists())
+        return env;
+
+    const QString tempOutputFileName = QDir::tempPath() + QLatin1String("\\qtcreator-msvc-environment.txt");
+    QTemporaryFile tf(QDir::tempPath() + "\\XXXXXX.bat");
+    tf.setAutoRemove(true);
+    if (!tf.open())
+        return env;
+
+    const QString filename = tf.fileName();
+
+    QByteArray call = "call ";
+    call += Utils::QtcProcess::quoteArg(varsBat).toLocal8Bit();
+    if (!args.isEmpty()) {
+        call += ' ';
+        call += args.toLocal8Bit();
+    }
+    call += "\r\n";
+    tf.write(call);
+    const QByteArray redirect = "set > " + Utils::QtcProcess::quoteArg(
+                QDir::toNativeSeparators(tempOutputFileName)).toLocal8Bit() + "\r\n";
+    tf.write(redirect);
+    tf.flush();
+    tf.waitForBytesWritten(30000);
+
+    Utils::QtcProcess run;
+    run.setEnvironment(env);
+    const QString cmdPath = QString::fromLocal8Bit(qgetenv("COMSPEC"));
+    run.setCommand(cmdPath, QString::fromLatin1("/c \"%1\"").arg(QDir::toNativeSeparators(filename)));
+    run.start();
+    if (!run.waitForStarted()) {
+        qWarning("%s: Unable to run '%s': %s", Q_FUNC_INFO, qPrintable(varsBat),
+            qPrintable(run.errorString()));
+        return env;
+    }
+    if (!run.waitForFinished()) {
+        qWarning("%s: Timeout running '%s'", Q_FUNC_INFO, qPrintable(varsBat));
+        Utils::SynchronousProcess::stopProcess(run);
+        return env;
+    }
+    tf.close();
+
+    QFile varsFile(tempOutputFileName);
+    if (!varsFile.open(QIODevice::ReadOnly|QIODevice::Text))
+        return env;
+
+    QRegExp regexp(QLatin1String("(\\w*)=(.*)"));
+    Utils::Environment result;
+    while (!varsFile.atEnd()) {
+        const QString line = QString::fromLocal8Bit(varsFile.readLine()).trimmed();
+        if (regexp.exactMatch(line)) {
+            const QString varName = regexp.cap(1);
+            const QString expandedValue = winExpandDelayedEnvReferences(regexp.cap(2), env);
+            if (!expandedValue.isEmpty())
+                env.set(varName, expandedValue);
+        }
+    }
+    varsFile.close();
+    varsFile.remove();
+
+    return env;
+}
+
+// --------------------------------------------------------------------------
+// MsvcToolChain
+// --------------------------------------------------------------------------
+
+MsvcToolChain::MsvcToolChain(Type type, const QString &name, Platform platform,
+                             const QString &varsBat, const QString &varsBatArg, bool autodetect) :
+    ToolChain(QLatin1String(Constants::MSVC_TOOLCHAIN_ID), autodetect),
+    m_varsBat(varsBat),
+    m_varsBatArg(varsBatArg),
+    m_is64bit(true),
+    m_architecture(Abi::x86)
+{
+    Q_ASSERT(!name.isEmpty());
+    Q_ASSERT(!m_varsBat.isEmpty());
+    Q_ASSERT(QFileInfo(m_varsBat).exists());
+
+    switch (platform)
+    {
+    case ProjectExplorer::Internal::MsvcToolChain::s32:
+        m_is64bit = false;
+        break;
+    case ProjectExplorer::Internal::MsvcToolChain::ia64:
+        m_architecture = Abi::Itanium;
+        break;
+    case ProjectExplorer::Internal::MsvcToolChain::s64:
+    case ProjectExplorer::Internal::MsvcToolChain::amd64:
+        break;
+    };
+
+    setId(QString::fromLatin1("%1:%2.%3").arg(Constants::MSVC_TOOLCHAIN_ID).arg(m_varsBat)
+            .arg(m_varsBatArg));
+
+    setDisplayName(generateDisplayName(name, type, platform));
+}
+
+QString MsvcToolChain::typeName() const
+{
+    return MsvcToolChainFactory::tr("MSVC");
+}
+
+Abi MsvcToolChain::targetAbi() const
+{
+    return Abi(m_architecture, Abi::Windows, Abi::Windows_msvc, Abi::Format_PE, m_is64bit ? 64 : 32);
+}
+
+bool MsvcToolChain::isValid() const
+{
+    return !m_varsBat.isEmpty();
+}
+
+QByteArray MsvcToolChain::predefinedMacros() const
+{
+    if (m_predefinedMacros.isEmpty()) {
+        Utils::Environment env(m_lastEnvironment);
+        addToEnvironment(env);
+        m_predefinedMacros = msvcPredefinedMacros(env.toStringList());
+    }
+    return m_predefinedMacros;
+}
+
+QList<HeaderPath> MsvcToolChain::systemHeaderPaths() const
+{
+    if (m_headerPathes.isEmpty()) {
+        Utils::Environment env(m_lastEnvironment);
+        addToEnvironment(env);
+        foreach (const QString &path, env.value("INCLUDE").split(QLatin1Char(';')))
+            m_headerPathes.append(HeaderPath(path, HeaderPath::GlobalHeaderPath));
+    }
+    return m_headerPathes;
+}
+
+void MsvcToolChain::addToEnvironment(Utils::Environment &env) const
+{
+    // We cache the full environment (incoming + modifications by setup script).
+    if (!m_resultEnvironment.size() || env != m_lastEnvironment) {
+        m_lastEnvironment = env;
+        m_resultEnvironment = msvcReadEnvironmentSetting(m_varsBat, m_varsBatArg, env);
+    }
+    env = m_resultEnvironment;
+}
+
+QString MsvcToolChain::makeCommand() const
+{
+    if (ProjectExplorerPlugin::instance()->projectExplorerSettings().useJom) {
+        // We want jom! Try to find it.
+        QString jom = QCoreApplication::applicationDirPath() + QLatin1String("/jom.exe");
+        if (QFileInfo(jom).exists())
+            return jom;
+        else
+            return QLatin1String("jom.exe");
+    }
+    return QLatin1String("nmake.exe");
+}
+
+IOutputParser *MsvcToolChain::outputParser() const
+{
+    return new MsvcParser;
+}
+
+ToolChainConfigWidget *MsvcToolChain::configurationWidget()
+{
+    return new MsvcToolChainConfigWidget(this);
+}
+
+bool MsvcToolChain::canClone() const
+{
+    return false;
+}
+
+ToolChain *MsvcToolChain::clone() const
+{
+    return 0;
+}
+
+// --------------------------------------------------------------------------
+// MsvcToolChainConfigWidget
+// --------------------------------------------------------------------------
+
+MsvcToolChainConfigWidget::MsvcToolChainConfigWidget(ToolChain *tc) :
+    ToolChainConfigWidget(tc)
+{
+    QLabel *label = new QLabel;
+    label->setText(tc->displayName());
+    QVBoxLayout *layout = new QVBoxLayout(this);
+    layout->addWidget(label);
+}
+
+void MsvcToolChainConfigWidget::apply()
+{
+    // Nothing to apply!
+}
+
+void MsvcToolChainConfigWidget::discard()
+{
+    // Nothing to apply!
+}
+
+bool MsvcToolChainConfigWidget::isDirty() const
+{
+    return false;
+}
+
+// --------------------------------------------------------------------------
+// MsvcToolChainFactory
+// --------------------------------------------------------------------------
+
+QString MsvcToolChainFactory::displayName() const
+{
+    return tr("MSVC");
+}
+
+QString MsvcToolChainFactory::id() const
+{
+    return QLatin1String(Constants::MSVC_TOOLCHAIN_ID);
+}
+
+QList<ToolChain *> MsvcToolChainFactory::autoDetect()
+{
+    QList<ToolChain *> results;
+
+#ifdef Q_OS_WIN
+    // 1) Installed SDKs preferred over standalone Visual studio
+    const QSettings sdkRegistry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows",
+                                QSettings::NativeFormat);
+    const QString defaultSdkPath = sdkRegistry.value(QLatin1String("CurrentInstallFolder")).toString();
+    if (!defaultSdkPath.isEmpty()) {
+        foreach (const QString &sdkKey, sdkRegistry.childGroups()) {
+            const QString name = sdkRegistry.value(sdkKey + QLatin1String("/ProductName")).toString();
+            const QString folder = sdkRegistry.value(sdkKey + QLatin1String("/InstallationFolder")).toString();
+            if (folder.isEmpty())
+                continue;
+
+            const QString sdkVcVarsBat = folder + QLatin1String("bin\\SetEnv.cmd");
+            if (!QFileInfo(sdkVcVarsBat).exists())
+                continue;
+            QList<ToolChain *> tmp;
+            tmp.append(new MsvcToolChain(MsvcToolChain::WindowsSDK, name,MsvcToolChain::s32,
+                                         sdkVcVarsBat, QLatin1String("/x86"), true));
+#ifdef Q_OS_WIN64
+            // Add all platforms
+            tmp.append(new MsvcToolChain(MsvcToolChain::WindowsSDK, name, MsvcToolChain::s64,
+                                         sdkVcVarsBat, QLatin1String("/x64"), true));
+            tmp.append(new MsvcToolChain(MsvcToolChain::WindowsSDK, name, MsvcToolChain::ia64,
+                                         sdkVcVarsBat, QLatin1String("/ia64"), true));
+#endif
+            // Make sure the default is front.
+            if (folder == defaultSdkPath)
+                results = tmp + results;
+            else
+                results += tmp;
+        } // foreach
+    }
+
+    // 2) Installed MSVCs
+    const QSettings vsRegistry(
+#ifdef Q_OS_WIN64
+                QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7"),
+#else
+                QLatin1String("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VC7"),
+#endif
+                QSettings::NativeFormat);
+    foreach (const QString &vsName, vsRegistry.allKeys()) {
+        // Scan for version major.minor
+        const int dotPos = vsName.indexOf(QLatin1Char('.'));
+        if (dotPos == -1)
+            continue;
+
+        const QString path = vsRegistry.value(vsName).toString();
+        const int version = vsName.left(dotPos).toInt();
+        // Check existence of various install scripts
+        const QString vcvars32bat = path + QLatin1String("bin\\vcvars32.bat");
+        if (QFileInfo(vcvars32bat).isFile())
+            results.append(new MsvcToolChain(MsvcToolChain::VS, vsName, MsvcToolChain::s32,
+                                             vcvars32bat, QString(), true));
+        if (version >= 10) {
+            // Just one common file
+            const QString vcvarsAllbat = path + QLatin1String("vcvarsall.bat");
+            if (QFileInfo(vcvarsAllbat).isFile()) {
+                results.append(new MsvcToolChain(MsvcToolChain::VS, vsName, MsvcToolChain::s32,
+                                                 vcvarsAllbat, QLatin1String("x86"), true));
+                results.append(new MsvcToolChain(MsvcToolChain::VS, vsName, MsvcToolChain::amd64,
+                                                 vcvarsAllbat, QLatin1String("amd64"), true));
+                results.append(new MsvcToolChain(MsvcToolChain::VS, vsName, MsvcToolChain::s64,
+                                                 vcvarsAllbat, QLatin1String("x64"), true));
+                results.append(new MsvcToolChain(MsvcToolChain::VS, vsName, MsvcToolChain::ia64,
+                                                 vcvarsAllbat, QLatin1String("ia64"), true));
+            } else {
+                qWarning("Unable to find MSVC setup script %s in version %d", qPrintable(vcvarsAllbat), version);
+            }
+        } else {
+            // Amd 64 is the preferred 64bit platform
+            const QString vcvarsAmd64bat = path + QLatin1String("bin\\amd64\\vcvarsamd64.bat");
+            if (QFileInfo(vcvarsAmd64bat).isFile())
+                results.append(new MsvcToolChain(MsvcToolChain::VS, vsName, MsvcToolChain::amd64,
+                                                 vcvarsAmd64bat, QString(), true));
+            const QString vcvarsAmd64bat2 = path + QLatin1String("bin\\vcvarsx86_amd64.bat");
+            if (QFileInfo(vcvarsAmd64bat2).isFile())
+                results.append(new MsvcToolChain(MsvcToolChain::VS, vsName, MsvcToolChain::amd64,
+                                                 vcvarsAmd64bat2, QString(), true));
+            const QString vcvars64bat = path + QLatin1String("bin\\vcvars64.bat");
+            if (QFileInfo(vcvars64bat).isFile())
+                results.append(new MsvcToolChain(MsvcToolChain::VS, vsName, MsvcToolChain::s64,
+                                                 vcvars64bat, QString(), true));
+            const QString vcvarsIA64bat = path + QLatin1String("bin\\vcvarsx86_ia64.bat");
+            if (QFileInfo(vcvarsIA64bat).isFile())
+                results.append(new MsvcToolChain(MsvcToolChain::VS, vsName, MsvcToolChain::ia64,
+                                                 vcvarsIA64bat, QString(), true));
+        }
+    }
+#endif
+    return results;
+}
+
+} // namespace Internal
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h
new file mode 100644
index 0000000000000000000000000000000000000000..512c6eb6d788fad020dca8c3e5ce52d2e8ad80cc
--- /dev/null
+++ b/src/plugins/projectexplorer/msvctoolchain.h
@@ -0,0 +1,121 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef MSVCTOOLCHAIN_H
+#define MSVCTOOLCHAIN_H
+
+#include "toolchain.h"
+#include "toolchainconfigwidget.h"
+
+#include <utils/environment.h>
+
+namespace ProjectExplorer {
+namespace Internal {
+
+// --------------------------------------------------------------------------
+// MsvcToolChain
+// --------------------------------------------------------------------------
+
+class MsvcToolChain : public ToolChain
+{
+public:
+    enum Type { WindowsSDK, VS };
+    enum Platform { s32, s64, ia64, amd64 };
+
+    MsvcToolChain(Type type, const QString &name, Platform platform, const QString &varsBat,
+                  const QString &varsBatArg, bool autodetect = false);
+
+    QString typeName() const;
+    Abi targetAbi() const;
+
+    bool isValid() const;
+
+    QByteArray predefinedMacros() const;
+    QList<HeaderPath> systemHeaderPaths() const;
+    void addToEnvironment(Utils::Environment &env) const;
+    QString makeCommand() const;
+    IOutputParser *outputParser() const;
+
+    ToolChainConfigWidget *configurationWidget();
+
+    bool canClone() const;
+    ToolChain *clone() const;
+
+private:
+    QString m_varsBat; // Script to setup environment
+    QString m_varsBatArg; // Argument
+    mutable QByteArray m_predefinedMacros;
+    mutable Utils::Environment m_lastEnvironment;
+    mutable Utils::Environment m_resultEnvironment;
+    mutable QList<HeaderPath> m_headerPathes;
+    bool m_is64bit;
+    Abi::Architecture m_architecture;
+};
+
+// --------------------------------------------------------------------------
+// MsvcToolChainFactory
+// --------------------------------------------------------------------------
+
+class MsvcToolChainFactory : public ToolChainFactory
+{
+    Q_OBJECT
+
+public:
+    QString displayName() const;
+    QString id() const;
+
+    QList<ToolChain *> autoDetect();
+
+    ToolChainConfigWidget *configurationWidget(ToolChain *);
+};
+
+// --------------------------------------------------------------------------
+// MsvcToolChainConfigWidget
+// --------------------------------------------------------------------------
+
+class MsvcToolChainConfigWidget : public ToolChainConfigWidget
+{
+    Q_OBJECT
+
+public:
+    MsvcToolChainConfigWidget(ToolChain *);
+
+    void apply();
+    void discard();
+    bool isDirty() const;
+};
+
+} // namespace Internal
+} // namespace ProjectExplorer
+
+#endif // MSVCTOOLCHAIN_H
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index 8cbd0004b9b22e2820a302b27b800a10a6c5cea8..a32e51637766f41d8567c9883df162ffc656e267 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -35,10 +35,14 @@
 
 #include "buildsteplist.h"
 #include "deployconfiguration.h"
+#include "gcctoolchain.h"
+#include "msvctoolchain.h"
 #include "project.h"
 #include "projectexplorersettings.h"
 #include "target.h"
 #include "targetsettingspanel.h"
+#include "toolchainmanager.h"
+#include "toolchainoptionspage.h"
 #include "copytaskhandler.h"
 #include "showineditortaskhandler.h"
 #include "vcsannotatetaskhandler.h"
@@ -211,13 +215,16 @@ struct ProjectExplorerPluginPrivate {
     Internal::ProjectWelcomePage *m_welcomePage;
 
     Core::IMode *m_projectsMode;
+
+    ToolChainManager *m_toolChainManager;
 };
 
 ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate() :
     m_currentProject(0),
     m_currentNode(0),
     m_delayedRunConfiguration(0),
-    m_projectsMode(0)
+    m_projectsMode(0),
+    m_toolChainManager(0)
 {
 }
 
@@ -258,6 +265,7 @@ ProjectExplorerPlugin::~ProjectExplorerPlugin()
 {
     removeObject(d->m_welcomePage);
     delete d->m_welcomePage;
+    delete d->m_toolChainManager;
     removeObject(this);
     delete d;
 }
@@ -279,6 +287,19 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
         return false;
     addObject(this);
 
+    // Add ToolChainFactories:
+#ifndef Q_OS_WIN
+    addAutoReleasedObject(new Internal::GccToolChainFactory);
+    addAutoReleasedObject(new Internal::LinuxIccToolChainFactory);
+#else
+    addAutoReleasedObject(new Internal::MingwToolChainFactory);
+    addAutoReleasedObject(new Internal::MsvcToolChainFactory);
+#endif
+
+    d->m_toolChainManager = new ToolChainManager(this);
+
+    addAutoReleasedObject(new Internal::ToolChainOptionsPage);
+
     addAutoReleasedObject(new TaskHub);
 
     Core::ICore *core = Core::ICore::instance();
@@ -986,6 +1007,8 @@ void ProjectExplorerPlugin::clearSession()
 
 void ProjectExplorerPlugin::extensionsInitialized()
 {
+    d->m_toolChainManager->restoreToolChains();
+
     d->m_proWindow->extensionsInitialized();
     d->m_fileFactories = ProjectFileFactory::createFactories(&d->m_projectFilterString);
     foreach (ProjectFileFactory *pf, d->m_fileFactories) {
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index aecfb0fcad347c60d5ee1a506878e9cd0017d38d..0d01e7babe6835899bfd7a8c5d42c8bccd24f242 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -231,6 +231,9 @@ private slots:
 
     void testMsvcOutputParsers_data();
     void testMsvcOutputParsers();
+
+    void testGccAbiGuessing_data();
+    void testGccAbiGuessing();
 #endif
 
 private:
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index c67aba3d9c15f518ae9da0f9310d647752353695..d293604f1db7489ce378ff8c245b87b8e16d6d90 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -10,6 +10,9 @@ include(../../libs/utils/utils.pri)
 include(customwizard/customwizard.pri)
 INCLUDEPATH += $$PWD/../../libs/utils
 HEADERS += projectexplorer.h \
+    abi.h \
+    gcctoolchain.h \
+    msvctoolchain.h \
     projectexplorer_export.h \
     projectwindow.h \
     buildmanager.h \
@@ -70,6 +73,9 @@ HEADERS += projectexplorer.h \
     projectmodels.h \
     currentprojectfind.h \
     toolchain.h \
+    toolchainconfigwidget.h \
+    toolchainmanager.h \
+    toolchainoptionspage.h \
     userfileaccessor.h \
     cesdkhandler.h \
     gccparser.h \
@@ -98,11 +104,13 @@ HEADERS += projectexplorer.h \
     customexecutableconfigurationwidget.h \
     sessionnodeimpl.h \
     metatypedeclarations.h \
-    toolchaintype.h \
     publishing/publishingwizardselectiondialog.h \
     publishing/ipublishingwizardfactory.h
 
 SOURCES += projectexplorer.cpp \
+    abi.cpp \
+    gcctoolchain.cpp \
+    msvctoolchain.cpp \
     projectwindow.cpp \
     buildmanager.cpp \
     buildsteplist.cpp \
@@ -156,6 +164,9 @@ SOURCES += projectexplorer.cpp \
     projectmodels.cpp \
     currentprojectfind.cpp \
     toolchain.cpp \
+    toolchainconfigwidget.cpp \
+    toolchainmanager.cpp \
+    toolchainoptionspage.cpp \
     cesdkhandler.cpp \
     userfileaccessor.cpp \
     gccparser.cpp \
@@ -185,6 +196,7 @@ SOURCES += projectexplorer.cpp \
     publishing/publishingwizardselectiondialog.cpp
 
 FORMS += processstep.ui \
+    toolchainoptionspage.ui \
     editorsettingspropertiespage.ui \
     runsettingspropertiespage.ui \
     sessiondialog.ui \
@@ -212,4 +224,12 @@ win32 {
     macx:LIBS += -framework Carbon
 }
 RESOURCES += projectexplorer.qrc
+
+# Some way to override the architecture used in Abi:
+!isEmpty($$(QTC_CPU)) {
+    DEFINES += QTC_CPU=$$(QTC_CPU)
+} else {
+    DEFINES += QTC_CPU=x86
+}
+
 DEFINES += PROJECTEXPLORER_LIBRARY
diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h
index 005f029c24d112731ce758d53368fad13f1122fc..4c87b694a059fe3f106e5fdc8c742dc2e814b33c 100644
--- a/src/plugins/projectexplorer/projectexplorerconstants.h
+++ b/src/plugins/projectexplorer/projectexplorerconstants.h
@@ -184,6 +184,7 @@ const char * const ICON_DEBUG           = ":/projectexplorer/images/debugger_sta
 const char * const ICON_DEBUG_SMALL     = ":/projectexplorer/images/debugger_start_small.png";
 const char * const ICON_CLOSETAB        = ":/projectexplorer/images/closetab.png";
 const char * const ICON_STOP            = ":/projectexplorer/images/stop.png";
+const char * const ICON_TOOLCHAIN_SETTINGS_CATEGORY = ":projectexplorer/images/build.png"; // FIXME: Need an icon!
 
 // find filters
 const char * const FIND_CUR_PROJECT     = "ProjectExplorer.FindFilter.CurrentProject";
@@ -206,6 +207,8 @@ const char * const PROJECTEXPLORER_SETTINGS_CATEGORY  = "K.ProjectExplorer";
 const char * const PROJECTEXPLORER_SETTINGS_TR_CATEGORY = QT_TRANSLATE_NOOP("ProjectExplorer", "Projects");
 const char * const PROJECTEXPLORER_SETTINGS_CATEGORY_ICON  = ":/core/images/category_project.png";
 const char * const PROJECTEXPLORER_SETTINGS_ID = "ProjectExplorer.ProjectExplorer";
+const char * const TOOLCHAIN_SETTINGS_CATEGORY = "ProjectExplorer.Settings.ToolChains";
+const char * const TOOLCHAIN_SETTINGS_PAGE_ID = "M.ProjectExplorer.ToolChainOptions";
 
 // task categories
 const char * const TASK_CATEGORY_COMPILE = "Task.Category.Compile";
@@ -224,6 +227,12 @@ const char * const BUILDSTEPS_DEPLOY = "ProjectExplorer.BuildSteps.Deploy";
 // Deploy Configuration id:
 const char * const DEFAULT_DEPLOYCONFIGURATION_ID = "ProjectExplorer.DefaultDeployConfiguration";
 
+// ToolChain Ids
+const char * const GCC_TOOLCHAIN_ID = "ProjectExplorer.ToolChain.Gcc";
+const char * const MINGW_TOOLCHAIN_ID = "ProjectExplorer.ToolChain.Mingw";
+const char * const LINUXICC_TOOLCHAIN_ID = "ProjectExplorer.ToolChain.LinuxIcc";
+const char * const MSVC_TOOLCHAIN_ID = "ProjectExplorer.ToolChain.Msvc";
+
 // Run Configuration defaults:
 const int QML_DEFAULT_DEBUG_SERVER_PORT = 3768;
 
diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp
index 231f56a5cbdff6a344304c2991ba57fd25dd9a70..0b2a62266eefb0ef0cf92959ad53f8cbf5fd92e2 100644
--- a/src/plugins/projectexplorer/runconfiguration.cpp
+++ b/src/plugins/projectexplorer/runconfiguration.cpp
@@ -36,6 +36,7 @@
 #include "outputformatter.h"
 #include "project.h"
 #include "target.h"
+#include "toolchain.h"
 #include "buildconfiguration.h"
 #include "projectexplorerconstants.h"
 #include <extensionsystem/pluginmanager.h>
@@ -241,6 +242,17 @@ QVariantMap RunConfiguration::toMap() const
     return map;
 }
 
+ProjectExplorer::Abi RunConfiguration::abi() const
+{
+    BuildConfiguration *bc = target()->activeBuildConfiguration();
+    if (!bc)
+        return Abi::hostAbi();
+    ToolChain *tc = bc->toolChain();
+    if (!tc)
+        return Abi::hostAbi();
+    return tc->targetAbi();
+}
+
 bool RunConfiguration::fromMap(const QVariantMap &map)
 {
     m_useCppDebugger = map.value(QLatin1String(USE_CPP_DEBUGGER_KEY), true).toBool();
diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h
index fa636b3a8dfc4147c9b828744c07861e2aef6dab..b5458c36a5ad551dc3fbf3888dc67217c1f52ce8 100644
--- a/src/plugins/projectexplorer/runconfiguration.h
+++ b/src/plugins/projectexplorer/runconfiguration.h
@@ -34,6 +34,7 @@
 #ifndef RUNCONFIGURATION_H
 #define RUNCONFIGURATION_H
 
+#include "abi.h"
 #include "projectconfiguration.h"
 #include "projectexplorer_export.h"
 #include "outputformat.h"
@@ -102,6 +103,8 @@ public:
 
     virtual QVariantMap toMap() const;
 
+    virtual ProjectExplorer::Abi abi() const;
+
 signals:
     void isEnabledChanged(bool value);
     void debuggersChanged();
diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp
index 92b390306ac061feb9aafe1bc91f508c73b042b6..3f63cd5b02ff0d10992d8dec65d19828ff8599e7 100644
--- a/src/plugins/projectexplorer/target.cpp
+++ b/src/plugins/projectexplorer/target.cpp
@@ -38,6 +38,7 @@
 #include "project.h"
 #include "projectexplorerconstants.h"
 #include "runconfiguration.h"
+#include "toolchainmanager.h"
 
 #include <limits>
 #include <utils/qtcassert.h>
@@ -354,6 +355,25 @@ void Target::setToolTip(const QString &text)
     emit toolTipChanged();
 }
 
+QList<ToolChain *> Target::possibleToolChains(BuildConfiguration *) const
+{
+    QList<ToolChain *> tcList = ToolChainManager::instance()->toolChains();
+    QList<ToolChain *> result;
+    foreach (ToolChain *tc, tcList) {
+        if (!tc->restrictedToTargets().contains(id()))
+            result.append(tc);
+    }
+    return result;
+}
+
+ToolChain *Target::preferredToolChain(BuildConfiguration *bc) const
+{
+    QList<ToolChain *> tcs = possibleToolChains(bc);
+    if (tcs.isEmpty())
+        return 0;
+    return tcs.at(0);
+}
+
 QVariantMap Target::toMap() const
 {
     const QList<BuildConfiguration *> bcs = buildConfigurations();
diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h
index 9f741da05fec89e508a5c0150d6cc76326cd24e2..f42a4d82ad75a1adfaf16b4bb3eba7e91a1d233e 100644
--- a/src/plugins/projectexplorer/target.h
+++ b/src/plugins/projectexplorer/target.h
@@ -45,6 +45,7 @@ class Environment;
 
 namespace ProjectExplorer {
 class RunConfiguration;
+class ToolChain;
 class BuildConfiguration;
 class DeployConfiguration;
 class IBuildConfigurationFactory;
@@ -108,6 +109,10 @@ public:
     QString toolTip() const;
     void setToolTip(const QString &text);
 
+    virtual QList<ToolChain *> possibleToolChains(BuildConfiguration *) const;
+    virtual ToolChain *preferredToolChain(BuildConfiguration *) const;
+
+
     virtual QVariantMap toMap() const;
 
 signals:
diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp
index 54eabbed1484fcf41238a363f9c7bb70febc507e..1713a08fa64f5c89943609f7c786d686d43f3011 100644
--- a/src/plugins/projectexplorer/toolchain.cpp
+++ b/src/plugins/projectexplorer/toolchain.cpp
@@ -32,903 +32,160 @@
 **************************************************************************/
 
 #include "toolchain.h"
-#include "project.h"
-#include "cesdkhandler.h"
-#include "projectexplorersettings.h"
-#include "gccparser.h"
-#include "msvcparser.h"
-#include "linuxiccparser.h"
-
-#include <utils/synchronousprocess.h>
-#include <utils/qtcprocess.h>
-
-#include <QtCore/QDebug>
-#include <QtCore/QFileInfo>
-#include <QtCore/QProcess>
-#include <QtCore/QSettings>
-#include <QtCore/QDir>
-#include <QtCore/QTemporaryFile>
-#include <QtCore/QString>
-#include <QtCore/QCoreApplication>
-
-using namespace ProjectExplorer;
-using namespace ProjectExplorer::Internal;
-
-enum { debug = 0 };
-
-#ifdef Q_OS_WIN64
-static const char MSVC_RegKey[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7";
-#else
-static const char MSVC_RegKey[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VC7";
-#endif
-
-bool ToolChain::equals(const ToolChain *a, const ToolChain *b)
-{
-    if (a == b)
-        return true;
-    if (a == 0 || b == 0)
-        return false;
-    if (a->type() == b->type())
-        return a->equals(b);
-    return false;
-}
-
-ToolChain::ToolChain()
-{
-}
-
-ToolChain::~ToolChain()
-{
-}
-
-ToolChain *ToolChain::createGccToolChain(const QString &gcc)
-{
-    return new GccToolChain(gcc);
-}
-
-ToolChain *ToolChain::createMinGWToolChain(const QString &gcc, const QString &mingwPath)
-{
-    return new MinGWToolChain(gcc, mingwPath);
-}
-
-ToolChain *ToolChain::createLinuxIccToolChain()
-{
-    return new LinuxIccToolChain();
-}
-
-ToolChain *ToolChain::createMSVCToolChain(const QString &name, bool amd64)
-{
-    return MSVCToolChain::create(name, amd64);
-}
-
-ToolChain *ToolChain::createWinCEToolChain(const QString &name, const QString &platform)
-{
-    return WinCEToolChain::create(name, platform);
-}
-
-QStringList ToolChain::availableMSVCVersions()
-{
-    QStringList rc;
-    foreach(const MSVCToolChain::Installation &i, MSVCToolChain::installations())
-        rc.push_back(i.name);
-    return rc;
-}
-
-QStringList ToolChain::availableMSVCVersions(bool amd64)
-{
-    QStringList rc;
-    foreach(const MSVCToolChain::Installation &i, MSVCToolChain::installations())
-        if (i.is64bit() == amd64)
-            rc.push_back(i.name);
-    return rc;
-}
-
-QList<ToolChainType> ToolChain::supportedToolChains()
-{
-    QList<ToolChainType> toolChains;
-    for (int i = 0; i < ToolChain_LAST_VALID; ++i) {
-        toolChains.append(ToolChainType(i));
-    }
-    return toolChains;
-}
-
-QString ToolChain::toolChainName(ToolChainType tc)
-{
-    switch (tc) {
-    case ToolChain_GCC:
-        return QCoreApplication::translate("ToolChain", "GCC");
-    case ToolChain_LINUX_ICC:
-        return QCoreApplication::translate("ToolChain", "Intel C++ Compiler (Linux)");
-    case ToolChain_MinGW:
-        return QString::fromLatin1("MinGW");
-    case ToolChain_MSVC:
-        return QCoreApplication::translate("ToolChain", "Microsoft Visual C++");
-    case ToolChain_WINCE:
-        return QCoreApplication::translate("ToolChain", "Windows CE");
-    case ToolChain_WINSCW:
-        return QCoreApplication::translate("ToolChain", "WINSCW");
-    case ToolChain_GCCE:
-        return QCoreApplication::translate("ToolChain", "GCCE");
-    case ToolChain_GCCE_GNUPOC:
-        return QCoreApplication::translate("ToolChain", "GCCE/GnuPoc");
-    case ToolChain_RVCT_ARMV5_GNUPOC:
-        return QCoreApplication::translate("ToolChain", "RVCT (ARMV6)/GnuPoc");
-    case ToolChain_RVCT2_ARMV5:
-        return QCoreApplication::translate("ToolChain", "RVCT 2 (ARMV5)");
-    case ToolChain_RVCT2_ARMV6:
-        return QCoreApplication::translate("ToolChain", "RVCT 2 (ARMV6)");
-    case ToolChain_RVCT4_ARMV5:
-        return QCoreApplication::translate("ToolChain", "RVCT 4 (ARMV5)");
-    case ToolChain_RVCT4_ARMV6:
-        return QCoreApplication::translate("ToolChain", "RVCT 4 (ARMV6)");
-    case ToolChain_GCC_MAEMO5:
-        return QCoreApplication::translate("ToolChain", "GCC for Maemo5");
-    case ToolChain_GCC_HARMATTAN:
-        return QCoreApplication::translate("ToolChain", "GCC for Harmattan");
-    case ToolChain_GCC_MEEGO:
-        return QCoreApplication::translate("ToolChain", "GCC for Meego");
-    case ToolChain_OTHER:
-        return QCoreApplication::translate("ToolChain", "Other");
-    case ToolChain_INVALID:
-        return QCoreApplication::translate("ToolChain", "<Invalid>");
-    case ToolChain_UNKNOWN:
-        break;
-    default:
-        Q_ASSERT("Missing name for Toolchaintype");
-    };
-    return QCoreApplication::translate("ToolChain", "<Unknown>");
-}
-
-GccToolChain::GccToolChain(const QString &gcc)
-    : m_gcc(gcc)
-{
-
-}
-
-ToolChainType GccToolChain::type() const
-{
-    return ToolChain_GCC;
-}
-
-static QByteArray gccPredefinedMacros(const QString &gcc, const QStringList &env)
-{
-    QStringList arguments;
-    arguments << QLatin1String("-xc++")
-              << QLatin1String("-E")
-              << QLatin1String("-dM")
-              << QLatin1String("-");
-
-    QProcess cpp;
-    cpp.setEnvironment(env);
-    cpp.start(gcc, arguments);
-    if (!cpp.waitForStarted()) {
-        qWarning("%s: Cannot start '%s': %s", Q_FUNC_INFO, qPrintable(gcc),
-            qPrintable(cpp.errorString()));
-        return QByteArray();
-    }
-    cpp.closeWriteChannel();
-    if (!cpp.waitForFinished()) {
-        Utils::SynchronousProcess::stopProcess(cpp);
-        qWarning("%s: Timeout running '%s'.", Q_FUNC_INFO, qPrintable(gcc));
-        return QByteArray();
-    }
-    if (cpp.exitStatus() != QProcess::NormalExit) {
-        qWarning("%s: '%s' crashed.", Q_FUNC_INFO, qPrintable(gcc));
-        return QByteArray();
-    }
-    QByteArray predefinedMacros = cpp.readAllStandardOutput();
-#ifdef Q_OS_MAC
-    // Turn off flag indicating Apple's blocks support
-    const QByteArray blocksDefine("#define __BLOCKS__ 1");
-    const QByteArray blocksUndefine("#undef __BLOCKS__");
-    const int idx = predefinedMacros.indexOf(blocksDefine);
-    if (idx != -1) {
-        predefinedMacros.replace(idx, blocksDefine.length(), blocksUndefine);
-    }
-
-    // Define __strong and __weak (used for Apple's GC extension of C) to be empty
-    predefinedMacros.append("#define __strong\n");
-    predefinedMacros.append("#define __weak\n");
-#endif // Q_OS_MAC
-    return predefinedMacros;
-}
-
-QByteArray GccToolChain::predefinedMacros()
-{
-    if (m_predefinedMacros.isEmpty()) {
-        Utils::Environment env = Utils::Environment::systemEnvironment();
-        addToEnvironment(env);
-        m_predefinedMacros = gccPredefinedMacros(m_gcc, env.toStringList());
-    }
-    return m_predefinedMacros;
-}
-
-static QList<HeaderPath> gccSystemHeaderPaths(const QString &gcc, Utils::Environment env)
-{
-    QList<HeaderPath> systemHeaderPaths;
-    QStringList arguments;
-    arguments << QLatin1String("-xc++")
-              << QLatin1String("-E")
-              << QLatin1String("-v")
-              << QLatin1String("-");
-
-    QProcess cpp;
-    env.set(QLatin1String("LC_ALL"), QLatin1String("C"));   //override current locale settings
-    cpp.setEnvironment(env.toStringList());
-    cpp.setReadChannelMode(QProcess::MergedChannels);
-    cpp.start(gcc, arguments);
-    if (!cpp.waitForStarted()) {
-        qWarning("%s: Cannot start '%s': %s", Q_FUNC_INFO, qPrintable(gcc),
-            qPrintable(cpp.errorString()));
-        return systemHeaderPaths;
-    }
-    cpp.closeWriteChannel();
-    if (!cpp.waitForFinished()) {
-        Utils::SynchronousProcess::stopProcess(cpp);
-        qWarning("%s: Timeout running '%s'.", Q_FUNC_INFO, qPrintable(gcc));
-        return systemHeaderPaths;
-    }
-    if (cpp.exitStatus() != QProcess::NormalExit) {
-        qWarning("%s: '%s' crashed.", Q_FUNC_INFO, qPrintable(gcc));
-        return systemHeaderPaths;
-    }
-    QByteArray line;
-    while (cpp.canReadLine()) {
-        line = cpp.readLine();
-        if (line.startsWith("#include"))
-            break;
-    }
-
-    if (! line.isEmpty() && line.startsWith("#include")) {
-        HeaderPath::Kind kind = HeaderPath::UserHeaderPath;
-        while (cpp.canReadLine()) {
-            line = cpp.readLine();
-            if (line.startsWith("#include")) {
-                kind = HeaderPath::GlobalHeaderPath;
-            } else if (! line.isEmpty() && QChar(line.at(0)).isSpace()) {
-                HeaderPath::Kind thisHeaderKind = kind;
-
-                line = line.trimmed();
-                if (line.endsWith('\n'))
-                    line.chop(1);
-
-                const int index = line.indexOf(" (framework directory)");
-                if (index != -1) {
-                    line.truncate(index);
-                    thisHeaderKind = HeaderPath::FrameworkHeaderPath;
-                }
-
-                systemHeaderPaths.append(HeaderPath(QFile::decodeName(line), thisHeaderKind));
-            } else if (line.startsWith("End of search list.")) {
-                break;
-            } else {
-                qWarning() << "ignore line:" << line;
-            }
-        }
-    }
-    return systemHeaderPaths;
-}
-
-QList<HeaderPath> GccToolChain::systemHeaderPaths()
-{
-    if (m_systemHeaderPaths.isEmpty()) {
-        Utils::Environment env = Utils::Environment::systemEnvironment();
-        addToEnvironment(env);
-        m_systemHeaderPaths = gccSystemHeaderPaths(m_gcc, env);
-    }
-    return m_systemHeaderPaths;
-}
-
-void GccToolChain::addToEnvironment(Utils::Environment &env)
-{
-    Q_UNUSED(env)
-}
-
-QString GccToolChain::makeCommand() const
-{
-    return QLatin1String("make");
-}
-
-IOutputParser *GccToolChain::outputParser() const
-{
-    return new GccParser;
-}
+#include <extensionsystem/pluginmanager.h>
+#include <utils/environment.h>
 
-bool GccToolChain::equals(const ToolChain *other) const
-{
-    return (m_gcc == static_cast<const GccToolChain *>(other)->m_gcc);
-}
+#include <QtCore/QCoreApplication>
 
-MinGWToolChain::MinGWToolChain(const QString &gcc, const QString &mingwPath)
-    : GccToolChain(gcc), m_mingwPath(mingwPath)
-{
+static const char *const ID_KEY = "ProjectExplorer.ToolChain.Id";
+static const char *const DISPLAY_NAME_KEY = "ProjectExplorer.ToolChain.DisplayName";
 
-}
+namespace ProjectExplorer {
+namespace Internal {
 
-ToolChainType MinGWToolChain::type() const
-{
-    return ToolChain_MinGW;
-}
+// --------------------------------------------------------------------------
+// ToolChainPrivate
+// --------------------------------------------------------------------------
 
-bool MinGWToolChain::equals(const ToolChain *other) const
+class ToolChainPrivate
 {
-    const MinGWToolChain *o = static_cast<const MinGWToolChain *>(other);
-    return (m_mingwPath == o->m_mingwPath && this->GccToolChain::equals(other));
-}
+public:
+    ToolChainPrivate(const QString &id, bool autodetect) :
+        m_id(id),
+        m_autodetect(autodetect)
+    { Q_ASSERT(!id.isEmpty()); }
 
-void MinGWToolChain::addToEnvironment(Utils::Environment &env)
-{
-    if (debug)
-        qDebug() << "MinGWToolChain::addToEnvironment" << m_mingwPath;
-    if (m_mingwPath.isEmpty())
-        return;
-    const QString binDir = m_mingwPath + "/bin";
-    if (QFileInfo(binDir).exists())
-        env.prependOrSetPath(binDir);
-}
+    QString m_id;
+    bool m_autodetect;
+    mutable QString m_displayName;
+};
 
-QString MinGWToolChain::makeCommand() const
-{
-    return QLatin1String("mingw32-make.exe");
-}
+} // namespace Internal
 
-IOutputParser *MinGWToolChain::outputParser() const
-{
-    return new GccParser;
-}
+// --------------------------------------------------------------------------
+// ToolChain
+// --------------------------------------------------------------------------
 
-LinuxIccToolChain::LinuxIccToolChain()
-    : GccToolChain(QLatin1String("icpc"))
-{
-}
+ToolChain::ToolChain(const QString &id, bool autodetect) :
+    m_d(new Internal::ToolChainPrivate(id, autodetect))
+{ }
 
-ToolChainType LinuxIccToolChain::type() const
+ToolChain::ToolChain(const ToolChain &other) :
+    m_d(new Internal::ToolChainPrivate(other.id(), false))
 {
-    return ToolChain_LINUX_ICC;
+    // leave the autodetection bit at false.
+    m_d->m_displayName = other.displayName();
 }
 
-IOutputParser *LinuxIccToolChain::outputParser() const
+ToolChain::~ToolChain()
 {
-    return new LinuxIccParser;
+    delete m_d;
 }
 
-// ---------------- MSVC installation location code
-
-// Format the name of an SDK or VC installation version with platform
-static inline QString installationName(const QString &name,
-                                       MSVCToolChain::Installation::Type t,
-                                       MSVCToolChain::Installation::Platform p)
+QString ToolChain::displayName() const
 {
-    if (t == MSVCToolChain::Installation::WindowsSDK) {
-        QString sdkName = name;
-        sdkName += QLatin1String(" (");
-        sdkName += MSVCToolChain::Installation::platformName(p);
-        sdkName += QLatin1Char(')');
-        return sdkName;
-    }
-    // Comes as "9.0" from the registry
-    QString vcName = QLatin1String("Microsoft Visual C++ Compilers ");
-    vcName += name;
-    vcName+= QLatin1String(" (");
-    vcName += MSVCToolChain::Installation::platformName(p);
-    vcName += QLatin1Char(')');
-    return vcName;
+    if (m_d->m_displayName.isEmpty())
+        return typeName();
+    return m_d->m_displayName;
 }
 
-MSVCToolChain::Installation::Installation(Type t, const QString &n, Platform p,
-                                          const QString &v, const QString &a) :
-    type(t), name(installationName(n, t, p)), platform(p), varsBat(v), varsBatArg(a)
+void ToolChain::setDisplayName(const QString &name) const
 {
+    m_d->m_displayName = name;
 }
 
-MSVCToolChain::Installation::Installation() : platform(s32)
+bool ToolChain::isAutoDetected() const
 {
+    return m_d->m_autodetect;
 }
 
-QString MSVCToolChain::Installation::platformName(Platform t)
+QString ToolChain::id() const
 {
-    switch (t) {
-    case s32:
-        return QLatin1String("x86");
-    case s64:
-        return QLatin1String("x64");
-    case ia64:
-        return QLatin1String("ia64");
-    case amd64:
-        return QLatin1String("amd64");
-    }
-    return QString();
+    return m_d->m_id;
 }
 
-bool MSVCToolChain::Installation::is64bit() const
+QStringList ToolChain::restrictedToTargets() const
 {
-    return platform != s32;
+    return QStringList();
 }
 
-MSVCToolChain::InstallationList MSVCToolChain::installations()
+bool ToolChain::canClone() const
 {
-    static InstallationList installs;
-    static bool firstTime = true;
-    if (firstTime) {
-        firstTime = false;
-        // 1) Installed SDKs preferred over standalone Visual studio
-        const char sdk_RegKeyC[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows";
-        const QSettings sdkRegistry(sdk_RegKeyC, QSettings::NativeFormat);
-        const QString defaultSdkPath = sdkRegistry.value(QLatin1String("CurrentInstallFolder")).toString();
-        if (!defaultSdkPath.isEmpty()) {
-            foreach(const QString &sdkKey, sdkRegistry.childGroups()) {
-                const QString name = sdkRegistry.value(sdkKey + QLatin1String("/ProductName")).toString();
-                const QString folder = sdkRegistry.value(sdkKey + QLatin1String("/InstallationFolder")).toString();
-                if (!folder.isEmpty()) {
-                    const QString sdkVcVarsBat = folder + QLatin1String("bin\\SetEnv.cmd");
-                    if (QFileInfo(sdkVcVarsBat).exists()) {
-                        // Add all platforms
-                        InstallationList newInstalls;
-                        newInstalls.push_back(Installation(Installation::WindowsSDK, name, Installation::s32, sdkVcVarsBat, QLatin1String("/x86")));
-#ifdef Q_OS_WIN64
-                        newInstalls.push_back(Installation(Installation::WindowsSDK, name, Installation::s64, sdkVcVarsBat, QLatin1String("/x64")));
-                        newInstalls.push_back(Installation(Installation::WindowsSDK, name, Installation::ia64, sdkVcVarsBat, QLatin1String("/ia64")));
-#endif
-                        // Make sure the default is front.
-                        if (folder == defaultSdkPath && !installs.empty()) {
-                            const InstallationList old = installs;
-                            installs = newInstalls + old;
-                        } else {
-                            installs.append(newInstalls);
-                        }
-                    } // bat exists
-                } // folder
-            } // foreach
-        }
-        // 2) Installed MSVCs
-        const QSettings vsRegistry(MSVC_RegKey, QSettings::NativeFormat);
-        foreach(const QString &vsName, vsRegistry.allKeys()) {
-            const int dotPos = vsName.indexOf(QLatin1Char('.'));
-            if (dotPos != -1) { // Scan for version major.minor
-                const QString path = vsRegistry.value(vsName).toString();
-                const int version = vsName.left(dotPos).toInt();
-                // Check existence of various install scripts
-                const QString vcvars32bat = path + QLatin1String("bin\\vcvars32.bat");
-                if (QFileInfo(vcvars32bat).isFile())
-                    installs.push_back(Installation(Installation::VS, vsName, Installation::s32, vcvars32bat));
-                if (version >= 10) {
-                    // Just one common file
-                    const QString vcvarsAllbat = path + QLatin1String("vcvarsall.bat");
-                    if (QFileInfo(vcvarsAllbat).isFile()) {
-                        installs.push_back(Installation(Installation::VS, vsName, Installation::s32, vcvarsAllbat, QLatin1String("x86")));
-                        installs.push_back(Installation(Installation::VS, vsName, Installation::amd64, vcvarsAllbat, QLatin1String("amd64")));
-                        installs.push_back(Installation(Installation::VS, vsName, Installation::s64, vcvarsAllbat, QLatin1String("x64")));
-                        installs.push_back(Installation(Installation::VS, vsName, Installation::ia64, vcvarsAllbat, QLatin1String("ia64")));
-                    } else {
-                        qWarning("Unable to find MSVC setup script %s in version %d", qPrintable(vcvarsAllbat), version);
-                    }
-                } else {
-                    // Amd 64 is the preferred 64bit platform
-                    const QString vcvarsAmd64bat = path + QLatin1String("bin\\amd64\\vcvarsamd64.bat");
-                    if (QFileInfo(vcvarsAmd64bat).isFile())
-                        installs.push_back(Installation(Installation::VS, vsName, Installation::amd64, vcvarsAmd64bat));
-                    const QString vcvarsAmd64bat2 = path + QLatin1String("bin\\vcvarsx86_amd64.bat");
-                    if (QFileInfo(vcvarsAmd64bat2).isFile())
-                        installs.push_back(Installation(Installation::VS, vsName, Installation::amd64, vcvarsAmd64bat2));
-                    const QString vcvars64bat = path + QLatin1String("bin\\vcvars64.bat");
-                    if (QFileInfo(vcvars64bat).isFile())
-                        installs.push_back(Installation(Installation::VS, vsName, Installation::s64, vcvars64bat));
-                    const QString vcvarsIA64bat = path + QLatin1String("bin\\vcvarsx86_ia64.bat");
-                    if (QFileInfo(vcvarsIA64bat).isFile())
-                        installs.push_back(Installation(Installation::VS, vsName, Installation::ia64, vcvarsIA64bat));
-                }
-            }
-        }
-    }
-    if (debug)
-        foreach(const Installation &i, installs)
-            qDebug() << i;
-    return installs;
+    return true;
 }
 
-// Return a substring to match the MSVC official version against by mkSpec name.
-static inline const QString msvcVersionStringFromMkSpec(const QString &mkSpec)
+QString ToolChain::defaultMakeTarget() const
 {
-    if (mkSpec.isEmpty())
-        return QString();
-    if (mkSpec.endsWith(QLatin1String("msvc2002")))
-       return QLatin1String(" 7.0");
-    if (mkSpec.endsWith(QLatin1String("msvc2003")))
-       return QLatin1String(" 7.1");
-    if (mkSpec.endsWith(QLatin1String("msvc2005")))
-       return QLatin1String(" 8.0");
-    if (mkSpec.endsWith(QLatin1String("msvc2008")))
-        return QLatin1String(" 9.0");
-    if (mkSpec.endsWith(QLatin1String("msvc2010")))
-        return QLatin1String(" 10.0");
     return QString();
 }
 
-MSVCToolChain::Installation MSVCToolChain::findInstallationByMkSpec(bool is64Bit,
-                                                                    const QString &mkSpec,
-                                                                    bool excludeSDK)
+bool ToolChain::operator == (const ToolChain &tc) const
 {
-    const QString mkSpecMatchString = msvcVersionStringFromMkSpec(mkSpec);
-    if (!mkSpecMatchString.isEmpty()) {
-        foreach(const Installation &i, installations()) {
-            if ((i.type == Installation::VS) && (i.is64bit() == is64Bit)
-                && (i.name.indexOf(mkSpecMatchString) != -1))
-                    return i;
-        }
-    }
-    return findInstallationByName(is64Bit, QString(), excludeSDK);
-}
-
-MSVCToolChain::Installation MSVCToolChain::findInstallationByName(bool is64Bit,
-                                                            const QString &name,
-                                                            bool excludeSDK)
-{
-    if (debug)
-        qDebug() << "find" << (is64Bit ? 64 : 32) << name << excludeSDK;
-    foreach(const Installation &i, installations()) {
-        if (i.type != Installation::WindowsSDK || !excludeSDK) {
-            if ((i.is64bit() == is64Bit) && (name.isEmpty() || name == i.name))
-                return i;
-        }
-    }
-    return Installation();
-}
-
-namespace ProjectExplorer {
-PROJECTEXPLORER_EXPORT QDebug operator<<(QDebug in, const MSVCToolChain::Installation &i)
-{
-    QDebug nsp = in.nospace();
-    nsp << "Type: " << i.type << " Platform: " << i.platform << " Name: " << i.name
-        << "\nSetup: " << i.varsBat;
-    if (!i.varsBatArg.isEmpty())
-        nsp << "\nSetup argument: " << i.varsBatArg;
-    return in;
-}
-}
-
-MSVCToolChain *MSVCToolChain::create(const QString &name, bool amd64)
-{
-    return new MSVCToolChain(MSVCToolChain::findInstallationByName(amd64, name));
-}
-
-MSVCToolChain::MSVCToolChain(const Installation &in) :
-    m_installation(in),
-    m_valuesSet(false)
-{
-    if (debug)
-        qDebug() << "\nMSVCToolChain::CT\n" << m_installation;
-}
-
-ToolChainType MSVCToolChain::type() const
-{
-    return ToolChain_MSVC;
-}
-
-bool MSVCToolChain::equals(const ToolChain *other) const
-{
-    const MSVCToolChain *o = static_cast<const MSVCToolChain *>(other);
-    return (m_installation.name == o->m_installation.name);
-}
-
-QByteArray msvcCompilationFile() {
-    static const char* macros[] = {"_ATL_VER", "_CHAR_UNSIGNED", "__CLR_VER",
-                                   "__cplusplus_cli", "__COUNTER__", "__cplusplus",
-                                   "_CPPLIB_VER", "_CPPRTTI", "_CPPUNWIND",
-                                   "_DEBUG", "_DLL", "__FUNCDNAME__",
-                                   "__FUNCSIG__","__FUNCTION__","_INTEGRAL_MAX_BITS",
-                                   "_M_ALPHA","_M_CEE","_M_CEE_PURE",
-                                   "_M_CEE_SAFE","_M_IX86","_M_IA64",
-                                   "_M_IX86_FP","_M_MPPC","_M_MRX000",
-                                   "_M_PPC","_M_X64","_MANAGED",
-                                   "_MFC_VER","_MSC_BUILD", /* "_MSC_EXTENSIONS", */
-                                   "_MSC_FULL_VER","_MSC_VER","__MSVC_RUNTIME_CHECKS",
-                                   "_MT", "_NATIVE_WCHAR_T_DEFINED", "_OPENMP",
-                                   "_VC_NODEFAULTLIB", "_WCHAR_T_DEFINED", "_WIN32",
-                                   "_WIN32_WCE", "_WIN64", "_Wp64", "__DATE__",
-                                    "__DATE__", "__TIME__", "__TIMESTAMP__",
-                                   0};
-    QByteArray file = "#define __PPOUT__(x) V##x=x\n\n";
-    int i =0;
-    while (macros[i] != 0) {
-        const QByteArray macro(macros[i]);
-        file += "#if defined(" + macro + ")\n__PPOUT__("
-                + macro + ")\n#endif\n";
-        ++i;
-    }
-    file += "\nvoid main(){}\n\n";
-    return file;
-}
-
-// Run MSVC 'cl' compiler to obtain #defines.
-static QByteArray msvcPredefinedMacros(const QStringList &env)
-{
-    QByteArray predefinedMacros = "#define __MSVCRT__\n"
-                      "#define __w64\n"
-                      "#define __int64 long long\n"
-                      "#define __int32 long\n"
-                      "#define __int16 short\n"
-                      "#define __int8 char\n"
-                      "#define __ptr32\n"
-                      "#define __ptr64\n";
-
-    QString tmpFilePath;
-    {
-        // QTemporaryFile is buggy and will not unlock the file for cl.exe
-        QTemporaryFile tmpFile(QDir::tempPath()+"/envtestXXXXXX.cpp");
-        tmpFile.setAutoRemove(false);
-        if (!tmpFile.open())
-            return predefinedMacros;
-        tmpFilePath = QFileInfo(tmpFile).canonicalFilePath();
-        tmpFile.write(msvcCompilationFile());
-        tmpFile.close();
-    }
-    QProcess cpp;
-    cpp.setEnvironment(env);
-    cpp.setWorkingDirectory(QDir::tempPath());
-    QStringList arguments;
-    const QString binary = QLatin1String("cl.exe");
-    arguments << QLatin1String("/EP") << QDir::toNativeSeparators(tmpFilePath);
-    cpp.start(QLatin1String("cl.exe"), arguments);
-    if (!cpp.waitForStarted()) {
-        qWarning("%s: Cannot start '%s': %s", Q_FUNC_INFO, qPrintable(binary),
-            qPrintable(cpp.errorString()));
-        return predefinedMacros;
-    }
-    cpp.closeWriteChannel();
-    if (!cpp.waitForFinished()) {
-        Utils::SynchronousProcess::stopProcess(cpp);
-        qWarning("%s: Timeout running '%s'.", Q_FUNC_INFO, qPrintable(binary));
-        return predefinedMacros;
-    }
-    if (cpp.exitStatus() != QProcess::NormalExit) {
-        qWarning("%s: '%s' crashed.", Q_FUNC_INFO, qPrintable(binary));
-        return predefinedMacros;
-    }
-
-    const QList<QByteArray> output = cpp.readAllStandardOutput().split('\n');
-    foreach (const QByteArray& line, output) {
-        if (line.startsWith('V')) {
-            QList<QByteArray> split = line.split('=');
-            const QByteArray key = split.at(0).mid(1);
-            QByteArray value = split.at(1);
-            if (!value.isEmpty()) {
-                value.chop(1); //remove '\n'
-            }
-            predefinedMacros += "#define ";
-            predefinedMacros += key;
-            predefinedMacros += ' ';
-            predefinedMacros += value;
-            predefinedMacros += '\n';
-        }
-    }
-    QFile::remove(tmpFilePath);
-    return predefinedMacros;
-}
+    if (this == &tc)
+        return true;
 
-QByteArray MSVCToolChain::predefinedMacros()
-{
-    if (m_predefinedMacros.isEmpty()) {
-        Utils::Environment env = Utils::Environment::systemEnvironment();
-        addToEnvironment(env);
-        m_predefinedMacros = msvcPredefinedMacros(env.toStringList());
-    }
-    return m_predefinedMacros;
+    return id() == tc.id();
 }
 
-QList<HeaderPath> MSVCToolChain::systemHeaderPaths()
+QVariantMap ToolChain::toMap() const
 {
-    //TODO fix this code
-    Utils::Environment env = Utils::Environment::systemEnvironment();
-    addToEnvironment(env);
-    QList<HeaderPath> headerPaths;
-    foreach(const QString &path, env.value("INCLUDE").split(QLatin1Char(';'))) {
-        headerPaths.append(HeaderPath(path, HeaderPath::GlobalHeaderPath));
-    }
-    return headerPaths;
-}
+    QVariantMap result;
+    if (isAutoDetected())
+        return result;
 
-MSVCToolChain::StringStringPairList MSVCToolChain::readEnvironmentSetting(const QString &varsBat,
-                                                                          const QStringList &args,
-                                                                          const Utils::Environment &env)
-{
-    const StringStringPairList rc = readEnvironmentSettingI(varsBat, args, env);
-    if (debug) {
-        qDebug() << "Running: " << varsBat << args;
-        if (debug > 1) {
-            qDebug() << "Incoming: " << env.toStringList();
-            foreach(const StringStringPair &e, rc)
-                qDebug() << e.first << e.second;
-        } else {
-            qDebug() << "Read: " << rc.size() << " variables.";
-        }
-    }
-    return rc;
-}
+    result.insert(QLatin1String(ID_KEY), id());
+    result.insert(QLatin1String(DISPLAY_NAME_KEY), displayName());
 
-// Windows: Expand the delayed evaluation references returned by the
-// SDK setup scripts: "PATH=!Path!;foo". Some values might expand
-// to empty and should not be added
-static inline QString winExpandDelayedEnvReferences(QString in, const Utils::Environment &env)
-{
-    const QChar exclamationMark = QLatin1Char('!');
-    for (int pos = 0; pos < in.size(); ) {
-        // Replace "!REF!" by its value in process environment
-        pos = in.indexOf(exclamationMark, pos);
-        if (pos == -1)
-            break;
-        const int nextPos = in.indexOf(exclamationMark, pos + 1);
-        if (nextPos == -1)
-            break;
-        const QString var = in.mid(pos + 1, nextPos - pos - 1);
-        const QString replacement = env.value(var.toUpper());
-        in.replace(pos, nextPos + 1 - pos, replacement);
-        pos += replacement.size();
-    }
-    return in;
+    return result;
 }
 
-MSVCToolChain::StringStringPairList MSVCToolChain::readEnvironmentSettingI(const QString &varsBat,
-                                                                           const QStringList &args,
-                                                                           const Utils::Environment &env)
+void ToolChain::setId(const QString &id)
 {
-    // Run the setup script and extract the variables
-    if (!QFileInfo(varsBat).exists())
-        return StringStringPairList();
-    const QString tempOutputFileName = QDir::tempPath() + QLatin1String("\\qtcreator-msvc-environment.txt");
-    QTemporaryFile tf(QDir::tempPath() + "\\XXXXXX.bat");
-    tf.setAutoRemove(true);
-    if (!tf.open())
-        return StringStringPairList();
-    const QString filename = tf.fileName();
-    QByteArray call = "call ";
-    call += Utils::QtcProcess::quoteArg(varsBat).toLocal8Bit();
-    if (!args.isEmpty()) {
-        call += ' ';
-        call += Utils::QtcProcess::joinArgs(args).toLocal8Bit();
-    }
-    call += "\r\n";
-    tf.write(call);
-    const QByteArray redirect = "set > " + Utils::QtcProcess::quoteArg(
-                QDir::toNativeSeparators(tempOutputFileName)).toLocal8Bit() + "\r\n";
-    tf.write(redirect);
-    tf.flush();
-    tf.waitForBytesWritten(30000);
-
-    QProcess run;
-    run.setEnvironment(env.toStringList());
-    const QString cmdPath = QString::fromLocal8Bit(qgetenv("COMSPEC"));
-    run.start(cmdPath, QStringList()<< QLatin1String("/c")<<QDir::toNativeSeparators(filename));
-    if (!run.waitForStarted()) {
-        qWarning("%s: Unable to run '%s': %s", Q_FUNC_INFO, qPrintable(varsBat),
-            qPrintable(run.errorString()));
-        return StringStringPairList();
-    }
-    if (!run.waitForFinished()) {
-        qWarning("%s: Timeout running '%s'", Q_FUNC_INFO, qPrintable(varsBat));
-        Utils::SynchronousProcess::stopProcess(run);
-        return StringStringPairList();
-    }
-    tf.close();
-
-    QFile varsFile(tempOutputFileName);
-    if (!varsFile.open(QIODevice::ReadOnly|QIODevice::Text))
-        return StringStringPairList();
-
-    QRegExp regexp(QLatin1String("(\\w*)=(.*)"));
-    StringStringPairList rc;
-    while (!varsFile.atEnd()) {
-        const QString line = QString::fromLocal8Bit(varsFile.readLine()).trimmed();
-        if (regexp.exactMatch(line)) {
-            const QString varName = regexp.cap(1);
-            const QString expandedValue = winExpandDelayedEnvReferences(regexp.cap(2), env);
-            if (!expandedValue.isEmpty())
-                rc.append(StringStringPair(varName, expandedValue));
-        }
-    }
-    varsFile.close();
-    varsFile.remove();
-    return rc;
+    Q_ASSERT(!id.isEmpty());
+    m_d->m_id = id;
 }
 
-void MSVCToolChain::addToEnvironment(Utils::Environment &env)
+bool ToolChain::fromMap(const QVariantMap &data)
 {
-    if (debug)
-        qDebug() << "MSVCToolChain::addToEnvironment" << m_installation.name;
-    if (m_installation.name.isEmpty() || m_installation.varsBat.isEmpty()) {
-        qWarning("%s: Attempt to set up invalid MSVC Toolchain.", Q_FUNC_INFO);
-        return;
-    }
-    // We cache the full environment (incoming + modifications by setup script).
-    if (!m_valuesSet || env != m_lastEnvironment) {
-        m_lastEnvironment = env;
-        const QStringList args = m_installation.varsBatArg.isEmpty() ?
-                                 QStringList() :  QStringList(m_installation.varsBatArg);
-        m_values = readEnvironmentSetting(m_installation.varsBat, args, env);
-        m_valuesSet = true;
-    }
-
-    const StringStringPairList::const_iterator end = m_values.constEnd();
-    for (StringStringPairList::const_iterator it = m_values.constBegin(); it != end; ++it)
-        env.set((*it).first, (*it).second);
-}
+    Q_ASSERT(!isAutoDetected());
+    // do not read the id: That is already set anyway.
+    m_d->m_displayName = data.value(QLatin1String(DISPLAY_NAME_KEY)).toString();
 
-QString MSVCToolChain::makeCommand() const
-{
-    if (ProjectExplorerPlugin::instance()->projectExplorerSettings().useJom) {
-        // We want jom! Try to find it.
-        QString jom = QCoreApplication::applicationDirPath() + QLatin1String("/jom.exe");
-        if (QFileInfo(jom).exists())
-            return jom;
-        else
-            return QLatin1String("jom.exe");
-    }
-    return QLatin1String("nmake.exe");
+    return true;
 }
 
-IOutputParser *MSVCToolChain::outputParser() const
-{
-    return new MsvcParser;
-}
+// --------------------------------------------------------------------------
+// ToolChainFactory
+// --------------------------------------------------------------------------
 
-WinCEToolChain *WinCEToolChain::create(const QString &name, const QString &platform)
+QList<ToolChain *> ToolChainFactory::autoDetect()
 {
-    const bool excludeSDK = true;
-    return new WinCEToolChain(findInstallationByName(false, name, excludeSDK), platform);
+    return QList<ToolChain *>();
 }
 
-WinCEToolChain::WinCEToolChain(const Installation &in, const QString &platform) :
-        MSVCToolChain(in),
-        m_platform(platform)
+bool ToolChainFactory::canCreate()
 {
+    return false;
 }
 
-ToolChainType WinCEToolChain::type() const
+ToolChain *ToolChainFactory::create()
 {
-    return ToolChain_WINCE;
+    return 0;
 }
 
-bool WinCEToolChain::equals(const ToolChain *other) const
+bool ToolChainFactory::canRestore(const QVariantMap &)
 {
-    const WinCEToolChain *o = static_cast<const WinCEToolChain *>(other);
-    return (m_platform == o->m_platform && this->MSVCToolChain::equals(other));
+    return false;
 }
 
-QByteArray WinCEToolChain::predefinedMacros()
+ToolChain *ToolChainFactory::restore(const QVariantMap &)
 {
-    //TODO
-    return MSVCToolChain::predefinedMacros();
+    return 0;
 }
 
-QList<HeaderPath> WinCEToolChain::systemHeaderPaths()
+QString ToolChainFactory::idFromMap(const QVariantMap &data)
 {
-    //TODO fix this code
-    Utils::Environment env = Utils::Environment::systemEnvironment();
-    addToEnvironment(env);
-
-    QList<HeaderPath> headerPaths;
-
-    const QStringList includes = env.value("INCLUDE").split(QLatin1Char(';'));
-
-    foreach (const QString &path, includes) {
-        const HeaderPath headerPath(path, HeaderPath::GlobalHeaderPath);
-        headerPaths.append(headerPath);
-    }
-
-    return headerPaths;
+    return data.value(QLatin1String(ID_KEY)).toString();
 }
 
-void WinCEToolChain::addToEnvironment(Utils::Environment &env)
-{
-    MSVCToolChain::addToEnvironment(env);
-    QSettings registry(MSVC_RegKey, QSettings::NativeFormat);
-    QString path = registry.value(m_installation.name).toString();
-
-    // Find MSVC path
-
-    path += QLatin1Char('/');
-
-    // Find Platform name
-    CeSdkHandler cesdkhandler;
-    cesdkhandler.parse(path);
-    cesdkhandler.find(m_platform).addToEnvironment(env);
-}
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h
index 1c9b166962ebef544c63939778cd87282353b6a0..5a97e9a7b016342258ff9b58e3f96532f6f6a642 100644
--- a/src/plugins/projectexplorer/toolchain.h
+++ b/src/plugins/projectexplorer/toolchain.h
@@ -35,18 +35,32 @@
 #define TOOLCHAIN_H
 
 #include "projectexplorer_export.h"
-#include "toolchaintype.h"
 
-#include <utils/environment.h>
+#include "abi.h"
 
+#include <QtCore/QObject>
 #include <QtCore/QString>
 #include <QtCore/QPair>
 #include <QtCore/QMetaType>
+#include <QtCore/QVariantMap>
+
+namespace Utils {
+class Environment;
+}
 
 namespace ProjectExplorer {
 
+namespace Internal {
+class ToolChainPrivate;
+}
+
 class IOutputParser;
-class Project;
+class ToolChainConfigWidget;
+class ToolChainFactory;
+
+// --------------------------------------------------------------------------
+// HeaderPath
+// --------------------------------------------------------------------------
 
 class PROJECTEXPLORER_EXPORT HeaderPath
 {
@@ -58,191 +72,103 @@ public:
     };
 
     HeaderPath()
-        : _kind(GlobalHeaderPath)
+        : m_kind(GlobalHeaderPath)
     { }
 
     HeaderPath(const QString &path, Kind kind)
-        : _path(path), _kind(kind)
+        : m_path(path), m_kind(kind)
     { }
 
-    QString path() const { return _path; }
-    Kind    kind() const { return _kind; }
+    QString path() const { return m_path; }
+    Kind kind() const { return m_kind; }
 
 private:
-    QString _path;
-    Kind _kind;
+    QString m_path;
+    Kind m_kind;
 };
 
-
+// --------------------------------------------------------------------------
+// ToolChain
+// --------------------------------------------------------------------------
 
 class PROJECTEXPLORER_EXPORT ToolChain
 {
 public:
-    virtual QByteArray predefinedMacros() = 0;
-    virtual QList<HeaderPath> systemHeaderPaths() = 0;
-    virtual void addToEnvironment(Utils::Environment &env) = 0;
-    virtual ToolChainType type() const = 0;
-    virtual QString makeCommand() const = 0;
-    virtual IOutputParser *outputParser() const = 0;
-    virtual QString sysroot() const { return QString(); }
-
-    ToolChain();
     virtual ~ToolChain();
 
-    static bool equals(const ToolChain *, const ToolChain *);
-    // Factory methods
-    static ToolChain *createGccToolChain(const QString &gcc);
-    static ToolChain *createMinGWToolChain(const QString &gcc, const QString &mingwPath);
-    static ToolChain *createLinuxIccToolChain();
-    static ToolChain *createMSVCToolChain(const QString &name, bool amd64);
-    static ToolChain *createWinCEToolChain(const QString &name, const QString &platform);
-    static QStringList availableMSVCVersions();
-    static QStringList availableMSVCVersions(bool amd64); // filter 32/64bit apart
-    static QList<ToolChainType> supportedToolChains();
-
-    static QString toolChainName(ToolChainType tc);
+    QString displayName() const;
+    void setDisplayName(const QString &name) const;
 
-protected:
-    virtual bool equals(const ToolChain *other) const = 0;
-};
-
-class PROJECTEXPLORER_EXPORT GccToolChain : public ToolChain
-{
-public:
-    GccToolChain(const QString &gcc);
-    virtual QByteArray predefinedMacros();
-    virtual QList<HeaderPath> systemHeaderPaths();
-    virtual void addToEnvironment(Utils::Environment &env);
-    virtual ToolChainType type() const;
-    virtual QString makeCommand() const;
-    virtual IOutputParser *outputParser() const;
+    bool isAutoDetected() const;
+    QString id() const;
 
-protected:
-    virtual bool equals(const ToolChain *other) const;
-    QByteArray m_predefinedMacros;
-    QList<HeaderPath> m_systemHeaderPaths;
-    QString gcc() const { return m_gcc; }
+    virtual QString typeName() const = 0;
+    virtual Abi targetAbi() const = 0;
 
-private:
-    QString m_gcc;
-};
-
-// TODO this class needs to fleshed out more
-class PROJECTEXPLORER_EXPORT MinGWToolChain : public GccToolChain
-{
-public:
-    MinGWToolChain(const QString &gcc, const QString &mingwPath);
-    virtual void addToEnvironment(Utils::Environment &env);
-    virtual ToolChainType type() const;
-    virtual QString makeCommand() const;
-    virtual IOutputParser *outputParser() const;
+    virtual bool isValid() const = 0;
 
-protected:
-    virtual bool equals(const ToolChain *other) const;
+    /// Returns a list of target ids that this ToolChain is restricted to.
+    /// An empty list is shows that the toolchain is compatible with all targets.
+    virtual QStringList restrictedToTargets() const;
 
-private:
-    QString m_mingwPath;
-};
+    virtual QByteArray predefinedMacros() const = 0;
+    virtual QList<HeaderPath> systemHeaderPaths() const = 0;
+    virtual void addToEnvironment(Utils::Environment &env) const = 0;
+    virtual QString makeCommand() const = 0;
+    virtual QString defaultMakeTarget() const;
+    virtual IOutputParser *outputParser() const = 0;
 
-class PROJECTEXPLORER_EXPORT LinuxIccToolChain : public GccToolChain
-{
-public:
-    LinuxIccToolChain();
-    virtual ToolChainType type() const;
+    virtual bool operator ==(const ToolChain &) const;
 
-    virtual IOutputParser *outputParser() const;
-};
+    virtual ToolChainConfigWidget *configurationWidget() = 0;
+    virtual bool canClone() const;
+    virtual ToolChain *clone() const = 0;
 
-// TODO some stuff needs to be moved into this
-class PROJECTEXPLORER_EXPORT MSVCToolChain : public ToolChain
-{
-    Q_DISABLE_COPY(MSVCToolChain)
-public:
-    // A MSVC installation (SDK or VS) with name and setup script with args
-    struct Installation {
-        enum Type { WindowsSDK, VS };
-        enum Platform { s32, s64, ia64, amd64 };
-
-        explicit Installation(Type t, const QString &name, Platform p,
-                              const QString &varsBat,
-                              const QString &varBatArg = QString());
-        Installation();
-        static QString platformName(Platform t);
-        bool is64bit() const;
-
-        Type type;
-        QString name;
-        Platform platform;
-        QString varsBat;    // Script to setup environment
-        QString varsBatArg; // Argument
-    };
-    // Find all installations
-    typedef QList<Installation> InstallationList;
-    static InstallationList installations();
-    // Return matching installation or empty one
-    static Installation findInstallationByName(bool is64Bit,
-                                               const QString &name = QString(),
-                                               bool excludeSDK = false);
-    static Installation findInstallationByMkSpec(bool is64Bit,
-                                                 const QString &mkSpec,
-                                                 bool excludeSDK = false);
-
-    static MSVCToolChain *create(const QString &name,
-                                 bool amd64 = false);
-    virtual QByteArray predefinedMacros();
-    virtual QList<HeaderPath> systemHeaderPaths();
-    virtual void addToEnvironment(Utils::Environment &env);
-    virtual ToolChainType type() const;
-    virtual QString makeCommand() const;
-    virtual IOutputParser *outputParser() const;
+    // Used by the toolchainmanager to save user-generated ToolChains.
+    // Make sure to call this method when deriving!
+    virtual QVariantMap toMap() const;
 
 protected:
-    explicit MSVCToolChain(const Installation &in);
-
-    typedef QPair<QString, QString> StringStringPair;
-    typedef QList<StringStringPair> StringStringPairList;
+    ToolChain(const QString &id, bool autoDetect);
+    explicit ToolChain(const ToolChain &);
 
-    virtual bool equals(const ToolChain *other) const;
-    static StringStringPairList readEnvironmentSetting(const QString &varsBat,
-                                                       const QStringList &args,
-                                                       const Utils::Environment &env);
+    void setId(const QString &id);
 
-    QByteArray m_predefinedMacros;
-    const Installation m_installation;
+    // Make sure to call this method when deriving!
+    virtual bool fromMap(const QVariantMap &data);
 
 private:
-    static StringStringPairList readEnvironmentSettingI(const QString &varsBat,
-                                                        const QStringList &args,
-                                                        const Utils::Environment &env);
+    Internal::ToolChainPrivate *const m_d;
 
-    mutable StringStringPairList m_values;
-    mutable bool m_valuesSet;
-    mutable Utils::Environment m_lastEnvironment;
+    friend class ToolChainFactory;
 };
 
-PROJECTEXPLORER_EXPORT QDebug operator<<(QDebug in, const MSVCToolChain::Installation &i);
+// --------------------------------------------------------------------------
+// ToolChainFactory
+// --------------------------------------------------------------------------
 
-// TODO some stuff needs to be moved into here
-class PROJECTEXPLORER_EXPORT WinCEToolChain : public MSVCToolChain
+class PROJECTEXPLORER_EXPORT ToolChainFactory : public QObject
 {
+    Q_OBJECT
+
 public:
-    static WinCEToolChain *create(const QString &name, const QString &platform);
+    // Name used to display the name of the toolchain that will be created.
+    virtual QString displayName() const = 0;
+    virtual QString id() const = 0;
 
-    virtual QByteArray predefinedMacros();
-    virtual QList<HeaderPath> systemHeaderPaths();
-    virtual void addToEnvironment(Utils::Environment &env);
-    virtual ToolChainType type() const;
+    virtual QList<ToolChain *> autoDetect();
 
-protected:
-    explicit WinCEToolChain(const Installation &in, const QString &platform);
-    virtual bool equals(const ToolChain *other) const;
+    virtual bool canCreate();
+    virtual ToolChain *create();
 
-private:
-    const QString m_platform;
-};
+    // Used by the ToolChainManager to restore user-generated ToolChains
+    virtual bool canRestore(const QVariantMap &data);
+    virtual ToolChain *restore(const QVariantMap &data);
 
-}
+protected:
+    static QString idFromMap(const QVariantMap &data);
+};
 
-Q_DECLARE_METATYPE(ProjectExplorer::ToolChainType)
+} // namespace ProjectExplorer
 
 #endif // TOOLCHAIN_H
diff --git a/src/plugins/projectexplorer/toolchainconfigwidget.cpp b/src/plugins/projectexplorer/toolchainconfigwidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3bb62406559c2d20ba6c2be20b061aa7be3d2dcb
--- /dev/null
+++ b/src/plugins/projectexplorer/toolchainconfigwidget.cpp
@@ -0,0 +1,77 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "toolchainconfigwidget.h"
+
+#include "toolchain.h"
+
+namespace ProjectExplorer {
+namespace Internal {
+
+// --------------------------------------------------------------------------
+// ToolChainConfigWidgetPrivate
+// --------------------------------------------------------------------------
+
+class ToolChainConfigWidgetPrivate
+{
+public:
+    ToolChainConfigWidgetPrivate(ToolChain *tc) :
+        m_toolChain(tc)
+    {
+        Q_ASSERT(tc);
+    }
+
+    ToolChain *m_toolChain;
+};
+
+} // namespace Internal
+
+// --------------------------------------------------------------------------
+// ToolChainConfigWidget
+// --------------------------------------------------------------------------
+
+ToolChainConfigWidget::ToolChainConfigWidget(ToolChain *tc) :
+    m_d(new Internal::ToolChainConfigWidgetPrivate(tc))
+{ }
+
+void ToolChainConfigWidget::setDisplayName(const QString &name)
+{
+    m_d->m_toolChain->setDisplayName(name);
+}
+
+ToolChain *ToolChainConfigWidget::toolChain() const
+{
+    return m_d->m_toolChain;
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/toolchaintype.h b/src/plugins/projectexplorer/toolchainconfigwidget.h
similarity index 61%
rename from src/plugins/projectexplorer/toolchaintype.h
rename to src/plugins/projectexplorer/toolchainconfigwidget.h
index 353c4d0e8a2d50bc2a5e34dc3684d9dc7f838cdf..8f7a7238e4eb184f3835027ffafbe42576e3b021 100644
--- a/src/plugins/projectexplorer/toolchaintype.h
+++ b/src/plugins/projectexplorer/toolchainconfigwidget.h
@@ -31,35 +31,47 @@
 **
 **************************************************************************/
 
-#ifndef TOOLCHAINTYPE_H
-#define TOOLCHAINTYPE_H
+#ifndef TOOLCHAINCONFIGWIDGET_H
+#define TOOLCHAINCONFIGWIDGET_H
+
+#include "projectexplorer_export.h"
+
+#include <QtGui/QWidget>
 
 namespace ProjectExplorer {
 
-enum ToolChainType
+namespace Internal {
+class ToolChainConfigWidgetPrivate;
+} // namespace Internal
+
+class ToolChain;
+
+// --------------------------------------------------------------------------
+// ToolChainConfigWidget
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT ToolChainConfigWidget : public QWidget
 {
-    ToolChain_GCC = 0,
-    ToolChain_LINUX_ICC = 1,
-    ToolChain_MinGW = 2,
-    ToolChain_MSVC = 3,
-    ToolChain_WINCE = 4,
-    ToolChain_WINSCW = 5,
-    ToolChain_GCCE = 6,
-    ToolChain_RVCT2_ARMV5 = 7,
-    ToolChain_RVCT2_ARMV6 = 8,
-    ToolChain_GCC_MAEMO5 = 9,
-    ToolChain_GCCE_GNUPOC = 10,
-    ToolChain_RVCT_ARMV5_GNUPOC = 11,
-    ToolChain_RVCT4_ARMV5 = 12,
-    ToolChain_RVCT4_ARMV6 = 13,
-    ToolChain_GCC_HARMATTAN = 14,
-    ToolChain_GCC_MEEGO = 15,
-    ToolChain_LAST_VALID = 15,
-    ToolChain_OTHER = 200,
-    ToolChain_UNKNOWN = 201,
-    ToolChain_INVALID = 202
+    Q_OBJECT
+
+public:
+    ToolChainConfigWidget(ProjectExplorer::ToolChain *);
+
+    void setDisplayName(const QString &);
+    virtual void apply() = 0;
+    virtual void discard() = 0;
+
+    ProjectExplorer::ToolChain *toolChain() const;
+
+    virtual bool isDirty() const = 0;
+
+signals:
+    void dirty(ProjectExplorer::ToolChain *);
+
+private:
+    Internal::ToolChainConfigWidgetPrivate *m_d;
 };
 
 } // namespace ProjectExplorer
 
-#endif // TOOLCHAINTYPE_H
+#endif // TOOLCHAINCONFIGWIDGET_H
diff --git a/src/plugins/projectexplorer/toolchainmanager.cpp b/src/plugins/projectexplorer/toolchainmanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7e091ed3daa5fd7c6bcc96c32a453f71a8a2eff9
--- /dev/null
+++ b/src/plugins/projectexplorer/toolchainmanager.cpp
@@ -0,0 +1,191 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "toolchainmanager.h"
+
+#include "toolchain.h"
+
+#include <extensionsystem/pluginmanager.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QSettings>
+
+
+static const char *const ORGANIZATION_NAME = "Nokia";
+static const char *const APPLICATION_NAME = "toolChains";
+static const char *const ARRAY_NAME = "ToolChain";
+static const char *const TOOLCHAIN_DATA_KEY = "Data";
+
+namespace ProjectExplorer {
+
+ToolChainManager *ToolChainManager::m_instance = 0;
+
+namespace Internal {
+
+// --------------------------------------------------------------------------
+// ToolChainManagerPrivate
+// --------------------------------------------------------------------------
+
+class ToolChainManagerPrivate
+{
+public:
+    QList<ToolChain *> m_toolChains;
+};
+
+} // namespace Internal
+
+// --------------------------------------------------------------------------
+// ToolChainManager
+// --------------------------------------------------------------------------
+
+ToolChainManager *ToolChainManager::instance()
+{
+    Q_ASSERT(m_instance);
+    return m_instance;
+}
+
+ToolChainManager::ToolChainManager(QObject *parent) :
+    QObject(parent),
+    m_d(new Internal::ToolChainManagerPrivate)
+{
+    Q_ASSERT(!m_instance);
+    m_instance = this;
+}
+
+void ToolChainManager::restoreToolChains()
+{
+    QList<ToolChainFactory *> factories =
+            ExtensionSystem::PluginManager::instance()->getObjects<ToolChainFactory>();
+    // Autodetect ToolChains:
+    foreach (ToolChainFactory *f, factories) {
+        QList<ToolChain *> tcs = f->autoDetect();
+        foreach (ToolChain *tc, tcs)
+            registerToolChain(tc);
+    }
+
+    // Restore user generated ToolChains:
+    QSettings settings(QSettings::IniFormat, QSettings::UserScope,
+                       ORGANIZATION_NAME, APPLICATION_NAME);
+    int size = settings.beginReadArray(QLatin1String(ARRAY_NAME));
+    if (size <= 0)
+        return;
+
+    for (int i = 0; i < size; ++i) {
+        settings.setArrayIndex(i);
+        QVariantMap tmp = settings.value(QLatin1String(TOOLCHAIN_DATA_KEY)).toMap();
+        foreach (ToolChainFactory *f, factories) {
+            if (!f->canRestore(tmp))
+                continue;
+            ToolChain *tc = f->restore(tmp);
+            if (!tc)
+                continue;
+            registerToolChain(tc);
+        }
+    }
+}
+
+ToolChainManager::~ToolChainManager()
+{
+    QSettings settings(QSettings::IniFormat, QSettings::UserScope,
+                       ORGANIZATION_NAME, APPLICATION_NAME);
+    settings.beginWriteArray(QLatin1String(ARRAY_NAME));
+    int count = 0;
+    foreach (ToolChain *tc, m_d->m_toolChains) {
+        if (!tc->isAutoDetected() && tc->isValid()) {
+            settings.setArrayIndex(count);
+            ++count;
+
+            QVariantMap tmp = tc->toMap();
+            if (tmp.isEmpty())
+                continue;
+            settings.setValue(QLatin1String(TOOLCHAIN_DATA_KEY), tmp);
+        }
+    }
+    settings.endArray();
+
+    QList<ToolChain *> copy = m_d->m_toolChains;
+    foreach (ToolChain *tc, copy)
+        deregisterToolChain(tc);
+
+    delete m_d;
+    m_instance = 0;
+}
+
+QList<ToolChain *> ToolChainManager::toolChains() const
+{
+    return m_d->m_toolChains;
+}
+
+QList<ToolChain *> ToolChainManager::findToolChains(const Abi &abi) const
+{
+    QList<ToolChain *> result;
+    foreach (ToolChain *tc, m_d->m_toolChains) {
+        Abi targetAbi = tc->targetAbi();
+        if (targetAbi.isCompatibleWith(abi))
+            result.append(tc);
+    }
+    return result;
+}
+
+ToolChain *ToolChainManager::findToolChain(const QString &id) const
+{
+    foreach (ToolChain *tc, m_d->m_toolChains) {
+        if (tc->id() == id)
+            return tc;
+    }
+    return 0;
+}
+
+void ToolChainManager::registerToolChain(ToolChain *tc)
+{
+    if (!tc || m_d->m_toolChains.contains(tc))
+        return;
+    foreach (ToolChain *current, m_d->m_toolChains) {
+        if (*tc == *current)
+            return;
+    }
+
+    m_d->m_toolChains.append(tc);
+    emit toolChainAdded(tc);
+}
+
+void ToolChainManager::deregisterToolChain(ToolChain *tc)
+{
+    if (!tc || !m_d->m_toolChains.contains(tc))
+        return;
+    m_d->m_toolChains.removeOne(tc);
+    emit toolChainRemoved(tc);
+    delete tc;
+}
+
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/toolchainmanager.h b/src/plugins/projectexplorer/toolchainmanager.h
new file mode 100644
index 0000000000000000000000000000000000000000..c8ed7405495874a2b8e4cb317311d1c3c2d6674c
--- /dev/null
+++ b/src/plugins/projectexplorer/toolchainmanager.h
@@ -0,0 +1,96 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef TOOLCHAINMANAGER_H
+#define TOOLCHAINMANAGER_H
+
+#include "projectexplorer_export.h"
+
+#include "abi.h"
+#include "toolchain.h"
+
+#include <QtCore/QList>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+
+namespace ProjectExplorer {
+class ProjectExplorerPlugin;
+class ToolChain;
+class ToolChainFactory;
+
+namespace Internal {
+class ToolChainManagerPrivate;
+}
+
+// --------------------------------------------------------------------------
+// ToolChainManager
+// --------------------------------------------------------------------------
+
+class PROJECTEXPLORER_EXPORT ToolChainManager : public QObject
+{
+    Q_OBJECT
+
+public:
+    static ToolChainManager *instance();
+    ~ToolChainManager();
+
+    QList<ToolChain *> toolChains() const;
+    QList<ToolChain *> findToolChains(const Abi &abi) const;
+    ToolChain *findToolChain(const QString &id) const;
+
+public slots:
+    void registerToolChain(ProjectExplorer::ToolChain *tc);
+    void deregisterToolChain(ProjectExplorer::ToolChain *tc);
+
+signals:
+    void toolChainAdded(ProjectExplorer::ToolChain *);
+    // ToolChain is still valid when this call happens!
+    void toolChainRemoved(ProjectExplorer::ToolChain *);
+
+private:
+    explicit ToolChainManager(QObject *parent = 0);
+
+    // Make sure the ToolChain Manager is only created after all
+    // ToolChain Factories are registered!
+    void restoreToolChains();
+
+    Internal::ToolChainManagerPrivate *const m_d;
+
+    static ToolChainManager *m_instance;
+
+    friend class ProjectExplorerPlugin;
+};
+
+} // namespace ProjectExplorer
+
+#endif // TOOLCHAINMANAGER_H
diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e3665c39d1161e12f6299e02b75c82654bf6fc30
--- /dev/null
+++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp
@@ -0,0 +1,608 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "toolchainoptionspage.h"
+
+#include "projectexplorerconstants.h"
+#include "toolchainconfigwidget.h"
+#include "toolchainmanager.h"
+
+#include <coreplugin/icore.h>
+#include <extensionsystem/pluginmanager.h>
+
+#include <QtCore/QSignalMapper>
+#include <QtCore/QTextStream>
+#include <QtGui/QAction>
+#include <QtGui/QItemSelectionModel>
+#include <QtGui/QLabel>
+#include <QtGui/QMenu>
+#include <QtGui/QMessageBox>
+
+namespace ProjectExplorer {
+namespace Internal {
+
+class ToolChainNode
+{
+public:
+    explicit ToolChainNode(ToolChainNode *p, ToolChain *tc = 0, bool c = false) :
+        parent(p), toolChain(tc), changed(c)
+    {
+        if (p)
+            p->childNodes.append(this);
+        widget = tc ? tc->configurationWidget() : 0;
+        if (widget) {
+            widget->setEnabled(tc ? !tc->isAutoDetected() : false);
+            widget->setVisible(false);
+        }
+    }
+
+    ~ToolChainNode()
+    {
+        qDeleteAll(childNodes);
+        // Do not delete toolchain, we do not own it.
+        delete widget;
+    }
+
+    ToolChainNode *parent;
+    QString newName;
+    QList<ToolChainNode *> childNodes;
+    ToolChain *toolChain;
+    ToolChainConfigWidget *widget;
+    bool changed;
+};
+
+// --------------------------------------------------------------------------
+// ToolChainModel
+// --------------------------------------------------------------------------
+
+ToolChainModel::ToolChainModel(QObject *parent) :
+    QAbstractItemModel(parent)
+{
+    connect(ToolChainManager::instance(), SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)),
+            this, SLOT(addToolChain(ProjectExplorer::ToolChain*)));
+    connect(ToolChainManager::instance(), SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
+            this, SLOT(removeToolChain(ProjectExplorer::ToolChain*)));
+
+    m_autoRoot = new ToolChainNode(0);
+    m_manualRoot = new ToolChainNode(0);
+
+    foreach (ToolChain *tc, ToolChainManager::instance()->toolChains()) {
+        if (tc->isAutoDetected())
+            new ToolChainNode(m_autoRoot, tc);
+        else {
+            ToolChainNode *node = new ToolChainNode(m_manualRoot, tc);
+            if (node->widget)
+                connect(node->widget, SIGNAL(dirty(ProjectExplorer::ToolChain*)),
+                        this, SLOT(setDirty(ProjectExplorer::ToolChain*)));
+        }
+    }
+}
+
+ToolChainModel::~ToolChainModel()
+{
+    delete m_autoRoot;
+    delete m_manualRoot;
+}
+
+QModelIndex ToolChainModel::index(int row, int column, const QModelIndex &parent) const
+{
+    if (!parent.isValid()) {
+        if (row == 0)
+            return createIndex(0, 0, static_cast<void *>(m_autoRoot));
+        else
+            return createIndex(1, 0, static_cast<void *>(m_manualRoot));
+    }
+    ToolChainNode *node = static_cast<ToolChainNode *>(parent.internalPointer());
+    if (row < node->childNodes.count() && column < 2)
+        return createIndex(row, column, static_cast<void *>(node->childNodes.at(row)));
+    else
+        return QModelIndex();
+}
+
+QModelIndex ToolChainModel::parent(const QModelIndex &idx) const
+{
+    ToolChainNode *node = static_cast<ToolChainNode *>(idx.internalPointer());
+    if (node->parent == 0)
+        return QModelIndex();
+    return index(node->parent);
+}
+
+int ToolChainModel::rowCount(const QModelIndex &parent) const
+{
+    if (!parent.isValid())
+        return 2;
+    ToolChainNode *node = static_cast<ToolChainNode *>(parent.internalPointer());
+    return node->childNodes.count();
+}
+
+int ToolChainModel::columnCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent);
+    return 2;
+}
+
+QVariant ToolChainModel::data(const QModelIndex &index, int role) const
+{
+    if (!index.isValid())
+        return QVariant();
+
+    ToolChainNode *node = static_cast<ToolChainNode *>(index.internalPointer());
+    Q_ASSERT(node);
+    if (node == m_autoRoot && index.column() == 0 && role == Qt::DisplayRole)
+        return tr("Auto-detected");
+    if (node == m_manualRoot && index.column() == 0 && role == Qt::DisplayRole)
+        return tr("Manual");
+    if (node->toolChain) {
+        if (role == Qt::FontRole) {
+            QFont f = QApplication::font();
+            if (node->changed) {
+                f.setBold(true);
+            }
+            return f;
+        }
+        if (role == Qt::DisplayRole || role == Qt::EditRole) {
+            if (index.column() == 0) {
+                return node->newName.isEmpty() ?
+                    node->toolChain->displayName() : node->newName;
+            }
+            return node->toolChain->typeName();
+        }
+        if (role == Qt::ToolTipRole) {
+            return tr("<nobr><b>ABI:</b> %1")
+                    .arg(node->changed ? tr("not up-to-date") : node->toolChain->targetAbi().toString());
+        }
+    }
+    return QVariant();
+}
+
+bool ToolChainModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+    if (!index.isValid())
+        return false;
+
+    ToolChainNode *node = static_cast<ToolChainNode *>(index.internalPointer());
+    Q_ASSERT(node);
+    if (index.column() != 0 || !node->toolChain || role != Qt::EditRole)
+        return false;
+    node->newName = value.toString();
+    if (!node->newName.isEmpty() && node->newName != node->toolChain->displayName())
+        node->changed = true;
+    return true;
+}
+
+Qt::ItemFlags ToolChainModel::flags(const QModelIndex &index) const
+{
+    if (!index.isValid())
+        return 0;
+
+    ToolChainNode *node = static_cast<ToolChainNode *>(index.internalPointer());
+    Q_ASSERT(node);
+    if (!node->toolChain)
+        return Qt::ItemIsEnabled;
+
+    if (node->toolChain->isAutoDetected())
+        return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+    else if (index.column() == 0)
+        return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
+    else
+        return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
+QVariant ToolChainModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
+        return section == 0 ? tr("Name") : tr("Type");
+    return QVariant();
+}
+
+ToolChain *ToolChainModel::toolChain(const QModelIndex &index)
+{
+    if (!index.isValid())
+        return 0;
+    ToolChainNode *node = static_cast<ToolChainNode *>(index.internalPointer());
+    Q_ASSERT(node);
+    return node->toolChain;
+}
+
+int ToolChainModel::manualToolChains() const
+{
+    return m_manualRoot->childNodes.count();
+}
+
+ToolChainConfigWidget *ToolChainModel::widget(const QModelIndex &index)
+{
+    if (!index.isValid())
+        return 0;
+    ToolChainNode *node = static_cast<ToolChainNode *>(index.internalPointer());
+    Q_ASSERT(node);
+    return node->widget;
+}
+
+bool ToolChainModel::isDirty() const
+{
+    foreach (ToolChainNode *n, m_manualRoot->childNodes) {
+        if (n->changed)
+            return true;
+    }
+    return false;
+}
+
+bool ToolChainModel::isDirty(ToolChain *tc) const
+{
+    foreach (ToolChainNode *n, m_manualRoot->childNodes) {
+        if (n->toolChain == tc && n->changed)
+            return true;
+    }
+    return false;
+}
+
+void ToolChainModel::setDirty(ToolChain *tc)
+{
+    foreach (ToolChainNode *n, m_manualRoot->childNodes) {
+        if (n->toolChain == tc) {
+            n->changed = true;
+            emit dataChanged(index(n, 0), index(n, columnCount(QModelIndex())));
+        }
+    }
+}
+
+void ToolChainModel::apply()
+{
+    // Remove unused ToolChains:
+    QList<ToolChainNode *> nodes = m_toRemoveList;
+    foreach (ToolChainNode *n, nodes) {
+        ToolChainManager::instance()->deregisterToolChain(n->toolChain);
+    }
+    Q_ASSERT(m_toRemoveList.isEmpty());
+
+    // Update toolchains:
+    foreach (ToolChainNode *n, m_manualRoot->childNodes) {
+        Q_ASSERT(n);
+        if (n->changed) {
+            Q_ASSERT(n->toolChain);
+            if (!n->newName.isEmpty())
+                n->toolChain->setDisplayName(n->newName);
+            if (n->widget)
+                n->widget->apply();
+            n->changed = false;
+
+            emit dataChanged(index(n, 0), index(n, columnCount(QModelIndex())));
+        }
+    }
+
+    // Add new (and already updated) toolchains
+    nodes = m_toAddList;
+    foreach (ToolChainNode *n, nodes) {
+        ToolChainManager::instance()->registerToolChain(n->toolChain);
+    }
+    Q_ASSERT(m_toAddList.isEmpty());
+}
+
+void ToolChainModel::discard()
+{
+    // Remove newly "added" toolchains:
+    foreach (ToolChainNode *n, m_toAddList) {
+        int pos = m_manualRoot->childNodes.indexOf(n);
+        Q_ASSERT(pos >= 0);
+        m_manualRoot->childNodes.removeAt(pos);
+
+        // Clean up Node: We still own the toolchain!
+        delete n->toolChain;
+        n->toolChain = 0;
+    }
+    qDeleteAll(m_toAddList);
+    m_toAddList.clear();
+
+    // Add "removed" toolchains again:
+    foreach (ToolChainNode *n, m_toRemoveList) {
+        m_manualRoot->childNodes.append(n);
+    }
+    m_toRemoveList.clear();
+
+    // Reset toolchains:
+    foreach (ToolChainNode *n, m_manualRoot->childNodes) {
+        Q_ASSERT(n);
+        n->newName.clear();
+        if (n->widget)
+            n->widget->discard();
+        n->changed = false;
+    }
+}
+
+void ToolChainModel::markForRemoval(ToolChain *tc)
+{
+    ToolChainNode *node = 0;
+    foreach (ToolChainNode *n, m_manualRoot->childNodes) {
+        if (n->toolChain == tc) {
+            node = n;
+            break;
+        }
+    }
+    if (node) {
+        m_toRemoveList.append(node);
+        emit beginRemoveRows(index(m_manualRoot), m_manualRoot->childNodes.indexOf(node), m_manualRoot->childNodes.indexOf(node));
+        m_manualRoot->childNodes.removeOne(node);
+        emit endRemoveRows();
+    }
+}
+
+void ToolChainModel::markForAddition(ToolChain *tc)
+{
+    int pos = m_manualRoot->childNodes.size();
+    emit beginInsertRows(index(m_manualRoot), pos, pos);
+
+    ToolChainNode *node = new ToolChainNode(m_manualRoot, tc);
+    node->changed = true;
+    m_toAddList.append(node);
+
+    emit endInsertRows();
+}
+
+QModelIndex ToolChainModel::index(ToolChainNode *node, int column) const
+{
+    if (!node->parent)
+        return index(node == m_autoRoot ? 0 : 1, column, QModelIndex());
+    else
+        return index(node->parent->childNodes.indexOf(node), column, index(node->parent));
+}
+
+void ToolChainModel::addToolChain(ToolChain *tc)
+{
+    QList<ToolChainNode *> nodes = m_toAddList;
+    foreach (ToolChainNode *n, nodes) {
+        if (n->toolChain == tc) {
+            m_toAddList.removeOne(n);
+            // do not delete n: Still used elsewhere!
+            return;
+        }
+    }
+
+    ToolChainNode *parent = m_manualRoot;
+    if (tc->isAutoDetected())
+        parent = m_autoRoot;
+    int row = parent->childNodes.count();
+
+    beginInsertRows(index(parent), row, row);
+    new ToolChainNode(parent, tc, true);
+    endInsertRows();
+
+    emit toolChainStateChanged();
+}
+
+void ToolChainModel::removeToolChain(ToolChain *tc)
+{
+    QList<ToolChainNode *> nodes = m_toRemoveList;
+    foreach (ToolChainNode *n, nodes) {
+        if (n->toolChain == tc) {
+            m_toRemoveList.removeOne(n);
+            delete n;
+            return;
+        }
+    }
+
+    ToolChainNode *parent = m_manualRoot;
+    if (tc->isAutoDetected())
+        parent = m_autoRoot;
+    int row = 0;
+    ToolChainNode *node = 0;
+    foreach (ToolChainNode *current, parent->childNodes) {
+        if (current->toolChain == tc) {
+            node = current;
+            break;
+        }
+        ++row;
+    }
+
+    beginRemoveRows(index(parent), row, row);
+    parent->childNodes.removeAt(row);
+    delete node;
+    endRemoveRows();
+
+    emit toolChainStateChanged();
+}
+
+// --------------------------------------------------------------------------
+// ToolChainOptionsPage
+// --------------------------------------------------------------------------
+
+ToolChainOptionsPage::ToolChainOptionsPage() :
+    m_ui(0), m_cloneAction(0), m_model(0), m_selectionModel(0), m_currentTcWidget(0)
+{ }
+
+QString ToolChainOptionsPage::id() const
+{
+    return QLatin1String(Constants::TOOLCHAIN_SETTINGS_PAGE_ID);
+}
+
+QString ToolChainOptionsPage::displayName() const
+{
+    return tr("Toolchains");
+}
+
+QString ToolChainOptionsPage::category() const
+{
+    return QLatin1String(Constants::TOOLCHAIN_SETTINGS_CATEGORY);
+}
+
+QString ToolChainOptionsPage::displayCategory() const
+{
+    return tr("Toolchains");
+}
+
+QIcon ToolChainOptionsPage::categoryIcon() const
+{
+    return QIcon(QLatin1String(Constants::ICON_TOOLCHAIN_SETTINGS_CATEGORY));
+}
+
+QWidget *ToolChainOptionsPage::createPage(QWidget *parent)
+{
+    // Actual page setup:
+    m_configWidget = new QWidget(parent);
+
+    m_currentTcWidget = 0;
+
+    m_ui = new Ui::ToolChainOptionsPage;
+    m_ui->setupUi(m_configWidget);
+
+    m_model = new ToolChainModel(m_ui->toolChainView);
+    connect(m_model, SIGNAL(toolChainStateChanged()), this, SLOT(updateState()));
+
+    m_ui->toolChainView->setModel(m_model);
+    m_ui->toolChainView->header()->setResizeMode(0, QHeaderView::ResizeToContents);
+    m_ui->toolChainView->header()->setResizeMode(1, QHeaderView::ResizeToContents);
+    m_ui->toolChainView->expandAll();
+
+    m_selectionModel = m_ui->toolChainView->selectionModel();
+    connect(m_selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+            this, SLOT(toolChainSelectionChanged(QModelIndex,QModelIndex)));
+
+    // Get toolchainfactories:
+    m_factories = ExtensionSystem::PluginManager::instance()->getObjects<ToolChainFactory>();
+
+    // Set up add menu:
+    QMenu *addMenu = new QMenu(m_ui->addButton);
+    QSignalMapper *mapper = new QSignalMapper(addMenu);
+    connect(mapper, SIGNAL(mapped(QObject*)), this, SLOT(createToolChain(QObject*)));
+
+    foreach (ToolChainFactory *factory, m_factories) {
+        if (factory->canCreate()) {
+            QAction *action = new QAction(addMenu);
+            action->setText(factory->displayName());
+            connect(action, SIGNAL(triggered()), mapper, SLOT(map()));
+            mapper->setMapping(action, static_cast<QObject *>(factory));
+
+            addMenu->addAction(action);
+        }
+    }
+    m_cloneAction = new QAction(addMenu);
+    m_cloneAction->setText(tr("Clone ..."));
+    connect(m_cloneAction, SIGNAL(triggered()), mapper, SLOT(map()));
+    mapper->setMapping(m_cloneAction, static_cast<QObject *>(0));
+
+    if (!addMenu->isEmpty())
+        addMenu->addSeparator();
+    addMenu->addAction(m_cloneAction);
+    m_ui->addButton->setMenu(addMenu);
+
+    connect(m_ui->delButton, SIGNAL(clicked()), this, SLOT(removeToolChain()));
+
+    // setup keywords:
+    if (m_searchKeywords.isEmpty()) {
+        QLatin1Char sep(' ');
+        QTextStream stream(&m_searchKeywords);
+        stream << tr("Toolchains");
+        foreach (ToolChainFactory *f, m_factories)
+            stream << sep << f->displayName();
+
+        m_searchKeywords.remove(QLatin1Char('&'));
+    }
+
+    return m_configWidget;
+}
+
+void ToolChainOptionsPage::apply()
+{
+    m_model->apply();
+}
+
+void ToolChainOptionsPage::finish()
+{
+    m_model->discard();
+}
+
+bool ToolChainOptionsPage::matches(const QString &s) const
+{
+    return m_searchKeywords.contains(s, Qt::CaseInsensitive);
+}
+
+void ToolChainOptionsPage::toolChainSelectionChanged(const QModelIndex &current,
+                                                     const QModelIndex &previous)
+{
+    Q_UNUSED(previous);
+    if (m_currentTcWidget) {
+        m_configWidget->layout()->removeWidget(m_currentTcWidget);
+        m_currentTcWidget->setVisible(false);
+    }
+
+    m_currentTcWidget = m_model->widget(current);
+
+    if (m_currentTcWidget) {
+        m_configWidget->layout()->addWidget(m_currentTcWidget);
+        m_currentTcWidget->setVisible(true);
+    }
+
+    updateState();
+}
+
+void ToolChainOptionsPage::createToolChain(QObject *factoryObject)
+{
+    ToolChain *tc = 0;
+
+    ToolChainFactory *factory = static_cast<ToolChainFactory *>(factoryObject);
+    if (!factory) {
+        // Copy current item!
+        ToolChain *oldTc = m_model->toolChain(m_selectionModel->currentIndex());
+        Q_ASSERT(oldTc);
+        tc = oldTc->clone();
+    } else {
+        Q_ASSERT(factory->canCreate());
+        tc = factory->create();
+    } if (!tc)
+        return;
+    m_model->markForAddition(tc);
+}
+
+void ToolChainOptionsPage::removeToolChain()
+{
+    ToolChain *tc = m_model->toolChain(m_selectionModel->currentIndex());
+    Q_ASSERT(tc && !tc->isAutoDetected());
+    m_model->markForRemoval(tc);
+}
+
+void ToolChainOptionsPage::updateState()
+{
+
+    bool canCopy = false;
+    bool canDelete = false;
+    ToolChain *tc = m_model->toolChain(m_selectionModel->currentIndex());
+    if (tc) {
+        canCopy = tc->isValid() && tc->canClone();
+        canDelete = !tc->isAutoDetected();
+    }
+
+    m_cloneAction->setEnabled(canCopy);
+    m_ui->delButton->setEnabled(canDelete);
+}
+
+} // namespace Internal
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/toolchainoptionspage.h b/src/plugins/projectexplorer/toolchainoptionspage.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad620addd7a64362f695b5e5e64f69ddc198d120
--- /dev/null
+++ b/src/plugins/projectexplorer/toolchainoptionspage.h
@@ -0,0 +1,155 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef TOOLCHAINOPTIONSPAGE_H
+#define TOOLCHAINOPTIONSPAGE_H
+
+#include "ui_toolchainoptionspage.h"
+
+#include <coreplugin/dialogs/ioptionspage.h>
+
+#include <QtCore/QAbstractItemModel>
+
+QT_BEGIN_NAMESPACE
+class QTreeWidgetItem;
+QT_END_NAMESPACE
+
+namespace ProjectExplorer {
+
+class ToolChain;
+class ToolChainConfigWidget;
+class ToolChainFactory;
+class ToolChainManager;
+
+namespace Internal {
+
+class ToolChainNode;
+// --------------------------------------------------------------------------
+// ToolChainModel
+// --------------------------------------------------------------------------
+
+class ToolChainModel : public QAbstractItemModel
+{
+    Q_OBJECT
+
+public:
+    explicit ToolChainModel(QObject *parent = 0);
+    ~ToolChainModel();
+
+    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+    QModelIndex parent(const QModelIndex &index) const;
+    int rowCount(const QModelIndex &parent = QModelIndex()) const;
+    int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+    Qt::ItemFlags flags(const QModelIndex &index) const;
+    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+
+    ToolChain *toolChain(const QModelIndex &);
+    int manualToolChains() const;
+
+    ToolChainConfigWidget *widget(const QModelIndex &);
+
+    bool isDirty() const;
+    bool isDirty(ToolChain *) const;
+
+    void apply();
+    void discard();
+
+    void markForRemoval(ToolChain *);
+    void markForAddition(ToolChain *);
+
+signals:
+    void toolChainStateChanged();
+
+private slots:
+    void addToolChain(ProjectExplorer::ToolChain *);
+    void removeToolChain(ProjectExplorer::ToolChain *);
+    void setDirty(ProjectExplorer::ToolChain *);
+
+private:
+    QModelIndex index(ToolChainNode *, int column = 0) const;
+
+    ToolChainNode * m_root;
+    ToolChainNode * m_autoRoot;
+    ToolChainNode * m_manualRoot;
+
+    QList<ToolChainNode *> m_toAddList;
+    QList<ToolChainNode *> m_toRemoveList;
+};
+
+// --------------------------------------------------------------------------
+// ToolChainOptionsPage
+// --------------------------------------------------------------------------
+
+class ToolChainOptionsPage : public Core::IOptionsPage
+{
+    Q_OBJECT
+
+public:
+    ToolChainOptionsPage();
+
+    virtual QString id() const;
+    virtual QString displayName() const;
+    virtual QString category() const;
+    virtual QString displayCategory() const;
+    virtual QIcon categoryIcon() const;
+
+    virtual QWidget *createPage(QWidget *parent);
+    virtual void apply();
+    virtual void finish();
+    virtual bool matches(const QString &) const;
+
+private slots:
+    void toolChainSelectionChanged(const QModelIndex &, const QModelIndex &);
+    void createToolChain(QObject *);
+    void removeToolChain();
+    void updateState();
+
+private:
+    Ui::ToolChainOptionsPage *m_ui;
+    QWidget *m_configWidget;
+    QString m_searchKeywords;
+    QAction *m_cloneAction;
+
+    ToolChainModel *m_model;
+    QList<ToolChainFactory *> m_factories;
+    QItemSelectionModel * m_selectionModel;
+    ToolChainConfigWidget *m_currentTcWidget;
+};
+
+} // namespace Internal
+} // namespace ProjectExplorer
+
+#endif // TOOLCHAINOPTIONSPAGE_H
diff --git a/src/plugins/projectexplorer/toolchainoptionspage.ui b/src/plugins/projectexplorer/toolchainoptionspage.ui
new file mode 100644
index 0000000000000000000000000000000000000000..3243954052ff5aecc262428992c807d21d583bb4
--- /dev/null
+++ b/src/plugins/projectexplorer/toolchainoptionspage.ui
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ToolChainOptionsPage</class>
+ <widget class="QWidget" name="ToolChainOptionsPage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>398</width>
+    <height>296</height>
+   </rect>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QTreeView" name="toolChainView">
+       <property name="uniformRowHeights">
+        <bool>true</bool>
+       </property>
+       <attribute name="headerStretchLastSection">
+        <bool>false</bool>
+       </attribute>
+      </widget>
+     </item>
+     <item>
+      <layout class="QVBoxLayout" name="_2">
+       <property name="spacing">
+        <number>6</number>
+       </property>
+       <property name="margin">
+        <number>0</number>
+       </property>
+       <item>
+        <widget class="QToolButton" name="addButton">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>21</width>
+           <height>23</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>+</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QToolButton" name="delButton">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize">
+          <size>
+           <width>21</width>
+           <height>23</height>
+          </size>
+         </property>
+         <property name="text">
+          <string>-</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer>
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>10</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/plugins/projectexplorer/userfileaccessor.cpp b/src/plugins/projectexplorer/userfileaccessor.cpp
index 26b927c849643f157a7ace195e4e60c2fd9e73cc..43fb4f789aefa954eae2d846ab87fd90875766da 100644
--- a/src/plugins/projectexplorer/userfileaccessor.cpp
+++ b/src/plugins/projectexplorer/userfileaccessor.cpp
@@ -40,7 +40,6 @@
 #include "projectexplorersettings.h"
 #include "projectexplorerconstants.h"
 #include "target.h"
-#include "toolchaintype.h"
 
 #include <coreplugin/icore.h>
 #include <coreplugin/ifile.h>
@@ -976,13 +975,13 @@ QVariantMap Version0Handler::update(Project *project, const QVariantMap &map)
         if (!ok) {
             QString toolChainName(toolchain.toString());
             if (toolChainName == QLatin1String("gcc"))
-                type = ProjectExplorer::ToolChain_GCC;
+                type = 0;
             else if (toolChainName == QLatin1String("mingw"))
-                type = ProjectExplorer::ToolChain_MinGW;
+                type = 2;
             else if (toolChainName == QLatin1String("msvc"))
-                type = ProjectExplorer::ToolChain_MSVC;
+                type = 3;
             else if (toolChainName == QLatin1String("wince"))
-                type = ProjectExplorer::ToolChain_WINCE;
+                type = 4;
         }
         result.insert(QLatin1String("GenericProjectManager.GenericProject.Toolchain"), type);
     }
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
index 06e95fe195ec15337a701dd67195ee31e5d97df3..8a2f4bc36c0e5878a6f72f0783500b084ac4e1ab 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp
@@ -287,6 +287,13 @@ Utils::Environment QmlProjectRunConfiguration::environment() const
     return env;
 }
 
+ProjectExplorer::Abi QmlProjectRunConfiguration::abi() const
+{
+    ProjectExplorer::Abi hostAbi = ProjectExplorer::Abi::hostAbi();
+    return ProjectExplorer::Abi(hostAbi.architecture(), hostAbi.os(), hostAbi.osFlavor(),
+                                ProjectExplorer::Abi::Format_Runtime_QML, hostAbi.wordWidth());
+}
+
 QVariantMap QmlProjectRunConfiguration::toMap() const
 {
     QVariantMap map(ProjectExplorer::RunConfiguration::toMap());
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
index 9ac9c0cce10773f8d28132c15f9472c71a1c641e..7e0af9f2988cbb0febf43ee5424d08ebeffb15c1 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h
@@ -103,6 +103,8 @@ public:
     ProjectExplorer::OutputFormatter *createOutputFormatter() const;
     QVariantMap toMap() const;
 
+    ProjectExplorer::Abi abi() const;
+
 public slots:
     void changeCurrentFile(Core::IEditor*);
 
diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationwidget.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationwidget.cpp
index cf843ab5edd32ba36cd721dffd4d3d76854dee1c..dfd66b64836d44a91d489c5865b167436c30d308 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationwidget.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfigurationwidget.cpp
@@ -41,6 +41,7 @@
 #include <projectexplorer/projectexplorer.h>
 #include <utils/debuggerlanguagechooser.h>
 #include <utils/detailswidget.h>
+#include <utils/environment.h>
 #include <utils/qtcassert.h>
 #include <qt4projectmanager/qt4projectmanagerconstants.h>
 #include <qt4projectmanager/qtversionmanager.h>
diff --git a/src/plugins/qt4projectmanager/debugginghelperbuildtask.cpp b/src/plugins/qt4projectmanager/debugginghelperbuildtask.cpp
index fcb99b6421c40236b0a9ad6ee2cc354819f4bf76..411e3210f86feddd763cfb48518020a27ae27b3b 100644
--- a/src/plugins/qt4projectmanager/debugginghelperbuildtask.cpp
+++ b/src/plugins/qt4projectmanager/debugginghelperbuildtask.cpp
@@ -35,6 +35,9 @@
 #include "qmldumptool.h"
 #include "qmlobservertool.h"
 #include "qmldebugginglibrary.h"
+#include "qt4projectmanager/qt4projectmanagerconstants.h"
+
+#include <projectexplorer/toolchainmanager.h>
 #include <projectexplorer/debugginghelper.h>
 
 #include <QtCore/QCoreApplication>
@@ -46,6 +49,8 @@ using ProjectExplorer::DebuggingHelperLibrary;
 
 DebuggingHelperBuildTask::DebuggingHelperBuildTask(QtVersion *version, Tools tools)
 {
+    if (!version || !version->isValid())
+        return;
     // allow type to be used in queued connections.
     qRegisterMetaType<DebuggingHelperBuildTask::Tools>("DebuggingHelperBuildTask::Tools");
 
@@ -68,29 +73,20 @@ DebuggingHelperBuildTask::DebuggingHelperBuildTask(QtVersion *version, Tools too
     version->addToEnvironment(m_environment);
 
     // TODO: the debugging helper doesn't comply to actual tool chain yet
-    ProjectExplorer::ToolChain *tc = 0;
-    foreach (ProjectExplorer::ToolChainType toolChainType, version->possibleToolChainTypes()) {
-        tc = version->toolChain(toolChainType);
-        if (tc)
-            break;
-    }
-
-    if (!tc) {
+    QList<ProjectExplorer::ToolChain *> tcList = ProjectExplorer::ToolChainManager::instance()->findToolChains(version->qtAbis().at(0));
+    if (tcList.isEmpty()) {
         m_errorMessage =
                 QCoreApplication::translate(
                     "QtVersion",
                     "The Qt Version has no toolchain.");
         return;
     }
-
+    ProjectExplorer::ToolChain *tc = tcList.at(0);
     tc->addToEnvironment(m_environment);
 
-    if (tc->type() == ProjectExplorer::ToolChain_GCC_MAEMO5
-            || tc->type() == ProjectExplorer::ToolChain_GCC_HARMATTAN
-            || tc->type() == ProjectExplorer::ToolChain_GCC_MEEGO) {
+    if (tc->targetAbi().os() == ProjectExplorer::Abi::Linux
+        && ProjectExplorer::Abi::hostAbi().os() == ProjectExplorer::Abi::Windows)
         m_target = QLatin1String("-unix");
-    }
-
     m_qmakeCommand = version->qmakeCommand();
     m_makeCommand = tc->makeCommand();
     m_mkspec = version->mkspec();
diff --git a/src/plugins/qt4projectmanager/librarydetailscontroller.cpp b/src/plugins/qt4projectmanager/librarydetailscontroller.cpp
index 23634d1785e0790cfaff9f8cac2644a5db73e6e3..8aafd1d5da1c0bcc379bc45221ef14a956cc688d 100644
--- a/src/plugins/qt4projectmanager/librarydetailscontroller.cpp
+++ b/src/plugins/qt4projectmanager/librarydetailscontroller.cpp
@@ -40,6 +40,7 @@
 #include <projectexplorer/projectexplorer.h>
 #include <projectexplorer/session.h>
 #include <projectexplorer/target.h>
+#include <projectexplorer/toolchain.h>
 #include <projectexplorer/buildconfiguration.h>
 
 #include <QtCore/QFileInfo>
@@ -86,8 +87,10 @@ LibraryDetailsController::LibraryDetailsController(
     Qt4BuildConfiguration *qt4BuildConfiguration =
             qobject_cast<Qt4BuildConfiguration *>(project->activeTarget()->activeBuildConfiguration());
     // if its toolchain is maemo behave the same as we would be on linux
-    if (qt4BuildConfiguration && (qt4BuildConfiguration->toolChainType() == ProjectExplorer::ToolChain_GCC_MAEMO5
-            || qt4BuildConfiguration->toolChainType() == ProjectExplorer::ToolChain_GCC_HARMATTAN))
+    if (qt4BuildConfiguration
+            && qt4BuildConfiguration->toolChain()
+            && (qt4BuildConfiguration->toolChain()->targetAbi().osFlavor() == ProjectExplorer::Abi::Linux_harmattan
+                || qt4BuildConfiguration->toolChain()->targetAbi().osFlavor() == ProjectExplorer::Abi::Linux_maemo))
         m_creatorPlatform = CreatorLinux;
 #endif
 
diff --git a/src/plugins/qt4projectmanager/makestep.cpp b/src/plugins/qt4projectmanager/makestep.cpp
index 6d5ca85112413000d9ed8a885ffd0f1cf344b80d..ddf478c8ead548a5250717574c49d935ade60793 100644
--- a/src/plugins/qt4projectmanager/makestep.cpp
+++ b/src/plugins/qt4projectmanager/makestep.cpp
@@ -173,13 +173,10 @@ bool MakeStep::init()
     // so we only do it for unix and if the user didn't override the make command
     // but for now this is the least invasive change
 
-    if (toolchain) {
-        if (toolchain->type() != ProjectExplorer::ToolChain_MSVC &&
-            toolchain->type() != ProjectExplorer::ToolChain_WINCE) {
-            if (m_makeCmd.isEmpty())
-                Utils::QtcProcess::addArg(&args, QLatin1String("-w"));
-        }
-    }
+    if (toolchain
+            && toolchain->targetAbi().binaryFormat() != ProjectExplorer::Abi::Format_PE
+            && m_makeCmd.isEmpty())
+        Utils::QtcProcess::addArg(&args, QLatin1String("-w"));
 
     setEnabled(true);
     pp->setArguments(args);
@@ -304,14 +301,11 @@ void MakeStepConfigWidget::updateDetails()
     // so we only do it for unix and if the user didn't override the make command
     // but for now this is the least invasive change
     QString args = m_makeStep->userArguments();
-    ProjectExplorer::ToolChainType t = ProjectExplorer::ToolChain_UNKNOWN;
     ProjectExplorer::ToolChain *toolChain = bc->toolChain();
-    if (toolChain)
-        t = toolChain->type();
-    if (t != ProjectExplorer::ToolChain_MSVC && t != ProjectExplorer::ToolChain_WINCE) {
-        if (m_makeStep->m_makeCmd.isEmpty())
-            Utils::QtcProcess::addArg(&args, QLatin1String("-w"));
-    }
+    if (toolChain
+        && toolChain->targetAbi().binaryFormat() != ProjectExplorer::Abi::Format_PE
+        && m_makeStep->m_makeCmd.isEmpty())
+        Utils::QtcProcess::addArg(&args, QLatin1String("-w"));
     param.setArguments(args);
     m_summaryText = param.summaryInWorkdir(displayName());
     emit updateSummary();
diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp
index e6afac81834d8aeb691537b84fb08bb73ee0fd10..bb8c94ebc781eca123b2beb0dbc1b9f8a93a3a17 100644
--- a/src/plugins/qt4projectmanager/qmakestep.cpp
+++ b/src/plugins/qt4projectmanager/qmakestep.cpp
@@ -33,7 +33,7 @@
 
 #include "qmakestep.h"
 
-#include "projectexplorer/projectexplorerconstants.h"
+#include <projectexplorer/projectexplorerconstants.h>
 #include <proparser/profileevaluator.h>
 #include "qmakeparser.h"
 #include "qt4buildconfiguration.h"
@@ -45,6 +45,7 @@
 #include "debugginghelperbuildtask.h"
 
 #include <projectexplorer/buildsteplist.h>
+#include <projectexplorer/toolchain.h>
 
 #include <coreplugin/icore.h>
 #include <coreplugin/progressmanager/progressmanager.h>
@@ -155,11 +156,10 @@ QStringList QMakeStep::moreArguments()
     Qt4BuildConfiguration *bc = qt4BuildConfiguration();
     QStringList arguments;
 #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
-    const ProjectExplorer::ToolChainType type = bc->toolChainType();
-    if (type == ProjectExplorer::ToolChain_GCC_MAEMO5
-            || type == ProjectExplorer::ToolChain_GCC_HARMATTAN) {
+    ProjectExplorer::ToolChain *tc = bc->toolChain();
+    if (tc && (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::Linux_harmattan
+               || tc->targetAbi().osFlavor() == ProjectExplorer::Abi::Linux_maemo))
         arguments << QLatin1String("-unix");
-    }
 #endif
     if (!bc->qtVersion()->supportsShadowBuilds()) {
         // We have a target which does not allow shadow building.
diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp
index 0c9f05d8926a20ac78818cf29391f7a154d7f793..b35db1ae31ed4e9ee8012c7d92b621936a4eef1b 100644
--- a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.cpp
@@ -52,6 +52,7 @@
 #include <projectexplorer/buildstep.h>
 #include <projectexplorer/environmentwidget.h>
 #include <projectexplorer/persistentsettings.h>
+#include <projectexplorer/toolchain.h>
 #include <utils/qtcassert.h>
 #include <utils/qtcprocess.h>
 #include <utils/pathchooser.h>
@@ -694,11 +695,6 @@ Qt4RunConfiguration::BaseEnvironmentBase Qt4RunConfiguration::baseEnvironmentBas
 {
     return m_baseEnvironmentBase;
 }
-ProjectExplorer::ToolChainType Qt4RunConfiguration::toolChainType() const
-{
-    Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
-    return qt4bc->toolChainType();
-}
 
 ProjectExplorer::OutputFormatter *Qt4RunConfiguration::createOutputFormatter() const
 {
diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h
index 1d4afd484169560a2c86c91e1ad3eda570a90cd0..8222f5fed3916d38b35c6982497d40e47ae1d28b 100644
--- a/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h
@@ -94,7 +94,6 @@ public:
     virtual Utils::Environment environment() const;
     virtual QString dumperLibrary() const;
     virtual QStringList dumperLibraryLocations() const;
-    virtual ProjectExplorer::ToolChainType toolChainType() const;
 
     bool isUsingDyldImageSuffix() const;
     void setUsingDyldImageSuffix(bool state);
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodebugsupport.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemodebugsupport.cpp
index 0a25f6792306a2d5a48ec37821e808c89159853c..d042add87f32906bd859cefe0610bb193c9e3a02 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemodebugsupport.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemodebugsupport.cpp
@@ -46,8 +46,7 @@
 #include <debugger/debuggerstartparameters.h>
 #include <debugger/debuggerrunner.h>
 #include <debugger/debuggerengine.h>
-#include <projectexplorer/toolchaintype.h>
-#include <qt4projectmanager/qt4buildconfiguration.h>
+#include <projectexplorer/toolchain.h>
 
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
@@ -75,8 +74,7 @@ RunControl *MaemoDebugSupport::createDebugRunControl(MaemoRunConfiguration *runC
     if (debuggingType != MaemoRunConfiguration::DebugQmlOnly) {
         params.processArgs = runConfig->arguments();
         params.sysRoot = runConfig->sysRoot();
-        params.toolChainType
-            = runConfig->activeQt4BuildConfiguration()->toolChainType();
+        params.toolChainAbi = runConfig->abi();
         params.dumperLibrary = runConfig->dumperLib();
         params.remoteDumperLib = uploadDir(devConf).toUtf8() + '/'
             + QFileInfo(runConfig->dumperLib()).fileName().toUtf8();
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp
index 2f02d58a37fd6b171a2d07d8ded9f66f91468520..424d624d21f4a3307631382b25c7615da3570ea8 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.cpp
@@ -839,9 +839,9 @@ QString MaemoDeployStep::deployMountPoint() const
         + QLatin1String("/deployMountPoint_") + packagingStep()->projectName();
 }
 
-const AbstractMaemoToolChain *MaemoDeployStep::toolChain() const
+const MaemoToolChain *MaemoDeployStep::toolChain() const
 {
-    return static_cast<AbstractMaemoToolChain *>(qt4BuildConfiguration()->toolChain());
+    return static_cast<MaemoToolChain *>(qt4BuildConfiguration()->toolChain());
 }
 
 const AbstractQt4MaemoTarget *MaemoDeployStep::maemotarget() const
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.h b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.h
index c0a111263443b6f27afc60b37a5b1bb5c4fe7e0d..0861cc2cfbac6b28ee83f15f37d32be78b31b7ca 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemodeploystep.h
@@ -66,7 +66,7 @@ namespace Internal {
 class MaemoRemoteMounter;
 class MaemoDeviceConfig;
 class MaemoPackageCreationStep;
-class AbstractMaemoToolChain;
+class MaemoToolChain;
 class MaemoUsedPortsGatherer;
 
 class MaemoDeployStep : public ProjectExplorer::BuildStep
@@ -145,7 +145,7 @@ private:
     void getDeployTimesFromMap(const QVariantMap &map);
     const MaemoPackageCreationStep *packagingStep() const;
     QString deployMountPoint() const;
-    const AbstractMaemoToolChain *toolChain() const;
+    const MaemoToolChain *toolChain() const;
     void copyNextFileToDevice();
     void installToSysroot();
     QString uploadDir() const;
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemoglobal.h b/src/plugins/qt4projectmanager/qt-maemo/maemoglobal.h
index 72afdc52d1bfd0a571769efaa5258075efd4235e..3fb2cac002e6cc7bec76d55ffea0b22a734b906f 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemoglobal.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemoglobal.h
@@ -91,6 +91,7 @@ public:
     static QString targetName(const QtVersion *qtVersion);
     static QString madCommand(const QtVersion *qtVersion);
     static MaemoVersion version(const QtVersion *qtVersion);
+    // TODO: IS this still needed with Qt Version having an Abi?
     static QString architecture(const QtVersion *version);
 
     static bool callMad(QProcess &proc, const QStringList &args,
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemomanager.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.cpp
index e8e16fd6865ae09e570da6e630a1b546f64719ed..0fbd115f19834d73d65771a0efc23f55b7afc692 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemomanager.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.cpp
@@ -36,6 +36,7 @@
 #include "maemoconstants.h"
 #include "maemodeploystepfactory.h"
 #include "maemodeviceconfigurations.h"
+#include "maemoglobal.h"
 #include "maemopackagecreationfactory.h"
 #include "maemopublishingwizardfactories.h"
 #include "maemoqemumanager.h"
@@ -43,9 +44,10 @@
 #include "maemosettingspages.h"
 #include "maemotoolchain.h"
 #include "qt4maemotargetfactory.h"
+#include "qt4projectmanager/qtversionmanager.h"
+#include "qt4projectmanager/qt4projectmanagerconstants.h"
 
 #include <extensionsystem/pluginmanager.h>
-#include <qt4projectmanager/qtversionmanager.h>
 
 #include <QtCore/QDir>
 #include <QtCore/QFile>
@@ -69,6 +71,7 @@ MaemoManager::MaemoManager()
     , m_qemuSettingsPage(new MaemoQemuSettingsPage(this))
     , m_publishingFactoryFremantleFree(new MaemoPublishingWizardFactoryFremantleFree(this))
     , m_maemoTargetFactory(new Qt4MaemoTargetFactory(this))
+    , m_toolChainFactory(new MaemoToolChainFactory)
 {
     Q_ASSERT(!m_instance);
 
@@ -77,6 +80,7 @@ MaemoManager::MaemoManager()
     MaemoDeviceConfigurations::instance(this);
 
     PluginManager *pluginManager = PluginManager::instance();
+    pluginManager->addObject(m_toolChainFactory);
     pluginManager->addObject(m_runControlFactory);
     pluginManager->addObject(m_runConfigurationFactory);
     pluginManager->addObject(m_packageCreationFactory);
@@ -98,6 +102,8 @@ MaemoManager::~MaemoManager()
     pluginManager->removeObject(m_packageCreationFactory);
     pluginManager->removeObject(m_runConfigurationFactory);
     pluginManager->removeObject(m_runControlFactory);
+    pluginManager->removeObject(m_toolChainFactory);
+    delete m_toolChainFactory;
 
     m_instance = 0;
 }
@@ -108,20 +114,5 @@ MaemoManager &MaemoManager::instance()
     return *m_instance;
 }
 
-ToolChain* MaemoManager::maemo5ToolChain(const QtVersion *version) const
-{
-    return new Maemo5ToolChain(version);
-}
-
-ToolChain* MaemoManager::harmattanToolChain(const QtVersion *version) const
-{
-    return new HarmattanToolChain(version);
-}
-
-ToolChain* MaemoManager::meegoToolChain(const QtVersion *version) const
-{
-    return new MeegoToolChain(version);
-}
-
 } // namespace Internal
 } // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemomanager.h b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.h
index 641f4f28d68e920d8711075f74c3be99d6b847bc..acacf34452b21ae99a8b07ba5a7d4e4f827622a0 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemomanager.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemomanager.h
@@ -36,11 +36,6 @@
 
 #include <QtCore/QObject>
 
-namespace ProjectExplorer {
-    class ToolChain;
-}
-using ProjectExplorer::ToolChain;
-
 namespace Qt4ProjectManager {
     class QtVersion;
 namespace Internal {
@@ -54,6 +49,7 @@ class MaemoDeviceConfigurationsSettingsPage;
 class MaemoQemuManager;
 class MaemoQemuSettingsPage;
 class Qt4MaemoTargetFactory;
+class MaemoToolChainFactory;
 
 class MaemoManager : public QObject
 {
@@ -64,10 +60,6 @@ public:
     ~MaemoManager();
     static MaemoManager &instance();
 
-    ToolChain *maemo5ToolChain(const Qt4ProjectManager::QtVersion *version) const;
-    ToolChain *harmattanToolChain(const Qt4ProjectManager::QtVersion *version) const;
-    ToolChain *meegoToolChain(const Qt4ProjectManager::QtVersion *version) const;
-
     MaemoDeviceConfigurationsSettingsPage *deviceConfigurationsSettingsPage() const { return m_deviceConfigurationsSettingsPage; }
     MaemoQemuSettingsPage *qemuSettingsPage() const { return m_qemuSettingsPage; }
 
@@ -83,6 +75,7 @@ private:
     MaemoQemuManager *m_qemuRuntimeManager;
     MaemoPublishingWizardFactoryFremantleFree *m_publishingFactoryFremantleFree;
     Qt4MaemoTargetFactory *m_maemoTargetFactory;
+    MaemoToolChainFactory *m_toolChainFactory;
 };
 
     } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
index aa38e8e93c53aa6661b2c5a9b160fefa22349754..a5c99dde599e5a68490c0ebb89298f25d65de3f3 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.cpp
@@ -217,11 +217,11 @@ MaemoDeviceConfig::ConstPtr MaemoRunConfiguration::deviceConfig() const
     return step ? step->deviceConfig() : MaemoDeviceConfig::ConstPtr();
 }
 
-const AbstractMaemoToolChain *MaemoRunConfiguration::toolchain() const
+const MaemoToolChain *MaemoRunConfiguration::toolchain() const
 {
     Qt4BuildConfiguration *qt4bc(activeQt4BuildConfiguration());
     QTC_ASSERT(qt4bc, return 0);
-    AbstractMaemoToolChain *tc = dynamic_cast<AbstractMaemoToolChain *>(qt4bc->toolChain());
+    MaemoToolChain *tc = dynamic_cast<MaemoToolChain *>(qt4bc->toolChain());
     QTC_ASSERT(tc != 0, return 0);
     return tc;
 }
@@ -238,7 +238,7 @@ MaemoDeployStep *MaemoRunConfiguration::deployStep() const
 
 const QString MaemoRunConfiguration::sysRoot() const
 {
-    if (const AbstractMaemoToolChain *tc = toolchain())
+    if (const MaemoToolChain *tc = toolchain())
         return tc->sysroot();
     return QString();
 }
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h
index ff368db43f909fd46adfe7da552f5b0f86d0dbf0..62b9d539cf8fe47bbe9515703bd5d966fe1ef588 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemorunconfiguration.h
@@ -63,7 +63,7 @@ class MaemoDeployStep;
 class MaemoManager;
 class MaemoRemoteMountsModel;
 class MaemoRunConfigurationFactory;
-class AbstractMaemoToolChain;
+class MaemoToolChain;
 
 class MaemoRunConfiguration : public ProjectExplorer::RunConfiguration
 {
@@ -91,7 +91,7 @@ public:
     MaemoDeployStep *deployStep() const;
     MaemoRemoteMountsModel *remoteMounts() const { return m_remoteMounts; }
 
-    const AbstractMaemoToolChain *toolchain() const;
+    const MaemoToolChain *toolchain() const;
     QString localExecutableFilePath() const;
     QString remoteExecutableFilePath() const;
     const QString sysRoot() const;
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.cpp
index 8109d41d1c643e0c471d5b74d2454153246a85a8..f671e710e1d6d9043170174c92e9311a00014d2d 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.cpp
@@ -33,41 +33,69 @@
 
 #include "maemotoolchain.h"
 
-#include "maemoconstants.h"
 #include "maemoglobal.h"
+#include "maemomanager.h"
+#include "qt4projectmanagerconstants.h"
 #include "qtversionmanager.h"
 
-#include <QtCore/QDir>
-#include <QtCore/QStringBuilder>
-#include <QtCore/QTextStream>
+#include <projectexplorer/gccparser.h>
+#include <projectexplorer/toolchainmanager.h>
+#include <utils/environment.h>
 
-using namespace ProjectExplorer;
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtGui/QLabel>
+#include <QtGui/QVBoxLayout>
 
 namespace Qt4ProjectManager {
 namespace Internal {
 
-AbstractMaemoToolChain::AbstractMaemoToolChain(const QtVersion *qtVersion)
-    : GccToolChain(MaemoGlobal::targetRoot(qtVersion) % QLatin1String("/bin/gcc"))
-    , m_sysrootInitialized(false)
-    , m_qtVersionId(qtVersion->uniqueId())
+static const char *const MAEMO_QT_VERSION_KEY = "Qt4ProjectManager.Maemo.QtVersion";
+
+// --------------------------------------------------------------------------
+// MaemoToolChain
+// --------------------------------------------------------------------------
+
+MaemoToolChain::MaemoToolChain(bool autodetected) :
+    ProjectExplorer::GccToolChain(QLatin1String(Constants::MAEMO_TOOLCHAIN_ID), autodetected),
+    m_qtVersionId(-1)
 {
+    updateId();
 }
 
-AbstractMaemoToolChain::~AbstractMaemoToolChain()
+MaemoToolChain::MaemoToolChain(const MaemoToolChain &tc) :
+    ProjectExplorer::GccToolChain(tc),
+    m_qtVersionId(tc.m_qtVersionId)
+{ }
+
+MaemoToolChain::~MaemoToolChain()
+{ }
+
+QString MaemoToolChain::typeName() const
 {
+    return MaemoToolChainFactory::tr("Maemo GCC");
 }
 
-void AbstractMaemoToolChain::addToEnvironment(Utils::Environment &env)
+ProjectExplorer::Abi MaemoToolChain::targetAbi() const
 {
-    QtVersion *version = QtVersionManager::instance()->version(m_qtVersionId);
-    const QString maddeRoot = MaemoGlobal::maddeRoot(version);
-    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin")
-        .arg(maddeRoot)));
+    return m_targetAbi;
+}
+
+bool MaemoToolChain::isValid() const
+{
+    return GccToolChain::isValid() && m_qtVersionId >= 0 && m_targetAbi.isValid();
+}
+
+void MaemoToolChain::addToEnvironment(Utils::Environment &env) const
+{
+    QtVersion *v = QtVersionManager::instance()->version(m_qtVersionId);
+    const QString maddeRoot = MaemoGlobal::maddeRoot(v);
+    env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin").arg(maddeRoot)));
     env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/bin")
-        .arg(MaemoGlobal::targetRoot(version))));
+                                                  .arg(MaemoGlobal::targetRoot(v))));
 
     // put this into environment to make pkg-config stuff work
-    env.prependOrSet(QLatin1String("SYSROOT_DIR"), sysroot());
+    env.prependOrSet(QLatin1String("SYSROOT_DIR"), QDir::toNativeSeparators(sysroot()));
     env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/madbin")
         .arg(maddeRoot)));
     env.prependOrSetPath(QDir::toNativeSeparators(QString("%1/madlib")
@@ -76,82 +104,208 @@ void AbstractMaemoToolChain::addToEnvironment(Utils::Environment &env)
         QDir::toNativeSeparators(QString("%1/madlib/perl5").arg(maddeRoot)));
 }
 
-QString AbstractMaemoToolChain::makeCommand() const
+QString MaemoToolChain::sysroot() const
 {
-    return QLatin1String("make" EXEC_SUFFIX);
+    QtVersion *v = QtVersionManager::instance()->version(m_qtVersionId);
+    if (!v)
+        return QString();
+
+    if (m_sysroot.isEmpty()) {
+        QFile file(QDir::cleanPath(MaemoGlobal::targetRoot(v)) + 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 && list.at(0) == QLatin1String("sysroot"))
+                    m_sysroot = MaemoGlobal::maddeRoot(v) + QLatin1String("/sysroots/") + list.at(1);
+            }
+        }
+    }
+    return m_sysroot;
 }
 
-bool AbstractMaemoToolChain::equals(const ToolChain *other) const
+bool MaemoToolChain::operator ==(const ProjectExplorer::ToolChain &tc) const
 {
-    const AbstractMaemoToolChain *toolChain = static_cast<const AbstractMaemoToolChain*> (other);
-    return other->type() == type() && toolChain->m_qtVersionId == m_qtVersionId;
+    if (!ToolChain::operator ==(tc))
+        return false;
+
+    const MaemoToolChain *tcPtr = static_cast<const MaemoToolChain *>(&tc);
+    return m_qtVersionId == tcPtr->m_qtVersionId;
 }
 
-QString AbstractMaemoToolChain::sysroot() const
+ProjectExplorer::ToolChainConfigWidget *MaemoToolChain::configurationWidget()
 {
-    if (!m_sysrootInitialized)
-        setSysroot();
-    return m_sysrootRoot;
+    return new MaemoToolChainConfigWidget(this);
 }
 
-void AbstractMaemoToolChain::setSysroot() const
+QVariantMap MaemoToolChain::toMap() const
 {
-    QtVersion *version = QtVersionManager::instance()->version(m_qtVersionId);
-    QFile file(QDir::cleanPath(MaemoGlobal::targetRoot(version))
-        + 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 = MaemoGlobal::maddeRoot(version)
-                    + QLatin1String("/sysroots/") + list.at(1);
-            }
-        }
+    QVariantMap result = GccToolChain::toMap();
+    result.insert(QLatin1String(MAEMO_QT_VERSION_KEY), m_qtVersionId);
+    return result;
+}
+
+bool MaemoToolChain::fromMap(const QVariantMap &data)
+{
+    if (!GccToolChain::fromMap(data))
+        return false;
+
+    m_qtVersionId = data.value(QLatin1String(MAEMO_QT_VERSION_KEY), -1).toInt();
+
+    return isValid();
+}
+
+void MaemoToolChain::setQtVersionId(int id)
+{
+    if (id < 0) {
+        m_targetAbi = ProjectExplorer::Abi();
+        m_qtVersionId = -1;
+        updateId();
+        return;
     }
 
-    m_sysrootInitialized = true;
+    QtVersion *version = QtVersionManager::instance()->version(id);
+    Q_ASSERT(version);
+    ProjectExplorer::Abi::OSFlavour flavour = ProjectExplorer::Abi::Linux_harmattan;
+    if (MaemoGlobal::isValidMaemo5QtVersion(version))
+        flavour = ProjectExplorer::Abi::Linux_maemo;
+    else if (MaemoGlobal::isValidHarmattanQtVersion(version))
+        flavour = ProjectExplorer::Abi::Linux_harmattan;
+    else if (MaemoGlobal::isValidMeegoQtVersion(version))
+        flavour = ProjectExplorer::Abi::Linux_meego;
+    else
+        return;
+
+    m_qtVersionId = id;
+
+    Q_ASSERT(version->qtAbis().count() == 1);
+    m_targetAbi = version->qtAbis().at(0);
+
+    updateId();
+    setDisplayName(MaemoToolChainFactory::tr("Maemo Gcc for %1").arg(version->displayName()));
 }
 
+int MaemoToolChain::qtVersionId() const
+{
+    return m_qtVersionId;
+}
+
+void MaemoToolChain::updateId()
+{
+    setId(QString::fromLatin1("%1:%2").arg(Constants::MAEMO_TOOLCHAIN_ID).arg(m_qtVersionId));
+}
+
+// --------------------------------------------------------------------------
+// ToolChainConfigWidget
+// --------------------------------------------------------------------------
 
-Maemo5ToolChain::Maemo5ToolChain(const QtVersion *qtVersion)
-        : AbstractMaemoToolChain(qtVersion)
+MaemoToolChainConfigWidget::MaemoToolChainConfigWidget(MaemoToolChain *tc) :
+    ProjectExplorer::ToolChainConfigWidget(tc)
 {
+    QVBoxLayout *layout = new QVBoxLayout(this);
+    QLabel *label = new QLabel;
+    QtVersion *v = QtVersionManager::instance()->version(tc->qtVersionId());
+    Q_ASSERT(v);
+    label->setText(tr("MADDE Root: %1<br>Target Root: %2")
+                   .arg(MaemoGlobal::maddeRoot(v))
+                   .arg(MaemoGlobal::targetRoot(v)));
+    layout->addWidget(label);
 }
 
-Maemo5ToolChain::~Maemo5ToolChain() {}
+void MaemoToolChainConfigWidget::apply()
+{
+    // nothing to do!
+}
 
-ProjectExplorer::ToolChainType Maemo5ToolChain::type() const
+void MaemoToolChainConfigWidget::discard()
 {
-    return ProjectExplorer::ToolChain_GCC_MAEMO5;
+    // nothing to do!
 }
 
-HarmattanToolChain::HarmattanToolChain(const QtVersion *qtVersion)
-        : AbstractMaemoToolChain(qtVersion)
+bool MaemoToolChainConfigWidget::isDirty() const
 {
+    return false;
 }
 
-HarmattanToolChain::~HarmattanToolChain() {}
+// --------------------------------------------------------------------------
+// ToolChainFactory
+// --------------------------------------------------------------------------
+
+MaemoToolChainFactory::MaemoToolChainFactory() :
+    ProjectExplorer::ToolChainFactory()
+{ }
 
-ProjectExplorer::ToolChainType HarmattanToolChain::type() const
+QString MaemoToolChainFactory::displayName() const
 {
-    return ProjectExplorer::ToolChain_GCC_HARMATTAN;
+    return tr("Maemo GCC");
 }
 
+QString MaemoToolChainFactory::id() const
+{
+    return QLatin1String(Constants::MAEMO_TOOLCHAIN_ID);
+}
 
-MeegoToolChain::MeegoToolChain(const QtVersion *qtVersion)
-        : AbstractMaemoToolChain(qtVersion)
+QList<ProjectExplorer::ToolChain *> MaemoToolChainFactory::autoDetect()
 {
+    QList<ProjectExplorer::ToolChain *> result;
+
+    QtVersionManager *vm = QtVersionManager::instance();
+    connect(vm, SIGNAL(qtVersionsChanged(QList<int>)),
+            this, SLOT(handleQtVersionChanges(QList<int>)));
+
+    QList<int> versionList;
+    foreach (QtVersion *v, vm->versions())
+        versionList.append(v->uniqueId());
+
+    return createToolChainList(versionList);
 }
 
-MeegoToolChain::~MeegoToolChain() {}
+void MaemoToolChainFactory::handleQtVersionChanges(const QList<int> &changes)
+{
+    ProjectExplorer::ToolChainManager *tcm = ProjectExplorer::ToolChainManager::instance();
+    QList<ProjectExplorer::ToolChain *> tcList = createToolChainList(changes);
+    foreach (ProjectExplorer::ToolChain *tc, tcList)
+        tcm->registerToolChain(tc);
+}
 
-ProjectExplorer::ToolChainType MeegoToolChain::type() const
+QList<ProjectExplorer::ToolChain *> MaemoToolChainFactory::createToolChainList(const QList<int> &changes)
 {
-    return ProjectExplorer::ToolChain_GCC_MEEGO;
+    ProjectExplorer::ToolChainManager *tcm = ProjectExplorer::ToolChainManager::instance();
+    QtVersionManager *vm = QtVersionManager::instance();
+    QList<ProjectExplorer::ToolChain *> result;
+
+    foreach (int i, changes) {
+        QtVersion *v = vm->version(i);
+        if (!v) {
+            // remove ToolChain:
+            QList<ProjectExplorer::ToolChain *> toRemove;
+            foreach (ProjectExplorer::ToolChain *tc, tcm->toolChains()) {
+                if (!tc->id().startsWith(QLatin1String(Constants::MAEMO_TOOLCHAIN_ID)))
+                    continue;
+                MaemoToolChain *mTc = static_cast<MaemoToolChain *>(tc);
+                if (mTc->qtVersionId() == i)
+                    toRemove.append(mTc);
+            }
+            foreach (ProjectExplorer::ToolChain *tc, toRemove)
+                tcm->deregisterToolChain(tc);
+        } else if (v->supportsTargetId(Constants::MAEMO5_DEVICE_TARGET_ID)
+                   || v->supportsTargetId(Constants::HARMATTAN_DEVICE_TARGET_ID)
+                   || v->supportsTargetId(Constants::MEEGO_DEVICE_TARGET_ID)) {
+            // add ToolChain:
+            MaemoToolChain *mTc = new MaemoToolChain(true);
+            mTc->setQtVersionId(i);
+            QString target = "Maemo 5";
+            if (v->supportsTargetId(Constants::HARMATTAN_DEVICE_TARGET_ID))
+                target = "Maemo 6";
+            else if (v->supportsTargetId(Constants::MEEGO_DEVICE_TARGET_ID))
+                target = "Meego";
+            mTc->setDisplayName(tr("%1 GCC (%2)").arg(target).arg(MaemoGlobal::maddeRoot(v)));
+            mTc->setCompilerPath(MaemoGlobal::targetRoot(v) + QLatin1String("/bin/gcc"));
+            result.append(mTc);
+        }
+    }
+    return result;
 }
 
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.h b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.h
index 8b33d4053a25da3fa07c74be7cab73b480708fcd..3dd1aa2683746adeb35e5d1d1c0cb1996ccd453c 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/maemotoolchain.h
@@ -34,59 +34,90 @@
 #ifndef MAEMOTOOLCHAIN_H
 #define MAEMOTOOLCHAIN_H
 
-#include <projectexplorer/toolchain.h>
+#include <projectexplorer/gcctoolchain.h>
+#include <projectexplorer/toolchainconfigwidget.h>
 
 namespace Qt4ProjectManager {
 class QtVersion;
+
 namespace Internal {
 
-class AbstractMaemoToolChain : public ProjectExplorer::GccToolChain
+// --------------------------------------------------------------------------
+// MaemoToolChain
+// --------------------------------------------------------------------------
+
+class MaemoToolChain : public ProjectExplorer::GccToolChain
 {
 public:
-    AbstractMaemoToolChain(const QtVersion *qtVersion);
-    virtual ~AbstractMaemoToolChain();
+    ~MaemoToolChain();
+
+    QString typeName() const;
+    ProjectExplorer::Abi targetAbi() const;
 
-    void addToEnvironment(Utils::Environment &env);
-    QString makeCommand() const;
+    bool isValid() const;
+
+    void addToEnvironment(Utils::Environment &env) const;
     QString sysroot() const;
 
-protected:
-    bool equals(const ToolChain *other) const;
+    bool operator ==(const ProjectExplorer::ToolChain &) const;
 
-private:
-    void setSysroot() const;
+    ProjectExplorer::ToolChainConfigWidget *configurationWidget();
+
+
+    QVariantMap toMap() const;
+    bool fromMap(const QVariantMap &data);
+
+    void setQtVersionId(int);
+    int qtVersionId() const;
 
 private:
-    mutable QString m_sysrootRoot;
-    mutable bool m_sysrootInitialized;
+    void updateId();
+
+    explicit MaemoToolChain(bool);
+    MaemoToolChain(const MaemoToolChain &);
+
     int m_qtVersionId;
+    mutable QString m_sysroot;
+    ProjectExplorer::Abi m_targetAbi;
+
+    friend class MaemoToolChainFactory;
 };
 
-class Maemo5ToolChain : public AbstractMaemoToolChain
+// --------------------------------------------------------------------------
+// MaemoToolChainConfigWidget
+// --------------------------------------------------------------------------
+
+class MaemoToolChainConfigWidget : public ProjectExplorer::ToolChainConfigWidget
 {
+    Q_OBJECT
+
 public:
-    Maemo5ToolChain(const QtVersion *qtVersion);
-    ~Maemo5ToolChain();
+    MaemoToolChainConfigWidget(MaemoToolChain *);
 
-    ProjectExplorer::ToolChainType type() const;
+    void apply();
+    void discard();
+    bool isDirty() const;
 };
 
-class HarmattanToolChain : public AbstractMaemoToolChain
+// --------------------------------------------------------------------------
+// MaemoToolChainFactory
+// --------------------------------------------------------------------------
+
+class MaemoToolChainFactory : public ProjectExplorer::ToolChainFactory
 {
+    Q_OBJECT
+
 public:
-    HarmattanToolChain(const QtVersion *qtVersion);
-    ~HarmattanToolChain();
+    MaemoToolChainFactory();
 
-    ProjectExplorer::ToolChainType type() const;
-};
+    QString displayName() const;
+    QString id() const;
 
-class MeegoToolChain : public AbstractMaemoToolChain
-{
-public:
-    MeegoToolChain(const QtVersion *qtVersion);
-    ~MeegoToolChain();
+    QList<ProjectExplorer::ToolChain *> autoDetect();
 
-    ProjectExplorer::ToolChainType type() const;
+private slots:
+    void handleQtVersionChanges(const QList<int> &);
+    QList<ProjectExplorer::ToolChain *> createToolChainList(const QList<int> &);
 };
 
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt4maemotarget.cpp b/src/plugins/qt4projectmanager/qt-maemo/qt4maemotarget.cpp
index 788af72f740331c41d7083817aa40fcc4041cdf4..61454d1fa52788b2058fc043ae51b9b61524d56d 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/qt4maemotarget.cpp
+++ b/src/plugins/qt4projectmanager/qt-maemo/qt4maemotarget.cpp
@@ -37,6 +37,7 @@
 #include "maemopackagecreationstep.h"
 #include "maemopertargetdeviceconfigurationlistmodel.h"
 #include "maemorunconfiguration.h"
+#include "maemotoolchain.h"
 #include "qt4maemodeployconfiguration.h"
 
 #include <coreplugin/icore.h>
@@ -120,10 +121,45 @@ AbstractQt4MaemoTarget::AbstractQt4MaemoTarget(Qt4Project *parent, const QString
 }
 
 AbstractQt4MaemoTarget::~AbstractQt4MaemoTarget()
+{ }
+
+AbstractQt4MaemoTarget::DebugArchitecture AbstractQt4MaemoTarget::debugArchitecture() const
+{
+    const QString arch
+        = MaemoGlobal::architecture(activeBuildConfiguration()->qtVersion());
+    if (arch.startsWith(QLatin1String("arm"))) {
+        return DebugArchitecture(QLatin1String("arm"),
+            QLatin1String("arm-none-linux-gnueabi"));
+    } else if (arch.startsWith(QLatin1String("x86_64"))) {
+        return DebugArchitecture(QLatin1String("i386:x86-64"),
+            QLatin1String("x86_64-unknown-linux-gnu "));
+    } else {
+        return DebugArchitecture(QLatin1String("x86"),
+            QLatin1String("i386-unknown-linux-gnu "));
+    }
+}
+
+QList<ProjectExplorer::ToolChain *> AbstractQt4MaemoTarget::possibleToolChains(ProjectExplorer::BuildConfiguration *bc) const
 {
+    QList<ProjectExplorer::ToolChain *> result;
+
+    Qt4BuildConfiguration *qt4Bc = qobject_cast<Qt4BuildConfiguration *>(bc);
+    if (!qt4Bc)
+        return result;
+
+    QList<ProjectExplorer::ToolChain *> candidates = Qt4BaseTarget::possibleToolChains(bc);
+    foreach (ProjectExplorer::ToolChain *i, candidates) {
+        MaemoToolChain *tc = dynamic_cast<MaemoToolChain *>(i);
+        if (!tc)
+            continue;
+        if (tc->qtVersionId() == qt4Bc->qtVersion()->uniqueId())
+            result.append(tc);
+    }
 
+    return result;
 }
 
+
 Qt4BuildConfigurationFactory *AbstractQt4MaemoTarget::buildConfigurationFactory() const
 {
     return m_buildConfigurationFactory;
@@ -346,23 +382,6 @@ void AbstractQt4MaemoTarget::raiseError(const QString &reason)
     QMessageBox::critical(0, tr("Error creating Maemo templates"), reason);
 }
 
-AbstractQt4MaemoTarget::DebugArchitecture AbstractQt4MaemoTarget::debugArchitecture() const
-{
-    const QString arch
-        = MaemoGlobal::architecture(activeBuildConfiguration()->qtVersion());
-    if (arch.startsWith(QLatin1String("arm"))) {
-        return DebugArchitecture(QLatin1String("arm"),
-            QLatin1String("arm-none-linux-gnueabi"));
-    } else if (arch.startsWith(QLatin1String("x86_64"))) {
-        return DebugArchitecture(QLatin1String("i386:x86-64"),
-            QLatin1String("x86_64-unknown-linux-gnu "));
-    } else {
-        return DebugArchitecture(QLatin1String("x86"),
-            QLatin1String("i386-unknown-linux-gnu "));
-    }
-}
-
-
 AbstractDebBasedQt4MaemoTarget::AbstractDebBasedQt4MaemoTarget(Qt4Project *parent,
     const QString &id) : AbstractQt4MaemoTarget(parent, id)
 {
diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt4maemotarget.h b/src/plugins/qt4projectmanager/qt-maemo/qt4maemotarget.h
index 1dbaf6025def77afad4cc56056c113c5a1bfcfac..e5ebb545f6dbe48a7ec66a370a5ffab9abbb5422 100644
--- a/src/plugins/qt4projectmanager/qt-maemo/qt4maemotarget.h
+++ b/src/plugins/qt4projectmanager/qt-maemo/qt4maemotarget.h
@@ -77,16 +77,20 @@ public:
     bool setShortDescription(const QString &description);
 
     struct DebugArchitecture {
-        DebugArchitecture(const QString &a, const QString &t) :
-            architecture(a), gnuTarget(t) {}
+        explicit DebugArchitecture(const QString &a = QString(), const QString &t = QString()) :
+            architecture(a), gnuTarget(t)
+        { }
+
         QString architecture;
         QString gnuTarget;
     };
+    // TODO: Is this needed with the ABI info we have?
     DebugArchitecture debugArchitecture() const;
 
     MaemoPerTargetDeviceConfigurationListModel *deviceConfigurationsModel() const {
         return m_deviceConfigurationsListModel;
     }
+    QList<ProjectExplorer::ToolChain *> possibleToolChains(ProjectExplorer::BuildConfiguration *bc) const;
 
 protected:
     enum ActionStatus { NoActionRequired, ActionSuccessful, ActionFailed };
diff --git a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp
index fd4558ded8c7f0f4c62f515e182f4c3515a1a87c..186887de15374553c60e5ce9ef51dfeaaf0d7601 100644
--- a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.cpp
@@ -32,73 +32,68 @@
 **************************************************************************/
 
 #include "gccetoolchain.h"
-#include "qt4project.h"
+#include "qt4projectmanagerconstants.h"
 
-#include <utils/qtcassert.h>
+#include <utils/environment.h>
 #include <utils/synchronousprocess.h>
 
 #include <QtCore/QDir>
-#include <QtCore/QProcess>
-#include <QtCore/QtDebug>
 
-enum { debug = 0 };
+namespace Qt4ProjectManager {
+namespace Internal {
 
-using namespace ProjectExplorer;
-using namespace Qt4ProjectManager::Internal;
-
-// Locate the compiler via path.
-static QString gcceCommand(const QString &dir)
+static QString gcceVersion(const QString &command)
 {
+    if (command.isEmpty())
+        return QString();
+
+    QProcess gxx;
+    QStringList arguments;
+    arguments << QLatin1String("-dumpversion");
     Utils::Environment env = Utils::Environment::systemEnvironment();
-    if (!dir.isEmpty()) {
-        env.prependOrSetPath(dir + QLatin1String("/bin"));
-        env.prependOrSetPath(dir);
+    env.set(QLatin1String("LC_ALL"), QLatin1String("C"));   //override current locale settings
+    gxx.setEnvironment(env.toStringList());
+    gxx.setReadChannelMode(QProcess::MergedChannels);
+    gxx.start(command, arguments);
+    if (!gxx.waitForStarted()) {
+        qWarning("Cannot start '%s': %s", qPrintable(command), qPrintable(gxx.errorString()));
+        return QString();
     }
-    QString gcce = QLatin1String("arm-none-symbianelf-gcc");
-#ifdef Q_OS_WIN
-    gcce += QLatin1String(".exe");
-#endif
-    const QString rc = env.searchInPath(gcce);
-    if (debug && rc.isEmpty()) {
-        const QString msg = QString::fromLatin1("GCCEToolChain: Unable to locate '%1' in '%2' (GCCE root: '%3')")
-                            .arg(gcce, env.value(QLatin1String("PATH")), dir);
-        qWarning("%s", qPrintable(msg));
-        return gcce;
+    gxx.closeWriteChannel();
+    if (!gxx.waitForFinished())      {
+        Utils::SynchronousProcess::stopProcess(gxx);
+        qWarning("Timeout running '%s'.", qPrintable(command));
+        return QString();
+    }
+    if (gxx.exitStatus() != QProcess::NormalExit) {
+        qWarning("'%s' crashed.", qPrintable(command));
+        return QString();
     }
-    return rc;
-}
 
-// The GccToolChain base class constructor wants to know the gcc command
-GCCEToolChain *GCCEToolChain::create(const S60Devices::Device &device,
-                                     const QString &gcceRoot,
-                                     ProjectExplorer::ToolChainType type)
-{
-    const QString gccCommand = gcceCommand(gcceRoot);
-    const QFileInfo gccCommandFi(gccCommand);
-    const QString binPath = gccCommandFi.isRelative() ? QString() : gccCommandFi.absolutePath();
-    return new GCCEToolChain(device, binPath, gccCommand, type);
+    if (gxx.canReadLine())
+        return gxx.readLine().trimmed();
+
+    return QString();
 }
 
-GCCEToolChain::GCCEToolChain(const S60Devices::Device &device,
-                             const QString &gcceBinPath,
-                             const QString &gcceCommand,
-                             ProjectExplorer::ToolChainType type) :
-    GccToolChain(gcceCommand),
-    m_mixin(device),
-    m_type(type),
-    m_gcceBinPath(gcceBinPath)
+
+// ==========================================================================
+// GcceToolChain
+// ==========================================================================
+
+QString GcceToolChain::typeName() const
 {
-    QTC_ASSERT(m_type == ProjectExplorer::ToolChain_GCCE || m_type == ProjectExplorer::ToolChain_GCCE_GNUPOC, return)
-    if (debug)
-        qDebug() << "GCCEToolChain on" << m_type << gcceCommand << gcceBinPath << m_mixin.device();
+    return GcceToolChainFactory::tr("GCCE");
 }
 
-ProjectExplorer::ToolChainType GCCEToolChain::type() const
+ProjectExplorer::Abi GcceToolChain::targetAbi() const
 {
-    return m_type;
+    return ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Symbian,
+                                ProjectExplorer::Abi::Symbian_device,
+                                ProjectExplorer::Abi::Format_ELF, false);
 }
 
-QByteArray GCCEToolChain::predefinedMacros()
+QByteArray GcceToolChain::predefinedMacros() const
 {
     if (m_predefinedMacros.isEmpty()) {
         ProjectExplorer::GccToolChain::predefinedMacros();
@@ -109,97 +104,90 @@ QByteArray GCCEToolChain::predefinedMacros()
     return m_predefinedMacros;
 }
 
-QList<HeaderPath> GCCEToolChain::systemHeaderPaths()
+void GcceToolChain::addToEnvironment(Utils::Environment &env) const
 {
-    if (m_systemHeaderPaths.isEmpty()) {
-        GccToolChain::systemHeaderPaths();
-        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;
+    GccToolChain::addToEnvironment(env);
+
+    if (m_gcceVersion.isEmpty())
+        m_gcceVersion = gcceVersion(compilerPath());
+    if (m_gcceVersion.isEmpty())
+        return;
+
+    env.set(QLatin1String("QT_GCCE_VERSION"), m_gcceVersion);
+    QString version = m_gcceVersion;
+    env.set(QString::fromLatin1("SBS_GCCE") + version.remove(QLatin1Char('.'))
+            + QLatin1String("BIN"),
+            QDir::toNativeSeparators(QFileInfo(compilerPath()).absolutePath()));
 }
 
-void GCCEToolChain::addToEnvironment(Utils::Environment &env)
+QString GcceToolChain::defaultMakeTarget() const
 {
-    if (debug)
-        qDebug() << "GCCEToolChain::addToEnvironment" << m_type << gcc() << m_gcceBinPath<< m_mixin.device();
-
-    if (!m_gcceBinPath.isEmpty())
-        env.prependOrSetPath(m_gcceBinPath);
-    switch (m_type) {
-    case ProjectExplorer::ToolChain_GCCE:
-        m_mixin.addEpocToEnvironment(&env);
-        break;
-    case ProjectExplorer::ToolChain_GCCE_GNUPOC:
-        m_mixin.addGnuPocToEnvironment(&env);
-        break;
-    default:
-        break;
-    }
-    QString version = gcceVersion();
-    env.set(QLatin1String("QT_GCCE_VERSION"), version);
-    version = version.remove(QLatin1Char('.'));
-    env.set(QString::fromLatin1("SBS_GCCE") + version + QLatin1String("BIN"), QDir::toNativeSeparators(m_gcceBinPath));
+    return QLatin1String("gcce");
 }
 
-QString GCCEToolChain::makeCommand() const
+ProjectExplorer::ToolChain *GcceToolChain::clone() const
+{
+    return new GcceToolChain(*this);
+}
+
+GcceToolChain::GcceToolChain(bool autodetected) :
+    GccToolChain(QLatin1String(Constants::GCCE_TOOLCHAIN_ID), autodetected)
+{ }
+
+// ==========================================================================
+// GcceToolChainFactory
+// ==========================================================================
+
+QString GcceToolChainFactory::displayName() const
 {
-#if defined (Q_OS_WIN)
-    return QLatin1String("make.exe");
-#else
-    return QLatin1String("make");
-#endif
+    return tr("GCCE");
 }
 
-bool GCCEToolChain::equals(const ToolChain *otherIn) const
+QString GcceToolChainFactory::id() const
 {
-    if (otherIn->type() != type())
-                return false;
-    const GCCEToolChain *other = static_cast<const GCCEToolChain *>(otherIn);
-    return m_mixin == other->m_mixin
-           && m_gcceBinPath == other->m_gcceBinPath
-           && gcc() == other->gcc();
+    return QLatin1String(Constants::GCCE_TOOLCHAIN_ID);
 }
 
-QString GCCEToolChain::gcceVersion() const
+QList<ProjectExplorer::ToolChain *> GcceToolChainFactory::autoDetect()
 {
-    if (m_gcceVersion.isEmpty()) {
-        QString command = gcceCommand(m_gcceBinPath);
-        if (command.isEmpty())
-            return QString();
-        QProcess gxx;
-        QStringList arguments;
-        arguments << QLatin1String("-dumpversion");
-        Utils::Environment env = Utils::Environment::systemEnvironment();
-        env.set(QLatin1String("LC_ALL"), QLatin1String("C"));   //override current locale settings
-        gxx.setEnvironment(env.toStringList());
-        gxx.setReadChannelMode(QProcess::MergedChannels);
-        gxx.start(command, arguments);
-        if (!gxx.waitForStarted()) {
-            qWarning("Cannot start '%s': %s", qPrintable(command), qPrintable(gxx.errorString()));
-            return QString();
-        }
-        gxx.closeWriteChannel();
-        if (!gxx.waitForFinished())      {
-            Utils::SynchronousProcess::stopProcess(gxx);
-            qWarning("Timeout running '%s'.", qPrintable(command));
-            return QString();
-        }
-        if (gxx.exitStatus() != QProcess::NormalExit) {
-            qWarning("'%s' crashed.", qPrintable(command));
-            return QString();
-        }
-
-        if (gxx.canReadLine())
-            m_gcceVersion = gxx.readLine().trimmed();
+    QList<ProjectExplorer::ToolChain *> result;
+
+    QString fullPath = Utils::Environment::systemEnvironment().searchInPath(QLatin1String("arm-none-symbianelf-gcc"));
+    if (!fullPath.isEmpty()) {
+        GcceToolChain *tc = new GcceToolChain(true);
+        tc->setCompilerPath(fullPath);
+        tc->setDisplayName(tr("GCCE (%1)").arg(gcceVersion(fullPath)));
+        result.append(tc);
     }
-    return m_gcceVersion;
+    return result;
 }
+
+bool GcceToolChainFactory::canCreate()
+{
+    return true;
+}
+
+ProjectExplorer::ToolChain *GcceToolChainFactory::create()
+{
+    GcceToolChain *tc = new GcceToolChain(false);
+    tc->setDisplayName(tr("GCCE"));
+    return tc;
+}
+
+bool GcceToolChainFactory::canRestore(const QVariantMap &data)
+{
+    return idFromMap(data).startsWith(QLatin1String(Constants::GCCE_TOOLCHAIN_ID));
+}
+
+ProjectExplorer::ToolChain *GcceToolChainFactory::restore(const QVariantMap &data)
+{
+    GcceToolChain *tc = new GcceToolChain(false);
+    if (tc->fromMap(data))
+        return tc;
+
+    delete tc;
+    return 0;
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h
index 31c63882d5b0db642e29371009b2a9afda07c0c1..eed230c9226b5cd2260c8429b70a65efed8cc5cf 100644
--- a/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h
+++ b/src/plugins/qt4projectmanager/qt-s60/gccetoolchain.h
@@ -36,37 +36,54 @@
 
 #include "s60devices.h"
 
-#include <projectexplorer/toolchain.h>
+#include <projectexplorer/gcctoolchain.h>
 
 namespace Qt4ProjectManager {
 namespace Internal {
 
-class GCCEToolChain : public ProjectExplorer::GccToolChain
+// ==========================================================================
+// GcceToolChain
+// ==========================================================================
+
+class GcceToolChain : public ProjectExplorer::GccToolChain
 {
-    explicit GCCEToolChain(const S60Devices::Device &device,
-                           const QString &gcceBinPath,
-                           const QString &gcceCommand,
-                           ProjectExplorer::ToolChainType type);
 public:
-    static GCCEToolChain *create(const S60Devices::Device &device,
-                                 const QString &gcceRoot,
-                                 ProjectExplorer::ToolChainType type);
+    QString typeName() const;
+    ProjectExplorer::Abi targetAbi() const;
 
-    QByteArray predefinedMacros();
-    virtual QList<ProjectExplorer::HeaderPath> systemHeaderPaths();
-    virtual void addToEnvironment(Utils::Environment &env);
-    virtual ProjectExplorer::ToolChainType type() const;
-    virtual QString makeCommand() const;
+    QByteArray predefinedMacros() const;
+    void addToEnvironment(Utils::Environment &env) const;
+    QString defaultMakeTarget() const;
 
-protected:
-    virtual bool equals(const ToolChain *other) const;
+    ProjectExplorer::ToolChain *clone() const;
 
 private:
-    QString gcceVersion() const;
-    const S60ToolChainMixin m_mixin;
-    const ProjectExplorer::ToolChainType m_type;
-    const QString m_gcceBinPath;
+    explicit GcceToolChain(bool autodetected);
+
     mutable QString m_gcceVersion;
+
+    friend class GcceToolChainFactory;
+};
+
+// ==========================================================================
+// GcceToolChainFactory
+// ==========================================================================
+
+class GcceToolChainFactory : public ProjectExplorer::ToolChainFactory
+{
+    Q_OBJECT
+
+public:
+    QString displayName() const;
+    QString id() const;
+
+    QList<ProjectExplorer::ToolChain *> autoDetect();
+
+    bool canCreate();
+    ProjectExplorer::ToolChain *create();
+
+    bool canRestore(const QVariantMap &data);
+    ProjectExplorer::ToolChain *restore(const QVariantMap &data);
 };
 
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-s60/qt-s60-todo.txt b/src/plugins/qt4projectmanager/qt-s60/qt-s60-todo.txt
index ba0a022f7cc92d48987fe781729c07ea18093a92..cbb483b58c28dade0f02f45e972c30455c5f3994 100644
--- a/src/plugins/qt4projectmanager/qt-s60/qt-s60-todo.txt
+++ b/src/plugins/qt4projectmanager/qt-s60/qt-s60-todo.txt
@@ -6,19 +6,13 @@
 * QtVersion:
     * gui for overriding the default make target if necessary,
       make arguments --> make options
-    * build parser should be defined/created by toolchain, not make step
 
 * Tool chains
-    * Qt4Project::setQtVersion should think about tool chains,
-      might be better to remove the magic in toolChainType method
     * should the default make target be defined by the project
       instead of tool chain, or perhaps by the QtVersion dependent on a
       tool chain?
-    * seems that the make for building for device doesn't return useful exit code,
-      so a run is started even if the build has errors
 
 * Run on device
-    * passphrase for signing
     * time stamp of copied sisx is ridiculous
     * don't copy the sisx all the time
     * don't hardcode copy destination
diff --git a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
index 33fd9b04d6923cde9b255b7ed8e0fff8c1dd9e75..a693c71e6e9790266e65b0df7e9e27e5e8fa5c78 100644
--- a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
+++ b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
@@ -67,4 +67,6 @@ HEADERS += $$PWD/s60devices.h \
 
 FORMS += $$PWD/s60devicespreferencepane.ui \
     $$PWD/s60createpackagestep.ui \
-    $$PWD/s60certificatedetailsdialog.ui
+    $$PWD/s60certificatedetailsdialog.ui \
+    qt-s60/rvcttoolchainconfigwidget.ui \
+    qt-s60/winscwtoolchainconfigwidget.ui
diff --git a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.cpp b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.cpp
index 2d378f88471e145fc0bc3d5621e9a05ec5c3f43f..1c5a7254bd138fe40f98226ec30507bec064cd05 100644
--- a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.cpp
@@ -39,8 +39,9 @@
 #include "qt-s60/s60devicerunconfiguration.h"
 
 #include <coreplugin/coreconstants.h>
-#include <projectexplorer/project.h>
 #include <projectexplorer/customexecutablerunconfiguration.h>
+#include <projectexplorer/project.h>
+#include <projectexplorer/toolchainmanager.h>
 #include <symbianutils/symbiandevicemanager.h>
 #include <QtGui/QPainter>
 #include <QtGui/QApplication>
@@ -96,30 +97,24 @@ ProjectExplorer::DeployConfigurationFactory *Qt4SymbianTarget::deployConfigurati
     return m_deployConfigurationFactory;
 }
 
-QList<ProjectExplorer::ToolChainType> Qt4SymbianTarget::filterToolChainTypes(const QList<ProjectExplorer::ToolChainType> &candidates) const
+QList<ProjectExplorer::ToolChain *> Qt4SymbianTarget::possibleToolChains(ProjectExplorer::BuildConfiguration *bc) const
 {
-    QList<ProjectExplorer::ToolChainType> tmp(candidates);
+    QList<ProjectExplorer::ToolChain *> candidates = Qt4BaseTarget::possibleToolChains(bc);
+
+    QList<ProjectExplorer::ToolChain *> tmp;
     if (id() == QLatin1String(Constants::S60_EMULATOR_TARGET_ID)) {
-        if (tmp.contains(ProjectExplorer::ToolChain_WINSCW))
-            return QList<ProjectExplorer::ToolChainType>() << ProjectExplorer::ToolChain_WINSCW;
-        else
-            return QList<ProjectExplorer::ToolChainType>();
+        foreach (ProjectExplorer::ToolChain *tc, candidates) {
+            if (tc->id().startsWith(QLatin1String(Constants::WINSCW_TOOLCHAIN_ID)))
+                tmp.append(tc);
+        }
     } else if (id() == QLatin1String(Constants::S60_DEVICE_TARGET_ID)) {
-        tmp.removeAll(ProjectExplorer::ToolChain_WINSCW);
-        return tmp;
+        foreach (ProjectExplorer::ToolChain *tc, candidates) {
+            if (!tc->id().startsWith(Qt4ProjectManager::Constants::WINSCW_TOOLCHAIN_ID))
+                tmp.append(tc);
+        }
     }
-    return tmp;
-}
 
-ProjectExplorer::ToolChainType Qt4SymbianTarget::preferredToolChainType(const QList<ProjectExplorer::ToolChainType> &candidates) const
-{
-    ProjectExplorer::ToolChainType preferredType = ProjectExplorer::ToolChain_INVALID;
-    if (id() == QLatin1String(Constants::S60_EMULATOR_TARGET_ID) &&
-        candidates.contains(ProjectExplorer::ToolChain_WINSCW))
-        preferredType = ProjectExplorer::ToolChain_WINSCW;
-    if (!candidates.isEmpty())
-        preferredType = candidates.at(0);
-    return preferredType;
+    return tmp;
 }
 
 QString Qt4SymbianTarget::defaultBuildDirectory() const
diff --git a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.h b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.h
index cbfc3aebcd8b4e153788dd14e445dce2c23475e2..110aba55abc310468318901bb7058b1ead1e1482 100644
--- a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.h
+++ b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.h
@@ -54,8 +54,7 @@ public:
     Internal::Qt4BuildConfigurationFactory *buildConfigurationFactory() const;
     ProjectExplorer::DeployConfigurationFactory *deployConfigurationFactory() const;
 
-    QList<ProjectExplorer::ToolChainType> filterToolChainTypes(const QList<ProjectExplorer::ToolChainType> &candidates) const;
-    ProjectExplorer::ToolChainType preferredToolChainType(const QList<ProjectExplorer::ToolChainType> &candidates) const;
+    QList<ProjectExplorer::ToolChain *> possibleToolChains(ProjectExplorer::BuildConfiguration *bc) const;
 
     QString defaultBuildDirectory() const;
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp
index fe681c802ffbec7fc3bddf3d4a7518778210b02f..370807e2950a6ba8d4fe29a42599d3260a314937 100644
--- a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp
@@ -33,178 +33,133 @@
 
 #include "rvcttoolchain.h"
 #include "rvctparser.h"
+#include "ui_rvcttoolchainconfigwidget.h"
+#include "qt4projectmanager/qt4projectmanagerconstants.h"
 
-#include <utils/qtcassert.h>
+#include <utils/environment.h>
+#include <utils/environmentmodel.h>
 #include <utils/synchronousprocess.h>
 
-#include <QtCore/QProcess>
-#include <QtCore/QProcessEnvironment>
-#include <QtCore/QDebug>
-#include <QtCore/QFileInfo>
 #include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QProcess>
+#include <QtGui/QGridLayout>
+#include <QtGui/QLabel>
 
-using namespace ProjectExplorer;
-using namespace Qt4ProjectManager::Internal;
-
-static const char rvctBinaryC[] = "armcc";
+namespace Qt4ProjectManager {
+namespace Internal {
 
-static inline QStringList headerPathToStringList(const QList<ProjectExplorer::HeaderPath> &hl)
-{
-    QStringList rc;
-    foreach (const ProjectExplorer::HeaderPath &hp, hl)
-        rc.push_back(hp.path());
-    return rc;
-}
+#if defined Q_OS_WIN
+static const char *const RVCT_BINARY = "armcc.exe";
+#else
+static const char *const RVCT_BINARY = "armcc";
+#endif
 
-// ==========================================================================
-// RVCTToolChain
-// ==========================================================================
+static const char *const RVCT_LICENSE_KEY = "ARMLMD_LICENSE_FILE";
 
-RVCTToolChain::RVCTToolChain(const S60Devices::Device &device, ProjectExplorer::ToolChainType type) :
-    m_mixin(device),
-    m_type(type),
-    m_versionUpToDate(false),
-    m_major(0),
-    m_minor(0),
-    m_build(0)
-{
-}
+static const char *const RVCT_PATH_KEY = "Qt4ProjectManager.RvctToolChain.CompilerPath";
+static const char *const RVCT_ENVIRONMENT_KEY = "Qt4ProjectManager.RvctToolChain.Environment";
+static const char *const RVCT_ARM_VERSION_KEY = "Qt4ProjectManager.RvctToolChain.ArmVersion";
 
-QSet<QPair<int, int> > RVCTToolChain::configuredRvctVersions()
+static QString valueOf(const QList<Utils::EnvironmentItem> &items, const QString &suffix)
 {
-    static QSet<QPair<int, int> > result;
-
-    if (result.isEmpty()) {
-        QRegExp regex(QLatin1String("^RVCT(\\d)(\\d)BIN=.*$"));
-        Q_ASSERT(regex.isValid());
-        QStringList environment = QProcessEnvironment::systemEnvironment().toStringList();
-        foreach (const QString &v, environment) {
-            if (regex.exactMatch(v)) {
-                int major = regex.cap(1).toInt();
-                int minor = regex.cap(2).toInt();
-                result.insert(qMakePair(major, minor));
-            }
-        }
+    foreach (const Utils::EnvironmentItem &i, items) {
+        if (i.name.mid(6) == suffix && !i.unset)
+            return i.value;
     }
-    return result;
+    return QString();
 }
 
-QStringList RVCTToolChain::configuredEnvironment()
+static QString armVersionString(RvctToolChain::ArmVersion av)
 {
-    updateVersion();
-
-    if (m_additionalEnvironment.isEmpty()) {
-        const QString binVarName = QString::fromLocal8Bit(rvctBinEnvironmentVariable());
-        const QString varName = binVarName.left(binVarName.count() - 3 /* BIN */);
-        QStringList environment = QProcessEnvironment::systemEnvironment().toStringList();
-        foreach (const QString &v, environment) {
-            if ((v.startsWith(varName) && !v.startsWith(binVarName))
-                 || v.startsWith(QLatin1String("ARMLMD_LICENSE_FILE="))) {
-                m_additionalEnvironment.append(v);
-            }
-        }
-    }
-    return m_additionalEnvironment;
+    switch (av) {
+    case RvctToolChain::ARMv5:
+        return RvctToolChainFactory::tr("ARMv5");
+    case RvctToolChain::ARMv6:
+        return RvctToolChainFactory::tr("ARMv6");
+    };
+    return QString();
 }
 
-// Return the environment variable indicating the RVCT version
-// 'RVCT<major><minor>BIN'
-QByteArray RVCTToolChain::rvctBinEnvironmentVariableForVersion(int major)
+static Utils::Environment baseEnvironment(RvctToolChain *tc)
 {
-    QSet<QPair<int, int> > versions = configuredRvctVersions();
-
-    for (QSet<QPair<int, int> >::const_iterator it = versions.constBegin();
-         it != versions.constEnd(); ++it) {
-        if (it->first == major) {
-            if (it->first < 0 || it->first > 9) continue;
-            if (it->second < 0 || it->second > 9) continue;
-            QByteArray result = "RVCT..BIN";
-            result[4] = '0' + it->first;
-            result[5] = '0' + it->second;
-            return result;
-        }
-    }
-    return QByteArray();
+    Utils::Environment result;
+    tc->addToEnvironment(result);
+    return result;
 }
 
-QString RVCTToolChain::rvctBinPath()
-{
-    if (m_binPath.isEmpty()) {
-        const QByteArray binVar = rvctBinEnvironmentVariable();
-        if (!binVar.isEmpty()) {
-            const QByteArray binPathB = qgetenv(binVar);
-            if (!binPathB.isEmpty()) {
-                const QFileInfo fi(QString::fromLocal8Bit(binPathB));
-                if (fi.isDir())
-                    m_binPath = fi.absoluteFilePath();
-            }
-        }
-    }
-    return m_binPath;
-}
+// ==========================================================================
+// RvctToolChain
+// ==========================================================================
 
-// Return binary expanded by path or resort to PATH
-QString RVCTToolChain::rvctBinary()
-{
-    QString executable = QLatin1String(rvctBinaryC);
-#ifdef Q_OS_WIN
-    executable += QLatin1String(".exe");
-#endif
-    const QString binPath = rvctBinPath();
-    return binPath.isEmpty() ? executable : (binPath + QLatin1Char('/') + executable);
-}
+RvctToolChain::RvctToolChain(bool autodetected) :
+    ToolChain(QLatin1String(Constants::RVCT_TOOLCHAIN_ID), autodetected),
+    m_armVersion(ARMv5)
+{ }
 
-ProjectExplorer::ToolChainType RVCTToolChain::type() const
-{
-    return m_type;
-}
+RvctToolChain::RvctToolChain(const RvctToolChain &tc) :
+    ToolChain(tc),
+    m_compilerPath(tc.m_compilerPath),
+    m_environmentChanges(tc.m_environmentChanges),
+    m_armVersion(tc.m_armVersion)
+{ }
 
-void RVCTToolChain::updateVersion()
+RvctToolChain::RvctVersion RvctToolChain::version(const QString &rvctPath)
 {
-    if (m_versionUpToDate)
-        return;
+    RvctToolChain::RvctVersion v;
 
-    m_versionUpToDate = true;
-    m_major = 0;
-    m_minor = 0;
-    m_build = 0;
     QProcess armcc;
-    Utils::Environment env = Utils::Environment::systemEnvironment();
-    addToEnvironment(env);
-    armcc.setEnvironment(env.toStringList());
-    const QString binary = rvctBinary();
+    const QString binary = rvctPath;
     armcc.start(binary, QStringList());
     if (!armcc.waitForStarted()) {
         qWarning("Unable to run rvct binary '%s' when trying to determine version.", qPrintable(binary));
-        return;
+        return v;
     }
     armcc.closeWriteChannel();
     if (!armcc.waitForFinished()) {
         Utils::SynchronousProcess::stopProcess(armcc);
         qWarning("Timeout running rvct binary '%s' trying to determine version.", qPrintable(binary));
-        return;
+        return v;
     }
     if (armcc.exitStatus() != QProcess::NormalExit) {
         qWarning("A crash occurred when running rvct binary '%s' trying to determine version.", qPrintable(binary));
-        return;
+        return v;
     }
     QString versionLine = QString::fromLocal8Bit(armcc.readAllStandardOutput());
     versionLine += QString::fromLocal8Bit(armcc.readAllStandardError());
     const QRegExp versionRegExp(QLatin1String("RVCT(\\d*)\\.(\\d*).*\\[Build.(\\d*)\\]"),
                                 Qt::CaseInsensitive);
-    QTC_ASSERT(versionRegExp.isValid(), return);
+    Q_ASSERT(versionRegExp.isValid());
+
     if (versionRegExp.indexIn(versionLine) != -1) {
-        m_major = versionRegExp.cap(1).toInt();
-        m_minor = versionRegExp.cap(2).toInt();
-        m_build = versionRegExp.cap(3).toInt();
+        v.majorVersion = versionRegExp.cap(1).toInt();
+        v.minorVersion = versionRegExp.cap(2).toInt();
+        v.build = versionRegExp.cap(3).toInt();
     }
+    return v;
+}
+
+QString RvctToolChain::typeName() const
+{
+    return RvctToolChainFactory::tr("RVCT");
+}
+
+ProjectExplorer::Abi RvctToolChain::targetAbi() const
+{
+    return ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Symbian,
+                                ProjectExplorer::Abi::Symbian_device, ProjectExplorer::Abi::Format_ELF,
+                                32);
 }
 
-QByteArray RVCTToolChain::predefinedMacros()
+bool RvctToolChain::isValid() const
+{
+    return !m_compilerPath.isEmpty();
+}
+
+QByteArray RvctToolChain::predefinedMacros() const
 {
     // see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0205f/Babbacdb.html (version 2.2)
     // and http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491b/BABJFEFG.html (version 4.0)
-    updateVersion();
     QByteArray ba("#define __ARRAY_OPERATORS\n"
                   "#define _BOOL\n"
                   "#define __cplusplus\n"
@@ -224,101 +179,36 @@ QByteArray RVCTToolChain::predefinedMacros()
     return ba;
 }
 
-QList<HeaderPath> RVCTToolChain::systemHeaderPaths()
-{
-    if (m_systemHeaderPaths.isEmpty()) {
-        updateVersion();
-        QString rvctInclude = qgetenv(QString::fromLatin1("RVCT%1%2INC").arg(m_major).arg(m_minor).toLatin1());
-        if (!rvctInclude.isEmpty())
-            m_systemHeaderPaths.append(HeaderPath(rvctInclude, HeaderPath::GlobalHeaderPath));
-        switch (m_type) {
-        case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC:
-            m_systemHeaderPaths += m_mixin.gnuPocRvctHeaderPaths(m_major, m_minor);
-            break;
-        default:
-            m_systemHeaderPaths += m_mixin.epocHeaderPaths();
-            break;
-        }
-    }
-    return m_systemHeaderPaths;
-}
-
-// Expand an RVCT variable, such as RVCT22BIN, by some new values
-void RVCTToolChain::addToRVCTPathVariable(const QString &postfix, const QStringList &values,
-                                          Utils::Environment &env) const
-{
-    // get old values
-    const QChar separator = QLatin1Char(',');
-    const QString variable = QString::fromLatin1("RVCT%1%2%3").arg(m_major).arg(m_minor).arg(postfix);
-    const QString oldValueS = env.value(variable);
-    const QStringList oldValue = oldValueS.isEmpty() ? QStringList() : oldValueS.split(separator);
-    // merge new values
-    QStringList newValue = oldValue;
-    foreach(const QString &v, values) {
-        const QString normalized = QDir::toNativeSeparators(v);
-        if (!newValue.contains(normalized))
-            newValue.push_back(normalized);
-    }
-    if (newValue != oldValue)
-        env.set(variable, newValue.join(QString(separator)));
-}
-
-// Figure out lib path via
-QStringList RVCTToolChain::libPaths()
+QList<ProjectExplorer::HeaderPath> RvctToolChain::systemHeaderPaths() const
 {
-    const QByteArray binLocation = qgetenv(rvctBinEnvironmentVariable());
-    if (binLocation.isEmpty())
-        return QStringList();
-    const QString pathRoot = QFileInfo(QString::fromLocal8Bit(binLocation)).path();
-    QStringList rc;
-    rc.push_back(pathRoot + QLatin1String("/lib"));
-    rc.push_back(pathRoot + QLatin1String("/lib/armlib"));
-    return rc;
+    return QList<ProjectExplorer::HeaderPath>()
+            << ProjectExplorer::HeaderPath(valueOf(m_environmentChanges, QLatin1String("INC")),
+                                           ProjectExplorer::HeaderPath::GlobalHeaderPath);
 }
 
-void RVCTToolChain::addToEnvironment(Utils::Environment &env)
+void RvctToolChain::addToEnvironment(Utils::Environment &env) const
 {
-    updateVersion();
+    if (m_compilerPath.isEmpty())
+        return;
 
-    // Push additional configuration variables for the compiler through:
-    QStringList additionalVariables = configuredEnvironment();
-    foreach (const QString &var, additionalVariables) {
-        int pos = var.indexOf(QLatin1Char('='));
-        Q_ASSERT(pos >= 0);
-        const QString key = var.left(pos);
-        const QString value = var.mid(pos + 1);
-        env.set(key, value);
-    }
+    if (m_version.isNull())
+        setVersion(version(m_compilerPath));
+    if (m_version.isNull())
+        return;
 
-    switch (m_type) {
-    case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC: {
-        m_mixin.addGnuPocToEnvironment(&env);
-        // setup RVCT22INC, LIB
-        addToRVCTPathVariable(QLatin1String("INC"),
-                      headerPathToStringList(m_mixin.gnuPocRvctHeaderPaths(m_major, m_minor)),
-                      env);
-        addToRVCTPathVariable(QLatin1String("LIB"),
-                              libPaths() + m_mixin.gnuPocRvctLibPaths(5, true),
-                              env);
-        }
-        break;
-    default:
-        m_mixin.addEpocToEnvironment(&env);
-        break;
-    }
+    env.modify(m_environmentChanges);
 
-    const QString binPath = rvctBinPath();
-    env.set(rvctBinEnvironmentVariable(), QDir::toNativeSeparators(binPath));
+    env.set(QLatin1String("QT_RVCT_VERSION"), QString::fromLatin1("%1.%2")
+            .arg(m_version.majorVersion).arg(m_version.minorVersion));
+    env.set(varName(QLatin1String("BIN")), QDir::toNativeSeparators(QFileInfo(m_compilerPath).absolutePath()));
 
     // Add rvct to path and set locale to 'C'
-    if (!binPath.isEmpty())
-        env.prependOrSetPath(binPath);
+    if (!m_compilerPath.isEmpty())
+        env.prependOrSetPath(QFileInfo(m_compilerPath).absolutePath());
     env.set(QLatin1String("LANG"), QString(QLatin1Char('C')));
-
-    env.set(QLatin1String("QT_RVCT_VERSION"), QString::fromLatin1("%1.%2").arg(m_major).arg(m_minor));
 }
 
-QString RVCTToolChain::makeCommand() const
+QString RvctToolChain::makeCommand() const
 {
 #if defined(Q_OS_WIN)
     return QLatin1String("make.exe");
@@ -327,76 +217,304 @@ QString RVCTToolChain::makeCommand() const
 #endif
 }
 
-ProjectExplorer::IOutputParser *RVCTToolChain::outputParser() const
+QString RvctToolChain::defaultMakeTarget() const
+{
+    if (!isValid())
+        return QString();
+    if (m_armVersion == ARMv6)
+        return QLatin1String("armv6");
+    return QLatin1String("armv5");
+
+}
+
+ProjectExplorer::IOutputParser *RvctToolChain::outputParser() const
 {
     return new RvctParser;
 }
 
-// ==========================================================================
-// RVCT2ToolChain
-// ==========================================================================
+bool RvctToolChain::operator ==(const ToolChain &other) const
+{
+    if (!ToolChain::operator ==(other))
+        return false;
+    const RvctToolChain *otherPtr = dynamic_cast<const RvctToolChain *>(&other);
+    return m_compilerPath == otherPtr->m_compilerPath
+            && m_environmentChanges == otherPtr->m_environmentChanges
+            && m_armVersion == otherPtr->m_armVersion;
+}
 
-RVCT2ToolChain::RVCT2ToolChain(const S60Devices::Device &device, ProjectExplorer::ToolChainType type) :
-    RVCTToolChain(device, type)
-{ }
+void RvctToolChain::setEnvironmentChanges(const QList<Utils::EnvironmentItem> &changes)
+{
+    m_environmentChanges = changes;
+}
+
+QList<Utils::EnvironmentItem> RvctToolChain::environmentChanges() const
+{
+    return m_environmentChanges;
+}
+
+void RvctToolChain::setCompilerPath(const QString &path)
+{
+    if (m_compilerPath == path)
+        return;
+
+    m_compilerPath = path;
+    m_version.reset();
+    updateId();
+}
+
+QString RvctToolChain::compilerPath() const
+{
+    return m_compilerPath;
+}
+
+void RvctToolChain::setArmVersion(RvctToolChain::ArmVersion av)
+{
+    m_armVersion = av;
+}
+
+RvctToolChain::ArmVersion RvctToolChain::armVersion() const
+{
+    return m_armVersion;
+}
+
+void RvctToolChain::setVersion(const RvctVersion &v) const
+{
+    m_version = v;
+}
 
-QByteArray RVCT2ToolChain::rvctBinEnvironmentVariable()
+ProjectExplorer::ToolChainConfigWidget *RvctToolChain::configurationWidget()
 {
-    return rvctBinEnvironmentVariableForVersion(2);
+    return new RvctToolChainConfigWidget(this);
 }
 
-QByteArray RVCT2ToolChain::predefinedMacros()
+ProjectExplorer::ToolChain *RvctToolChain::clone() const
 {
-    QByteArray result = RVCTToolChain::predefinedMacros();
-    result.append(QString::fromLatin1("#define __arm__arm__\n"
-                                      "#define __ARMCC_VERSION %1%2%3%4\n"
-                                      "#define c_plusplus\n"
-                                      )
-                  .arg(m_major, 1, 10, QLatin1Char('0'))
-                  .arg(m_minor, 1, 10, QLatin1Char('0'))
-                  .arg("0")
-                  .arg(m_build, 3, 10, QLatin1Char('0')).toLatin1());
+    return new RvctToolChain(*this);
+}
+
+
+QVariantMap RvctToolChain::toMap() const
+{
+    QVariantMap result = ToolChain::toMap();
+    result.insert(QLatin1String(RVCT_PATH_KEY), m_compilerPath);
+    QVariantMap tmp;
+    foreach (const Utils::EnvironmentItem &i, m_environmentChanges)
+        tmp.insert(i.name, i.value);
+    result.insert(QLatin1String(RVCT_ENVIRONMENT_KEY), tmp);
+    result.insert(QLatin1String(RVCT_ARM_VERSION_KEY), static_cast<int>(m_armVersion));
     return result;
 }
 
-bool RVCT2ToolChain::equals(const ToolChain *otherIn) const
+bool RvctToolChain::fromMap(const QVariantMap &data)
 {
-    if (otherIn->type() != type())
+    if (!ToolChain::fromMap(data))
         return false;
-    const RVCT2ToolChain *other = static_cast<const RVCT2ToolChain *>(otherIn);
-    return other->m_mixin == m_mixin;
+    m_compilerPath = data.value(QLatin1String(RVCT_PATH_KEY)).toString();
+
+    m_environmentChanges.clear();
+    QVariantMap tmp = data.value(QLatin1String(RVCT_ENVIRONMENT_KEY)).toMap();
+    for (QVariantMap::const_iterator i = tmp.constBegin(); i != tmp.constEnd(); ++i)
+        m_environmentChanges.append(Utils::EnvironmentItem(i.key(), i.value().toString()));
+    m_armVersion = static_cast<ArmVersion>(data.value(QLatin1String(RVCT_ARM_VERSION_KEY), 0).toInt());
+
+    return isValid();
+}
+
+void RvctToolChain::updateId()
+{
+    setId(QString::fromLatin1("%1:%2").arg(Constants::RVCT_TOOLCHAIN_ID).arg(m_compilerPath));
+}
+
+QString RvctToolChain::varName(const QString &postFix) const
+{
+    return QString::fromLatin1("RVCT%1%2%3")
+            .arg(m_version.majorVersion).arg(m_version.minorVersion).arg(postFix);
 }
 
 // ==========================================================================
-// RVCT4ToolChain
+// RvctToolChainConfigWidget
 // ==========================================================================
 
-RVCT4ToolChain::RVCT4ToolChain(const S60Devices::Device &device,
-                               ProjectExplorer::ToolChainType type) :
-    RVCT2ToolChain(device, type)
-{ }
+RvctToolChainConfigWidget::RvctToolChainConfigWidget(RvctToolChain *tc) :
+    ProjectExplorer::ToolChainConfigWidget(tc),
+    m_ui(new Ui::RvctToolChainConfigWidget()),
+    m_model(new Utils::EnvironmentModel(this))
+{
+    m_ui->setupUi(this);
+
+    m_ui->environmentView->setModel(m_model);
+    m_ui->environmentView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
+    m_ui->environmentView->horizontalHeader()->setStretchLastSection(true);
+    connect(m_model, SIGNAL(userChangesChanged()), this, SLOT(makeDirty()));
+
+    m_ui->compilerPath->setExpectedKind(Utils::PathChooser::ExistingCommand);
+    m_ui->compilerPath->setPath(tc->compilerPath());
+    connect(m_ui->compilerPath, SIGNAL(changed(QString)), this, SLOT(makeDirty()));
+    m_ui->versionComboBox->setCurrentIndex(static_cast<int>(tc->armVersion()));
+    connect(m_ui->versionComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(makeDirty()));
+
+    discard();
+}
+
+void RvctToolChainConfigWidget::apply()
+{
+    RvctToolChain *tc = static_cast<RvctToolChain *>(toolChain());
+    Q_ASSERT(tc);
+
+    QList<Utils::EnvironmentItem> changes = environmentChanges();
+    tc->setCompilerPath(m_ui->compilerPath->path());
+    tc->setArmVersion(static_cast<RvctToolChain::ArmVersion>(m_ui->versionComboBox->currentIndex()));
+    tc->setEnvironmentChanges(changes);
+
+    m_model->setUserChanges(changes);
+}
+
+void RvctToolChainConfigWidget::discard()
+{
+    RvctToolChain *tc = static_cast<RvctToolChain *>(toolChain());
+    Q_ASSERT(tc);
+
+    m_model->setBaseEnvironment(baseEnvironment(tc));
+
+    m_ui->compilerPath->setPath(tc->compilerPath());
+    m_ui->versionComboBox->setCurrentIndex(static_cast<int>(tc->armVersion()));
+}
+
+bool RvctToolChainConfigWidget::isDirty() const
+{
+    RvctToolChain *tc = static_cast<RvctToolChain *>(toolChain());
+    Q_ASSERT(tc);
+
+    return tc->compilerPath() != m_ui->compilerPath->path()
+            || tc->armVersion() != static_cast<RvctToolChain::ArmVersion>(m_ui->versionComboBox->currentIndex())
+            || tc->environmentChanges() != environmentChanges();
+}
+
+void RvctToolChainConfigWidget::makeDirty()
+{
+    emit dirty(toolChain());
+}
+
+QList<Utils::EnvironmentItem> RvctToolChainConfigWidget::environmentChanges() const
+{
+    Utils::Environment baseEnv;
+    Utils::Environment resultEnv = baseEnvironment(static_cast<RvctToolChain *>(toolChain()));
+    resultEnv.modify(m_model->userChanges());
+    return baseEnv.diff(resultEnv);
+}
+
+// ==========================================================================
+// RvctToolChainFactory
+// ==========================================================================
+
+QString RvctToolChainFactory::displayName() const
+{
+    return tr("RVCT");
+}
 
-QByteArray RVCT4ToolChain::rvctBinEnvironmentVariable()
+QString RvctToolChainFactory::id() const
 {
-    return rvctBinEnvironmentVariableForVersion(4);
+    return QLatin1String(Constants::RVCT_TOOLCHAIN_ID);
 }
 
-QByteArray RVCT4ToolChain::predefinedMacros()
+QList<ProjectExplorer::ToolChain *> RvctToolChainFactory::autoDetect()
 {
-    QByteArray result = RVCTToolChain::predefinedMacros();
-    result.append(QString::fromLatin1("#define __arm__\n"
-                                      "#define __ARMCC_VERSION %1%2%3\n")
-                  .arg(m_major, 1, 10, QLatin1Char('0'))
-                  .arg(m_minor, 1, 10, QLatin1Char('0'))
-                  .arg(m_build, 3, 10, QLatin1Char('0')).toLatin1());
+    Utils::Environment env = Utils::Environment::systemEnvironment();
+
+    QMap<QString, QList<Utils::EnvironmentItem> > rvcts;
+    QList<Utils::EnvironmentItem> globalItems;
+
+    // Find all RVCT..x variables
+    for (Utils::Environment::const_iterator i = env.constBegin(); i != env.constEnd(); ++i) {
+        if (i.key() == QLatin1String(RVCT_LICENSE_KEY))
+            globalItems.append(Utils::EnvironmentItem(i.key(), i.value()));
+        if (!i.key().startsWith(QLatin1String("RVCT")))
+            continue;
+
+        const QString key = i.key().left(6);
+        QList<Utils::EnvironmentItem> values = rvcts.value(key);
+
+        values.append(Utils::EnvironmentItem(i.key(), i.value()));
+
+        rvcts.insert(key, values);
+    }
+
+    // Set up toolchains for each RVCT.. set
+    QList<ProjectExplorer::ToolChain *> result;
+    for (QMap<QString, QList<Utils::EnvironmentItem> >::const_iterator i = rvcts.constBegin();
+         i != rvcts.constEnd(); ++i) {
+        QList<Utils::EnvironmentItem> changes = i.value();
+        changes.append(globalItems);
+
+        QString binary = QDir::fromNativeSeparators(valueOf(changes, QLatin1String("BIN")));
+        if (binary.isEmpty())
+            continue;
+        binary = binary + QLatin1Char('/') + RVCT_BINARY;
+        QFileInfo fi(binary);
+        if (!fi.exists() || !fi.isExecutable())
+            continue;
+
+        RvctToolChain::RvctVersion v = RvctToolChain::version(binary);
+        if (v.majorVersion == 0 && v.minorVersion == 0 && v.build == 0)
+            continue; // Failed to start.
+
+        //: %1 arm version, %2 major version, %3 minor version, %4 build number
+        const QString name = tr("RVCT (%1 %2.%3 Build %4)");
+
+        RvctToolChain *tc = new RvctToolChain(true);
+        tc->setCompilerPath(binary);
+        tc->setEnvironmentChanges(changes);
+        tc->setDisplayName(name.arg(armVersionString(tc->armVersion()))
+                           .arg(v.majorVersion).arg(v.minorVersion).arg(v.build));
+        tc->setVersion(v);
+        result.append(tc);
+
+        tc = new RvctToolChain(true);
+        tc->setCompilerPath(binary);
+        tc->setEnvironmentChanges(changes);
+        tc->setArmVersion(RvctToolChain::ARMv6);
+        tc->setDisplayName(name.arg(armVersionString(tc->armVersion()))
+                           .arg(v.majorVersion).arg(v.minorVersion).arg(v.build));
+        tc->setVersion(v);
+        result.append(tc);
+    }
+
     return result;
 }
 
+bool RvctToolChainFactory::canCreate()
+{
+    return true;
+}
 
-bool RVCT4ToolChain::equals(const ToolChain *otherIn) const
+ProjectExplorer::ToolChain *RvctToolChainFactory::create()
 {
-    if (otherIn->type() != type())
-        return false;
-    const RVCT4ToolChain *other = static_cast<const RVCT4ToolChain *>(otherIn);
-    return other->m_mixin == m_mixin;
+    RvctToolChain *tc = new RvctToolChain(false);
+    Utils::Environment env = Utils::Environment::systemEnvironment();
+    if (env.hasKey(QLatin1String(RVCT_LICENSE_KEY))) {
+        tc->setEnvironmentChanges(QList<Utils::EnvironmentItem>()
+                                  << Utils::EnvironmentItem(QLatin1String(RVCT_LICENSE_KEY),
+                                                            env.value(QLatin1String(RVCT_LICENSE_KEY))));
+    }
+    tc->setDisplayName(tr("RVCT"));
+    return tc;
 }
+
+bool RvctToolChainFactory::canRestore(const QVariantMap &data)
+{
+    return idFromMap(data).startsWith(QLatin1String(Constants::RVCT_TOOLCHAIN_ID));
+}
+
+ProjectExplorer::ToolChain *RvctToolChainFactory::restore(const QVariantMap &data)
+{
+    RvctToolChain *tc = new RvctToolChain(false);
+    if (tc->fromMap(data))
+        return tc;
+
+    delete tc;
+    return 0;
+
+}
+
+} // Internal
+} // Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h
index 2294212d2038309f9c7f55f7bfdf49dc549fe78c..fb7ce3c26b7a75b63ab6076117b2aad02948560c 100644
--- a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h
+++ b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h
@@ -34,97 +34,141 @@
 #ifndef RVCTTOOLCHAIN_H
 #define RVCTTOOLCHAIN_H
 
-#include "s60devices.h"
-
 #include <projectexplorer/toolchain.h>
+#include <projectexplorer/toolchainconfigwidget.h>
+#include <utils/environment.h>
+
+namespace Utils {
+class EnvironmentModel;
+class PathChooser;
+} // namespace Utils
 
 namespace Qt4ProjectManager {
 namespace Internal {
 
+namespace Ui {
+class RvctToolChainConfigWidget;
+}
+
+class RvctToolChainFactory;
+
 // ==========================================================================
-// RVCTToolChain
+// RvctToolChain
 // ==========================================================================
 
-class RVCTToolChain : public ProjectExplorer::ToolChain
+class RvctToolChain : public ProjectExplorer::ToolChain
 {
 public:
-    explicit RVCTToolChain(const S60Devices::Device &device,
-                           ProjectExplorer::ToolChainType type);
-    QByteArray predefinedMacros();
-    QList<ProjectExplorer::HeaderPath> systemHeaderPaths();
-    void addToEnvironment(Utils::Environment &env);
-    ProjectExplorer::ToolChainType type() const;
+    struct RvctVersion {
+        RvctVersion() : majorVersion(0), minorVersion(0), build(0)
+        { }
+
+        bool isNull() { return majorVersion == 0 && minorVersion == 0 && build == 0; }
+        void reset() { majorVersion = 0; minorVersion = 0; build = 0; }
+
+        int majorVersion;
+        int minorVersion;
+        int build;
+    };
+
+    static RvctVersion version(const QString &rvctPath);
+
+    enum ArmVersion { ARMv5, ARMv6 };
+
+    QString typeName() const;
+    ProjectExplorer::Abi targetAbi() const;
+
+    bool isValid() const;
+
+    QByteArray predefinedMacros() const;
+    QList<ProjectExplorer::HeaderPath> systemHeaderPaths() const;
+    void addToEnvironment(Utils::Environment &env) const;
     QString makeCommand() const;
+    QString defaultMakeTarget() const;
     ProjectExplorer::IOutputParser *outputParser() const;
 
-    static QSet<QPair<int, int> > configuredRvctVersions();
+    bool operator ==(const ToolChain &) const;
 
-    // Return the environment variable indicating the RVCT version
-    // 'RVCT2<minor>BIN' and its setting
-    virtual QByteArray rvctBinEnvironmentVariable() = 0;
+    void setEnvironmentChanges(const QList<Utils::EnvironmentItem> &changes);
+    QList<Utils::EnvironmentItem> environmentChanges() const;
 
-    QString rvctBinPath();
-    QString rvctBinary();
+    void setCompilerPath(const QString &path);
+    QString compilerPath() const;
 
-protected:
-    bool equals(const ToolChain *other) const = 0;
+    void setArmVersion(ArmVersion);
+    ArmVersion armVersion() const;
 
-    QStringList configuredEnvironment();
+    void setVersion(const RvctVersion &v) const;
 
-    QByteArray rvctBinEnvironmentVariableForVersion(int major);
-    void addToRVCTPathVariable(const QString &postfix, const QStringList &values,
-                               Utils::Environment &env) const;
-    QStringList libPaths();
-    void updateVersion();
+    ProjectExplorer::ToolChainConfigWidget *configurationWidget();
+    ProjectExplorer::ToolChain *clone() const;
 
-    QByteArray m_predefinedMacros;
-    QList<ProjectExplorer::HeaderPath> m_systemHeaderPaths;
-
-    const S60ToolChainMixin m_mixin;
-    const ProjectExplorer::ToolChainType m_type;
-    bool m_versionUpToDate;
-    int m_major;
-    int m_minor;
-    int m_build;
+    QVariantMap toMap() const;
+    bool fromMap(const QVariantMap &data);
 
 private:
-    QString m_binPath;
-    QStringList m_additionalEnvironment;
+    void updateId();
+
+    explicit RvctToolChain(bool autodetected = false);
+    RvctToolChain(const RvctToolChain &);
+
+    QString varName(const QString &postFix) const;
+
+    QList<ProjectExplorer::HeaderPath> m_systemHeaderPaths;
+    QString m_compilerPath;
+    QList<Utils::EnvironmentItem> m_environmentChanges;
+    ArmVersion m_armVersion;
+    mutable RvctVersion m_version;
+
+    friend class RvctToolChainFactory;
 };
 
 // ==========================================================================
-// RVCT2ToolChain
+// RvctToolChainConfigWidget
 // ==========================================================================
 
-class RVCT2ToolChain : public RVCTToolChain
+class RvctToolChainConfigWidget : public ProjectExplorer::ToolChainConfigWidget
 {
+    Q_OBJECT
+
 public:
-    explicit RVCT2ToolChain(const S60Devices::Device &device,
-                            ProjectExplorer::ToolChainType type);
-    QByteArray rvctBinEnvironmentVariable();
+    RvctToolChainConfigWidget(RvctToolChain *tc);
+
+    void apply();
+    void discard();
+    bool isDirty() const;
 
-    QByteArray predefinedMacros();
+private slots:
+    void makeDirty();
 
-protected:
-    bool equals(const ToolChain *other) const;
+private:
+    QList<Utils::EnvironmentItem> environmentChanges() const;
+
+    Ui::RvctToolChainConfigWidget *m_ui;
+    Utils::EnvironmentModel *m_model;
 };
 
 // ==========================================================================
-// RVCT4ToolChain
+// RvctToolChainFactory
 // ==========================================================================
 
-class RVCT4ToolChain : public RVCT2ToolChain
+class RvctToolChainFactory : public ProjectExplorer::ToolChainFactory
 {
+    Q_OBJECT
+
 public:
-    explicit RVCT4ToolChain(const S60Devices::Device &device,
-                            ProjectExplorer::ToolChainType type);
+    // Name used to display the name of the toolchain that will be created.
+    QString displayName() const;
+    QString id() const;
 
-    QByteArray rvctBinEnvironmentVariable();
+    QList<ProjectExplorer::ToolChain *> autoDetect();
 
-    QByteArray predefinedMacros();
+    bool canCreate();
+    ProjectExplorer::ToolChain *create();
 
-protected:
-    bool equals(const ToolChain *other) const;
+    // Used by the ToolChainManager to restore user-generated ToolChains
+    bool canRestore(const QVariantMap &data);
+    ProjectExplorer::ToolChain *restore(const QVariantMap &data);
 };
 
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchainconfigwidget.ui b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchainconfigwidget.ui
new file mode 100644
index 0000000000000000000000000000000000000000..e2eded3ab502b37496dba367ef88e263befe7cb6
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchainconfigwidget.ui
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Qt4ProjectManager::Internal::RvctToolChainConfigWidget</class>
+ <widget class="QWidget" name="Qt4ProjectManager::Internal::RvctToolChainConfigWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>432</width>
+    <height>173</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Compiler path:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="Utils::PathChooser" name="compilerPath"/>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>ARM version:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QComboBox" name="versionComboBox">
+     <item>
+      <property name="text">
+       <string>Version 5</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Version 6</string>
+      </property>
+     </item>
+    </widget>
+   </item>
+   <item row="2" column="0" colspan="2">
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::Fixed</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>0</width>
+       <height>3</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="3" column="0" colspan="2">
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string>Environment variables:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="0" colspan="2">
+    <widget class="QTableView" name="environmentView"/>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>Utils::PathChooser</class>
+   <extends>QLineEdit</extends>
+   <header>utils/pathchooser.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
index e3f8b5fd8d3e893de7b6c8242b96b49be5398a3d..4dd5ed7bb739c75529e8ee400e6912a557504fa9 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.cpp
@@ -33,6 +33,7 @@
 
 #include "s60deployconfiguration.h"
 #include "s60deployconfigurationwidget.h"
+#include "s60manager.h"
 #include "qt4project.h"
 #include "qt4target.h"
 #include "qt4projectmanagerconstants.h"
@@ -47,6 +48,7 @@
 #include <projectexplorer/buildconfiguration.h>
 #include <projectexplorer/buildsteplist.h>
 #include <projectexplorer/project.h>
+#include <projectexplorer/toolchain.h>
 
 #include <QtCore/QFileInfo>
 
@@ -182,7 +184,7 @@ QStringList S60DeployConfiguration::packageFileNamesWithTargetInfo() const
         QString baseFileName = ti.buildDir + QLatin1Char('/') + ti.target;
         baseFileName += QLatin1Char('_')
                 + (isDebug() ? QLatin1String("debug") : QLatin1String("release"))
-                + QLatin1Char('-') + symbianPlatform() + QLatin1String(".sis");
+                + QLatin1Char('-') + S60Manager::platform(qt4Target()->activeBuildConfiguration()->toolChain()) + QLatin1String(".sis");
         result << baseFileName;
     }
     return result;
@@ -246,26 +248,11 @@ bool S60DeployConfiguration::isSigned() const
     return false;
 }
 
-ProjectExplorer::ToolChainType S60DeployConfiguration::toolChainType() const
+ProjectExplorer::ToolChain *S60DeployConfiguration::toolChain() const
 {
     if (Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(target()->activeBuildConfiguration()))
-        return bc->toolChainType();
-    return ProjectExplorer::ToolChain_INVALID;
-}
-
-QString S60DeployConfiguration::symbianPlatform() const
-{
-    const Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
-    switch (qt4bc->toolChainType()) {
-    case ProjectExplorer::ToolChain_GCCE:
-    case ProjectExplorer::ToolChain_GCCE_GNUPOC:
-        return QLatin1String("gcce");
-    case ProjectExplorer::ToolChain_RVCT2_ARMV5:
-    case ProjectExplorer::ToolChain_RVCT4_ARMV5:
-        return QLatin1String("armv5");
-    default: // including ProjectExplorer::RVCT_ARMV6_GNUPOC:
-        return QLatin1String("armv6");
-    }
+        return bc->toolChain();
+    return 0;
 }
 
 bool S60DeployConfiguration::isDebug() const
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h
index 8efedf6ce04c4ed0b8951aa335d319c2274f03b4..d57f4dd1f576e9155a20f947e5a9355bd84f3e09 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60deployconfiguration.h
@@ -35,11 +35,11 @@
 #define S60DEPLOYCONFIGURATION_H
 
 #include <projectexplorer/deployconfiguration.h>
-#include <projectexplorer/toolchaintype.h>
 
 namespace ProjectExplorer {
 class BuildConfiguration;
 class RunConfiguration;
+class ToolChain;
 }
 
 namespace Qt4ProjectManager {
@@ -72,7 +72,7 @@ public:
 
     const QtVersion *qtVersion() const;
     Qt4SymbianTarget *qt4Target() const;
-    ProjectExplorer::ToolChainType toolChainType() const;
+    ProjectExplorer::ToolChain *toolChain() const;
 
     QString serialPortName() const;
     void setSerialPortName(const QString &name);
@@ -120,7 +120,6 @@ protected:
 private:
     void ctor();
     bool isSigned() const;
-    QString symbianPlatform() const;
     QString symbianTarget() const;
     QString createPackageName(const QString &baseName) const;
     bool isDebug() const;
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
index ae9a6614ccc38b0c09316827b0bc1c20223ac296..bcce8710bb5192443a5da88e97d2f24facbb9f33 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -155,39 +155,16 @@ Qt4SymbianTarget *S60DeviceRunConfiguration::qt4Target() const
     return static_cast<Qt4SymbianTarget *>(target());
 }
 
-ProjectExplorer::ToolChainType S60DeviceRunConfiguration::toolChainType(
-    ProjectExplorer::BuildConfiguration *configuration) const
-{
-    if (Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(configuration))
-        return bc->toolChainType();
-    return ProjectExplorer::ToolChain_INVALID;
-}
-
-ProjectExplorer::ToolChainType S60DeviceRunConfiguration::toolChainType() const
-{
-    if (Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(target()->activeBuildConfiguration()))
-        return bc->toolChainType();
-    return ProjectExplorer::ToolChain_INVALID;
-}
-
 bool S60DeviceRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configuration) const
 {
     if (!m_validParse)
         return false;
-    const Qt4BuildConfiguration *qt4bc = static_cast<const Qt4BuildConfiguration *>(configuration);
-    switch (qt4bc->toolChainType()) {
-    case ProjectExplorer::ToolChain_GCCE:
-    case ProjectExplorer::ToolChain_RVCT2_ARMV5:
-    case ProjectExplorer::ToolChain_RVCT2_ARMV6:
-    case ProjectExplorer::ToolChain_RVCT4_ARMV5:
-    case ProjectExplorer::ToolChain_RVCT4_ARMV6:
-    case ProjectExplorer::ToolChain_GCCE_GNUPOC:
-    case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC:
-        return true;
-    default:
-        break;
-    }
-    return false;
+
+    Q_ASSERT(configuration->target() == target());
+    Q_ASSERT(target()->id() == Constants::S60_DEVICE_TARGET_ID);
+
+    const Qt4BuildConfiguration *qt4bc = qobject_cast<const Qt4BuildConfiguration *>(configuration);
+    return qt4bc && qt4bc->toolChain();
 }
 
 QWidget *S60DeviceRunConfiguration::createConfigurationWidget()
@@ -266,21 +243,6 @@ QString S60DeviceRunConfiguration::symbianTarget() const
     return isDebug() ? QLatin1String("udeb") : QLatin1String("urel");
 }
 
-static inline QString symbianPlatformForToolChain(ProjectExplorer::ToolChainType t)
-{
-    switch (t) {
-    case ProjectExplorer::ToolChain_GCCE:
-    case ProjectExplorer::ToolChain_GCCE_GNUPOC:
-        return QLatin1String("gcce");
-    case ProjectExplorer::ToolChain_RVCT2_ARMV5:
-    case ProjectExplorer::ToolChain_RVCT4_ARMV5:
-        return QLatin1String("armv5");
-    default: // including ProjectExplorer::RVCT_ARMV6_GNUPOC:
-        break;
-    }
-    return QLatin1String("armv6");
-}
-
 /* Grep a package file for the '.exe' file. Currently for use on Linux only
  * as the '.pkg'-files on Windows do not contain drive letters, which is not
  * handled here. \code
@@ -313,47 +275,35 @@ static inline QString executableFromPackageUnix(const QString &packageFileName)
 static inline QString localExecutableFromDevice(const QtVersion *qtv,
                                                 const QString &symbianTarget, /* udeb/urel */
                                                 const QString &targetName,
-                                                ProjectExplorer::ToolChainType t)
+                                                const ProjectExplorer::ToolChain *tc)
 {
-    QTC_ASSERT(qtv, return QString(); )
+    Q_ASSERT(qtv);
+    if (!tc)
+        return QString();
 
             const S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(qtv);
     QString localExecutable;
+    QString platform = S60Manager::platform(tc);
+    if (qtv->isBuildWithSymbianSbsV2() && platform == QLatin1String("gcce"))
+        platform = "armv5";
     QTextStream(&localExecutable) << device.epocRoot << "/epoc32/release/"
-                                  << symbianPlatformForToolChain(t)
-                                  << '/' << symbianTarget << '/' << targetName
-                                  << ".exe";
+            << platform << '/' << symbianTarget << '/' << targetName << ".exe";
     return localExecutable;
 }
 
 QString S60DeviceRunConfiguration::localExecutableFileName() const
 {
-    const ProjectExplorer::ToolChainType toolChain = toolChainType();
-    switch (toolChain) {
-    case ProjectExplorer::ToolChain_GCCE_GNUPOC:
-    case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC: {
-        TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(projectFilePath());
-        if (!ti.valid)
-            return QString();
+    TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(projectFilePath());
+    if (!ti.valid)
+        return QString();
+
+    const ProjectExplorer::Abi hostAbi = ProjectExplorer::Abi::hostAbi();
+    if (hostAbi.os() == ProjectExplorer::Abi::Linux) {
         return executableFromPackageUnix(ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg"));
     }
-    case ProjectExplorer::ToolChain_RVCT2_ARMV5:
-    case ProjectExplorer::ToolChain_RVCT2_ARMV6:
-        return localExecutableFromDevice(qtVersion(), symbianTarget(), targetName(), toolChain);
-        break;
-    case ProjectExplorer::ToolChain_GCCE: {
-        // As of 4.7.1, qmake-gcce-Raptor builds were changed to put all executables into 'armv5'
-        const QtVersion *qtv = qtVersion();
-        QTC_ASSERT(qtv, return QString(); )
-                return qtv->isBuildWithSymbianSbsV2() ?
-                    localExecutableFromDevice(qtv, symbianTarget(), targetName(), ProjectExplorer::ToolChain_RVCT2_ARMV5) :
-                    localExecutableFromDevice(qtv, symbianTarget(), targetName(), toolChain);
-    }
-    break;
-    default:
-        break;
-    }
-    return QString();
+
+    ProjectExplorer::ToolChain *tc = qt4Target()->activeBuildConfiguration()->toolChain();
+    return localExecutableFromDevice(qtVersion(), symbianTarget(), targetName(), tc);
 }
 
 quint32 S60DeviceRunConfiguration::executableUid() const
@@ -515,7 +465,7 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR
     sp.remoteChannel = activeDeployConf->serialPortName();
     sp.processArgs = rc->commandLineArguments();
     sp.startMode = Debugger::StartInternal;
-    sp.toolChainType = rc->toolChainType();
+    sp.toolChainAbi = rc->abi();
     sp.executable = debugFileName;
     sp.executableUid = rc->executableUid();
     sp.enabledEngines = Debugger::GdbEngineType;
@@ -552,7 +502,7 @@ S60DeviceDebugRunControl::S60DeviceDebugRunControl(S60DeviceRunConfiguration *rc
 void S60DeviceDebugRunControl::start()
 {
     Debugger::ConfigurationCheck check =
-        Debugger::checkDebugConfiguration(startParameters().toolChainType);
+        Debugger::checkDebugConfiguration(startParameters().toolChainAbi);
 
     if (!check) {
         appendMessage(check.errorMessage, ErrorMessageFormat);
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
index 81fa2d7b9123ddcaaa9db580e237c4b82fcc9e6c..71de1644c0e412cc3932e16bed53bdd9aef649a1 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -36,7 +36,6 @@
 
 #include <debugger/debuggerrunner.h>
 #include <projectexplorer/runconfiguration.h>
-#include <projectexplorer/toolchaintype.h>
 
 #include <QtCore/QFutureInterface>
 #include <QtCore/QScopedPointer>
@@ -79,8 +78,6 @@ public:
 
     QString projectFilePath() const;
 
-    ProjectExplorer::ToolChainType toolChainType() const;
-
     QString targetName() const;
     QString localExecutableFileName() const;
     quint32 executableUid() const;
@@ -103,7 +100,6 @@ private slots:
     void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro, bool success);
 
 private:
-    ProjectExplorer::ToolChainType toolChainType(ProjectExplorer::BuildConfiguration *configuration) const;
     void ctor();
     void handleParserState(bool sucess);
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp
index 83e0b540e0f221149b4ffa0b5dc94e0f89104f90..1c80ff002d6b43eadce46430ec7c8c019b36e2c8 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devices.cpp
@@ -503,120 +503,6 @@ void GnuPocS60Devices::writeSettings()
     writeSdkQtAssociationSettings(Core::ICore::instance()->settings(), QLatin1String(GNUPOC_SETTINGS_GROUP));
 }
 
-// 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;
-}
-
-static const char *epocHeaderPathsC[] = {
-    "include", "mkspecs/common/symbian", "epoc32/include",
-    "epoc32/include/osextensions/stdapis", "epoc32/include/osextensions/stdapis/sys",
-    "epoc32/include/stdapis", "epoc32/include/stdapis/sys",
-    "epoc32/include/osextensions/stdapis/stlport", "epoc32/include/stdapis/stlport",
-    "epoc32/include/oem", "epoc32/include/middleware", "epoc32/include/domain/middleware",
-    "epoc32/include/osextensions", "epoc32/include/domain/osextensions",
-    "epoc32/include/domain/osextensions/loc", "epoc32/include/domain/middleware/loc",
-    "epoc32/include/domain/osextensions/loc/sc", "epoc32/include/domain/middleware/loc/sc"
-};
-
-QList<ProjectExplorer::HeaderPath> S60ToolChainMixin::epocHeaderPaths() const
-{
-    QList<ProjectExplorer::HeaderPath> rc;
-
-    QString root = m_device.epocRoot + QLatin1Char('/');
-    const int count = sizeof(epocHeaderPathsC) / sizeof(const char *);
-    for (int i = 0; i < count; ++i)
-        rc << ProjectExplorer::HeaderPath(root + QLatin1String(epocHeaderPathsC[i]),
-                                          ProjectExplorer::HeaderPath::GlobalHeaderPath);
-    return rc;
-}
-
-void S60ToolChainMixin::addEpocToEnvironment(Utils::Environment *env) const
-{
-#if defined(Q_OS_WIN)
-    QString winDir = QLatin1String(qgetenv("WINDIR"));
-    if (!winDir.isEmpty())
-        env->prependOrSetPath(QDir(winDir).filePath(QLatin1String("system32")));
-#endif
-
-    QDir epocDir(m_device.epocRoot);
-
-    env->prependOrSetPath(epocDir.filePath(QLatin1String("epoc32/tools"))); // e.g. make.exe
-
-    if (epocDir.exists(QLatin1String("epoc32/gcc/bin")))
-        env->prependOrSetPath(epocDir.filePath(QLatin1String("epoc32/gcc/bin"))); // e.g. cpp.exe, *NOT* gcc.exe
-    // Find perl in the special Symbian flavour:
-    if (epocDir.exists(QLatin1String("../../tools/perl/bin"))) {
-        epocDir.cd(QLatin1String("../../tools/perl/bin"));
-        env->prependOrSetPath(epocDir.absolutePath());
-    } else {
-        env->prependOrSetPath(epocDir.filePath(QLatin1String("perl/bin")));
-    }
-
-    addBaseToEnvironment(env);
-}
-
-static const char *gnuPocHeaderPathsC[] = {
-    "epoc32/include", "epoc32/include/variant", "epoc32/include/stdapis",
-    "epoc32/include/stdapis/stlport" };
-
-QList<ProjectExplorer::HeaderPath> S60ToolChainMixin::gnuPocHeaderPaths() const
-{
-    QList<ProjectExplorer::HeaderPath> rc;
-    const QString root = m_device.epocRoot + QLatin1Char('/');
-    const int count = sizeof(gnuPocHeaderPathsC)/sizeof(const char *);
-    for (int i = 0; i < count; i++)
-        rc.push_back(ProjectExplorer::HeaderPath(root + QLatin1String(gnuPocHeaderPathsC[i]),
-                                                 ProjectExplorer::HeaderPath::GlobalHeaderPath));
-    return rc;
-}
-
-QStringList S60ToolChainMixin::gnuPocRvctLibPaths(int armver, bool debug) const
-{
-    QStringList rc;
-    QString root;
-    QTextStream(&root) << m_device.epocRoot  << "epoc32/release/armv" << armver << '/';
-    rc.push_back(root + QLatin1String("lib"));
-    rc.push_back(root + (debug ? QLatin1String("udeb") : QLatin1String("urel")));
-    return rc;
-}
-
-QList<ProjectExplorer::HeaderPath> S60ToolChainMixin::gnuPocRvctHeaderPaths(int major, int minor) const
-{
-    // Additional header for rvct
-    QList<ProjectExplorer::HeaderPath> rc = gnuPocHeaderPaths();
-    QString rvctHeader;
-    QTextStream(&rvctHeader) << m_device.epocRoot << "/epoc32/include/rvct" << major << '_' << minor;
-    rc.push_back(ProjectExplorer::HeaderPath(rvctHeader, ProjectExplorer::HeaderPath::GlobalHeaderPath));
-    return rc;
-}
-
-void S60ToolChainMixin::addGnuPocToEnvironment(Utils::Environment *env) const
-{
-    env->prependOrSetPath(QDir::toNativeSeparators(m_device.toolsRoot + QLatin1String("/epoc32/tools")));
-    addBaseToEnvironment(env);
-}
-
-void S60ToolChainMixin::addBaseToEnvironment(Utils::Environment *env) const
-{
-    QString epocRootPath(m_device.epocRoot);
-    if (!epocRootPath.endsWith(QLatin1Char('/')))
-        epocRootPath.append(QLatin1Char('/'));
-    env->set(QLatin1String("EPOCROOT"), QDir::toNativeSeparators(S60Devices::cleanedRootPath(epocRootPath)));
-}
-
 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 ab819946303a57c7ef35783174f6a2e9a1347a11..80623c65c214f1429508ffd483b661c2a08420a0 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devices.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devices.h
@@ -168,39 +168,6 @@ private:
     virtual void writeSettings();
 };
 
-/* 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(Utils::Environment *env) const;
-
-    // GnuPoc
-    QList<ProjectExplorer::HeaderPath> gnuPocHeaderPaths() const;
-    QList<ProjectExplorer::HeaderPath> gnuPocRvctHeaderPaths(int major, int minor) const;
-    QStringList gnuPocRvctLibPaths(int armver, bool debug) const;
-    void addGnuPocToEnvironment(Utils::Environment *env) const;
-
-    void addBaseToEnvironment(Utils::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/s60emulatorrunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
index a6e8728c8ff96e3a8e10c9ba15fde713ce3ed1a4..1275b7aad10814023cd4244603ed4b6cd9095ed7 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60emulatorrunconfiguration.cpp
@@ -142,10 +142,11 @@ bool S60EmulatorRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration
 {
     if (!m_validParse)
         return false;
-    Qt4BuildConfiguration *qt4bc = qobject_cast<Qt4BuildConfiguration *>(configuration);
-    QTC_ASSERT(qt4bc, return false);
-    const ProjectExplorer::ToolChainType type = qt4bc->toolChainType();
-    return type == ProjectExplorer::ToolChain_WINSCW;
+    Q_ASSERT(configuration->target() == target());
+    Q_ASSERT(target()->id() == Constants::S60_EMULATOR_TARGET_ID);
+
+    const Qt4BuildConfiguration *qt4bc = qobject_cast<const Qt4BuildConfiguration *>(configuration);
+    return qt4bc && qt4bc->toolChain();
 }
 
 QWidget *S60EmulatorRunConfiguration::createConfigurationWidget()
@@ -323,9 +324,9 @@ QStringList S60EmulatorRunConfigurationFactory::availableCreationIds(Target *par
 
 QString S60EmulatorRunConfigurationFactory::displayNameForId(const QString &id) const
 {
-	if (!pathFromId(id).isEmpty())
+    if (!pathFromId(id).isEmpty())
         return tr("%1 in Symbian Emulator").arg(QFileInfo(pathFromId(id)).completeBaseName());
-	return QString();
+    return QString();
 }
 
 // ======== S60EmulatorRunControl
@@ -333,9 +334,8 @@ QString S60EmulatorRunConfigurationFactory::displayNameForId(const QString &id)
 S60EmulatorRunControl::S60EmulatorRunControl(S60EmulatorRunConfiguration *runConfiguration, QString mode)
     : RunControl(runConfiguration, mode)
 {
-    // stuff like the EPOCROOT and EPOCDEVICE env variable
-    Utils::Environment env = Utils::Environment::systemEnvironment();
-    runConfiguration->qt4Target()->activeBuildConfiguration()->toolChain()->addToEnvironment(env);
+    // FIXME: This should be configurable!
+    Utils::Environment env = runConfiguration->qt4Target()->activeBuildConfiguration()->environment();
     m_applicationLauncher.setEnvironment(env);
 
     m_executable = runConfiguration->executable();
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
index c616e409a709c0910c0968a3018b25d722482626..4c38fe58da1005ed5595ae4cb6dacd065c8402fd 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
@@ -35,9 +35,6 @@
 #include "qtversionmanager.h"
 
 #include "s60devicespreferencepane.h"
-#include "winscwtoolchain.h"
-#include "gccetoolchain.h"
-#include "rvcttoolchain.h"
 #include "s60emulatorrunconfiguration.h"
 #include "s60devicerunconfiguration.h"
 #include "s60createpackagestep.h"
@@ -46,6 +43,10 @@
 
 #include "qt4symbiantargetfactory.h"
 
+#include "gccetoolchain.h"
+#include "rvcttoolchain.h"
+#include "winscwtoolchain.h"
+
 #include <symbianutils/symbiandevicemanager.h>
 
 #include <coreplugin/icore.h>
@@ -112,25 +113,27 @@ S60Manager::S60Manager(QObject *parent)
 {
     m_instance = this;
 
+    addAutoReleasedObject(new GcceToolChainFactory);
+    addAutoReleasedObject(new RvctToolChainFactory);
+    addAutoReleasedObject(new WinscwToolChainFactory);
+
 #ifdef QTCREATOR_WITH_S60
     addAutoReleasedObject(new S60DevicesPreferencePane(m_devices, this));
 #endif
 
     addAutoReleasedObject(new S60EmulatorRunConfigurationFactory);
-    addAutoReleasedObject(new RunControlFactory<S60EmulatorRunControl,
-                                                S60EmulatorRunConfiguration>
-                                                (QLatin1String(ProjectExplorer::Constants::RUNMODE),
-                                                 tr("Run in Emulator"), parent));
+    addAutoReleasedObject(new RunControlFactory<S60EmulatorRunControl, S60EmulatorRunConfiguration>
+                          (QLatin1String(ProjectExplorer::Constants::RUNMODE),
+                           tr("Run in Emulator"), parent));
     addAutoReleasedObject(new S60DeviceRunConfigurationFactory);
     addAutoReleasedObject(new S60RunControlFactory(QLatin1String(ProjectExplorer::Constants::RUNMODE),
                                                  tr("Run on Device"), parent));
     addAutoReleasedObject(new S60CreatePackageStepFactory);
     addAutoReleasedObject(new S60DeployStepFactory);
 
-    addAutoReleasedObject(new RunControlFactory<S60DeviceDebugRunControl,
-                                            S60DeviceRunConfiguration>
-                                            (QLatin1String(Debugger::Constants::DEBUGMODE),
-                                             tr("Debug on Device"), parent));
+    addAutoReleasedObject(new RunControlFactory<S60DeviceDebugRunControl, S60DeviceRunConfiguration>
+                          (QLatin1String(Debugger::Constants::DEBUGMODE),
+                           tr("Debug on Device"), parent));
     addAutoReleasedObject(new Qt4SymbianTargetFactory);
 
     updateQtVersions();
@@ -149,14 +152,12 @@ S60Manager::~S60Manager()
     }
 }
 
-bool S60Manager::hasRvct2Compiler()
-{
-    return RVCT2ToolChain::configuredRvctVersions().contains(qMakePair(2, 2));
-}
-
-bool S60Manager::hasRvct4Compiler()
+QString S60Manager::platform(const ProjectExplorer::ToolChain *tc)
 {
-    return RVCT2ToolChain::configuredRvctVersions().contains(qMakePair(2, 2));
+    if (!tc || tc->targetAbi().os() == ProjectExplorer::Abi::Symbian)
+        return QString();
+    QString target = tc->defaultMakeTarget();
+    return target.right(target.lastIndexOf(QLatin1Char('-')));
 }
 
 void S60Manager::addAutoReleasedObject(QObject *o)
@@ -227,39 +228,6 @@ void S60Manager::updateQtVersions()
     }
 }
 
-ProjectExplorer::ToolChain *S60Manager::createWINSCWToolChain(const Qt4ProjectManager::QtVersion *version) const
-{
-    Q_ASSERT(version);
-    return new WINSCWToolChain(deviceForQtVersion(version), version->mwcDirectory());
-}
-
-ProjectExplorer::ToolChain *S60Manager::createGCCEToolChain(const Qt4ProjectManager::QtVersion *version) const
-{
-    Q_ASSERT(version);
-    return GCCEToolChain::create(deviceForQtVersion(version), version->gcceDirectory(), ProjectExplorer::ToolChain_GCCE);
-}
-
-ProjectExplorer::ToolChain *S60Manager::createGCCE_GnuPocToolChain(const Qt4ProjectManager::QtVersion *version) const
-{
-    Q_ASSERT(version);
-    return GCCEToolChain::create(deviceForQtVersion(version), version->gcceDirectory(), ProjectExplorer::ToolChain_GCCE_GNUPOC);
-}
-
-ProjectExplorer::ToolChain *S60Manager::createRVCTToolChain(
-        const Qt4ProjectManager::QtVersion *version,
-        ProjectExplorer::ToolChainType type) const
-{
-    Q_ASSERT(version);
-    if (type == ProjectExplorer::ToolChain_RVCT2_ARMV5
-            || type == ProjectExplorer::ToolChain_RVCT2_ARMV6
-            || type == ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC)
-        return new RVCT2ToolChain(deviceForQtVersion(version), type);
-    if (type == ProjectExplorer::ToolChain_RVCT4_ARMV5
-            || type == ProjectExplorer::ToolChain_RVCT4_ARMV6)
-        return new RVCT4ToolChain(deviceForQtVersion(version), type);
-    return 0;
-}
-
 S60Devices::Device S60Manager::deviceForQtVersion(const Qt4ProjectManager::QtVersion *version) const
 {
     Q_ASSERT(version);
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.h b/src/plugins/qt4projectmanager/qt-s60/s60manager.h
index e9a3af3bcf3f790ba156012364f2aa07ad55c73c..a4460bcedb73d456770358f907f08234f62d9055 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60manager.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.h
@@ -36,8 +36,6 @@
 
 #include "s60devices.h"
 
-#include <projectexplorer/toolchaintype.h>
-
 #include <QtCore/QObject>
 
 namespace ProjectExplorer {
@@ -57,18 +55,11 @@ public:
     ~S60Manager();
     static S60Manager *instance();
 
-    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::ToolChainType type) const;
-
     S60Devices *devices() const { return m_devices; }
     S60Devices::Device deviceForQtVersion(const Qt4ProjectManager::QtVersion *version) const;
     QString deviceIdFromDetectionSource(const QString &autoDetectionSource) const;
 
-    static bool hasRvct2Compiler();
-    static bool hasRvct4Compiler();
+    static QString platform(const ProjectExplorer::ToolChain *tc);
 
 private slots:
     void updateQtVersions();
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60runcontrolbase.cpp b/src/plugins/qt4projectmanager/qt-s60/s60runcontrolbase.cpp
index 717cdf862b8f649b710136711e5c97bda2c3b395..36b586af7b1701142500630ec8852e31dd64affe 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60runcontrolbase.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60runcontrolbase.cpp
@@ -74,8 +74,7 @@ QString S60RunControlBase::msgListFile(const QString &file)
 
 S60RunControlBase::S60RunControlBase(RunConfiguration *runConfiguration, const QString &mode) :
     RunControl(runConfiguration, mode),
-    m_launchProgress(0),
-    m_toolChain(ProjectExplorer::ToolChain_INVALID)
+    m_launchProgress(0)
 {
     connect(this, SIGNAL(finished()), this, SLOT(reportLaunchFinished()));
     connect(this, SIGNAL(finished()), this, SLOT(handleFinished()));
@@ -87,7 +86,6 @@ S60RunControlBase::S60RunControlBase(RunConfiguration *runConfiguration, const Q
     const S60DeployConfiguration *activeDeployConf = qobject_cast<S60DeployConfiguration *>(s60runConfig->qt4Target()->activeDeployConfiguration());
     QTC_ASSERT(activeDeployConf, return);
 
-    m_toolChain = s60runConfig->toolChainType();
     m_executableUid = s60runConfig->executableUid();
     m_targetName = s60runConfig->targetName();
     m_commandLineArguments = s60runConfig->commandLineArguments();
@@ -100,7 +98,7 @@ S60RunControlBase::S60RunControlBase(RunConfiguration *runConfiguration, const Q
     m_runSmartInstaller = activeDeployConf->runSmartInstaller();
 
     if (debug)
-        qDebug() << "S60RunControlBase::CT" << m_targetName << ProjectExplorer::ToolChain::toolChainName(m_toolChain);
+        qDebug() << "S60RunControlBase::CT" << m_targetName;
 }
 
 void S60RunControlBase::start()
@@ -210,11 +208,6 @@ void S60RunControlBase::reportLaunchFinished()
     setProgress(maxProgress());
 }
 
-ToolChainType S60RunControlBase::toolChain() const
-{
-    return m_toolChain;
-}
-
 quint32 S60RunControlBase::executableUid() const
 {
     return m_executableUid;
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60runcontrolbase.h b/src/plugins/qt4projectmanager/qt-s60/s60runcontrolbase.h
index 00a61c3cf4e3beae142b012c04c3b07b7e3d8beb..d0a567dd74a39c1ad80a481e271d4bf334cda519 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60runcontrolbase.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60runcontrolbase.h
@@ -35,7 +35,7 @@
 #define S60RUNCONTROLBASE_H
 
 #include <projectexplorer/runconfiguration.h>
-#include <projectexplorer/toolchaintype.h>
+#include <projectexplorer/toolchain.h>
 
 #include <QtCore/QFutureInterface>
 
@@ -61,7 +61,6 @@ protected:
     virtual bool setupLauncher() = 0;
 
 protected:
-    ProjectExplorer::ToolChainType toolChain() const;
     quint32 executableUid() const;
     QString executableName() const;
     const QString &targetName() const;
@@ -87,7 +86,6 @@ private slots:
 
 private:
     QFutureInterface<void> *m_launchProgress;
-    ProjectExplorer::ToolChainType m_toolChain;
     quint32 m_executableUid;
     QString m_targetName;
     QString m_commandLineArguments;
diff --git a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp
index 6cdf40216755af61761f5eb554b3ef71f0440c02..14c8ead8c63b2cfc9d57611786557afbbe208bbc 100644
--- a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp
@@ -33,100 +33,372 @@
 
 #include "winscwtoolchain.h"
 
+#include "qt4projectmanager/qt4projectmanagerconstants.h"
+
+#include "ui_winscwtoolchainconfigwidget.h"
 #include "winscwparser.h"
 
-#include <QtCore/QByteArray>
-#include <QtCore/QString>
+#include <utils/environment.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+static const char *const WINSCW_COMPILER_PATH_KEY = "Qt4ProjectManager.Winscw.CompilerPath";
+static const char *const WINSCW_SYSTEM_INCLUDE_PATH_KEY = "Qt4ProjectManager.Winscw.IncludePath";
+static const char *const WINSCW_SYSTEM_LIBRARY_PATH_KEY = "Qt4ProjectManager.Winscw.LibraryPath";
 
-using namespace ProjectExplorer;
-using namespace Qt4ProjectManager::Internal;
+static const char *const WINSCW_DEFAULT_SYSTEM_INCLUDES[] = {
+    "/MSL/MSL_C/MSL_Common/Include",
+    "/MSL/MSL_C/MSL_Win32/Include",
+    "/MSL/MSL_CMSL_X86",
+    "/MSL/MSL_C++/MSL_Common/Include",
+    "/MSL/MSL_Extras/MSL_Common/Include",
+    "/MSL/MSL_Extras/MSL_Win32/Include",
+    "/Win32-x86 Support/Headers/Win32 SDK",
+    0
+};
 
-WINSCWToolChain::WINSCWToolChain(const S60Devices::Device &device, const QString &mwcDirectory)
-    : m_mixin(device),
-    m_carbidePath(mwcDirectory),
-    m_deviceId(device.id),
-    m_deviceName(device.name),
-    m_deviceRoot(device.epocRoot)
+static const char *const WINSCW_DEFAULT_SYSTEM_LIBRARIES[] = {
+    "/Win32-x86 Support/Libraries/Win32 SDK",
+    "/Runtime/Runtime_x86/Runtime_Win32/Libs",
+    0
+};
+
+static QString winscwRoot(const QString &path)
 {
+    if (path.isEmpty())
+        return QString();
 
+    QDir dir(path);
+    dir.cdUp();
+    dir.cdUp();
+    dir.cdUp();
+    dir.cd("Symbian_Support");
+    return dir.absolutePath();
 }
 
-ProjectExplorer::ToolChainType WINSCWToolChain::type() const
+static QString toNativePath(const QStringList &list)
 {
-    return ProjectExplorer::ToolChain_WINSCW;
+    return QDir::toNativeSeparators(list.join(QString(QLatin1Char(';'))));
 }
 
-QByteArray WINSCWToolChain::predefinedMacros()
+static QStringList fromNativePath(const QString &list)
 {
-    return QByteArray("#define __SYMBIAN32__\n");
+    QString tmp = QDir::fromNativeSeparators(list);
+    return tmp.split(';');
 }
 
-QList<HeaderPath> WINSCWToolChain::systemHeaderPaths()
+static QStringList detectIncludesFor(const QString path)
 {
-    if (m_systemHeaderPaths.isEmpty()) {
-        foreach (const QString &value, systemIncludes()) {
-            m_systemHeaderPaths.append(HeaderPath(value, HeaderPath::GlobalHeaderPath));
-        }
-        m_systemHeaderPaths += m_mixin.epocHeaderPaths();
+    QString root = winscwRoot(path);
+    QStringList result;
+    for (int i = 0; WINSCW_DEFAULT_SYSTEM_INCLUDES[i] != 0; ++i) {
+        QDir dir(root + QLatin1String(WINSCW_DEFAULT_SYSTEM_INCLUDES[i]));
+        if (dir.exists())
+            result.append(dir.absolutePath());
     }
-    return m_systemHeaderPaths;
-}
-
-QStringList WINSCWToolChain::systemIncludes() const
-{
-    if (m_carbidePath.isEmpty()) {
-        Utils::Environment env = Utils::Environment::systemEnvironment();
-        QString symIncludesValue = env.value("MWCSYM2INCLUDES");
-        if (!symIncludesValue.isEmpty())
-            return symIncludesValue.split(QLatin1Char(';'));
-    } else {
-        QStringList symIncludes = QStringList()
-            << "\\MSL\\MSL_C\\MSL_Common\\Include"
-            << "\\MSL\\MSL_C\\MSL_Win32\\Include"
-            << "\\MSL\\MSL_CMSL_X86"
-            << "\\MSL\\MSL_C++\\MSL_Common\\Include"
-            << "\\MSL\\MSL_Extras\\MSL_Common\\Include"
-            << "\\MSL\\MSL_Extras\\MSL_Win32\\Include"
-            << "\\Win32-x86 Support\\Headers\\Win32 SDK";
-        for (int i = 0; i < symIncludes.size(); ++i)
-            symIncludes[i].prepend(QString("%1\\x86Build\\Symbian_Support").arg(m_carbidePath));
-        return symIncludes;
-    }
-    return QStringList();
+    return result;
 }
 
-void WINSCWToolChain::addToEnvironment(Utils::Environment &env)
+static QStringList detectLibrariesFor(const QString path)
 {
-    if (!m_carbidePath.isEmpty()) {
-        env.set("MWCSYM2INCLUDES", systemIncludes().join(QString(QLatin1Char(';'))));
-        QStringList symLibraries = QStringList()
-            << "\\Win32-x86 Support\\Libraries\\Win32 SDK"
-            << "\\Runtime\\Runtime_x86\\Runtime_Win32\\Libs";
-        for (int i = 0; i < symLibraries.size(); ++i)
-            symLibraries[i].prepend(QString("%1\\x86Build\\Symbian_Support").arg(m_carbidePath));
-        env.set("MWSYM2LIBRARIES", symLibraries.join(";"));
-        env.set("MWSYM2LIBRARYFILES", "MSL_All_MSE_Symbian_D.lib;gdi32.lib;user32.lib;kernel32.lib");
-        env.prependOrSetPath(QString("%1\\x86Build\\Symbian_Tools\\Command_Line_Tools").arg(m_carbidePath)); // compiler
+    QString root = winscwRoot(path);
+    QStringList result;
+    for (int i = 0; WINSCW_DEFAULT_SYSTEM_LIBRARIES[i] != 0; ++i) {
+        QDir dir(root + QLatin1String(WINSCW_DEFAULT_SYSTEM_LIBRARIES[i]));
+        if (dir.exists())
+            result.append(dir.absolutePath());
     }
-    m_mixin.addEpocToEnvironment(&env);
+    return result;
+}
+
+// --------------------------------------------------------------------------
+// WinscwToolChain
+// --------------------------------------------------------------------------
+
+WinscwToolChain::WinscwToolChain(bool autodetected) :
+    ProjectExplorer::ToolChain(QLatin1String(Constants::WINSCW_TOOLCHAIN_ID), autodetected)
+{ }
+
+WinscwToolChain::WinscwToolChain(const WinscwToolChain &tc) :
+    ProjectExplorer::ToolChain(tc),
+    m_systemIncludePathes(tc.m_systemIncludePathes),
+    m_systemLibraryPathes(tc.m_systemLibraryPathes),
+    m_compilerPath(tc.m_compilerPath)
+{ }
+
+WinscwToolChain::~WinscwToolChain()
+{ }
+
+QString WinscwToolChain::typeName() const
+{
+    return WinscwToolChainFactory::tr("WINSCW");
+}
+
+ProjectExplorer::Abi WinscwToolChain::targetAbi() const
+{
+    return ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Symbian,
+                                ProjectExplorer::Abi::Symbian_emulator,
+                                ProjectExplorer::Abi::Format_ELF, false);
+}
+
+bool WinscwToolChain::isValid() const
+{
+    if (m_compilerPath.isEmpty())
+        return false;
+
+    QFileInfo fi(m_compilerPath);
+    return fi.exists() && fi.isExecutable();
+}
+
+QByteArray WinscwToolChain::predefinedMacros() const
+{
+    return QByteArray("#define __SYMBIAN32__\n");
+}
+
+QList<ProjectExplorer::HeaderPath> WinscwToolChain::systemHeaderPaths() const
+{
+    QList<ProjectExplorer::HeaderPath> result;
+    foreach (const QString &value, m_systemIncludePathes)
+        result.append(ProjectExplorer::HeaderPath(value, ProjectExplorer::HeaderPath::GlobalHeaderPath));
+    return result;
+}
+
+void WinscwToolChain::addToEnvironment(Utils::Environment &env) const
+{
+    if (!isValid())
+        return;
+
+    env.set(QLatin1String("MWCSYM2INCLUDES"), toNativePath(m_systemIncludePathes));
+    env.set(QLatin1String("MWSYM2LIBRARIES"), toNativePath(m_systemLibraryPathes));
+    env.set(QLatin1String("MWSYM2LIBRARYFILES"),
+            QLatin1String("MSL_All_MSE_Symbian_D.lib;gdi32.lib;user32.lib;kernel32.lib"));
+    env.prependOrSetPath(QFileInfo(m_compilerPath).absolutePath());
 }
 
-QString WINSCWToolChain::makeCommand() const
+QString WinscwToolChain::makeCommand() const
 {
+#if defined Q_OS_WIN
+    return QLatin1String("make.exe");
+#else
     return QLatin1String("make");
+#endif
+}
+
+
+QString WinscwToolChain::defaultMakeTarget() const
+{
+    return QLatin1String("winscw");
 }
 
-IOutputParser *WINSCWToolChain::outputParser() const
+ProjectExplorer::IOutputParser *WinscwToolChain::outputParser() const
 {
     return new WinscwParser;
 }
 
-bool WINSCWToolChain::equals(const ToolChain *other) const
+bool WinscwToolChain::operator ==(const ProjectExplorer::ToolChain &tc) const
+{
+    if (!ToolChain::operator ==(tc))
+        return false;
+
+    const WinscwToolChain *tcPtr = dynamic_cast<const WinscwToolChain *>(&tc);
+    Q_ASSERT(tcPtr);
+    return m_compilerPath == tcPtr->m_compilerPath
+            && m_systemIncludePathes == tcPtr->m_systemIncludePathes
+            && m_systemLibraryPathes == tcPtr->m_systemLibraryPathes;
+}
+
+ProjectExplorer::ToolChainConfigWidget *WinscwToolChain::configurationWidget()
+{
+    return new WinscwToolChainConfigWidget(this);
+}
+
+ProjectExplorer::ToolChain *WinscwToolChain::clone() const
+{
+    return new WinscwToolChain(*this);
+}
+
+QVariantMap WinscwToolChain::toMap() const
+{
+    QVariantMap result = ToolChain::toMap();
+    result.insert(QLatin1String(WINSCW_COMPILER_PATH_KEY), m_compilerPath);
+    result.insert(QLatin1String(WINSCW_SYSTEM_INCLUDE_PATH_KEY), m_systemIncludePathes.join(QString(QLatin1Char(';'))));
+    result.insert(QLatin1String(WINSCW_SYSTEM_LIBRARY_PATH_KEY), m_systemLibraryPathes.join(QString(QLatin1Char(';'))));
+    return result;
+}
+
+bool WinscwToolChain::fromMap(const QVariantMap &data)
+{
+    if (!ToolChain::fromMap(data))
+        return false;
+    m_compilerPath = data.value(QLatin1String(WINSCW_COMPILER_PATH_KEY)).toString();
+    m_systemIncludePathes = data.value(QLatin1String(WINSCW_SYSTEM_INCLUDE_PATH_KEY)).toString().split(QLatin1Char(';'));
+    m_systemLibraryPathes = data.value(QLatin1String(WINSCW_SYSTEM_LIBRARY_PATH_KEY)).toString().split(QLatin1Char(';'));
+
+    return isValid();
+}
+
+void WinscwToolChain::setSystemIncludePathes(const QStringList &pathes)
 {
-    const WINSCWToolChain *otherWINSCW = static_cast<const WINSCWToolChain *>(other);
-    return (other->type() == type()
-            && m_deviceId == otherWINSCW->m_deviceId
-            && m_deviceName == otherWINSCW->m_deviceName
-            && m_deviceRoot == otherWINSCW->m_deviceRoot
-            && m_carbidePath == otherWINSCW->m_carbidePath);
+    m_systemIncludePathes = pathes;
 }
+
+QStringList WinscwToolChain::systemIncludePathes() const
+{
+    return m_systemIncludePathes;
+}
+
+void WinscwToolChain::setSystemLibraryPathes(const QStringList &pathes)
+{
+    m_systemLibraryPathes = pathes;
+}
+
+QStringList WinscwToolChain::systemLibraryPathes() const
+{
+    return m_systemLibraryPathes;
+}
+
+void WinscwToolChain::setCompilerPath(const QString &path)
+{
+    if (m_compilerPath == path)
+        return;
+
+    m_compilerPath = path;
+    updateId();
+}
+
+QString WinscwToolChain::compilerPath() const
+{
+    return m_compilerPath;
+}
+
+void WinscwToolChain::updateId()
+{
+    setId(QString::fromLatin1("%1:%2").arg(Constants::WINSCW_TOOLCHAIN_ID).arg(m_compilerPath));
+}
+
+// --------------------------------------------------------------------------
+// ToolChainConfigWidget
+// --------------------------------------------------------------------------
+
+WinscwToolChainConfigWidget::WinscwToolChainConfigWidget(WinscwToolChain *tc) :
+    ProjectExplorer::ToolChainConfigWidget(tc),
+    m_ui(new Ui::WinscwToolChainConfigWidget)
+{
+    m_ui->setupUi(this);
+
+    m_ui->compilerPath->setExpectedKind(Utils::PathChooser::ExistingCommand);
+    connect(m_ui->compilerPath, SIGNAL(changed(QString)),
+            this, SLOT(handleCompilerPathUpdate()));
+    connect(m_ui->includeEdit, SIGNAL(textChanged(QString)), this, SLOT(makeDirty()));
+    connect(m_ui->libraryEdit, SIGNAL(textChanged(QString)), this, SLOT(makeDirty()));
+
+    discard();
+}
+
+void WinscwToolChainConfigWidget::apply()
+{
+    WinscwToolChain *tc = static_cast<WinscwToolChain *>(toolChain());
+    Q_ASSERT(tc);
+    tc->setCompilerPath(m_ui->compilerPath->path());
+    tc->setSystemIncludePathes(fromNativePath(m_ui->includeEdit->text()));
+    tc->setSystemLibraryPathes(fromNativePath(m_ui->libraryEdit->text()));
+}
+
+void WinscwToolChainConfigWidget::discard()
+{
+    WinscwToolChain *tc = static_cast<WinscwToolChain *>(toolChain());
+    Q_ASSERT(tc);
+    m_ui->compilerPath->setPath(tc->compilerPath());
+    m_ui->includeEdit->setText(toNativePath(tc->systemIncludePathes()));
+    m_ui->libraryEdit->setText(toNativePath(tc->systemLibraryPathes()));
+}
+
+bool WinscwToolChainConfigWidget::isDirty() const
+{
+    WinscwToolChain *tc = static_cast<WinscwToolChain *>(toolChain());
+    Q_ASSERT(tc);
+    return tc->compilerPath() != m_ui->compilerPath->path()
+            || tc->systemIncludePathes() != fromNativePath(m_ui->includeEdit->text())
+            || tc->systemLibraryPathes() != fromNativePath(m_ui->libraryEdit->text());
+}
+
+void WinscwToolChainConfigWidget::handleCompilerPathUpdate()
+{
+    QString path = m_ui->compilerPath->path();
+    if (path.isEmpty())
+        return;
+    QFileInfo fi(path);
+    if (!fi.exists())
+        return;
+    m_ui->includeEdit->setText(toNativePath(detectIncludesFor(path)));
+    m_ui->libraryEdit->setText(toNativePath(detectLibrariesFor(path)));
+}
+
+void WinscwToolChainConfigWidget::makeDirty()
+{
+    emit dirty(toolChain());
+}
+
+// --------------------------------------------------------------------------
+// ToolChainFactory
+// --------------------------------------------------------------------------
+
+WinscwToolChainFactory::WinscwToolChainFactory() :
+    ProjectExplorer::ToolChainFactory()
+{ }
+
+QString WinscwToolChainFactory::displayName() const
+{
+    return tr("WINSCW");
+}
+
+QString WinscwToolChainFactory::id() const
+{
+    return QLatin1String(Constants::WINSCW_TOOLCHAIN_ID);
+}
+
+QList<ProjectExplorer::ToolChain *> WinscwToolChainFactory::autoDetect()
+{
+    QList<ProjectExplorer::ToolChain *> result;
+    QString cc = Utils::Environment::systemEnvironment().searchInPath(QLatin1String("mwwinrc"));
+    if (!cc.isEmpty()) {
+        WinscwToolChain *tc = new WinscwToolChain(true);
+        tc->setCompilerPath(cc);
+        tc->setSystemIncludePathes(detectIncludesFor(cc));
+        tc->setSystemLibraryPathes(detectLibrariesFor(cc));
+        result.append(tc);
+    }
+    return result;
+}
+
+bool WinscwToolChainFactory::canCreate()
+{
+    return true;
+}
+
+ProjectExplorer::ToolChain *WinscwToolChainFactory::create()
+{
+    return new WinscwToolChain(false);
+}
+
+bool WinscwToolChainFactory::canRestore(const QVariantMap &data)
+{
+    return idFromMap(data).startsWith(QLatin1String(Constants::WINSCW_TOOLCHAIN_ID));
+}
+
+ProjectExplorer::ToolChain *WinscwToolChainFactory::restore(const QVariantMap &data)
+{
+    WinscwToolChain *tc = new WinscwToolChain(false);
+    if (tc->fromMap(data))
+        return tc;
+
+    delete tc;
+    return 0;
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h
index b618045cb9bc3373b7a659ef42bc419eb9637e03..9d85de4ed2c4788194ce699dc3f4bde5fcde1dbc 100644
--- a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h
+++ b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h
@@ -34,37 +34,111 @@
 #ifndef WINSCWTOOLCHAIN_H
 #define WINSCWTOOLCHAIN_H
 
-#include "s60devices.h"
-
 #include <projectexplorer/toolchain.h>
+#include <projectexplorer/toolchainconfigwidget.h>
 
 namespace Qt4ProjectManager {
 namespace Internal {
+namespace Ui {
+class WinscwToolChainConfigWidget;
+} // namespace Ui
+
+// --------------------------------------------------------------------------
+// WinscwToolChain
+// --------------------------------------------------------------------------
 
-class WINSCWToolChain : public ProjectExplorer::ToolChain
+class WinscwToolChain : public ProjectExplorer::ToolChain
 {
 public:
-    explicit WINSCWToolChain(const S60Devices::Device &device, const QString &mwcDirectory);
-    QByteArray predefinedMacros();
-    QList<ProjectExplorer::HeaderPath> systemHeaderPaths();
-    void addToEnvironment(Utils::Environment &env);
-    ProjectExplorer::ToolChainType type() const;
+    WinscwToolChain(const WinscwToolChain &);
+    ~WinscwToolChain();
+
+    QString typeName() const;
+    ProjectExplorer::Abi targetAbi() const;
+
+    bool isValid() const;
+
+    QByteArray predefinedMacros() const;
+    QList<ProjectExplorer::HeaderPath> systemHeaderPaths() const;
+    void addToEnvironment(Utils::Environment &env) const;
     QString makeCommand() const;
+    QString defaultMakeTarget() const;
     ProjectExplorer::IOutputParser *outputParser() const;
 
-protected:
-    bool equals(const ToolChain *other) const;
+    bool operator ==(const ProjectExplorer::ToolChain &) const;
+
+    ProjectExplorer::ToolChainConfigWidget *configurationWidget();
+    ProjectExplorer::ToolChain *clone() const;
+
+    QVariantMap toMap() const;
+    bool fromMap(const QVariantMap &data);
+
+    void setSystemIncludePathes(const QStringList &);
+    QStringList systemIncludePathes() const;
+
+    void setSystemLibraryPathes(const QStringList &);
+    QStringList systemLibraryPathes() const;
+
+    void setCompilerPath(const QString &);
+    QString compilerPath() const;
 
 private:
-    QStringList systemIncludes() const;
+    void updateId();
+
+    explicit WinscwToolChain(bool);
+
+    QStringList m_systemIncludePathes;
+    QStringList m_systemLibraryPathes;
+    QString m_compilerPath;
+
+    friend class WinscwToolChainFactory;
+};
+
+// --------------------------------------------------------------------------
+// WinscwToolChainConfigWidget
+// --------------------------------------------------------------------------
+
+class WinscwToolChainConfigWidget : public ProjectExplorer::ToolChainConfigWidget
+{
+    Q_OBJECT
+
+public:
+    WinscwToolChainConfigWidget(WinscwToolChain *);
+
+    void apply();
+    void discard();
+    bool isDirty() const;
+
+private slots:
+    void handleCompilerPathUpdate();
+    void makeDirty();
+
+private:
+    Ui::WinscwToolChainConfigWidget *m_ui;
+};
+
+// --------------------------------------------------------------------------
+// WinscwToolChainFactory
+// --------------------------------------------------------------------------
+
+class WinscwToolChainFactory : public ProjectExplorer::ToolChainFactory
+{
+    Q_OBJECT
+
+public:
+    WinscwToolChainFactory();
+
+    QString displayName() const;
+    QString id() const;
+
+    QList<ProjectExplorer::ToolChain *> autoDetect();
 
-    const S60ToolChainMixin m_mixin;
+    bool canCreate();
+    ProjectExplorer::ToolChain *create();
 
-    QString m_carbidePath;
-    QString m_deviceId;
-    QString m_deviceName;
-    QString m_deviceRoot;
-    QList<ProjectExplorer::HeaderPath> m_systemHeaderPaths;
+    // Used by the ToolChainManager to restore user-generated ToolChains
+    bool canRestore(const QVariantMap &data);
+    ProjectExplorer::ToolChain *restore(const QVariantMap &data);
 };
 
 } // namespace Internal
diff --git a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchainconfigwidget.ui b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchainconfigwidget.ui
new file mode 100644
index 0000000000000000000000000000000000000000..cee838461209c91c7376d09d84b2dd7c1d9f63fd
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchainconfigwidget.ui
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Qt4ProjectManager::Internal::WinscwToolChainConfigWidget</class>
+ <widget class="QWidget" name="Qt4ProjectManager::Internal::WinscwToolChainConfigWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>428</width>
+    <height>95</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Compiler path:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="Utils::PathChooser" name="compilerPath"/>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>System include path:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QLineEdit" name="includeEdit"/>
+   </item>
+   <item row="2" column="0">
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string>System library path:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1">
+    <widget class="QLineEdit" name="libraryEdit"/>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>Utils::PathChooser</class>
+   <extends>QLineEdit</extends>
+   <header>utils/pathchooser.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/plugins/qt4projectmanager/qt4buildconfiguration.cpp b/src/plugins/qt4projectmanager/qt4buildconfiguration.cpp
index b64a83cb4f7490c3afa7ae5f0ea16a41c2a632a8..3998b765913eaff82508b2a4dd78e666a95d92d3 100644
--- a/src/plugins/qt4projectmanager/qt4buildconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt4buildconfiguration.cpp
@@ -45,6 +45,7 @@
 #include <limits>
 #include <projectexplorer/buildsteplist.h>
 #include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/toolchainmanager.h>
 
 #include <QtCore/QDebug>
 
@@ -72,7 +73,6 @@ Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target) :
     m_shadowBuild(true),
     m_isEnabled(false),
     m_qtVersionId(-1),
-    m_toolChainType(-1), // toolChainType() makes sure to return the default toolchainType
     m_qmakeBuildConfiguration(0),
     m_subNodeBuild(0)
 {
@@ -84,7 +84,6 @@ Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, const QStrin
     m_shadowBuild(true),
     m_isEnabled(false),
     m_qtVersionId(-1),
-    m_toolChainType(-1), // toolChainType() makes sure to return the default toolchainType
     m_qmakeBuildConfiguration(0),
     m_subNodeBuild(0)
 {
@@ -97,7 +96,6 @@ Qt4BuildConfiguration::Qt4BuildConfiguration(Qt4BaseTarget *target, Qt4BuildConf
     m_isEnabled(false),
     m_buildDirectory(source->m_buildDirectory),
     m_qtVersionId(source->m_qtVersionId),
-    m_toolChainType(source->m_toolChainType),
     m_qmakeBuildConfiguration(source->m_qmakeBuildConfiguration),
     m_subNodeBuild(0) // temporary value, so not copied
 {
@@ -115,7 +113,7 @@ QVariantMap Qt4BuildConfiguration::toMap() const
     map.insert(QLatin1String(USE_SHADOW_BUILD_KEY), m_shadowBuild);
     map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory);
     map.insert(QLatin1String(QT_VERSION_ID_KEY), m_qtVersionId);
-    map.insert(QLatin1String(TOOLCHAIN_KEY), m_toolChainType);
+    map.insert(QLatin1String(TOOLCHAIN_KEY), toolChain() ? toolChain()->id() : QLatin1String("<UNSET>"));
     map.insert(QLatin1String(BUILD_CONFIGURATION_KEY), int(m_qmakeBuildConfiguration));
     return map;
 }
@@ -129,7 +127,8 @@ bool Qt4BuildConfiguration::fromMap(const QVariantMap &map)
     m_shadowBuild = map.value(QLatin1String(USE_SHADOW_BUILD_KEY), true).toBool();
     m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), qt4Target()->defaultBuildDirectory()).toString();
     m_qtVersionId = map.value(QLatin1String(QT_VERSION_ID_KEY)).toInt();
-    m_toolChainType = map.value(QLatin1String(TOOLCHAIN_KEY)).toInt();
+    ProjectExplorer::ToolChain *tc = 0;
+    tc = ProjectExplorer::ToolChainManager::instance()->findToolChain(map.value(QLatin1String(TOOLCHAIN_KEY)).toString());
     m_qmakeBuildConfiguration = QtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt());
 
     // Pick a Qt version if the default version is used:
@@ -160,14 +159,15 @@ bool Qt4BuildConfiguration::fromMap(const QVariantMap &map)
         }
     }
 
-    if (version->isValid())
+    if (version->isValid()) {
+        if (!tc)
+            tc = qt4Target()->preferredToolChain(this);
+        if (tc && qt4Target()->possibleToolChains(this).contains(tc))
+            setToolChain(tc);
         m_shadowBuild = (m_shadowBuild && version->supportsShadowBuilds());
+    }
 
-    QList<ProjectExplorer::ToolChainType> possibleTcs(qt4Target()->filterToolChainTypes(qtVersion()->possibleToolChainTypes()));
-    if (!possibleTcs.contains(toolChainType()))
-        setToolChainType(qt4Target()->preferredToolChainType(possibleTcs));
-
-    if (toolChainType() == ProjectExplorer::ToolChain_INVALID) {
+    if (!toolChain()) {
         qWarning() << "No toolchain available for" << qtVersion()->displayName() << "used in" << target()->id() << "!";
         return false;
     }
@@ -298,12 +298,6 @@ void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const Q
     emit proFileEvaluateNeeded(this);
 }
 
-ProjectExplorer::ToolChain *Qt4BuildConfiguration::toolChain() const
-{
-    const ProjectExplorer::ToolChainType tct = toolChainType();
-    return qtVersion()->toolChain(tct);
-}
-
 QString Qt4BuildConfiguration::makeCommand() const
 {
     ToolChain *tc = toolChain();
@@ -322,25 +316,11 @@ static inline QString symbianMakeTarget(QtVersion::QmakeBuildConfigs buildConfig
 QString Qt4BuildConfiguration::defaultMakeTarget() const
 {
     ToolChain *tc = toolChain();
-    if (!tc)
+    if (!tc || target()->id() != Constants::S60_DEVICE_TARGET_ID)
         return QString();
     const QtVersion::QmakeBuildConfigs buildConfig = qmakeBuildConfiguration();
 
-    switch (tc->type()) {
-    case ProjectExplorer::ToolChain_GCCE:
-        return symbianMakeTarget(buildConfig, QLatin1String("gcce"));
-    case ProjectExplorer::ToolChain_RVCT2_ARMV5:
-    case ProjectExplorer::ToolChain_RVCT4_ARMV5:
-        return symbianMakeTarget(buildConfig, QLatin1String("armv5"));
-    case ProjectExplorer::ToolChain_RVCT2_ARMV6:
-    case ProjectExplorer::ToolChain_RVCT4_ARMV6:
-        return symbianMakeTarget(buildConfig, QLatin1String("armv6"));
-    case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC:
-    case ProjectExplorer::ToolChain_GCCE_GNUPOC:
-    default:
-        break;
-    }
-    return QString();
+    return symbianMakeTarget(buildConfig, tc->defaultMakeTarget());
 }
 
 QString Qt4BuildConfiguration::makefile() const
@@ -363,15 +343,8 @@ void Qt4BuildConfiguration::setQtVersion(QtVersion *version)
 
     m_qtVersionId = version->uniqueId();
 
-    if (!version->possibleToolChainTypes().contains(ProjectExplorer::ToolChainType(m_toolChainType))) {
-        QList<ProjectExplorer::ToolChainType> candidates =
-                qt4Target()->filterToolChainTypes(qtVersion()->possibleToolChainTypes());
-        if (candidates.isEmpty())
-            m_toolChainType = ProjectExplorer::ToolChain_INVALID;
-        else
-            m_toolChainType = candidates.first();
-    }
-
+    if (!qt4Target()->possibleToolChains(this).contains(toolChain()))
+        setToolChain(qt4Target()->preferredToolChain(this));
     m_shadowBuild = m_shadowBuild && qtVersion()->supportsShadowBuilds();
 
     emit proFileEvaluateNeeded(this);
@@ -380,25 +353,20 @@ void Qt4BuildConfiguration::setQtVersion(QtVersion *version)
     emitBuildDirectoryChanged();
 }
 
-void Qt4BuildConfiguration::setToolChainType(ProjectExplorer::ToolChainType type)
+void Qt4BuildConfiguration::setToolChain(ProjectExplorer::ToolChain *tc)
 {
-    if (!qt4Target()->filterToolChainTypes(qtVersion()->possibleToolChainTypes()).contains(type)
-        || m_toolChainType == type)
+    Q_ASSERT(qtVersion());
+    if (!qt4Target()->possibleToolChains(this).contains(tc)
+            || tc->restrictedToTargets().contains(target()->id()))
         return;
 
-    m_toolChainType = type;
+    BuildConfiguration::setToolChain(tc);
 
     emit proFileEvaluateNeeded(this);
-    emit toolChainTypeChanged();
     emit environmentChanged();
     emitBuildDirectoryChanged();
 }
 
-ProjectExplorer::ToolChainType Qt4BuildConfiguration::toolChainType() const
-{
-    return ProjectExplorer::ToolChainType(m_toolChainType);
-}
-
 QtVersion::QmakeBuildConfigs Qt4BuildConfiguration::qmakeBuildConfiguration() const
 {
     return m_qmakeBuildConfiguration;
diff --git a/src/plugins/qt4projectmanager/qt4buildconfiguration.h b/src/plugins/qt4projectmanager/qt4buildconfiguration.h
index df0e9f21236b35fed19bdfad399ad9dc747795cd..d194a4f502fca99298d217f50b75f0dc96ee1254 100644
--- a/src/plugins/qt4projectmanager/qt4buildconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt4buildconfiguration.h
@@ -37,7 +37,6 @@
 #include "qtversionmanager.h"
 
 #include <projectexplorer/buildconfiguration.h>
-#include <projectexplorer/toolchaintype.h>
 
 namespace ProjectExplorer {
 class ToolChain;
@@ -79,9 +78,7 @@ public:
     QtVersion *qtVersion() const;
     void setQtVersion(QtVersion *);
 
-    ProjectExplorer::ToolChain *toolChain() const;
-    void setToolChainType(ProjectExplorer::ToolChainType type);
-    ProjectExplorer::ToolChainType toolChainType() const;
+    void setToolChain(ProjectExplorer::ToolChain *tc);
 
     QtVersion::QmakeBuildConfigs qmakeBuildConfiguration() const;
     void setQMakeBuildConfiguration(QtVersion::QmakeBuildConfigs config);
@@ -134,9 +131,6 @@ signals:
     /// emitted if the qt version changes (either directly, or because the default qt version changed
     /// or because the user changed the settings for the qt version
     void qtVersionChanged();
-    /// emitted iff the setToolChainType() function is called, not emitted for qtversion changes
-    /// even if those result in a toolchain change
-    void toolChainTypeChanged();
     /// emitted for setQMakeBuildConfig, not emitted for qt version changes, even
     /// if those change the qmakebuildconfig
     void qmakeBuildConfigurationChanged();
@@ -168,7 +162,6 @@ private:
     QString m_buildDirectory;
     QString m_lastEmmitedBuildDirectory;
     int m_qtVersionId;
-    int m_toolChainType;
     QtVersion::QmakeBuildConfigs m_qmakeBuildConfiguration;
     Qt4ProjectManager::Internal::Qt4ProFileNode *m_subNodeBuild;
 };
diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
index c1f1e7a8c7f784bddf9ffd7cae182e78d55f84be..5a18b1a20efcfc0aacd0348e20322f471459d76f 100644
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ b/src/plugins/qt4projectmanager/qt4project.cpp
@@ -431,14 +431,10 @@ void Qt4Project::updateCppCodeModel()
     ToolChain *tc = activeBC->toolChain();
     if (tc) {
         predefinedMacros = tc->predefinedMacros();
-        //qDebug()<<"Predefined Macros";
-        //qDebug()<<tc->predefinedMacros();
-        //qDebug()<<"";
-        //qDebug()<<"System Header Paths";
-        //foreach(const HeaderPath &hp, tc->systemHeaderPaths())
-        //    qDebug()<<hp.path();
-
-        foreach (const HeaderPath &headerPath, tc->systemHeaderPaths()) {
+
+        QList<HeaderPath> headers = tc->systemHeaderPaths();
+        headers.append(activeBC->qtVersion()->systemHeaderPathes());
+        foreach (const HeaderPath &headerPath, headers) {
             if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
                 predefinedFrameworkPaths.append(headerPath.path());
             else
@@ -920,8 +916,11 @@ ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4ProFileNode)
             QtVersion *version = activeTarget()->activeBuildConfiguration()->qtVersion();
             if (version->isValid()) {
                 m_proFileOption->properties = version->versionInfo();
-                m_proFileOption->sysroot
-                    = activeTarget()->activeBuildConfiguration()->toolChain()->sysroot();
+                if (activeTarget()
+                        && activeTarget()->activeBuildConfiguration()
+                        && activeTarget()->activeBuildConfiguration()->toolChain())
+                    m_proFileOption->sysroot
+                            = activeTarget()->activeBuildConfiguration()->qtVersion()->systemRoot();
             }
         }
 
diff --git a/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp b/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp
index cb25702b00071cbe4c7b8b769d222fe61cba641b..77fda631ddbd9fa859fd055c76d33ed2bbea816d 100644
--- a/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp
+++ b/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp
@@ -44,7 +44,7 @@
 
 #include <coreplugin/icore.h>
 
-#include <projectexplorer/toolchain.h>
+#include <projectexplorer/toolchainmanager.h>
 #include <projectexplorer/projectexplorerconstants.h>
 #include <projectexplorer/buildconfiguration.h>
 #include <utils/qtcassert.h>
@@ -61,7 +61,7 @@ bool debug = false;
 
 using namespace Qt4ProjectManager;
 using namespace Qt4ProjectManager::Internal;
-using ProjectExplorer::ToolChain;
+using namespace ProjectExplorer;
 
 Qt4ProjectConfigWidget::Qt4ProjectConfigWidget(Qt4BaseTarget *target)
     : BuildConfigWidget(),
@@ -106,6 +106,9 @@ Qt4ProjectConfigWidget::Qt4ProjectConfigWidget(Qt4BaseTarget *target)
     connect(m_ui->manageQtVersionPushButtons, SIGNAL(clicked()),
             this, SLOT(manageQtVersions()));
 
+    connect(m_ui->manageToolChainPushButton, SIGNAL(clicked()),
+            this, SLOT(manageToolChains()));
+
     connect(target->qt4Project(), SIGNAL(environmentChanged()),
             this, SLOT(environmentChanged()));
 
@@ -139,7 +142,8 @@ void Qt4ProjectConfigWidget::updateDetails()
                    "with tool chain <b>%2</b><br>"
                    "building in <b>%3</b>")
                 .arg(versionString,
-                     ProjectExplorer::ToolChain::toolChainName(m_buildConfiguration->toolChainType()),
+                     m_buildConfiguration->toolChain() ? m_buildConfiguration->toolChain()->displayName() :
+                                                         tr("<Invalid ToolChain>"),
                      QDir::toNativeSeparators(m_buildConfiguration->buildDirectory())));
     }
 }
@@ -164,6 +168,13 @@ void Qt4ProjectConfigWidget::manageQtVersions()
     core->showOptionsDialog(Constants::QT_SETTINGS_CATEGORY, Constants::QTVERSION_SETTINGS_PAGE_ID);
 }
 
+void Qt4ProjectConfigWidget::manageToolChains()
+{
+    Core::ICore *core = Core::ICore::instance();
+    core->showOptionsDialog(ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_CATEGORY,
+                            ProjectExplorer::Constants::TOOLCHAIN_SETTINGS_PAGE_ID);
+}
+
 QString Qt4ProjectConfigWidget::displayName() const
 {
     return tr("General");
@@ -183,8 +194,8 @@ void Qt4ProjectConfigWidget::init(ProjectExplorer::BuildConfiguration *bc)
                    this, SLOT(qtVersionChanged()));
         disconnect(m_buildConfiguration, SIGNAL(qmakeBuildConfigurationChanged()),
                    this, SLOT(updateImportLabel()));
-        disconnect(m_buildConfiguration, SIGNAL(toolChainTypeChanged()),
-                   this, SLOT(toolChainTypeChanged()));
+        disconnect(m_buildConfiguration, SIGNAL(toolChainChanged()),
+                   this, SLOT(toolChainChanged()));
     }
     m_buildConfiguration = static_cast<Qt4BuildConfiguration *>(bc);
     m_ui->shadowBuildDirEdit->setEnvironment(m_buildConfiguration->environment());
@@ -195,8 +206,8 @@ void Qt4ProjectConfigWidget::init(ProjectExplorer::BuildConfiguration *bc)
             this, SLOT(qtVersionChanged()));
     connect(m_buildConfiguration, SIGNAL(qmakeBuildConfigurationChanged()),
             this, SLOT(updateImportLabel()));
-    connect(m_buildConfiguration, SIGNAL(toolChainTypeChanged()),
-            this, SLOT(toolChainTypeChanged()));
+    connect(m_buildConfiguration, SIGNAL(toolChainChanged()),
+            this, SLOT(toolChainChanged()));
 
     qtVersionsChanged();
     QtVersionManager *vm = QtVersionManager::instance();
@@ -211,6 +222,11 @@ void Qt4ProjectConfigWidget::init(ProjectExplorer::BuildConfiguration *bc)
     updateImportLabel();
     updateToolChainCombo();
     updateDetails();
+
+    connect(ToolChainManager::instance(), SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)),
+            this, SLOT(updateToolChainCombo()));
+    connect(ToolChainManager::instance(), SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
+            this, SLOT(updateToolChainCombo()));
 }
 
 void Qt4ProjectConfigWidget::qtVersionChanged()
@@ -435,14 +451,14 @@ void Qt4ProjectConfigWidget::qtVersionSelected(const QString &)
     updateDetails();
 }
 
-void Qt4ProjectConfigWidget::toolChainTypeChanged()
+void Qt4ProjectConfigWidget::toolChainChanged()
 {
     if (m_ignoreChange)
         return;
     for (int i=0; i < m_ui->toolChainComboBox->count(); ++i) {
-        ProjectExplorer::ToolChainType tt =
-                m_ui->toolChainComboBox->itemData(i, Qt::UserRole).value<ProjectExplorer::ToolChainType>();
-        if (tt == m_buildConfiguration->toolChainType()) {
+        ProjectExplorer::ToolChain *tc =
+                static_cast<ProjectExplorer::ToolChain *>(m_ui->toolChainComboBox->itemData(i, Qt::UserRole).value<void *>());
+        if (tc == m_buildConfiguration->toolChain()) {
             m_ignoreChange = true;
             m_ui->toolChainComboBox->setCurrentIndex(i);
             m_ignoreChange = false;
@@ -453,29 +469,38 @@ void Qt4ProjectConfigWidget::toolChainTypeChanged()
 void Qt4ProjectConfigWidget::updateToolChainCombo()
 {
     m_ui->toolChainComboBox->clear();
-    QList<ProjectExplorer::ToolChainType> toolchains =
-            m_buildConfiguration->qtVersion()->possibleToolChainTypes();
-
-    toolchains = m_buildConfiguration->qt4Target()->filterToolChainTypes(toolchains);
-
-    foreach (ProjectExplorer::ToolChainType toolchain, toolchains)
-        m_ui->toolChainComboBox->addItem(ToolChain::toolChainName(toolchain), qVariantFromValue(toolchain));
-    m_ui->toolChainComboBox->setEnabled(toolchains.size() > 1);
+    QList<ProjectExplorer::ToolChain *> toolchains =
+            m_buildConfiguration->qt4Target()->possibleToolChains(m_buildConfiguration);
 
+    foreach (ProjectExplorer::ToolChain *toolchain, toolchains)
+        m_ui->toolChainComboBox->addItem(toolchain->displayName(),
+                                         qVariantFromValue(static_cast<void *>(toolchain)));
     m_ignoreChange = true;
-    m_ui->toolChainComboBox->setCurrentIndex(toolchains.indexOf(m_buildConfiguration->toolChainType()));
+    if (!m_buildConfiguration->toolChain() || toolchains.isEmpty()) {
+        m_ui->toolChainComboBox->addItem(tr("<Invalid Toolchain>"), qVariantFromValue(static_cast<void *>(0)));
+        m_ui->toolChainComboBox->setCurrentIndex(m_ui->toolChainComboBox->count() - 1);
+    } else if (toolchains.contains(m_buildConfiguration->toolChain())) {
+        m_ui->toolChainComboBox->setCurrentIndex(toolchains.indexOf(m_buildConfiguration->toolChain()));
+    } else { // reset to some sensible toolchain
+        ToolChain *tc = 0;
+        if (!toolchains.isEmpty())
+            tc = toolchains.at(0);
+        m_buildConfiguration->setToolChain(tc);
+    }
     m_ignoreChange = false;
+    m_ui->toolChainComboBox->setEnabled(toolchains.size() > 1);
 }
 
 void Qt4ProjectConfigWidget::toolChainSelected(int index)
 {
     if (m_ignoreChange)
         return;
-    ProjectExplorer::ToolChainType selectedToolChainType =
-        m_ui->toolChainComboBox->itemData(index,
-            Qt::UserRole).value<ProjectExplorer::ToolChainType>();
+    ProjectExplorer::ToolChain *selectedToolChain =
+            static_cast<ProjectExplorer::ToolChain *>(
+                m_ui->toolChainComboBox->itemData(index,
+                                                  Qt::UserRole).value<void *>());
     m_ignoreChange = true;
-    m_buildConfiguration->setToolChainType(selectedToolChainType);
+    m_buildConfiguration->setToolChain(selectedToolChain);
     m_ignoreChange = false;
     updateDetails();
 }
diff --git a/src/plugins/qt4projectmanager/qt4projectconfigwidget.h b/src/plugins/qt4projectmanager/qt4projectconfigwidget.h
index cf2227bb87ebc2df881af1a461eb80551f428a9b..b4ae13b00e7a6be3207a8e6cb47edd2763031328 100644
--- a/src/plugins/qt4projectmanager/qt4projectconfigwidget.h
+++ b/src/plugins/qt4projectmanager/qt4projectconfigwidget.h
@@ -72,18 +72,20 @@ private slots:
     void qtVersionSelected(const QString &);
     void toolChainSelected(int index);
     void manageQtVersions();
+    void manageToolChains();
     void importLabelClicked();
 
     // Changes triggered from creator
     void qtVersionsChanged();
     void qtVersionChanged();
     void buildDirectoryChanged();
-    void toolChainTypeChanged();
+    void toolChainChanged();
     void updateImportLabel();
     void environmentChanged();
+    void updateToolChainCombo();
+
 private:
     void updateDetails();
-    void updateToolChainCombo();
     void updateShadowBuildUi();
 
     Ui::Qt4ProjectConfigWidget *m_ui;
diff --git a/src/plugins/qt4projectmanager/qt4projectconfigwidget.ui b/src/plugins/qt4projectmanager/qt4projectconfigwidget.ui
index 1bcb7177c94da0478edb9e14e34c399e6986bc06..7b40a1cfdb91dab451ec85d4bb11c00b111184ca 100644
--- a/src/plugins/qt4projectmanager/qt4projectconfigwidget.ui
+++ b/src/plugins/qt4projectmanager/qt4projectconfigwidget.ui
@@ -56,7 +56,28 @@
     </widget>
    </item>
    <item row="1" column="1">
-    <widget class="QComboBox" name="toolChainComboBox"/>
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <property name="spacing">
+      <number>4</number>
+     </property>
+     <item>
+      <widget class="QComboBox" name="toolChainComboBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="manageToolChainPushButton">
+       <property name="text">
+        <string>Manage</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
    </item>
    <item row="2" column="0">
     <widget class="QLabel" name="shadowBuildLabel">
diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h b/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h
index 8456f32cb1fd3ed403697eabd9e31ab9f24d0786..b796b6ac2009bb42ad55d7af3ed0ffa9321cfe8b 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h
+++ b/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h
@@ -128,6 +128,12 @@ const char * const HARMATTAN_DEVICE_TARGET_ID = "Qt4ProjectManager.Target.Harmat
 const char * const MEEGO_DEVICE_TARGET_ID = "Qt4ProjectManager.Target.MeegoDeviceTarget";
 const char * const QT_SIMULATOR_TARGET_ID = "Qt4ProjectManager.Target.QtSimulatorTarget";
 
+// ToolChains:
+const char * const GCCE_TOOLCHAIN_ID = "Qt4ProjectManager.ToolChain.GCCE";
+const char * const MAEMO_TOOLCHAIN_ID = "Qt4ProjectManager.ToolChain.Maemo";
+const char * const RVCT_TOOLCHAIN_ID = "Qt4ProjectManager.ToolChain.RVCT";
+const char * const WINSCW_TOOLCHAIN_ID = "Qt4ProjectManager.ToolChain.WINSCW";
+
 // ICONS
 const char * const ICON_QT_PROJECT = ":/qt4projectmanager/images/qt_project.png";
 const char * const ICON_WINDOW = ":/qt4projectmanager/images/window.png";
diff --git a/src/plugins/qt4projectmanager/qt4target.cpp b/src/plugins/qt4projectmanager/qt4target.cpp
index 72712311baab810ecdacf0d2f3f5902111883e64..1549a670d98cdc02502a2c339df40675e6bd5bcc 100644
--- a/src/plugins/qt4projectmanager/qt4target.cpp
+++ b/src/plugins/qt4projectmanager/qt4target.cpp
@@ -43,6 +43,7 @@
 #include <projectexplorer/buildsteplist.h>
 #include <projectexplorer/runconfiguration.h>
 #include <projectexplorer/customexecutablerunconfiguration.h>
+#include <projectexplorer/toolchainmanager.h>
 #include <projectexplorer/projectexplorerconstants.h>
 
 using namespace Qt4ProjectManager;
@@ -118,23 +119,32 @@ Qt4Project *Qt4BaseTarget::qt4Project() const
     return static_cast<Qt4Project *>(project());
 }
 
-QList<ProjectExplorer::ToolChainType> Qt4BaseTarget::filterToolChainTypes(const QList<ProjectExplorer::ToolChainType> &candidates) const
+QString Qt4BaseTarget::defaultBuildDirectory() const
 {
-    return candidates;
+    Qt4BaseTargetFactory *fac = Qt4BaseTargetFactory::qt4BaseTargetFactoryForId(id());
+    return fac->defaultShadowBuildDirectory(qt4Project()->defaultTopLevelBuildDirectory(), id());
 }
 
-ProjectExplorer::ToolChainType Qt4BaseTarget::preferredToolChainType(const QList<ProjectExplorer::ToolChainType> &candidates) const
+QList<ProjectExplorer::ToolChain *> Qt4BaseTarget::possibleToolChains(ProjectExplorer::BuildConfiguration *bc) const
 {
-    ProjectExplorer::ToolChainType preferredType = ProjectExplorer::ToolChain_INVALID;
-    if (!candidates.isEmpty())
-        preferredType = candidates.at(0);
-    return preferredType;
-}
+    QList<ProjectExplorer::ToolChain *> tmp;
+    QList<ProjectExplorer::ToolChain *> result;
 
-QString Qt4BaseTarget::defaultBuildDirectory() const
-{
-    Qt4BaseTargetFactory *fac = Qt4BaseTargetFactory::qt4BaseTargetFactoryForId(id());
-    return fac->defaultShadowBuildDirectory(qt4Project()->defaultTopLevelBuildDirectory(), id());
+    Qt4BuildConfiguration *qt4bc = qobject_cast<Qt4BuildConfiguration *>(bc);
+    if (!qt4bc && !qt4bc->qtVersion()->isValid())
+        return tmp;
+
+    QList<ProjectExplorer::Abi> abiList = qt4bc->qtVersion()->qtAbis();
+    foreach (const ProjectExplorer::Abi &abi, abiList)
+        tmp.append(ProjectExplorer::ToolChainManager::instance()->findToolChains(abi));
+
+    foreach (ProjectExplorer::ToolChain *tc, tmp) {
+        if (result.contains(tc))
+            continue;
+        if (tc->restrictedToTargets().isEmpty() || tc->restrictedToTargets().contains(id()))
+            result.append(tc);
+    }
+    return result;
 }
 
 void Qt4BaseTarget::removeUnconfiguredCustomExectutableRunConfigurations()
@@ -191,8 +201,6 @@ Qt4BuildConfiguration *Qt4BaseTarget::addQt4BuildConfiguration(QString displayNa
 
     // Finally set the qt version & ToolChain
     bc->setQtVersion(qtversion);
-    ProjectExplorer::ToolChainType defaultTc = preferredToolChainType(filterToolChainTypes(bc->qtVersion()->possibleToolChainTypes()));
-    bc->setToolChainType(defaultTc);
     if (!directory.isEmpty())
         bc->setShadowBuildAndDirectory(directory != project()->projectDirectory(), directory);
     addBuildConfiguration(bc);
diff --git a/src/plugins/qt4projectmanager/qt4target.h b/src/plugins/qt4projectmanager/qt4target.h
index 260fa6752c1e1bc11187824f5e49b5c1b91f095e..a50015cebabce0eba0f7aea2e992472e296733b7 100644
--- a/src/plugins/qt4projectmanager/qt4target.h
+++ b/src/plugins/qt4projectmanager/qt4target.h
@@ -80,11 +80,12 @@ public:
                                                             QString directory);
 
     virtual void createApplicationProFiles() = 0;
-    virtual QList<ProjectExplorer::ToolChainType> filterToolChainTypes(const QList<ProjectExplorer::ToolChainType> &candidates) const;
-    virtual ProjectExplorer::ToolChainType preferredToolChainType(const QList<ProjectExplorer::ToolChainType> &candidates) const;
     virtual QString defaultBuildDirectory() const;
 
     virtual QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Node *n) = 0;
+
+    QList<ProjectExplorer::ToolChain *> possibleToolChains(ProjectExplorer::BuildConfiguration *bc) const;
+
 signals:
     void buildDirectoryInitialized();
     /// emitted if the build configuration changed in a way that
diff --git a/src/plugins/qt4projectmanager/qtoptionspage.cpp b/src/plugins/qt4projectmanager/qtoptionspage.cpp
index bb4b33107b10b36d8be67e02b191e5b5529621b5..bb4a3c1d60689fad38b12542fcfd714ff0329ebc 100644
--- a/src/plugins/qt4projectmanager/qtoptionspage.cpp
+++ b/src/plugins/qt4projectmanager/qtoptionspage.cpp
@@ -44,8 +44,8 @@
 #include "qmldebugginglibrary.h"
 #include "debugginghelperbuildtask.h"
 
+#include <projectexplorer/abi.h>
 #include <projectexplorer/debugginghelper.h>
-#include <projectexplorer/toolchaintype.h>
 #include <coreplugin/coreconstants.h>
 #include <coreplugin/icore.h>
 #include <coreplugin/progressmanager/progressmanager.h>
@@ -151,15 +151,8 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent, QList<QtVersion *> ver
     m_versionUi->setupUi(versionInfoWidget);
     m_versionUi->qmakePath->setExpectedKind(Utils::PathChooser::File);
     m_versionUi->qmakePath->setPromptDialogTitle(tr("Select qmake Executable"));
-    m_versionUi->mingwPath->setExpectedKind(Utils::PathChooser::Directory);
-    m_versionUi->mingwPath->setPromptDialogTitle(tr("Select the MinGW Directory"));
-    m_versionUi->mwcPath->setExpectedKind(Utils::PathChooser::Directory);
-    m_versionUi->mwcPath->setPromptDialogTitle(tr("Select Carbide Install Directory"));
     m_versionUi->s60SDKPath->setExpectedKind(Utils::PathChooser::Directory);
     m_versionUi->s60SDKPath->setPromptDialogTitle(tr("Select S60 SDK Root"));
-    m_versionUi->gccePath->setExpectedKind(Utils::PathChooser::Directory);
-    m_versionUi->gccePath->setPromptDialogTitle(tr("Select the CSL ARM Toolchain (GCCE) Directory"));
-
 
     QWidget *debuggingHelperDetailsWidget = new QWidget();
     m_debuggingHelperUi->setupUi(debuggingHelperDetailsWidget);
@@ -198,17 +191,10 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent, QList<QtVersion *> ver
     connect(m_versionUi->nameEdit, SIGNAL(textEdited(const QString &)),
             this, SLOT(updateCurrentQtName()));
 
-
     connect(m_versionUi->qmakePath, SIGNAL(changed(QString)),
             this, SLOT(updateCurrentQMakeLocation()));
-    connect(m_versionUi->mingwPath, SIGNAL(changed(QString)),
-            this, SLOT(updateCurrentMingwDirectory()));
-    connect(m_versionUi->mwcPath, SIGNAL(changed(QString)),
-            this, SLOT(updateCurrentMwcDirectory()));
     connect(m_versionUi->s60SDKPath, SIGNAL(changed(QString)),
             this, SLOT(updateCurrentS60SDKDirectory()));
-    connect(m_versionUi->gccePath, SIGNAL(changed(QString)),
-            this, SLOT(updateCurrentGcceDirectory()));
     connect(m_versionUi->sbsV2Path, SIGNAL(changed(QString)),
             this, SLOT(updateCurrentSbsV2Directory()));
 
@@ -219,13 +205,9 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent, QList<QtVersion *> ver
 
     connect(m_versionUi->qmakePath, SIGNAL(browsingFinished()),
             this, SLOT(onQtBrowsed()));
-    connect(m_versionUi->mingwPath, SIGNAL(browsingFinished()),
-            this, SLOT(onMingwBrowsed()));
 
     connect(m_ui->qtdirList, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
             this, SLOT(versionChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
-    connect(m_versionUi->msvcComboBox, SIGNAL(currentIndexChanged(int)),
-            this, SLOT(msvcVersionChanged()));
 
     connect(m_debuggingHelperUi->rebuildButton, SIGNAL(clicked()),
             this, SLOT(buildDebuggingHelper()));
@@ -658,37 +640,17 @@ void QtOptionsPageWidget::updateState()
     m_ui->delButton->setEnabled(enabled && !isAutodetected);
     m_versionUi->nameEdit->setEnabled(enabled && !isAutodetected);
     m_versionUi->qmakePath->setEnabled(enabled && !isAutodetected);
-    m_versionUi->mingwPath->setEnabled(enabled);
-    m_versionUi->mwcPath->setEnabled(enabled);
     bool s60SDKPathEnabled = enabled &&
                              (isAutodetected ? version->s60SDKDirectory().isEmpty() : true);
     m_versionUi->s60SDKPath->setEnabled(s60SDKPathEnabled);
-    m_versionUi->gccePath->setEnabled(enabled);
 
     updateDebuggingHelperUi();
 }
 
-void QtOptionsPageWidget::makeMingwVisible(bool visible)
-{
-    m_versionUi->mingwLabel->setVisible(visible);
-    m_versionUi->mingwPath->setVisible(visible);
-}
-
-void QtOptionsPageWidget::makeMSVCVisible(bool visible)
-{
-    m_versionUi->msvcLabel->setVisible(visible);
-    m_versionUi->msvcComboBox->setVisible(visible);
-    m_versionUi->msvcNotFoundLabel->setVisible(false);
-}
-
 void QtOptionsPageWidget::makeS60Visible(bool visible)
 {
-    m_versionUi->mwcLabel->setVisible(visible);
-    m_versionUi->mwcPath->setVisible(visible);
     m_versionUi->s60SDKLabel->setVisible(visible);
     m_versionUi->s60SDKPath->setVisible(visible);
-    m_versionUi->gcceLabel->setVisible(visible);
-    m_versionUi->gccePath->setVisible(visible);
     m_versionUi->sbsV2Label->setVisible(visible);
     m_versionUi->sbsV2Path->setVisible(visible);
 }
@@ -697,66 +659,28 @@ void QtOptionsPageWidget::showEnvironmentPage(QTreeWidgetItem *item)
 {
     if (item) {
         int index = indexForTreeItem(item);
-        if (index < 0) {
+        QSharedPointerQtVersion qtVersion;
+        if (index >= 0)
+            qtVersion = m_versions.at(index);
+
+        if (qtVersion.isNull() || !qtVersion->isValid()) {
             m_versionUi->errorLabel->setText("");
-            makeMSVCVisible(false);
-            makeMingwVisible(false);
             makeS60Visible(false);
             return;
         }
-        const QSharedPointerQtVersion qtVersion = m_versions.at(index);
-        QList<ProjectExplorer::ToolChainType> types = qtVersion->possibleToolChainTypes();
-        QSet<QString> targets = qtVersion->supportedTargetIds();
-        if (types.isEmpty()) {
-            makeMSVCVisible(false);
-            makeMingwVisible(false);
-            makeS60Visible(false);
-        } else if (types.contains(ProjectExplorer::ToolChain_MinGW)) {
-            makeMSVCVisible(false);
-            makeMingwVisible(true);
-            makeS60Visible(false);
-            m_versionUi->mingwPath->setPath(m_versions.at(index)->mingwDirectory());
-        } else if (types.contains(ProjectExplorer::ToolChain_MSVC) ||
-                   types.contains(ProjectExplorer::ToolChain_WINCE)) {
-            makeMSVCVisible(false);
-            makeMingwVisible(false);
-            makeS60Visible(false);
-            const QStringList msvcEnvironments = ProjectExplorer::ToolChain::availableMSVCVersions(qtVersion->isQt64Bit());
-            if (msvcEnvironments.count() == 0) {
-                m_versionUi->msvcLabel->setVisible(true);
-                m_versionUi->msvcNotFoundLabel->setVisible(true);
-            } else {
-                 makeMSVCVisible(true);
-                 bool block = m_versionUi->msvcComboBox->blockSignals(true);
-                 m_versionUi->msvcComboBox->clear();
-                 foreach(const QString &msvcenv, msvcEnvironments) {
-                     m_versionUi->msvcComboBox->addItem(msvcenv);
-                     if (msvcenv == m_versions.at(index)->msvcVersion()) {
-                         m_versionUi->msvcComboBox->setCurrentIndex(m_versionUi->msvcComboBox->count() - 1);
-                     }
-                 }
-                 m_versionUi->msvcComboBox->blockSignals(block);
-            }
-        } else if (targets.contains(Constants::S60_DEVICE_TARGET_ID) ||
-                   targets.contains(Constants::S60_EMULATOR_TARGET_ID)) {
-            makeMSVCVisible(false);
-            makeMingwVisible(false);
+
+        ProjectExplorer::Abi qtAbi = qtVersion->qtAbis().at(0);
+
+        if (qtAbi.os() == ProjectExplorer::Abi::Symbian) {
             makeS60Visible(true);
-            m_versionUi->mwcPath->setPath(QDir::toNativeSeparators(m_versions.at(index)->mwcDirectory()));
             m_versionUi->s60SDKPath->setPath(QDir::toNativeSeparators(m_versions.at(index)->s60SDKDirectory()));
-            m_versionUi->gccePath->setPath(QDir::toNativeSeparators(m_versions.at(index)->gcceDirectory()));
             m_versionUi->sbsV2Path->setPath(m_versions.at(index)->sbsV2Directory());
             m_versionUi->sbsV2Path->setEnabled(m_versions.at(index)->isBuildWithSymbianSbsV2());
-        } else { //ProjectExplorer::ToolChain::GCC
-            makeMSVCVisible(false);
-            makeMingwVisible(false);
+        } else {
             makeS60Visible(false);
         }
-
         m_versionUi->errorLabel->setText(m_versions.at(index)->description());
     } else {
-        makeMSVCVisible(false);
-        makeMingwVisible(false);
         makeS60Visible(false);
     }
 }
@@ -816,16 +740,6 @@ void QtOptionsPageWidget::onQtBrowsed()
     updateState();
 }
 
-void QtOptionsPageWidget::onMingwBrowsed()
-{
-    const QString dir = m_versionUi->mingwPath->path();
-    if (dir.isEmpty())
-        return;
-
-    updateCurrentMingwDirectory();
-    updateState();
-}
-
 void QtOptionsPageWidget::updateCurrentQtName()
 {
     QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem();
@@ -905,37 +819,6 @@ void QtOptionsPageWidget::updateCurrentQMakeLocation()
     }
 }
 
-void QtOptionsPageWidget::updateCurrentMingwDirectory()
-{
-    QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem();
-    Q_ASSERT(currentItem);
-    int currentItemIndex = indexForTreeItem(currentItem);
-    if (currentItemIndex < 0)
-        return;
-    m_versions[currentItemIndex]->setMingwDirectory(m_versionUi->mingwPath->path());
-}
-
-void QtOptionsPageWidget::msvcVersionChanged()
-{
-    const QString &msvcVersion = m_versionUi->msvcComboBox->currentText();
-    QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem();
-    Q_ASSERT(currentItem);
-    int currentItemIndex = indexForTreeItem(currentItem);
-    if (currentItemIndex < 0)
-        return;
-    m_versions[currentItemIndex]->setMsvcVersion(msvcVersion);
-}
-
-void QtOptionsPageWidget::updateCurrentMwcDirectory()
-{
-    QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem();
-    Q_ASSERT(currentItem);
-    int currentItemIndex = indexForTreeItem(currentItem);
-    if (currentItemIndex < 0)
-        return;
-    m_versions[currentItemIndex]->setMwcDirectory(
-            QDir::fromNativeSeparators(m_versionUi->mwcPath->path()));
-}
 void QtOptionsPageWidget::updateCurrentS60SDKDirectory()
 {
     QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem();
@@ -947,17 +830,6 @@ void QtOptionsPageWidget::updateCurrentS60SDKDirectory()
             QDir::fromNativeSeparators(m_versionUi->s60SDKPath->path()));
 }
 
-void QtOptionsPageWidget::updateCurrentGcceDirectory()
-{
-    QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem();
-    Q_ASSERT(currentItem);
-    int currentItemIndex = indexForTreeItem(currentItem);
-    if (currentItemIndex < 0)
-        return;
-    m_versions[currentItemIndex]->setGcceDirectory(
-            QDir::fromNativeSeparators(m_versionUi->gccePath->path()));
-}
-
 void QtOptionsPageWidget::updateCurrentSbsV2Directory()
 {
     QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem();
@@ -986,11 +858,7 @@ QString QtOptionsPageWidget::searchKeywords() const
     QTextStream(&rc)
             << sep << m_versionUi->versionNameLabel->text()
             << sep << m_versionUi->pathLabel->text()
-            << sep << m_versionUi->mingwLabel->text()
-            << sep << m_versionUi->msvcLabel->text()
             << sep << m_versionUi->s60SDKLabel->text()
-            << sep << m_versionUi->gcceLabel->text()
-            << sep << m_versionUi->mwcLabel->text()
             << sep << m_versionUi->sbsV2Label->text()
             << sep << m_debuggingHelperUi->gdbHelperLabel->text()
             << sep << m_debuggingHelperUi->qmlDumpLabel->text()
diff --git a/src/plugins/qt4projectmanager/qtoptionspage.h b/src/plugins/qt4projectmanager/qtoptionspage.h
index b87ee99db070041200b8ea2b04bc70889c60e517..d6b175c0e7e4e7849548f788f7eed36445f83545 100644
--- a/src/plugins/qt4projectmanager/qtoptionspage.h
+++ b/src/plugins/qt4projectmanager/qtoptionspage.h
@@ -94,20 +94,13 @@ private slots:
     void addQtDir();
     void removeQtDir();
     void updateState();
-    void makeMingwVisible(bool visible);
-    void makeMSVCVisible(bool visible);
     void makeS60Visible(bool visible);
     void onQtBrowsed();
-    void onMingwBrowsed();
     void updateCurrentQtName();
     void updateCurrentQMakeLocation();
-    void updateCurrentMingwDirectory();
-    void updateCurrentMwcDirectory();
     void updateCurrentS60SDKDirectory();
-    void updateCurrentGcceDirectory();
     void updateCurrentSbsV2Directory();
     void updateDebuggingHelperUi();
-    void msvcVersionChanged();
     void buildDebuggingHelper(DebuggingHelperBuildTask::Tools tools
                               = DebuggingHelperBuildTask::AllTools);
     void buildGdbHelper();
diff --git a/src/plugins/qt4projectmanager/qtparser.h b/src/plugins/qt4projectmanager/qtparser.h
index a4296f05fdc800a76f46b7e70de5e0e2a65e8554..f3fb5e402cb4fed12d4cf420b028de8df15c0e9f 100644
--- a/src/plugins/qt4projectmanager/qtparser.h
+++ b/src/plugins/qt4projectmanager/qtparser.h
@@ -47,7 +47,7 @@ class QtParser : public ProjectExplorer::IOutputParser
 
 public:
     QtParser();
-    virtual void stdError(const QString &line);
+    void stdError(const QString &line);
 
 private:
     QRegExp m_mocRegExp;
diff --git a/src/plugins/qt4projectmanager/qtversioninfo.ui b/src/plugins/qt4projectmanager/qtversioninfo.ui
index c3d37f6e11e8cb6f579d07e94195775587ad5e54..6d77a108994a4eda4f2fb9f34b26c2b5813ffb7c 100644
--- a/src/plugins/qt4projectmanager/qtversioninfo.ui
+++ b/src/plugins/qt4projectmanager/qtversioninfo.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>404</width>
-    <height>197</height>
+    <height>105</height>
    </rect>
   </property>
   <layout class="QGridLayout">
@@ -34,97 +34,33 @@
    <item row="2" column="1">
     <widget class="Utils::PathChooser" name="qmakePath" native="true"/>
    </item>
-   <item row="3" column="0">
-    <widget class="QLabel" name="mingwLabel">
-     <property name="text">
-      <string>MinGW directory:</string>
-     </property>
-    </widget>
-   </item>
-   <item row="3" column="1">
-    <widget class="Utils::PathChooser" name="mingwPath" native="true"/>
-   </item>
    <item row="4" column="0">
-    <widget class="QLabel" name="msvcLabel">
-     <property name="text">
-      <string>Toolchain:</string>
-     </property>
-    </widget>
-   </item>
-   <item row="6" column="0">
     <widget class="QLabel" name="s60SDKLabel">
      <property name="text">
       <string>S60 SDK:</string>
      </property>
     </widget>
    </item>
-   <item row="6" column="1">
+   <item row="4" column="1">
     <widget class="Utils::PathChooser" name="s60SDKPath" native="true"/>
    </item>
-   <item row="7" column="0">
-    <widget class="QLabel" name="gcceLabel">
-     <property name="text">
-      <string>CSL/GCCE directory:</string>
-     </property>
-    </widget>
-   </item>
-   <item row="7" column="1">
-    <widget class="Utils::PathChooser" name="gccePath" native="true"/>
-   </item>
-   <item row="8" column="0">
-    <widget class="QLabel" name="mwcLabel">
-     <property name="text">
-      <string>Carbide directory:</string>
-     </property>
-    </widget>
-   </item>
-   <item row="8" column="1">
-    <widget class="Utils::PathChooser" name="mwcPath" native="true"/>
-   </item>
-   <item row="9" column="0">
+   <item row="5" column="0">
     <widget class="QLabel" name="sbsV2Label">
      <property name="text">
       <string>SBS v2 directory:</string>
      </property>
     </widget>
    </item>
-   <item row="9" column="1">
+   <item row="5" column="1">
     <widget class="Utils::PathChooser" name="sbsV2Path" native="true"/>
    </item>
-   <item row="10" column="0" colspan="2">
+   <item row="6" column="0" colspan="2">
     <widget class="QLabel" name="errorLabel">
      <property name="text">
       <string/>
      </property>
     </widget>
    </item>
-   <item row="4" column="1">
-    <layout class="QHBoxLayout" name="msvcHorizontalLayout">
-     <item>
-      <widget class="QComboBox" name="msvcComboBox">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QLabel" name="msvcNotFoundLabel">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="text">
-        <string>Unable to detect MSVC version.</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
   </layout>
  </widget>
  <customwidgets>
diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp
index 9543c89dac4eeeac4c005dfb19bec65d02dc3a5b..58e9e457f6f3d5c23f5e390f605ee12f711a57b9 100644
--- a/src/plugins/qt4projectmanager/qtversionmanager.cpp
+++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp
@@ -43,6 +43,8 @@
 #include "qt-s60/s60projectchecker.h"
 #include "qt-s60/abldparser.h"
 #include "qt-s60/sbsv2parser.h"
+#include "qt-s60/gccetoolchain.h"
+#include "qt-s60/winscwtoolchain.h"
 
 #include "qmlobservertool.h"
 #include "qmldumptool.h"
@@ -52,7 +54,10 @@
 #include <projectexplorer/gnumakeparser.h>
 #include <projectexplorer/projectexplorer.h>
 #include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/toolchainmanager.h>
 #include <projectexplorer/cesdkhandler.h>
+#include <projectexplorer/gcctoolchain.h>
+#include <projectexplorer/toolchainmanager.h>
 #include <utils/synchronousprocess.h>
 #include <coreplugin/coreconstants.h>
 #include <coreplugin/icore.h>
@@ -85,6 +90,24 @@ static const char *PATH_AUTODETECTION_SOURCE = "PATH";
 
 enum { debug = 0 };
 
+template<class T>
+static T *createToolChain(const QString &id)
+{
+    QList<ProjectExplorer::ToolChainFactory *> factories =
+            ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::ToolChainFactory>();
+    foreach (ProjectExplorer::ToolChainFactory *f, factories) {
+       if (f->id() == id) {
+           Q_ASSERT(f->canCreate());
+           return static_cast<T *>(f->create());
+       }
+    }
+    return 0;
+}
+
+// --------------------------------------------------------------------------
+// QtVersionManager
+// --------------------------------------------------------------------------
+
 QtVersionManager *QtVersionManager::m_self = 0;
 
 QtVersionManager::QtVersionManager()
@@ -136,12 +159,40 @@ QtVersionManager::QtVersionManager()
                                            id,
                                            isAutodetected,
                                            autodetectionSource);
-        version->setMingwDirectory(s->value("MingwDirectory").toString());
-        version->setMsvcVersion(s->value("msvcVersion").toString());
-        version->setMwcDirectory(s->value("MwcDirectory").toString());
         version->setS60SDKDirectory(s->value("S60SDKDirectory").toString());
-        version->setGcceDirectory(s->value("GcceDirectory").toString());
         version->setSbsV2Directory(s->value(QLatin1String("SBSv2Directory")).toString());
+
+        // Update from 2.1 or earlier:
+        QString mingwDir = s->value(QLatin1String("MingwDirectory")).toString();
+        if (!mingwDir.isEmpty()) {
+            ProjectExplorer::MingwToolChain *tc = createToolChain<ProjectExplorer::MingwToolChain>(ProjectExplorer::Constants::MINGW_TOOLCHAIN_ID);
+            if (tc) {
+                tc->setCompilerPath(QDir::fromNativeSeparators(mingwDir) + QLatin1String("/bin/gcc.exe"));
+                tc->setDisplayName(tr("Mingw from %1").arg(version->displayName()));
+                ProjectExplorer::ToolChainManager::instance()->registerToolChain(tc);
+            }
+        }
+        QString mwcDir = s->value(QLatin1String("MwcDirectory")).toString();
+        if (!mwcDir.isEmpty()) {
+            WinscwToolChain *tc = createToolChain<WinscwToolChain>(Constants::WINSCW_TOOLCHAIN_ID);
+            if (tc) {
+                tc->setCompilerPath(QDir::fromNativeSeparators(mwcDir)
+                                    + QLatin1String("/x86Build/Symbian_Tools/Command_Line_Tools/mwwinrc.exe"));
+                tc->setDisplayName(tr("WINSCW from %1").arg(version->displayName()));
+                ProjectExplorer::ToolChainManager::instance()->registerToolChain(tc);
+            }
+        }
+        QString gcceDir = s->value(QLatin1String("GcceDirectory")).toString();
+        if (!gcceDir.isEmpty()) {
+            GcceToolChain *tc = createToolChain<GcceToolChain>(Constants::GCCE_TOOLCHAIN_ID);
+            if (tc) {
+                tc->setCompilerPath(QDir::fromNativeSeparators(gcceDir)
+                                    + QLatin1String("/bin/arm-none-symbianelf-g++.exe"));
+                tc->setDisplayName(tr("GCCE from %1").arg(version->displayName()));
+                ProjectExplorer::ToolChainManager::instance()->registerToolChain(tc);
+            }
+        }
+
         m_versions.append(version);
     }
     s->endArray();
@@ -309,14 +360,10 @@ void QtVersionManager::writeVersionsIntoSettings()
         s->setValue("Path", version->versionInfo().value("QT_INSTALL_DATA"));
         s->setValue("QMakePath", version->qmakeCommand());
         s->setValue("Id", version->uniqueId());
-        s->setValue("MingwDirectory", version->mingwDirectory());
-        s->setValue("msvcVersion", version->msvcVersion());
         s->setValue("isAutodetected", version->isAutodetected());
         if (version->isAutodetected())
             s->setValue("autodetectionSource", version->autodetectionSource());
-        s->setValue("MwcDirectory", version->mwcDirectory());
         s->setValue("S60SDKDirectory", version->s60SDKDirectory());
-        s->setValue("GcceDirectory", version->gcceDirectory());
         s->setValue(QLatin1String("SBSv2Directory"), version->sbsV2Directory());
     }
     s->endArray();
@@ -352,13 +399,14 @@ QtVersion *QtVersionManager::version(int id) const
     return m_emptyVersion;
 }
 
+// FIXME: Rework this!
 void QtVersionManager::addNewVersionsFromInstaller()
 {
     // Add new versions which may have been installed by the WB installer in the form:
     // NewQtVersions="qt 4.3.2=c:\\qt\\qt432\bin\qmake.exe;qt embedded=c:\\qtembedded;"
-    // or NewQtVersions="qt 4.3.2=c:\\qt\\qt432bin\qmake.exe=c:\\qtcreator\\mingw\\=MSVCName;
+    // or NewQtVersions="qt 4.3.2=c:\\qt\\qt432bin\qmake.exe;
     // i.e.
-    // NewQtVersions="versionname=pathtoversion=mingw=s60sdk=gcce=carbide;"
+    // NewQtVersions="versionname=pathtoversion=s60sdk;"
     // Duplicate entries are not added, the first new version is set as default.
     QSettings *settings = Core::ICore::instance()->settings();
     QSettings *globalSettings = Core::ICore::instance()->settings(QSettings::SystemScope);
@@ -388,17 +436,9 @@ void QtVersionManager::addNewVersionsFromInstaller()
             if (QFile::exists(newVersionData[1])) {
                 QtVersion *version = new QtVersion(newVersionData[0], newVersionData[1], m_idcount++ );
                 if (newVersionData.count() >= 3)
-                    version->setMingwDirectory(newVersionData[2]);
+                    version->setS60SDKDirectory(QDir::fromNativeSeparators(newVersionData[2]));
                 if (newVersionData.count() >= 4)
-                    version->setS60SDKDirectory(QDir::fromNativeSeparators(newVersionData[3]));
-                if (newVersionData.count() >= 5)
-                    version->setGcceDirectory(QDir::fromNativeSeparators(newVersionData[4]));
-                if (newVersionData.count() >= 6)
-                    version->setMwcDirectory(QDir::fromNativeSeparators(newVersionData[5]));
-                if (newVersionData.count() >= 7)
-                    version->setMsvcVersion(newVersionData[6]);
-                if (newVersionData.count() >= 8)
-                    version->setSbsV2Directory(QDir::fromNativeSeparators(newVersionData[7]));
+                    version->setSbsV2Directory(QDir::fromNativeSeparators(newVersionData[3]));
 
                 bool versionWasAlreadyInList = false;
                 foreach(const QtVersion * const it, m_versions) {
@@ -467,10 +507,6 @@ bool QtVersionManager::equals(QtVersion *a, QtVersion *b)
         return false;
     if (a->m_id != b->m_id)
         return false;
-    if (a->m_mingwDirectory != b->m_mingwDirectory
-        || a->m_msvcVersion != b->m_msvcVersion
-        || a->m_mwcDirectory != b->m_mwcDirectory)
-        return false;
     if (a->m_displayName != b->displayName())
         return false;
     return true;
@@ -538,9 +574,9 @@ void QtVersionManager::setNewQtVersions(QList<QtVersion *> newVersions)
         emit qtVersionsChanged(changedVersions);
 }
 
-///
-/// QtVersion
-///
+// --------------------------------------------------------------------------
+// QtVersion
+// --------------------------------------------------------------------------
 
 QtVersion::QtVersion(const QString &name, const QString &qmakeCommand, int id,
                      bool isAutodetected, const QString &autodetectionSource)
@@ -551,15 +587,14 @@ QtVersion::QtVersion(const QString &name, const QString &qmakeCommand, int id,
     m_hasQmlDump(false),
     m_hasQmlDebuggingLibrary(false),
     m_hasQmlObserver(false),
-    m_toolChainUpToDate(false),
+    m_abiUpToDate(false),
     m_versionInfoUpToDate(false),
     m_notInstalled(false),
     m_defaultConfigIsDebug(true),
     m_defaultConfigIsDebugAndRelease(true),
     m_hasExamples(false),
     m_hasDemos(false),
-    m_hasDocumentation(false),
-    m_isBuildUsingSbsV2(false)
+    m_hasDocumentation(false)
 {
     if (id == -1)
         m_id = getUniqueId();
@@ -577,15 +612,14 @@ QtVersion::QtVersion(const QString &name, const QString &qmakeCommand,
     m_hasQmlDump(false),
     m_hasQmlDebuggingLibrary(false),
     m_hasQmlObserver(false),
-    m_toolChainUpToDate(false),
+    m_abiUpToDate(false),
     m_versionInfoUpToDate(false),
     m_notInstalled(false),
     m_defaultConfigIsDebug(true),
     m_defaultConfigIsDebugAndRelease(true),
     m_hasExamples(false),
     m_hasDemos(false),
-    m_hasDocumentation(false),
-    m_isBuildUsingSbsV2(false)
+    m_hasDocumentation(false)
 {
     m_id = getUniqueId();
     setQMakeCommand(qmakeCommand);
@@ -599,15 +633,14 @@ QtVersion::QtVersion(const QString &qmakeCommand, bool isAutodetected, const QSt
     m_hasQmlDump(false),
     m_hasQmlDebuggingLibrary(false),
     m_hasQmlObserver(false),
-    m_toolChainUpToDate(false),
+    m_abiUpToDate(false),
     m_versionInfoUpToDate(false),
     m_notInstalled(false),
     m_defaultConfigIsDebug(true),
     m_defaultConfigIsDebugAndRelease(true),
     m_hasExamples(false),
     m_hasDemos(false),
-    m_hasDocumentation(false),
-    m_isBuildUsingSbsV2(false)
+    m_hasDocumentation(false)
 {
     m_id = getUniqueId();
     setQMakeCommand(qmakeCommand);
@@ -621,20 +654,18 @@ QtVersion::QtVersion()
     m_hasQmlDump(false),
     m_hasQmlDebuggingLibrary(false),
     m_hasQmlObserver(false),
-    m_toolChainUpToDate(false),
+    m_abiUpToDate(false),
     m_versionInfoUpToDate(false),
     m_notInstalled(false),
     m_defaultConfigIsDebug(true),
     m_defaultConfigIsDebugAndRelease(true),
     m_hasExamples(false),
     m_hasDemos(false),
-    m_hasDocumentation(false),
-    m_isBuildUsingSbsV2(false)
+    m_hasDocumentation(false)
 {
     setQMakeCommand(QString());
 }
 
-
 QtVersion::~QtVersion()
 {
 }
@@ -646,30 +677,39 @@ QString QtVersion::toHtml() const
     str << "<html><body><table>";
     str << "<tr><td><b>" << QtVersionManager::tr("Name:")
         << "</b></td><td>" << displayName() << "</td></tr>";
-    str << "<tr><td><b>" << QtVersionManager::tr("Source:")
-        << "</b></td><td>" << sourcePath() << "</td></tr>";
-    str << "<tr><td><b>" << QtVersionManager::tr("mkspec:")
-        << "</b></td><td>" << mkspec() << "</td></tr>";
-    str << "<tr><td><b>" << QtVersionManager::tr("qmake:")
-        << "</b></td><td>" << m_qmakeCommand << "</td></tr>";
-    updateToolChainAndMkspec();
-    if (m_defaultConfigIsDebug || m_defaultConfigIsDebugAndRelease) {
-        str << "<tr><td><b>" << QtVersionManager::tr("Default:") << "</b></td><td>"
-            << (m_defaultConfigIsDebug ? "debug" : "release");
-        if (m_defaultConfigIsDebugAndRelease)
-            str << " debug_and_release";
-        str << "</td></tr>";
-    } // default config.
-    str << "<tr><td><b>" << QtVersionManager::tr("Version:")
-        << "</b></td><td>" << qtVersionString() << "</td></tr>";
-    if (hasDebuggingHelper())
-        str << "<tr><td><b>" << QtVersionManager::tr("Debugging helper:")
-            << "</b></td><td>" << debuggingHelperLibrary() << "</td></tr>";
-    const QHash<QString,QString> vInfo = versionInfo();
-    if (!vInfo.isEmpty()) {
-        const QHash<QString,QString>::const_iterator vcend = vInfo.constEnd();
-        for (QHash<QString,QString>::const_iterator it = vInfo.constBegin(); it != vcend; ++it)
-            str << "<tr><td><pre>" << it.key() <<  "</pre></td><td>" << it.value() << "</td></tr>";
+    if (!isValid()) {
+        str << "<tr><td colspan=2><b>" + QtVersionManager::tr("Invalid Qt version") +"</b></td></tr>";
+    } else {
+        QString prefix = QLatin1String("<tr><td><b>") + QtVersionManager::tr("ABI:") + QLatin1String("</b></td>");
+        foreach (const ProjectExplorer::Abi &abi, qtAbis()) {
+            str << prefix << "<td>" << abi.toString() << "</td></tr>";
+            prefix = QLatin1String("<tr><td></td>");
+        }
+        str << "<tr><td><b>" << QtVersionManager::tr("Source:")
+            << "</b></td><td>" << sourcePath() << "</td></tr>";
+        str << "<tr><td><b>" << QtVersionManager::tr("mkspec:")
+            << "</b></td><td>" << mkspec() << "</td></tr>";
+        str << "<tr><td><b>" << QtVersionManager::tr("qmake:")
+            << "</b></td><td>" << m_qmakeCommand << "</td></tr>";
+        updateAbiAndMkspec();
+        if (m_defaultConfigIsDebug || m_defaultConfigIsDebugAndRelease) {
+            str << "<tr><td><b>" << QtVersionManager::tr("Default:") << "</b></td><td>"
+                << (m_defaultConfigIsDebug ? "debug" : "release");
+            if (m_defaultConfigIsDebugAndRelease)
+                str << " debug_and_release";
+            str << "</td></tr>";
+        } // default config.
+        str << "<tr><td><b>" << QtVersionManager::tr("Version:")
+            << "</b></td><td>" << qtVersionString() << "</td></tr>";
+        if (hasDebuggingHelper())
+            str << "<tr><td><b>" << QtVersionManager::tr("Debugging helper:")
+                << "</b></td><td>" << debuggingHelperLibrary() << "</td></tr>";
+        const QHash<QString,QString> vInfo = versionInfo();
+        if (!vInfo.isEmpty()) {
+            const QHash<QString,QString>::const_iterator vcend = vInfo.constEnd();
+            for (QHash<QString,QString>::const_iterator it = vInfo.constBegin(); it != vcend; ++it)
+                str << "<tr><td><pre>" << it.key() <<  "</pre></td><td>" << it.value() << "</td></tr>";
+        }
     }
     str << "</table></body></html>";
     return rc;
@@ -768,19 +808,19 @@ QString QtVersion::sourcePath() const
 
 QString QtVersion::mkspec() const
 {
-    updateToolChainAndMkspec();
+    updateAbiAndMkspec();
     return m_mkspec;
 }
 
 QString QtVersion::mkspecPath() const
 {
-    updateToolChainAndMkspec();
+    updateAbiAndMkspec();
     return m_mkspecFullPath;
 }
 
 bool QtVersion::isBuildWithSymbianSbsV2() const
 {
-    updateToolChainAndMkspec();
+    updateAbiAndMkspec();
     return m_isBuildUsingSbsV2;
 }
 
@@ -840,7 +880,7 @@ void QtVersion::setQMakeCommand(const QString& qmakeCommand)
     m_linguistCommand.clear();
     m_qmlviewerCommand.clear();
     m_uicCommand.clear();
-    m_toolChainUpToDate = false;
+    m_abiUpToDate = false;
     // TODO do i need to optimize this?
     m_versionInfoUpToDate = false;
     m_qtVersionString = QString();
@@ -1306,15 +1346,50 @@ QString QtVersion::qmlviewerCommand() const
     return m_qmlviewerCommand;
 }
 
+QString QtVersion::systemRoot() const
+{
+    if (m_systemRoot.isNull()) {
+        if (supportsTargetId(Constants::S60_DEVICE_TARGET_ID)
+                || supportsTargetId(Constants::S60_EMULATOR_TARGET_ID)) {
+            S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(this);
+
+            m_systemRoot = device.epocRoot;
+            if (!m_systemRoot.endsWith(QLatin1Char('/')))
+                m_systemRoot.append(QLatin1Char('/'));
+
+        } else if (supportsTargetId(Constants::MAEMO5_DEVICE_TARGET_ID) ||
+                   supportsTargetId(Constants::HARMATTAN_DEVICE_TARGET_ID)) {
+            QFile file(QDir::cleanPath(MaemoGlobal::targetRoot(this))
+                       + 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_systemRoot = MaemoGlobal::maddeRoot(this)
+                                + QLatin1String("/sysroots/") + list.at(1);
+                    }
+                }
+            }
+        }
+        if (m_systemRoot.isNull())
+            m_systemRoot = QLatin1String("");
+    }
+    return m_systemRoot;
+}
+
 bool QtVersion::supportsTargetId(const QString &id) const
 {
-    updateToolChainAndMkspec();
+    updateAbiAndMkspec();
     return m_targetIds.contains(id);
 }
 
 QSet<QString> QtVersion::supportedTargetIds() const
 {
-    updateToolChainAndMkspec();
+    updateAbiAndMkspec();
     return m_targetIds;
 }
 
@@ -1328,42 +1403,20 @@ bool QtVersion::supportsMobileTarget() const
            supportsTargetId(Constants::QT_SIMULATOR_TARGET_ID);
 }
 
-QList<QSharedPointer<ProjectExplorer::ToolChain> > QtVersion::toolChains() const
+QList<ProjectExplorer::Abi> QtVersion::qtAbis() const
 {
-    updateToolChainAndMkspec();
-    return m_toolChains;
-}
-
-ProjectExplorer::ToolChain *QtVersion::toolChain(ProjectExplorer::ToolChainType type) const
-{
-    foreach(const QSharedPointer<ProjectExplorer::ToolChain> &tcptr, toolChains())
-        if (tcptr->type() == type)
-            return tcptr.data();
-    return 0;
-}
-
-QList<ProjectExplorer::ToolChainType> QtVersion::possibleToolChainTypes() const
-{
-    QList<ProjectExplorer::ToolChainType> types;
-    foreach(const QSharedPointer<ProjectExplorer::ToolChain> &tc, toolChains())
-        types << tc->type();
-    return types;
+    updateAbiAndMkspec();
+    return m_abis;
 }
 
 // if none, then it's INVALID everywhere this function is called
-void QtVersion::updateToolChainAndMkspec() const
+void QtVersion::updateAbiAndMkspec() const
 {
-    typedef QSharedPointer<ProjectExplorer::ToolChain> ToolChainPtr;
-    if (m_toolChainUpToDate)
+    if (m_id == -1 || m_abiUpToDate)
         return;
 
-    m_toolChains.clear();
     m_targetIds.clear();
-
-    if (!isValid()) {
-        m_targetIds.insert(Constants::DESKTOP_TARGET_ID);
-        return;
-    }
+    m_abis.clear();
 
 //    qDebug()<<"Finding mkspec for"<<qmakeCommand();
 
@@ -1446,11 +1499,8 @@ void QtVersion::updateToolChainAndMkspec() const
     }
 
     m_mkspec = mkspec;
-
     m_isBuildUsingSbsV2 = false;
 
-//    qDebug()<<"mkspec for "<<qmakeCommand()<<" is "<<m_mkspec<<m_mkspecFullPath;
-
     ProFileOption option;
     option.properties = versionInfo();
     ProMessageHandler msgHandler(true);
@@ -1467,74 +1517,62 @@ void QtVersion::updateToolChainAndMkspec() const
     QString makefileGenerator = evaluator.value("MAKEFILE_GENERATOR");
     QString ce_sdk = evaluator.values("CE_SDK").join(QLatin1String(" "));
     QString ce_arch = evaluator.value("CE_ARCH");
-    QString qt_arch = evaluator.value("QT_ARCH");
+
+
+    // Evaluate all the information we have:
     if (!ce_sdk.isEmpty() && !ce_arch.isEmpty()) {
-        QString wincePlatformName = ce_sdk + " (" + ce_arch + QLatin1Char(')');
-        m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatformName));
+        // Treat windows CE as desktop.
+        m_abis.append(ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Windows,
+                                           ProjectExplorer::Abi::Windows_ce, ProjectExplorer::Abi::Format_PE, false));
         m_targetIds.insert(Constants::DESKTOP_TARGET_ID);
     } else if (makefileGenerator == QLatin1String("SYMBIAN_ABLD") ||
                makefileGenerator == QLatin1String("SYMBIAN_SBSV2") ||
                makefileGenerator == QLatin1String("SYMBIAN_UNIX")) {
         m_isBuildUsingSbsV2 = (makefileGenerator == QLatin1String("SYMBIAN_SBSV2"));
-        if (S60Manager *s60mgr = S60Manager::instance()) {
-#    ifdef Q_OS_WIN
-            m_targetIds.insert(QLatin1String(Constants::S60_DEVICE_TARGET_ID));
-            m_toolChains << ToolChainPtr(s60mgr->createGCCEToolChain(this));
-            if (S60Manager::hasRvct2Compiler())
-                m_toolChains << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain_RVCT2_ARMV5))
-                             << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain_RVCT2_ARMV6));
-            if (S60Manager::hasRvct4Compiler())
-                m_toolChains << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain_RVCT4_ARMV5))
-                             << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain_RVCT4_ARMV6));
-            if (!mwcDirectory().isEmpty()) {
-                m_toolChains << ToolChainPtr(s60mgr->createWINSCWToolChain(this));
-                m_targetIds.insert(QLatin1String(Constants::S60_EMULATOR_TARGET_ID));
-            }
-#    else
-            if (S60Manager::hasRvct2Compiler())
-                m_toolChains << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC));
-            m_toolChains << ToolChainPtr(s60mgr->createGCCE_GnuPocToolChain(this));
+        if (S60Manager::instance()) {
+            m_abis.append(ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Symbian,
+                                               ProjectExplorer::Abi::UNKNOWN_OSFLAVOUR,
+                                               ProjectExplorer::Abi::Format_ELF,
+                                               32));
             m_targetIds.insert(QLatin1String(Constants::S60_DEVICE_TARGET_ID));
-#    endif
+            m_targetIds.insert(QLatin1String(Constants::S60_EMULATOR_TARGET_ID));
         }
     } else if (MaemoGlobal::isValidMaemo5QtVersion(this)) {
-        m_toolChains << ToolChainPtr(MaemoManager::instance().maemo5ToolChain(this));
+        m_abis.append(ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Linux,
+                                           ProjectExplorer::Abi::Linux_maemo, ProjectExplorer::Abi::Format_ELF,
+                                           32));
         m_targetIds.insert(QLatin1String(Constants::MAEMO5_DEVICE_TARGET_ID));
     } else if (MaemoGlobal::isValidHarmattanQtVersion(this)) {
-        m_toolChains << ToolChainPtr(MaemoManager::instance().harmattanToolChain(this));
+        m_abis.append(ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Linux,
+                                           ProjectExplorer::Abi::Linux_harmattan,
+                                           ProjectExplorer::Abi::Format_ELF,
+                                           32));
         m_targetIds.insert(QLatin1String(Constants::HARMATTAN_DEVICE_TARGET_ID));
     } else if (MaemoGlobal::isValidMeegoQtVersion(this)) {
-        m_toolChains << ToolChainPtr(MaemoManager::instance().meegoToolChain(this));
+        m_abis.append(ProjectExplorer::Abi(ProjectExplorer::Abi::ARM, ProjectExplorer::Abi::Linux,
+                                           ProjectExplorer::Abi::Linux_meego,
+                                           ProjectExplorer::Abi::Format_ELF, 32));
         m_targetIds.insert(QLatin1String(Constants::MEEGO_DEVICE_TARGET_ID));
-    } else if (qmakeCXX == "cl" || qmakeCXX == "icl") {
-        // TODO proper support for intel cl. Detect matching VC version unless set.
-        if (m_msvcVersion.isEmpty())
-            m_msvcVersion = ProjectExplorer::MSVCToolChain::findInstallationByMkSpec(isQt64Bit(), mkspec).name;
-        m_toolChains << ToolChainPtr(
-                ProjectExplorer::ToolChain::createMSVCToolChain(m_msvcVersion, isQt64Bit()));
-        m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
-    } else if (qmakeCXX == "g++" && makefileGenerator == "MINGW") {
-        Utils::Environment env = Utils::Environment::systemEnvironment();
-        //addToEnvironment(env);
-        env.prependOrSetPath(mingwDirectory() + "/bin");
-        qmakeCXX = env.searchInPath(qmakeCXX);
-        m_toolChains << ToolChainPtr(
-                ProjectExplorer::ToolChain::createMinGWToolChain(qmakeCXX, mingwDirectory()));
-        m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
-    } else if (qmakeCXX.contains("g++")) { // All g++ variants are treated as desktop g++
-                                           // we should try to do a better job, but for now that's good enough
-        Utils::Environment env = Utils::Environment::systemEnvironment();
-        //addToEnvironment(env);
-        qmakeCXX = env.searchInPath(qmakeCXX);
-        m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createGccToolChain(qmakeCXX));
-        m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
-    } else if (qmakeCXX == QLatin1String("icpc")) {
-        m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createLinuxIccToolChain());
+    } else if (qmakeCXX.contains("g++")
+               || qmakeCXX == "cl" || qmakeCXX == "icl" // intel cl
+               || qmakeCXX == QLatin1String("icpc")) {
+        m_abis = ProjectExplorer::Abi::abisOfBinary(qtCorePath());
+#if defined (Q_OS_WIN)
+        if (makefileGenerator == "MINGW") {
+            QList<ProjectExplorer::Abi> tmp = m_abis;
+            m_abis.clear();
+            foreach (const ProjectExplorer::Abi &abi, tmp)
+                m_abis.append(ProjectExplorer::Abi(abi.architecture(), abi.os(), ProjectExplorer::Abi::Windows_msys,
+                                                   abi.binaryFormat(), abi.wordWidth()));
+        }
+#endif
         m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
     }
-    if (m_toolChains.isEmpty()) {
-        qDebug()<<"Could not create ToolChain for"<<m_mkspecFullPath<<qmakeCXX;
-        qDebug()<<"Qt Creator doesn't know about the system includes, nor the systems defines.";
+
+    if (m_abis.isEmpty()) {
+        qDebug() << "Could not find ABI for" << m_mkspecFullPath << qmakeCXX;
+        qDebug() << "Qt Creator doesn't know about the system includes, "
+                    "nor the systems defines.";
     }
 
     QStringList configValues = evaluator.values("CONFIG");
@@ -1554,7 +1592,7 @@ void QtVersion::updateToolChainAndMkspec() const
     }
 
     ProFileCacheManager::instance()->decRefCount();
-    m_toolChainUpToDate = true;
+    m_abiUpToDate = true;
 }
 
 QString QtVersion::resolveLink(const QString &path) const
@@ -1568,16 +1606,26 @@ QString QtVersion::resolveLink(const QString &path) const
     return f.filePath();
 }
 
-QString QtVersion::mwcDirectory() const
+QString QtVersion::qtCorePath() const
 {
-    return m_mwcDirectory;
-}
+    QString path = libraryInstallPath();
 
-void QtVersion::setMwcDirectory(const QString &directory)
-{
-    m_mwcDirectory = directory;
-    m_toolChainUpToDate = false;
+    QStringList toTest;
+    toTest << path + QLatin1String("/libQtCore.so.") + qtVersionString();
+    toTest << path + QLatin1String("/libQtCore.so");
+    toTest << path + QLatin1String("/QtCore.dll");
+    toTest << path + QLatin1String("/QtCored.dll");
+    toTest << path + QLatin1String("/QtCore4.dll");
+    toTest << path + QLatin1String("/QtCored4.dll");
+    toTest << path + QLatin1String("/QtCore.framework/QtCore");
+
+    foreach (const QString &path, toTest) {
+        if (QFileInfo(path).exists())
+            return path;
+    }
+    return QString();
 }
+
 QString QtVersion::s60SDKDirectory() const
 {
     return m_s60SDKDirectory;
@@ -1586,18 +1634,7 @@ QString QtVersion::s60SDKDirectory() const
 void QtVersion::setS60SDKDirectory(const QString &directory)
 {
     m_s60SDKDirectory = directory;
-    m_toolChainUpToDate = false;
-}
-
-QString QtVersion::gcceDirectory() const
-{
-    return m_gcceDirectory;
-}
-
-void QtVersion::setGcceDirectory(const QString &directory)
-{
-    m_gcceDirectory = directory;
-    m_toolChainUpToDate = false;
+    m_abiUpToDate = false;
 }
 
 QString QtVersion::sbsV2Directory() const
@@ -1610,41 +1647,80 @@ void QtVersion::setSbsV2Directory(const QString &directory)
     m_sbsV2Directory = directory;
 }
 
-QString QtVersion::mingwDirectory() const
+void QtVersion::addToEnvironment(Utils::Environment &env) const
 {
-    return m_mingwDirectory;
-}
+    // Generic:
+    env.set("QTDIR", QDir::toNativeSeparators(versionInfo().value("QT_INSTALL_DATA")));
+    env.prependOrSetPath(versionInfo().value("QT_INSTALL_BINS"));
 
-void QtVersion::setMingwDirectory(const QString &directory)
-{
-    m_mingwDirectory = directory;
-    m_toolChainUpToDate = false;
-}
+    // Symbian specific:
+    if (supportsTargetId(Constants::S60_DEVICE_TARGET_ID)
+            || supportsTargetId(Constants::S60_EMULATOR_TARGET_ID)) {
+        // Generic Symbian environment:
+        QString epocRootPath(systemRoot());
+        QDir epocDir(epocRootPath);
+
+        if (!epocRootPath.endsWith(QLatin1Char('/')))
+            epocRootPath.append(QLatin1Char('/'));
+        env.set(QLatin1String("EPOCROOT"), QDir::toNativeSeparators(S60Devices::cleanedRootPath(epocRootPath)));
+
+        env.prependOrSetPath(epocDir.filePath(QLatin1String("epoc32/tools"))); // e.g. make.exe
+        // Windows only:
+        if (ProjectExplorer::Abi::hostAbi().os() == ProjectExplorer::Abi::Windows) {
+            QString winDir = QLatin1String(qgetenv("WINDIR"));
+            if (!winDir.isEmpty())
+                env.prependOrSetPath(QDir(winDir).filePath(QLatin1String("system32")));
+
+            if (epocDir.exists(QLatin1String("epoc32/gcc/bin")))
+                env.prependOrSetPath(epocDir.filePath(QLatin1String("epoc32/gcc/bin"))); // e.g. cpp.exe, *NOT* gcc.exe
+            // Find perl in the special Symbian flavour:
+            if (epocDir.exists(QLatin1String("../../tools/perl/bin"))) {
+                epocDir.cd(QLatin1String("../../tools/perl/bin"));
+                env.prependOrSetPath(epocDir.absolutePath());
+            } else {
+                env.prependOrSetPath(epocDir.filePath(QLatin1String("perl/bin")));
+            }
+        }
 
-QString QtVersion::msvcVersion() const
-{
-    return m_msvcVersion;
+        // SBSv2:
+        if (isBuildWithSymbianSbsV2()) {
+            QString sbsHome(env.value(QLatin1String("SBS_HOME")));
+            if (!m_sbsV2Directory.isEmpty()) {
+                env.prependOrSetPath(m_sbsV2Directory + QLatin1String("/bin"));
+                env.unset(QLatin1String("SBS_HOME")); // unset SBS_HOME to prevent SBS from picking it up
+            } else if (!sbsHome.isEmpty()) {
+                env.prependOrSetPath(sbsHome + QLatin1Char('/') + QLatin1String("bin"));
+            }
+        }
+    }
 }
 
-void QtVersion::setMsvcVersion(const QString &version)
-{
-    m_msvcVersion = version;
-    m_toolChainUpToDate = false;
-}
+static const char *S60_EPOC_HEADERS[] = {
+    "include", "mkspecs/common/symbian", "epoc32/include",
+    "epoc32/include/osextensions/stdapis", "epoc32/include/osextensions/stdapis/sys",
+    "epoc32/include/stdapis", "epoc32/include/stdapis/sys",
+    "epoc32/include/osextensions/stdapis/stlport", "epoc32/include/stdapis/stlport",
+    "epoc32/include/oem", "epoc32/include/middleware", "epoc32/include/domain/middleware",
+    "epoc32/include/osextensions", "epoc32/include/domain/osextensions",
+    "epoc32/include/domain/osextensions/loc", "epoc32/include/domain/middleware/loc",
+    "epoc32/include/domain/osextensions/loc/sc", "epoc32/include/domain/middleware/loc/sc"
+};
 
-void QtVersion::addToEnvironment(Utils::Environment &env) const
-{
-    env.set("QTDIR", QDir::toNativeSeparators(versionInfo().value("QT_INSTALL_DATA")));
-    if (isBuildWithSymbianSbsV2()) {
-        QString sbsHome(env.value(QLatin1String("SBS_HOME")));
-        if (!m_sbsV2Directory.isEmpty()) {
-            env.prependOrSetPath(m_sbsV2Directory);
-            env.unset(QLatin1String("SBS_HOME")); // unset SBS_HOME to prevent SBS from picking it up
-        } else if (!sbsHome.isEmpty()) {
-            env.prependOrSetPath(sbsHome + QLatin1Char('/') + QLatin1String("bin"));
+QList<ProjectExplorer::HeaderPath> QtVersion::systemHeaderPathes() const
+{
+    QList<ProjectExplorer::HeaderPath> result;
+    if (supportsTargetId(Constants::S60_DEVICE_TARGET_ID)
+            || supportsTargetId(Constants::S60_EMULATOR_TARGET_ID)) {
+        QString root = systemRoot() + QLatin1Char('/');
+        const int count = sizeof(S60_EPOC_HEADERS) / sizeof(const char *);
+        for (int i = 0; i < count; ++i) {
+            const QDir dir(root + QLatin1String(S60_EPOC_HEADERS[i]));
+            if (dir.exists())
+            result.append(ProjectExplorer::HeaderPath(dir.absolutePath(),
+                                                      ProjectExplorer::HeaderPath::GlobalHeaderPath));
         }
     }
-    env.prependOrSetPath(versionInfo().value("QT_INSTALL_BINS"));
+    return result;
 }
 
 int QtVersion::uniqueId() const
@@ -1660,12 +1736,15 @@ int QtVersion::getUniqueId()
 bool QtVersion::isValid() const
 {
     updateVersionInfo();
+    updateAbiAndMkspec();
+
     return m_id != -1
             && !qmakeCommand().isEmpty()
             && !displayName().isEmpty()
             && !m_notInstalled
             && m_versionInfo.contains("QT_INSTALL_BINS")
-            && (!m_mkspecFullPath.isEmpty() || !m_toolChainUpToDate);
+            && (!m_mkspecFullPath.isEmpty() || !m_abiUpToDate)
+            && !m_abis.isEmpty();
 }
 
 QString QtVersion::invalidReason() const
@@ -1681,7 +1760,7 @@ QString QtVersion::invalidReason() const
     if (!m_versionInfo.contains("QT_INSTALL_BINS"))
         return QCoreApplication::translate("QtVersion",
                                            "Could not determine the path to the binaries of the Qt installation, maybe the qmake path is wrong?");
-    if (m_toolChainUpToDate && m_mkspecFullPath.isEmpty())
+    if (m_abiUpToDate && m_mkspecFullPath.isEmpty())
         return QCoreApplication::translate("QtVersion", "The default mkspec symlink is broken.");
     return QString();
 }
@@ -1690,8 +1769,6 @@ QString QtVersion::description() const
 {
     if (!isValid())
         return invalidReason();
-    if (possibleToolChainTypes().isEmpty())
-        return QCoreApplication::translate("QtVersion", "This Qt Version has a unknown toolchain.");
     QSet<QString> targets = supportedTargetIds();
     QString envs;
     if (targets.contains(Constants::DESKTOP_TARGET_ID))
@@ -1715,7 +1792,7 @@ QString QtVersion::description() const
 
 QtVersion::QmakeBuildConfigs QtVersion::defaultBuildConfig() const
 {
-    updateToolChainAndMkspec();
+    updateAbiAndMkspec();
     QtVersion::QmakeBuildConfigs result = QtVersion::QmakeBuildConfig(0);
 
     if (m_defaultConfigIsDebugAndRelease)
@@ -1752,13 +1829,15 @@ bool QtVersion::hasQmlObserver() const
 
 Utils::Environment QtVersion::qmlToolsEnvironment() const
 {
+    // FIXME: This seems broken!
     Utils::Environment environment = Utils::Environment::systemEnvironment();
     addToEnvironment(environment);
 
     // add preferred toolchain, as that is how the tools are built, compare QtVersion::buildDebuggingHelperLibrary
-    QList<QSharedPointer<ProjectExplorer::ToolChain> > alltc = toolChains();
+    QList<ProjectExplorer::ToolChain *> alltc =
+            ProjectExplorer::ToolChainManager::instance()->findToolChains(qtAbis().at(0));
     if (!alltc.isEmpty())
-        alltc.first().data()->addToEnvironment(environment);
+        alltc.first()->addToEnvironment(environment);
 
     return environment;
 }
@@ -1805,31 +1884,9 @@ QStringList QtVersion::debuggingHelperLibraryLocations() const
 
 bool QtVersion::supportsBinaryDebuggingHelper() const
 {
-    foreach (ProjectExplorer::ToolChainType type, possibleToolChainTypes())
-        switch (type) {
-        case ProjectExplorer::ToolChain_GCC:
-        case ProjectExplorer::ToolChain_LINUX_ICC:
-        case ProjectExplorer::ToolChain_MinGW:
-        case ProjectExplorer::ToolChain_MSVC:
-        case ProjectExplorer::ToolChain_WINCE:
-        case ProjectExplorer::ToolChain_GCC_MAEMO5:
-        case ProjectExplorer::ToolChain_GCC_HARMATTAN:
-        case ProjectExplorer::ToolChain_GCC_MEEGO:
-        case ProjectExplorer::ToolChain_OTHER:
-        case ProjectExplorer::ToolChain_UNKNOWN:
-            return true;
-        case ProjectExplorer::ToolChain_WINSCW:
-        case ProjectExplorer::ToolChain_GCCE :
-        case ProjectExplorer::ToolChain_RVCT2_ARMV5:
-        case ProjectExplorer::ToolChain_RVCT2_ARMV6:
-        case ProjectExplorer::ToolChain_RVCT4_ARMV5:
-        case ProjectExplorer::ToolChain_RVCT4_ARMV6:
-        case ProjectExplorer::ToolChain_GCCE_GNUPOC:
-        case ProjectExplorer::ToolChain_RVCT_ARMV5_GNUPOC:
-        case ProjectExplorer::ToolChain_INVALID:
-            break;
-        }
-    return false;
+    if (!isValid())
+        return false;
+    return qtAbis().at(0).os() != ProjectExplorer::Abi::Symbian;
 }
 
 bool QtVersion::hasDocumentation() const
@@ -1872,6 +1929,12 @@ QString QtVersion::frameworkInstallPath() const
 #endif
 }
 
+QString QtVersion::libraryInstallPath() const
+{
+    updateVersionInfo();
+    return m_versionInfo["QT_INSTALL_LIBS"];
+}
+
 bool QtVersion::hasExamples() const
 {
     updateVersionInfo();
@@ -1884,16 +1947,6 @@ QString QtVersion::examplesPath() const
     return m_versionInfo["QT_INSTALL_EXAMPLES"];
 }
 
-bool QtVersion::isQt64Bit() const
-{
-#ifdef Q_OS_WIN
-    const QString qmake = qmakeCommand();
-    return qmake.isEmpty() ? false : Utils::winIs64BitBinary(qmake);
-#else
-    return false;
-#endif
-}
-
 void QtVersion::invalidateCache()
 {
     m_versionInfoUpToDate = false;
diff --git a/src/plugins/qt4projectmanager/qtversionmanager.h b/src/plugins/qt4projectmanager/qtversionmanager.h
index 479382ef8e39194cdb216dc4e2237093f9fc06a3..a2daba6889d92abe774dfb02f132335d20fef4b0 100644
--- a/src/plugins/qt4projectmanager/qtversionmanager.h
+++ b/src/plugins/qt4projectmanager/qtversionmanager.h
@@ -38,18 +38,15 @@
 
 #include <projectexplorer/ioutputparser.h>
 #include <projectexplorer/taskwindow.h>
-#include <projectexplorer/toolchain.h>
+#include <projectexplorer/abi.h>
 #include <projectexplorer/task.h>
+#include <projectexplorer/toolchain.h>
 
 #include <QtCore/QHash>
 #include <QtCore/QSet>
 #include <QtCore/QSharedPointer>
 #include <QtCore/QFutureInterface>
 
-namespace ProjectExplorer {
-class ToolChain;
-}
-
 namespace Utils {
 class Environment;
 }
@@ -88,13 +85,13 @@ public:
     QString designerCommand() const;
     QString linguistCommand() const;
     QString qmlviewerCommand() const;
+    QString systemRoot() const;
 
     bool supportsTargetId(const QString &id) const;
     QSet<QString> supportedTargetIds() const;
     bool supportsMobileTarget() const;
 
-    QList<ProjectExplorer::ToolChainType> possibleToolChainTypes() const;
-    ProjectExplorer::ToolChain *toolChain(ProjectExplorer::ToolChainType type) const;
+    QList<ProjectExplorer::Abi> qtAbis() const;
 
     /// @returns the name of the mkspec, which is generally not enough
     /// to pass to qmake.
@@ -114,28 +111,21 @@ public:
     // Returns the PREFIX, BINPREFIX, DOCPREFIX and similar information
     QHash<QString,QString> versionInfo() const;
 
-    QString mwcDirectory() const;
-    void setMwcDirectory(const QString &directory);
     QString s60SDKDirectory() const;
     void setS60SDKDirectory(const QString &directory);
-    QString gcceDirectory() const;
-    void setGcceDirectory(const QString &directory);
     QString sbsV2Directory() const;
     void setSbsV2Directory(const QString &directory);
 
-    QString mingwDirectory() const;
-    void setMingwDirectory(const QString &directory);
-    QString msvcVersion() const;
-    void setMsvcVersion(const QString &version);
     void addToEnvironment(Utils::Environment &env) const;
+    QList<ProjectExplorer::HeaderPath> systemHeaderPathes() const;
 
+    bool supportsBinaryDebuggingHelper() const;
     bool hasDebuggingHelper() const;
     QString debuggingHelperLibrary() const;
     QString qmlDebuggingHelperLibrary(bool debugVersion) const;
     QString qmlDumpTool(bool debugVersion) const;
     QString qmlObserverTool() const;
     QStringList debuggingHelperLibraryLocations() const;
-    bool supportsBinaryDebuggingHelper() const;
 
     bool hasQmlDump() const;
     bool hasQmlDebuggingLibrary() const;
@@ -155,10 +145,10 @@ public:
 
     QString headerInstallPath() const;
     QString frameworkInstallPath() const;
+    QString libraryInstallPath() const;
 
     // All valid Ids are >= 0
     int uniqueId() const;
-    bool isQt64Bit() const;
 
     enum QmakeBuildConfig
     {
@@ -183,18 +173,17 @@ public:
     ProjectExplorer::IOutputParser *createOutputParser() const;
 
 private:
-    QList<QSharedPointer<ProjectExplorer::ToolChain> > toolChains() const;
     static int getUniqueId();
     // Also used by QtOptionsPageWidget
     void updateSourcePath();
     void updateVersionInfo() const;
     QString findQtBinary(const QStringList &possibleName) const;
-    void updateToolChainAndMkspec() const;
+    void updateAbiAndMkspec() const;
     QString resolveLink(const QString &path) const;
+    QString qtCorePath() const;
+
     QString m_displayName;
     QString m_sourcePath;
-    QString m_mingwDirectory;
-    mutable QString m_msvcVersion;
     int m_id;
     bool m_isAutodetected;
     QString m_autodetectionSource;
@@ -203,15 +192,14 @@ private:
     mutable bool m_hasQmlDebuggingLibrary; // controlled by m_versionInfoUpdate
     mutable bool m_hasQmlObserver;     // controlled by m_versionInfoUpToDate
 
-    QString m_mwcDirectory;
     QString m_s60SDKDirectory;
-    QString m_gcceDirectory;
     QString m_sbsV2Directory;
+    mutable QString m_systemRoot;
 
-    mutable bool m_toolChainUpToDate;
+    mutable bool m_abiUpToDate;
     mutable QString m_mkspec; // updated lazily
     mutable QString m_mkspecFullPath;
-    mutable QList<QSharedPointer<ProjectExplorer::ToolChain> > m_toolChains;
+    mutable QList<ProjectExplorer::Abi> m_abis;
 
     mutable bool m_versionInfoUpToDate;
     mutable QHash<QString,QString> m_versionInfo; // updated lazily
@@ -305,8 +293,7 @@ private:
     int getUniqueId();
     void writeVersionsIntoSettings();
     void addNewVersionsFromInstaller();
-    void updateSystemVersion();
-    void updateDocumentation();
+    void updateSystemVersion(); void updateDocumentation();
 
     static int indexOfVersionInList(const QtVersion * const version, const QList<QtVersion *> &list);
     void updateUniqueIdToIndexMap();