diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..94b17e65cfb27461f53b5d9966e47f09c8aa0ce1
--- /dev/null
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
@@ -0,0 +1,269 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#include "abstractmsvctoolchain.h"
+
+#include "msvcparser.h"
+
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/projectexplorersettings.h>
+
+
+#include <utils/fileutils.h>
+#include <utils/qtcprocess.h>
+#include <utils/synchronousprocess.h>
+
+#include <QFileInfo>
+#include <QDir>
+#include <QTemporaryFile>
+
+enum { debug = 0 };
+
+namespace ProjectExplorer {
+namespace Internal {
+
+
+AbstractMsvcToolChain::AbstractMsvcToolChain(const QString &id,
+                                             bool autodetect,
+                                             const Abi &abi,
+                                             const QString& vcvarsBat) :
+    ToolChain(id, autodetect),
+    m_lastEnvironment(Utils::Environment::systemEnvironment()),
+    m_abi(abi),
+    m_vcvarsBat(vcvarsBat)
+{
+    Q_ASSERT(abi.os() == Abi::WindowsOS);
+    Q_ASSERT(abi.binaryFormat() == Abi::PEFormat);
+    Q_ASSERT(abi.osFlavor() != Abi::WindowsMSysFlavor);
+    Q_ASSERT(!m_vcvarsBat.isEmpty());
+}
+
+AbstractMsvcToolChain::AbstractMsvcToolChain(const QString &id, bool autodetect) :
+    ToolChain(id, autodetect),
+    m_lastEnvironment(Utils::Environment::systemEnvironment())
+{
+
+}
+
+Abi AbstractMsvcToolChain::targetAbi() const
+{
+    return m_abi;
+}
+
+bool AbstractMsvcToolChain::isValid() const
+{
+    return !m_vcvarsBat.isEmpty();
+}
+
+QByteArray AbstractMsvcToolChain::predefinedMacros() const
+{
+    if (m_predefinedMacros.isEmpty()) {
+        Utils::Environment env(m_lastEnvironment);
+        addToEnvironment(env);
+        m_predefinedMacros = msvcPredefinedMacros(env);
+    }
+    return m_predefinedMacros;
+}
+
+QList<HeaderPath> AbstractMsvcToolChain::systemHeaderPaths() const
+{
+    if (m_headerPaths.isEmpty()) {
+        Utils::Environment env(m_lastEnvironment);
+        addToEnvironment(env);
+        foreach (const QString &path, env.value("INCLUDE").split(QLatin1Char(';')))
+            m_headerPaths.append(HeaderPath(path, HeaderPath::GlobalHeaderPath));
+    }
+    return m_headerPaths;
+}
+
+void AbstractMsvcToolChain::addToEnvironment(Utils::Environment &env) const
+{
+    // We cache the full environment (incoming + modifications by setup script).
+    if (!m_resultEnvironment.size() || env != m_lastEnvironment) {
+        if (debug)
+            qDebug() << "addToEnvironment: " << displayName();
+        m_lastEnvironment = env;
+        m_resultEnvironment = readEnvironmentSetting(env);
+    }
+    env = m_resultEnvironment;
+}
+
+
+QString AbstractMsvcToolChain::makeCommand() const
+{
+    if (ProjectExplorerPlugin::instance()->projectExplorerSettings().useJom) {
+        // We want jom! Try to find it.
+        const QString jom = QLatin1String("jom.exe");
+        const QFileInfo installedJom = QFileInfo(QCoreApplication::applicationDirPath()
+                                                 + QLatin1Char('/') + jom);
+        if (installedJom.isFile() && installedJom.isExecutable()) {
+            return installedJom.absoluteFilePath();
+        } else {
+            return jom;
+        }
+    }
+    return QLatin1String("nmake.exe");
+}
+
+void AbstractMsvcToolChain::setDebuggerCommand(const QString &d)
+{
+    if (m_debuggerCommand == d)
+        return;
+    m_debuggerCommand = d;
+    updateId();
+    toolChainUpdated();
+}
+
+QString AbstractMsvcToolChain::debuggerCommand() const
+{
+    return m_debuggerCommand;
+}
+
+
+IOutputParser *AbstractMsvcToolChain::outputParser() const
+{
+    return new MsvcParser;
+}
+
+bool AbstractMsvcToolChain::canClone() const
+{
+    return true;
+}
+
+QByteArray AbstractMsvcToolChain::msvcPredefinedMacros(const Utils::Environment& env) const
+{
+    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";
+
+    return predefinedMacros;
+}
+
+
+bool AbstractMsvcToolChain::generateEnvironmentSettings(Utils::Environment &env,
+                                                        const QString& batchFile,
+                                                        const QString& batchArgs,
+                                                        QMap<QString, QString>& envPairs) const
+{
+    // Create a temporary file name for the output. Use a temporary file here
+    // as I don't know another way to do this in Qt...
+    // Note, can't just use a QTemporaryFile all the way through as it remains open
+    // internally so it can't be streamed to later.
+    QString tempOutFile;
+    QTemporaryFile* pVarsTempFile = new QTemporaryFile(QDir::tempPath() + "/XXXXXX.txt");
+    pVarsTempFile->setAutoRemove(false);
+    pVarsTempFile->open();
+    pVarsTempFile->close();
+    tempOutFile = pVarsTempFile->fileName();
+    delete pVarsTempFile;
+
+    // Create a batch file to create and save the env settings
+    Utils::TempFileSaver saver(QDir::tempPath() + "/XXXXXX.bat");
+
+    QByteArray call = "call ";
+    call += Utils::QtcProcess::quoteArg(batchFile).toLocal8Bit() + "\r\n";
+    if (!batchArgs.isEmpty()) {
+        call += ' ';
+        call += batchArgs.toLocal8Bit();
+    }
+    call += "\r\n";
+
+    saver.write(call);
+    const QByteArray redirect = "set > " + Utils::QtcProcess::quoteArg(
+                                    QDir::toNativeSeparators(tempOutFile)).toLocal8Bit() + "\r\n";
+    saver.write(redirect);
+    if (!saver.finalize()) {
+        qWarning("%s: %s", Q_FUNC_INFO, qPrintable(saver.errorString()));
+        return false;
+    }
+
+    Utils::QtcProcess run;
+    // As of WinSDK 7.1, there is logic preventing the path from being set
+    // correctly if "ORIGINALPATH" is already set. That can cause problems
+    // if Creator is launched within a session set up by setenv.cmd.
+    env.unset(QLatin1String("ORIGINALPATH"));
+    run.setEnvironment(env);
+    const QString cmdPath = QString::fromLocal8Bit(qgetenv("COMSPEC"));
+    // Windows SDK setup scripts require command line switches for environment expansion.
+    QString cmdArguments = QLatin1String(" /E:ON /V:ON /c \"");
+    cmdArguments += QDir::toNativeSeparators(saver.fileName());
+    cmdArguments += QLatin1Char('"');
+    run.setCommand(cmdPath, cmdArguments);
+    if (debug)
+        qDebug() << "readEnvironmentSetting: " << call << cmdPath << cmdArguments
+                 << " Env: " << env.size();
+    run.start();
+
+    if (!run.waitForStarted()) {
+        qWarning("%s: Unable to run '%s': %s", Q_FUNC_INFO, qPrintable(m_vcvarsBat),
+                 qPrintable(run.errorString()));
+        return false;
+    }
+    if (!run.waitForFinished()) {
+        qWarning("%s: Timeout running '%s'", Q_FUNC_INFO, qPrintable(m_vcvarsBat));
+        Utils::SynchronousProcess::stopProcess(run);
+        return false;
+    }
+
+    //
+    // Now parse the file to get the environment settings
+    QFile varsFile(tempOutFile);
+    if (!varsFile.open(QIODevice::ReadOnly))
+        return false;
+
+    QRegExp regexp(QLatin1String("(\\w*)=(.*)"));
+    while (!varsFile.atEnd()) {
+        const QString line = QString::fromLocal8Bit(varsFile.readLine()).trimmed();
+        if (regexp.exactMatch(line)) {
+            const QString varName = regexp.cap(1);
+            const QString varValue = regexp.cap(2);
+
+            if (!varValue.isEmpty())
+                envPairs.insert(varName, varValue);
+        }
+    }
+
+    // Tidy up and remove the file
+    varsFile.close();
+    varsFile.remove();
+
+    return true;
+}
+
+} // namespace Internal
+} // namespace ProjectExplorer
+
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.h b/src/plugins/projectexplorer/abstractmsvctoolchain.h
new file mode 100644
index 0000000000000000000000000000000000000000..1c346a13a6dab37808ea8b3d6a4e94b125457d0b
--- /dev/null
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.h
@@ -0,0 +1,90 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#ifndef ABSTRACTMSVCTOOLCHAIN_H
+#define ABSTRACTMSVCTOOLCHAIN_H
+
+#include "toolchain.h"
+#include "abi.h"
+
+#include <utils/environment.h>
+
+namespace ProjectExplorer {
+namespace Internal {
+
+class AbstractMsvcToolChain : public ToolChain
+{
+public:
+    AbstractMsvcToolChain(const QString &id, bool autodetect, const Abi &abi, const QString& vcvarsBat);
+    AbstractMsvcToolChain(const QString &id, bool autodetect);
+
+    Abi targetAbi() const;
+
+    bool isValid() const;
+    QByteArray predefinedMacros() const;
+
+    QList<HeaderPath> systemHeaderPaths() const;
+
+    void addToEnvironment(Utils::Environment &env) const;
+    QString makeCommand() const;
+    void setDebuggerCommand(const QString &d);
+
+    QString debuggerCommand() const;
+    IOutputParser *outputParser() const;
+
+    bool canClone() const;
+
+    QString varsBat() const { return m_vcvarsBat; }
+protected:
+    virtual Utils::Environment readEnvironmentSetting(Utils::Environment& env) const = 0;
+    virtual QByteArray msvcPredefinedMacros(const Utils::Environment& env) const;
+    virtual void updateId() = 0;
+
+    bool generateEnvironmentSettings(Utils::Environment &env,
+                                     const QString& batchFile,
+                                     const QString& batchArgs,
+                                     QMap<QString, QString>& envPairs) const;
+
+    QString m_debuggerCommand;
+    mutable QByteArray m_predefinedMacros;
+    mutable Utils::Environment m_lastEnvironment;   // Last checked 'incoming' environment.
+    mutable Utils::Environment m_resultEnvironment; // Resulting environment for VC
+    mutable QList<HeaderPath> m_headerPaths;
+    Abi m_abi;
+
+   QString m_vcvarsBat;
+};
+
+} // namespace Internal
+} // namespace ProjectExplorer
+
+#endif // ABSTRACTMSVCTOOLCHAIN_H
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index 9baa888e228423b8f29adccc50e3d11ce648a281..d7577b6a061919b5be10a356b3b9f648c0069ddd 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -40,18 +40,14 @@
 #include <projectexplorer/projectexplorersettings.h>
 
 #include <utils/fileutils.h>
-#include <utils/qtcprocess.h>
-#include <utils/qtcassert.h>
 #include <utils/synchronousprocess.h>
 #include <utils/winutils.h>
+#include <utils/qtcassert.h>
 
-#include <QtCore/QCoreApplication>
 #include <QtCore/QDir>
-#include <QtCore/QFileInfo>
+#include <QtCore/QProcess>
 #include <QtCore/QSettings>
 #include <QtCore/QUrl>
-#include <QtCore/QTemporaryFile>
-#include <QtGui/QLabel>
 #include <QtGui/QFormLayout>
 #include <QtGui/QDesktopServices>
 
@@ -170,16 +166,9 @@ static QByteArray msvcCompilationFile()
 }
 
 // Run MSVC 'cl' compiler to obtain #defines.
-static QByteArray msvcPredefinedMacros(const Utils::Environment &env)
+QByteArray MsvcToolChain::msvcPredefinedMacros(const Utils::Environment &env) const
 {
-    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";
+    QByteArray predefinedMacros = AbstractMsvcToolChain::msvcPredefinedMacros(env);
 
     Utils::TempFileSaver saver(QDir::tempPath()+"/envtestXXXXXX.cpp");
     saver.write(msvcCompilationFile());
@@ -258,77 +247,24 @@ static QString winExpandDelayedEnvReferences(QString in, const Utils::Environmen
     return in;
 }
 
-static Utils::Environment msvcReadEnvironmentSetting(const QString &varsBat,
-                                                     const QString &args,
-                                                     Utils::Environment env)
+Utils::Environment MsvcToolChain::readEnvironmentSetting(Utils::Environment& env) const
 {
-    // Run the setup script and extract the variables
     Utils::Environment result = env;
-    if (!QFileInfo(varsBat).exists())
+    if (!QFileInfo(m_vcvarsBat).exists())
         return result;
 
-    const QString tempOutputFileName = QDir::tempPath() + QLatin1String("\\qtcreator-msvc-environment.txt");
-    Utils::TempFileSaver saver(QDir::tempPath() + "\\XXXXXX.bat");
-    QByteArray call = "call ";
-    call += Utils::QtcProcess::quoteArg(varsBat).toLocal8Bit();
-    if (!args.isEmpty()) {
-        call += ' ';
-        call += args.toLocal8Bit();
-    }
-    call += "\r\n";
-    saver.write(call);
-    const QByteArray redirect = "set > " + Utils::QtcProcess::quoteArg(
-                QDir::toNativeSeparators(tempOutputFileName)).toLocal8Bit() + "\r\n";
-    saver.write(redirect);
-    if (!saver.finalize()) {
-        qWarning("%s: %s", Q_FUNC_INFO, qPrintable(saver.errorString()));
+    QMap<QString, QString> envPairs;
+    if (!generateEnvironmentSettings(env, m_vcvarsBat, m_varsBatArg, envPairs))
         return result;
-    }
-
-    Utils::QtcProcess run;
-    // As of WinSDK 7.1, there is logic preventing the path from being set
-    // correctly if "ORIGINALPATH" is already set. That can cause problems
-    // if Creator is launched within a session set up by setenv.cmd.
-    env.unset(QLatin1String("ORIGINALPATH"));
-    run.setEnvironment(env);
-    const QString cmdPath = QString::fromLocal8Bit(qgetenv("COMSPEC"));
-    // Windows SDK setup scripts require command line switches for environment expansion.
-    QString cmdArguments = QLatin1String(" /E:ON /V:ON /c \"");
-    cmdArguments += QDir::toNativeSeparators(saver.fileName());
-    cmdArguments += QLatin1Char('"');
-    run.setCommand(cmdPath, cmdArguments);
-    if (debug)
-        qDebug() << "msvcReadEnvironmentSetting: " << call << cmdPath << cmdArguments
-                 << " Env: " << env.size();
-    run.start();
 
-    if (!run.waitForStarted()) {
-        qWarning("%s: Unable to run '%s': %s", Q_FUNC_INFO, qPrintable(varsBat),
-            qPrintable(run.errorString()));
-        return result;
-    }
-    if (!run.waitForFinished()) {
-        qWarning("%s: Timeout running '%s'", Q_FUNC_INFO, qPrintable(varsBat));
-        Utils::SynchronousProcess::stopProcess(run);
-        return result;
+    // Now loop through and process them
+    QMap<QString,QString>::const_iterator envIter;
+    for (envIter = envPairs.begin(); envIter!=envPairs.end(); ++envIter) {
+        const QString expandedValue = winExpandDelayedEnvReferences(envIter.value(), env);
+        if (!expandedValue.isEmpty())
+            result.set(envIter.key(), expandedValue);
     }
 
-    QFile varsFile(tempOutputFileName);
-    if (!varsFile.open(QIODevice::ReadOnly|QIODevice::Text))
-        return result;
-
-    QRegExp regexp(QLatin1String("(\\w*)=(.*)"));
-    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())
-                result.set(varName, expandedValue);
-        }
-    }
-    varsFile.close();
-    varsFile.remove();
     if (debug) {
         const QStringList newVars = result.toStringList();
         const QStringList oldVars = env.toStringList();
@@ -347,26 +283,17 @@ static Utils::Environment msvcReadEnvironmentSetting(const QString &varsBat,
 
 MsvcToolChain::MsvcToolChain(const QString &name, const Abi &abi,
                              const QString &varsBat, const QString &varsBatArg, bool autodetect) :
-    ToolChain(QLatin1String(Constants::MSVC_TOOLCHAIN_ID), autodetect),
-    m_varsBat(varsBat),
-    m_varsBatArg(varsBatArg),
-    m_lastEnvironment(Utils::Environment::systemEnvironment()),
-    m_abi(abi)
+    AbstractMsvcToolChain(QLatin1String(Constants::MSVC_TOOLCHAIN_ID), autodetect, abi, varsBat),
+    m_varsBatArg(varsBatArg)
 {
     Q_ASSERT(!name.isEmpty());
-    Q_ASSERT(!m_varsBat.isEmpty());
-    Q_ASSERT(QFileInfo(m_varsBat).exists());
-    Q_ASSERT(abi.os() == Abi::WindowsOS);
-    Q_ASSERT(abi.binaryFormat() == Abi::PEFormat);
-    Q_ASSERT(abi.osFlavor() != Abi::WindowsMSysFlavor);
 
     updateId();
     setDisplayName(name);
 }
 
 MsvcToolChain::MsvcToolChain() :
-    ToolChain(QLatin1String(Constants::MSVC_TOOLCHAIN_ID), false),
-    m_lastEnvironment(Utils::Environment::systemEnvironment())
+    AbstractMsvcToolChain(QLatin1String(Constants::MSVC_TOOLCHAIN_ID), false)
 {
 }
 
@@ -384,7 +311,7 @@ void MsvcToolChain::updateId()
     const QChar colon = QLatin1Char(':');
     QString id = QLatin1String(Constants::MSVC_TOOLCHAIN_ID);
     id += colon;
-    id += m_varsBat;
+    id += m_vcvarsBat;
     id += colon;
     id += m_varsBatArg;
     id += colon;
@@ -397,49 +324,6 @@ QString MsvcToolChain::typeName() const
     return MsvcToolChainFactory::tr("MSVC");
 }
 
-Abi MsvcToolChain::targetAbi() const
-{
-    return m_abi;
-}
-
-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);
-    }
-    return m_predefinedMacros;
-}
-
-QList<HeaderPath> MsvcToolChain::systemHeaderPaths() const
-{
-    if (m_headerPaths.isEmpty()) {
-        Utils::Environment env(m_lastEnvironment);
-        addToEnvironment(env);
-        foreach (const QString &path, env.value("INCLUDE").split(QLatin1Char(';')))
-            m_headerPaths.append(HeaderPath(path, HeaderPath::GlobalHeaderPath));
-    }
-    return m_headerPaths;
-}
-
-void MsvcToolChain::addToEnvironment(Utils::Environment &env) const
-{
-    // We cache the full environment (incoming + modifications by setup script).
-    if (!m_resultEnvironment.size() || env != m_lastEnvironment) {
-        if (debug)
-            qDebug() << "addToEnvironment: " << displayName();
-        m_lastEnvironment = env;
-        m_resultEnvironment = msvcReadEnvironmentSetting(m_varsBat, m_varsBatArg, env);
-    }
-    env = m_resultEnvironment;
-}
-
 QString MsvcToolChain::mkspec() const
 {
     if (m_abi.osFlavor() == Abi::WindowsMsvc2005Flavor)
@@ -451,42 +335,12 @@ QString MsvcToolChain::mkspec() const
     return QString();
 }
 
-QString MsvcToolChain::makeCommand() const
-{
-    if (ProjectExplorerPlugin::instance()->projectExplorerSettings().useJom) {
-        // We want jom! Try to find it.
-        const QString jom = QLatin1String("jom.exe");
-        const QFileInfo installedJom = QFileInfo(QCoreApplication::applicationDirPath()
-                                                 + QLatin1Char('/') + jom);
-        if (installedJom.isFile() && installedJom.isExecutable()) {
-            return installedJom.absoluteFilePath();
-        } else {
-            return jom;
-        }
-    }
-    return QLatin1String("nmake.exe");
-}
-
-void MsvcToolChain::setDebuggerCommand(const QString &d)
-{
-    if (m_debuggerCommand == d)
-        return;
-    m_debuggerCommand = d;
-    updateId();
-    toolChainUpdated();
-}
-
-QString MsvcToolChain::debuggerCommand() const
-{
-    return m_debuggerCommand;
-}
-
 QVariantMap MsvcToolChain::toMap() const
 {
     QVariantMap data = ToolChain::toMap();
     if (!m_debuggerCommand.isEmpty())
         data.insert(QLatin1String(debuggerCommandKeyC), m_debuggerCommand);
-    data.insert(QLatin1String(varsBatKeyC), m_varsBat);
+    data.insert(QLatin1String(varsBatKeyC), m_vcvarsBat);
     if (!m_varsBatArg.isEmpty())
         data.insert(QLatin1String(varsBatArgKeyC), m_varsBatArg);
     data.insert(QLatin1String(supportedAbiKeyC), m_abi.toString());
@@ -497,30 +351,22 @@ bool MsvcToolChain::fromMap(const QVariantMap &data)
 {
     if (!ToolChain::fromMap(data))
         return false;
-    m_varsBat = data.value(QLatin1String(varsBatKeyC)).toString();
+    m_vcvarsBat = data.value(QLatin1String(varsBatKeyC)).toString();
     m_varsBatArg = data.value(QLatin1String(varsBatArgKeyC)).toString();
     m_debuggerCommand = data.value(QLatin1String(debuggerCommandKeyC)).toString();
     const QString abiString = data.value(QLatin1String(supportedAbiKeyC)).toString();
     m_abi = Abi(abiString);
     updateId();
-    return !m_varsBat.isEmpty() && m_abi.isValid();
-}
 
-IOutputParser *MsvcToolChain::outputParser() const
-{
-    return new MsvcParser;
+    return !m_vcvarsBat.isEmpty() && m_abi.isValid();
 }
 
+
 ToolChainConfigWidget *MsvcToolChain::configurationWidget()
 {
     return new MsvcToolChainConfigWidget(this);
 }
 
-bool MsvcToolChain::canClone() const
-{
-    return true;
-}
-
 ToolChain *MsvcToolChain::clone() const
 {
     return new MsvcToolChain(*this);
@@ -762,6 +608,7 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect()
         foreach (ToolChain *tc, results)
             static_cast<MsvcToolChain *>(tc)->setDebuggerCommand(tc->targetAbi().wordWidth() == 32 ? cdbDebugger.first : cdbDebugger.second);
     }
+
     return results;
 }
 
diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h
index 937154a9d91cefc72d00a66ef190d06fd1bd3100..fde8e1bb46c750a1f81d106642d650cfdb1da6e4 100644
--- a/src/plugins/projectexplorer/msvctoolchain.h
+++ b/src/plugins/projectexplorer/msvctoolchain.h
@@ -33,7 +33,7 @@
 #ifndef MSVCTOOLCHAIN_H
 #define MSVCTOOLCHAIN_H
 
-#include "toolchain.h"
+#include "abstractmsvctoolchain.h"
 #include "abi.h"
 #include "toolchainconfigwidget.h"
 
@@ -48,7 +48,7 @@ namespace Internal {
 // MsvcToolChain
 // --------------------------------------------------------------------------
 
-class MsvcToolChain : public ToolChain
+class MsvcToolChain : public AbstractMsvcToolChain
 {
 public:
     enum Type { WindowsSDK, VS };
@@ -60,44 +60,29 @@ public:
     static MsvcToolChain *readFromMap(const QVariantMap &data);
 
     QString typeName() const;
-    Abi targetAbi() const;
 
-    bool isValid() const;
-
-    QByteArray predefinedMacros() const;
-    QList<HeaderPath> systemHeaderPaths() const;
-    void addToEnvironment(Utils::Environment &env) const;
     QString mkspec() const;
-    QString makeCommand() const;
-    void setDebuggerCommand(const QString &d);
-    virtual QString debuggerCommand() const;
-    IOutputParser *outputParser() const;
 
-    virtual QVariantMap toMap() const;
-    virtual bool fromMap(const QVariantMap &data);
+    QVariantMap toMap() const;
+    bool fromMap(const QVariantMap &data);
 
     ToolChainConfigWidget *configurationWidget();
 
-    bool canClone() const;
     ToolChain *clone() const;
 
-    QString varsBat() const { return m_varsBat; }
     QString varsBatArg() const { return m_varsBatArg; }
 
     static QPair<QString, QString> autoDetectCdbDebugger();
 
+protected:
+    Utils::Environment readEnvironmentSetting(Utils::Environment& env) const;
+    QByteArray msvcPredefinedMacros(const Utils::Environment &env) const;
+
 private:
     MsvcToolChain();
     void updateId();
 
-    QString m_varsBat; // Script to setup environment
     QString m_varsBatArg; // Argument
-    QString m_debuggerCommand;
-    mutable QByteArray m_predefinedMacros;
-    mutable Utils::Environment m_lastEnvironment;   // Last checked 'incoming' environment.
-    mutable Utils::Environment m_resultEnvironment; // Resulting environment for VC
-    mutable QList<HeaderPath> m_headerPaths;
-    Abi m_abi;
 };
 
 // --------------------------------------------------------------------------
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index cf380ace6afa4346076f77b5ac8acf1e6470a92d..6cbed896af0d79d87325ef1c049927eb2e102257 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -85,6 +85,7 @@
 #ifdef Q_OS_WIN
 #    include "windebuginterface.h"
 #    include "msvctoolchain.h"
+#    include "wincetoolchain.h"
 #endif
 
 #include <extensionsystem/pluginspec.h>
@@ -318,6 +319,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
 
     addAutoReleasedObject(new Internal::MingwToolChainFactory);
     addAutoReleasedObject(new Internal::MsvcToolChainFactory);
+    addAutoReleasedObject(new Internal::WinCEToolChainFactory);
 #else
     addAutoReleasedObject(new Internal::GccToolChainFactory);
     addAutoReleasedObject(new Internal::LinuxIccToolChainFactory);
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index dd5f9abf2b22c841016c9b203769716704d5bd8f..b526d840fd7ad96e2faa98df4608b12175acc721 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -213,11 +213,15 @@ win32 {
     SOURCES += \
         windebuginterface.cpp \
         msvcparser.cpp \
-        msvctoolchain.cpp
+        msvctoolchain.cpp \
+        abstractmsvctoolchain.cpp \
+        wincetoolchain.cpp
     HEADERS += \
         windebuginterface.h \
         msvcparser.h \
-        msvctoolchain.h
+        msvctoolchain.h \
+        abstractmsvctoolchain.h \
+        wincetoolchain.h
 } else {
     macx:LIBS += -framework Carbon
 }
diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h
index 8111e3fd24773b597aa3bb53093dd0c635d7f18f..a43c8756c41e3bf73c1272b29ffb9ede0aef6e45 100644
--- a/src/plugins/projectexplorer/projectexplorerconstants.h
+++ b/src/plugins/projectexplorer/projectexplorerconstants.h
@@ -215,6 +215,7 @@ const char GCC_TOOLCHAIN_ID[] = "ProjectExplorer.ToolChain.Gcc";
 const char LINUXICC_TOOLCHAIN_ID[] = "ProjectExplorer.ToolChain.LinuxIcc";
 const char MINGW_TOOLCHAIN_ID[] = "ProjectExplorer.ToolChain.Mingw";
 const char MSVC_TOOLCHAIN_ID[] = "ProjectExplorer.ToolChain.Msvc";
+const char WINCE_TOOLCHAIN_ID[] = "ProjectExplorer.ToolChain.WinCE";
 
 // Run Configuration defaults:
 const int QML_DEFAULT_DEBUG_SERVER_PORT = 3768;
diff --git a/src/plugins/projectexplorer/wincetoolchain.cpp b/src/plugins/projectexplorer/wincetoolchain.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d3913524cf85cc4328f7d8b8553b076a73aa477c
--- /dev/null
+++ b/src/plugins/projectexplorer/wincetoolchain.cpp
@@ -0,0 +1,488 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#include "wincetoolchain.h"
+
+#include "msvcparser.h"
+#include "projectexplorerconstants.h"
+#include "headerpath.h"
+
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/projectexplorersettings.h>
+#include <utils/qtcassert.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QSettings>
+
+#include <QtGui/QFormLayout>
+#include <QtGui/QLabel>
+
+#include <QXmlStreamReader>
+
+#define KEY_ROOT "ProjectExplorer.WinCEToolChain."
+static const char debuggerCommandKeyC[] = KEY_ROOT"Debugger";
+static const char msvcVerKeyC[] = KEY_ROOT"MSVCVer";
+static const char ceVerKeyC[] = KEY_ROOT"CEVer";
+static const char binPathKeyC[] = KEY_ROOT"BinPath";
+static const char includePathKeyC[] = KEY_ROOT"IncludePath";
+static const char libPathKeyC[] = KEY_ROOT"LibPath";
+static const char supportedAbiKeyC[] = KEY_ROOT"SupportedAbi";
+static const char vcVarsKeyC[] = KEY_ROOT"VCVars";
+
+enum { debug = 0 };
+
+namespace ProjectExplorer {
+namespace Internal {
+
+// --------------------------------------------------------------------------
+// Helpers:
+// --------------------------------------------------------------------------
+
+// Just decodes from the integer version to the string used in Qt mkspecs
+static QString findMsvcVer(int version)
+{
+    if (10 == version)
+        return QLatin1String("msvc2010");
+    else if (9 == version)
+        return QLatin1String("msvc2008");;
+
+    return QLatin1String("msvc2005");
+}
+
+
+// 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 QString winExpandDelayedEnvReferences(QString in, const Utils::Environment &env)
+{
+    const QString firstDelimit = QLatin1String("$(");
+    const QChar secondDelimit = QLatin1Char(')');
+    for (int pos = 0; pos < in.size(); ) {
+        // Replace "$(REF)" by its value in process environment
+        pos = in.indexOf(firstDelimit, pos);
+        if (pos == -1)
+            break;
+        const int replaceStart = pos + firstDelimit.size();
+        const int nextPos = in.indexOf(secondDelimit, replaceStart);
+        if (nextPos == -1)
+            break;
+        const QString var = in.mid(replaceStart, nextPos - replaceStart);
+        QString replacement = env.value(var.toUpper());
+        if (replacement.isEmpty()) {
+            qWarning() << "No replacement for var: " << var;
+            pos = nextPos;
+        }
+        else {
+            // Not sure about this, but we need to account for the case where
+            // the end of the replacement doesn't have the directory seperator and
+            // neither does the start of the insert. This solution assumes:
+            //  1) Having \\ in a path is valid (it is on WinXP)
+            //  2) We're only replacing in paths. This will cause problems if there's
+            //     a replace of a string
+            if (!replacement.endsWith('\\'))
+                replacement += '\\';
+
+            in.replace(pos, nextPos + 1 - pos, replacement);
+            pos += replacement.size();
+        }
+    }
+    return in;
+}
+
+// This is pretty much the same as the ReadEnvironmentSetting in the msvctoolchain.cpp, but
+// this takes account of the library, binary and include paths to replace the vcvars versions
+// with the ones for this toolchain.
+Utils::Environment WinCEToolChain::readEnvironmentSetting(Utils::Environment& env) const
+{
+    Utils::Environment result = env;
+    if (!QFileInfo(m_vcvarsBat).exists())
+        return result;
+
+    // Get the env pairs
+    QMap<QString, QString> envPairs;
+
+    if (!generateEnvironmentSettings(env, m_vcvarsBat, QString(), envPairs))
+        return result;
+
+    QMap<QString,QString>::const_iterator envPairIter;
+    for (envPairIter = envPairs.begin(); envPairIter!=envPairs.end(); ++envPairIter) {
+        // Replace the env values with those from the WinCE SDK
+        QString varValue = envPairIter.value();
+        if ("PATH" == envPairIter.key())
+            varValue = m_binPath + ";" + varValue;
+        else if ("INCLUDE" == envPairIter.key())
+            varValue = m_includePath;
+        else if ("LIB" == envPairIter.key())
+            varValue = m_libPath;
+
+        if (!varValue.isEmpty())
+            result.set(envPairIter.key(), varValue);
+    }
+
+
+    // Now loop round and do the delayed expansion
+    Utils::Environment::const_iterator envIter = result.constBegin();
+    while (envIter != result.constEnd()) {
+        const QString key = result.key(envIter);
+        const QString unexpandedValue = result.value(envIter);
+
+        const QString expandedValue = winExpandDelayedEnvReferences(unexpandedValue, result);
+
+        result.set(key, expandedValue);
+
+        ++envIter;
+    }
+
+    if (debug) {
+        const QStringList newVars = result.toStringList();
+        const QStringList oldVars = env.toStringList();
+        QDebug nsp = qDebug().nospace();
+        foreach (const QString &n, newVars) {
+            if (!oldVars.contains(n))
+                nsp << n << '\n';
+        }
+    }
+    return result;
+}
+
+// Used to parse an SDK entry in the config file and extract information about this SDK
+static bool parseSDK(QXmlStreamReader& theReader,
+                     Abi::Architecture& sdkArch,
+                     QString& sdkName,
+                     QString& ceVer,
+                     QString& binPath,
+                     QString& includePath,
+                     QString& libPath)
+{
+    sdkArch = Abi::UnknownArchitecture;
+    sdkName = "";
+
+    // Loop through until either the end of the file or until is gets to the next
+    // end element.
+    while (!theReader.atEnd()) {
+        theReader.readNext();
+
+        if (theReader.isEndElement()) {
+            // Got to the end element so return...
+            if (theReader.name() == "Platform")
+                return (sdkArch!=Abi::UnknownArchitecture && !sdkName.isEmpty());
+        } else if (theReader.isStartElement()) {
+            const QStringRef elemName = theReader.name();
+            if (elemName == "PlatformName") {
+                sdkName = theReader.readElementText();
+            } else if (elemName == "Directories") {
+                // Populate the paths from this element. Note: we remove the
+                // $(PATH) from the binPath as this will be pre-pended in code
+                binPath = theReader.attributes().value("Path").toString();
+                binPath.remove("$(PATH)");
+                includePath = theReader.attributes().value("Include").toString();
+                libPath = theReader.attributes().value("Library").toString();
+            } else if (elemName == "OSMajorVersion") {
+                // Qt only supports CE5 and higher so drop out here if this version is
+                // invalid
+                ceVer = theReader.readElementText();
+                if (ceVer.toInt() < 5) {
+                    qDebug() << "Ignoring SDK as Qt only support CE 5 and higher.";
+                    return false;
+                }
+            } else if (elemName == "Macro") {
+                // Pull out the architecture from the macro values.
+                if (theReader.attributes().value("Name") == "ARCHFAM") {
+                    const QStringRef archFam = theReader.attributes().value("Value");
+
+                    if (archFam == "ARM")
+                        sdkArch = Abi::ArmArchitecture;
+                    else if (archFam == "x86")
+                        sdkArch = Abi::X86Architecture;
+                    else if (archFam == "MIPS")
+                        sdkArch = Abi::MipsArchitecture;
+                }
+            }
+        }
+    }
+
+    // If we've got to here then the end of the file has been reached before the
+    // end of element tag, so return error.
+    return false;
+}
+
+// --------------------------------------------------------------------------
+// WinCEToolChain
+// --------------------------------------------------------------------------
+
+WinCEToolChain::WinCEToolChain(const QString &name,
+                               const Abi &abi,
+                               const QString &vcvarsBat,
+                               const QString &msvcVer,
+                               const QString &ceVer,
+                               const QString &binPath,
+                               const QString &includePath,
+                               const QString &libPath,
+                               bool autodetect) :
+    AbstractMsvcToolChain(QLatin1String(Constants::WINCE_TOOLCHAIN_ID), autodetect, abi, vcvarsBat),
+    m_msvcVer(msvcVer),
+    m_ceVer(ceVer),
+    m_binPath(binPath),
+    m_includePath(includePath),
+    m_libPath(libPath)
+{
+    Q_ASSERT(!name.isEmpty());
+    Q_ASSERT(!m_binPath.isEmpty());
+    Q_ASSERT(!m_includePath.isEmpty());
+    Q_ASSERT(!m_libPath.isEmpty());
+
+    updateId();
+    setDisplayName(name);
+}
+
+WinCEToolChain::WinCEToolChain() :
+    AbstractMsvcToolChain(QLatin1String(Constants::WINCE_TOOLCHAIN_ID), false)
+{
+}
+
+WinCEToolChain *WinCEToolChain::readFromMap(const QVariantMap &data)
+{
+    WinCEToolChain *tc = new WinCEToolChain;
+    if (tc->fromMap(data))
+        return tc;
+    delete tc;
+    return 0;
+}
+
+void WinCEToolChain::updateId()
+{
+    const QChar colon = QLatin1Char(':');
+    QString id = QLatin1String(Constants::WINCE_TOOLCHAIN_ID);
+    id += colon;
+    id += m_msvcVer;
+    id += colon;
+    id += m_binPath;
+    id += colon;
+    id += m_includePath;
+    id += colon;
+    id += m_libPath;
+    id += colon;
+    id += m_debuggerCommand;
+    setId(id);
+}
+
+QString WinCEToolChain::typeName() const
+{
+    return WinCEToolChainFactory::tr("WinCE");
+}
+
+QString WinCEToolChain::mkspec() const
+{
+    const QChar specSeperator('-');
+
+    QString specString = QLatin1String("wince");
+
+    specString += m_ceVer;
+    specString += specSeperator;
+    specString += Abi::toString(m_abi.architecture());
+    specString += specSeperator;
+    specString += m_msvcVer;
+
+    return specString;
+}
+
+
+QString WinCEToolChain::ceVer() const
+{
+    return m_ceVer;
+}
+
+
+QVariantMap WinCEToolChain::toMap() const
+{
+    QVariantMap data = ToolChain::toMap();
+    if (!m_debuggerCommand.isEmpty())
+        data.insert(QLatin1String(debuggerCommandKeyC), m_debuggerCommand);
+
+    data.insert(QLatin1String(msvcVerKeyC), m_msvcVer);
+    data.insert(QLatin1String(ceVerKeyC), m_ceVer);
+    data.insert(QLatin1String(binPathKeyC), m_binPath);
+    data.insert(QLatin1String(includePathKeyC), m_includePath);
+    data.insert(QLatin1String(libPathKeyC), m_libPath);
+    data.insert(QLatin1String(vcVarsKeyC), m_vcvarsBat);
+
+    data.insert(QLatin1String(supportedAbiKeyC), m_abi.toString());
+    return data;
+}
+
+bool WinCEToolChain::fromMap(const QVariantMap &data)
+{
+    if (!ToolChain::fromMap(data))
+        return false;
+
+    m_msvcVer = data.value(QLatin1String(msvcVerKeyC)).toString();
+    m_ceVer = data.value(QLatin1String(ceVerKeyC)).toString();
+    m_binPath = data.value(QLatin1String(binPathKeyC)).toString();
+    m_includePath = data.value(QLatin1String(includePathKeyC)).toString();
+    m_libPath = data.value(QLatin1String(libPathKeyC)).toString();
+    m_vcvarsBat = data.value(QLatin1String(vcVarsKeyC)).toString();
+
+    m_debuggerCommand = data.value(QLatin1String(debuggerCommandKeyC)).toString();
+    const QString abiString = data.value(QLatin1String(supportedAbiKeyC)).toString();
+    m_abi = Abi(abiString);
+    updateId();
+
+    return isValid();
+}
+
+ToolChainConfigWidget *WinCEToolChain::configurationWidget()
+{
+    return new WinCEToolChainConfigWidget(this);
+}
+
+ToolChain *WinCEToolChain::clone() const
+{
+    return new WinCEToolChain(*this);
+}
+
+
+
+// --------------------------------------------------------------------------
+// WinCEToolChainFactory
+// --------------------------------------------------------------------------
+
+QString WinCEToolChainFactory::displayName() const
+{
+    return tr("WinCE");
+}
+
+QString WinCEToolChainFactory::id() const
+{
+    return QLatin1String(Constants::WINCE_TOOLCHAIN_ID);
+}
+
+
+QList<ToolChain *> WinCEToolChainFactory::autoDetect()
+{
+    QList<ToolChain *> results;
+
+    // 1) Installed WinCEs
+    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 = QDir::fromNativeSeparators(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");
+        QFile cePlatforms(path + "vcpackages/WCE.VCPlatform.config");
+
+        if (cePlatforms.exists()) {
+            const QString msvcVer = findMsvcVer(version);
+            cePlatforms.open(QIODevice::ReadOnly);
+            QXmlStreamReader platformReader(&cePlatforms);
+
+            // Rip through the config file getting all of the installed platforms.
+            while (!platformReader.atEnd()) {
+                platformReader.readNext();
+                if (platformReader.isStartElement()) {
+                    if (platformReader.name() == "Platform") {
+                        Abi::Architecture theArch;
+                        QString thePlat;
+                        QString binPath;
+                        QString includePath;
+                        QString libPath;
+                        QString ceVer;
+
+                        if (parseSDK(platformReader, theArch, thePlat, ceVer, binPath, includePath, libPath)) {
+                            WinCEToolChain *pChain = new WinCEToolChain(thePlat,
+                                                                        Abi(theArch, Abi::WindowsOS, Abi::WindowsCEFlavor, Abi::PEFormat, 32),
+                                                                        vcvars32bat,
+                                                                        msvcVer,
+                                                                        ceVer,
+                                                                        binPath,
+                                                                        includePath,
+                                                                        libPath,
+                                                                        true);
+                            results.append(pChain);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return results;
+}
+
+
+QString WinCEToolChain::autoDetectCdbDebugger(QStringList *checkedDirectories /* = 0 */)
+{
+    return QString();
+}
+
+bool WinCEToolChainFactory::canRestore(const QVariantMap &data)
+{
+    return idFromMap(data).startsWith(QLatin1String(Constants::WINCE_TOOLCHAIN_ID) + QLatin1Char(':'));
+}
+
+ToolChain *WinCEToolChainFactory::restore(const QVariantMap &data)
+{
+    return WinCEToolChain::readFromMap(data);
+}
+
+// --------------------------------------------------------------------------
+// WinCEToolChainConfigWidget
+// --------------------------------------------------------------------------
+
+WinCEToolChainConfigWidget::WinCEToolChainConfigWidget(ToolChain *tc) :
+    ToolChainConfigWidget(tc)
+{
+    WinCEToolChain *toolChain = static_cast<WinCEToolChain *>(tc);
+    QTC_ASSERT(tc, return);
+
+    QFormLayout *formLayout = new QFormLayout(this);
+    formLayout->addRow(tr("SDK:"), new QLabel(toolChain->displayName()));
+    formLayout->addRow(tr("WinCE Version:"), new QLabel(toolChain->ceVer()));
+    formLayout->addRow(tr("ABI:"), new QLabel(toolChain->targetAbi().toString()));
+    addErrorLabel(formLayout);
+}
+
+} // namespace Internal
+} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/wincetoolchain.h b/src/plugins/projectexplorer/wincetoolchain.h
new file mode 100644
index 0000000000000000000000000000000000000000..2bc28932acc222c0204470cfb9dcb8fedea7ee24
--- /dev/null
+++ b/src/plugins/projectexplorer/wincetoolchain.h
@@ -0,0 +1,139 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#ifndef WINCETOOLCHAIN_H
+#define WINCETOOLCHAIN_H
+
+#include "abstractmsvctoolchain.h"
+#include "abi.h"
+#include "toolchainconfigwidget.h"
+
+#include <utils/environment.h>
+
+#include <QtGui/QLabel>
+
+namespace ProjectExplorer {
+namespace Internal {
+
+// --------------------------------------------------------------------------
+// WinCEToolChain
+// --------------------------------------------------------------------------
+
+class WinCEToolChain : public AbstractMsvcToolChain
+{
+public:
+
+    WinCEToolChain(const QString &name,
+                   const Abi &abi,
+                   const QString &vcvarsBat,
+                   const QString &msvcVer,
+                   const QString &ceVer,
+                   const QString &binPath,
+                   const QString &includePath,
+                   const QString &libPath,
+                   bool autodetect = false);
+
+    static WinCEToolChain *readFromMap(const QVariantMap &data);
+
+    QString typeName() const;
+
+    QString mkspec() const;
+
+    QString ceVer() const;
+
+    QVariantMap toMap() const;
+    bool fromMap(const QVariantMap &data);
+
+    ToolChainConfigWidget *configurationWidget();
+
+    ToolChain *clone() const;
+
+    static QString autoDetectCdbDebugger(QStringList *checkedDirectories = 0);
+
+protected:
+    Utils::Environment readEnvironmentSetting(Utils::Environment& env) const;
+
+private:
+    WinCEToolChain();
+    void updateId();
+
+    QString m_msvcVer;
+    QString m_ceVer;
+    QString m_binPath;
+    QString m_includePath;
+    QString m_libPath;
+};
+
+// --------------------------------------------------------------------------
+// WinCEToolChainConfigWidget
+// --------------------------------------------------------------------------
+class WinCEToolChainConfigWidget : public ToolChainConfigWidget
+{
+    Q_OBJECT
+
+public:
+    WinCEToolChainConfigWidget(ToolChain *);
+
+    void apply() {}
+    void discard() { }
+    bool isDirty() const {return false;}
+
+};
+
+// --------------------------------------------------------------------------
+// WinCEToolChainFactory
+// --------------------------------------------------------------------------
+
+class WinCEToolChainFactory : public ToolChainFactory
+{
+    Q_OBJECT
+
+public:
+    QString displayName() const;
+    QString id() const;
+
+    QList<ToolChain *> autoDetect();
+
+    bool canRestore(const QVariantMap &data);
+    ToolChain *restore(const QVariantMap &data);
+
+    ToolChainConfigWidget *configurationWidget(ToolChain *);
+
+private:
+    QList<ToolChain *> detectCEToolKits(const QString& msvcPath, const QString& vcvarsbat);
+};
+
+
+} // namespace Internal
+} // namespace ProjectExplorer
+
+#endif // MSVCTOOLCHAIN_H
diff --git a/src/plugins/qt4projectmanager/winceqtversion.cpp b/src/plugins/qt4projectmanager/winceqtversion.cpp
index 44c8986e4de93289b82bfaa35cd09b1498544b2f..d0c99bb920c70f3438a62c256eebf9d957ed5de9 100644
--- a/src/plugins/qt4projectmanager/winceqtversion.cpp
+++ b/src/plugins/qt4projectmanager/winceqtversion.cpp
@@ -39,20 +39,22 @@ using namespace Qt4ProjectManager;
 using namespace Qt4ProjectManager::Internal;
 
 WinCeQtVersion::WinCeQtVersion()
-    : QtSupport::BaseQtVersion()
+    : QtSupport::BaseQtVersion(),
+      m_archType(ProjectExplorer::Abi::ArmArchitecture)
 {
-
 }
 
-WinCeQtVersion::WinCeQtVersion(const QString &path, bool isAutodetected, const QString &autodetectionSource)
-    : QtSupport::BaseQtVersion(path, isAutodetected, autodetectionSource)
+WinCeQtVersion::WinCeQtVersion(const QString &path, const QString& archType, bool isAutodetected, const QString &autodetectionSource)
+    : QtSupport::BaseQtVersion(path, isAutodetected, autodetectionSource), m_archType(ProjectExplorer::Abi::ArmArchitecture)
 {
-
+    if (0 == archType.compare("x86", Qt::CaseInsensitive))
+        m_archType = ProjectExplorer::Abi::X86Architecture;
+    else if (0 == archType.compare("mipsii", Qt::CaseInsensitive))
+        m_archType = ProjectExplorer::Abi::MipsArchitecture;
 }
 
 WinCeQtVersion::~WinCeQtVersion()
 {
-
 }
 
 WinCeQtVersion *WinCeQtVersion::clone() const
@@ -68,7 +70,7 @@ QString WinCeQtVersion::type() const
 QList<ProjectExplorer::Abi> WinCeQtVersion::detectQtAbis() const
 {
     return QList<ProjectExplorer::Abi>()
-            << ProjectExplorer::Abi(ProjectExplorer::Abi::ArmArchitecture,
+            << ProjectExplorer::Abi(m_archType,
                                     ProjectExplorer::Abi::WindowsOS,
                                     ProjectExplorer::Abi::WindowsCEFlavor,
                                     ProjectExplorer::Abi::PEFormat,
@@ -89,3 +91,29 @@ QString WinCeQtVersion::description() const
 {
     return QCoreApplication::translate("QtVersion", "Qt for WinCE", "Qt Version is meant for WinCE");
 }
+
+void WinCeQtVersion::fromMap(const QVariantMap &map)
+{
+    BaseQtVersion::fromMap(map);
+
+    // Default to an ARM architecture, then use the makespec to see what
+    // the architecture is. This assumes that a WinCE makespec will be
+    // named <Description>-<Architecture>-<Compiler> with no other '-' characters.
+    m_archType = ProjectExplorer::Abi::ArmArchitecture;
+
+    const QStringList splitSpec = mkspec().split("-");
+    if (splitSpec.length() == 3) {
+        const QString archString = splitSpec.value(1);
+        if (archString.contains("x86", Qt::CaseInsensitive))
+            m_archType = ProjectExplorer::Abi::X86Architecture;
+        else if (archString.contains("mips", Qt::CaseInsensitive))
+            m_archType = ProjectExplorer::Abi::MipsArchitecture;
+    }
+}
+
+QVariantMap WinCeQtVersion::toMap() const
+{
+    QVariantMap result = BaseQtVersion::toMap();
+
+    return result;
+}
diff --git a/src/plugins/qt4projectmanager/winceqtversion.h b/src/plugins/qt4projectmanager/winceqtversion.h
index b94b8c339826c8deb1ba3ab84463ed6bfc55f89d..03d2ff8385cab1553700b766e73ade099cc1b2f7 100644
--- a/src/plugins/qt4projectmanager/winceqtversion.h
+++ b/src/plugins/qt4projectmanager/winceqtversion.h
@@ -42,7 +42,7 @@ class WinCeQtVersion : public QtSupport::BaseQtVersion
 {
 public:
     WinCeQtVersion();
-    WinCeQtVersion(const QString &path, bool isAutodetected = false, const QString &autodetectionSource = QString());
+    WinCeQtVersion(const QString &path, const QString& archType, bool isAutodetected = false, const QString &autodetectionSource = QString());
     ~WinCeQtVersion();
     WinCeQtVersion *clone() const;
 
@@ -54,6 +54,12 @@ public:
     QSet<QString> supportedTargetIds() const;
 
     QString description() const;
+
+    virtual QVariantMap toMap() const;
+    virtual void fromMap(const QVariantMap &data);
+
+private:
+    ProjectExplorer::Abi::Architecture m_archType;
 };
 
 }
diff --git a/src/plugins/qt4projectmanager/winceqtversionfactory.cpp b/src/plugins/qt4projectmanager/winceqtversionfactory.cpp
index f6d9dbea5f979e40f70577838d13d6a11a423615..26a42fd5494e8c8c558787215646e14f71cd7163 100644
--- a/src/plugins/qt4projectmanager/winceqtversionfactory.cpp
+++ b/src/plugins/qt4projectmanager/winceqtversionfactory.cpp
@@ -79,7 +79,7 @@ QtSupport::BaseQtVersion *WinCeQtVersionFactory::create(const QString &qmakePath
     QString ce_arch = evaluator->value("CE_ARCH");
 
     if (!ce_sdk.isEmpty() && !ce_arch.isEmpty())
-        return new WinCeQtVersion(qmakePath, isAutoDetected, autoDetectionSource);
+        return new WinCeQtVersion(qmakePath, ce_arch, isAutoDetected, autoDetectionSource);
 
     return 0;
 }