diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
index 8116243fea86d1cc1d74ba7f4540e4331f344974..eb7115d7a5bcec591bdcb3588b3c76024683311d 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp
@@ -136,21 +136,6 @@ QString CMakeBuildConfiguration::buildDirectory() const
     return buildDirectory;
 }
 
-QString CMakeBuildConfiguration::buildParser() const
-{
-    if (!m_toolChain)
-        return QString::null;
-    if (m_toolChain->type() == ProjectExplorer::ToolChain::GCC
-        //|| m_toolChain->type() == ProjectExplorer::ToolChain::LinuxICC
-        || m_toolChain->type() == ProjectExplorer::ToolChain::MinGW) {
-        return ProjectExplorer::Constants::BUILD_PARSER_GCC;
-    } else if (m_toolChain->type() == ProjectExplorer::ToolChain::MSVC
-               || m_toolChain->type() == ProjectExplorer::ToolChain::WINCE) {
-        return ProjectExplorer::Constants::BUILD_PARSER_MSVC;
-    }
-    return QString::null;
-}
-
 ProjectExplorer::ToolChain::ToolChainType CMakeBuildConfiguration::toolChainType() const
 {
     if (m_toolChain)
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
index 24064ed34751933c7e15da89b2338c32feba268f..bdd9765bd6e07e90f9fba7dd5265db1e3906d5c8 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h
@@ -57,7 +57,6 @@ public:
     void setUseSystemEnvironment(bool b);
 
     virtual QString buildDirectory() const;
-    QString buildParser() const;
 
     ProjectExplorer::ToolChain::ToolChainType toolChainType() const;
     ProjectExplorer::ToolChain *toolChain() const;
diff --git a/src/plugins/cmakeprojectmanager/makestep.cpp b/src/plugins/cmakeprojectmanager/makestep.cpp
index 332f2fcc625cf83a51576ea806836c8c9d3a6f33..86a74073e51c7c6efd539ce3c377e4f99ce8be1f 100644
--- a/src/plugins/cmakeprojectmanager/makestep.cpp
+++ b/src/plugins/cmakeprojectmanager/makestep.cpp
@@ -32,6 +32,7 @@
 #include "cmakebuildconfiguration.h"
 
 #include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/gnumakeparser.h>
 
 #include <QtGui/QFormLayout>
 #include <QtGui/QGroupBox>
@@ -43,14 +44,14 @@ using namespace CMakeProjectManager;
 using namespace CMakeProjectManager::Internal;
 using namespace ProjectExplorer;
 
-MakeStep::MakeStep(BuildConfiguration *bc)
-    : AbstractMakeStep(bc), m_clean(false), m_futureInterface(0)
+MakeStep::MakeStep(BuildConfiguration *bc) :
+    AbstractProcessStep(bc), m_clean(false), m_futureInterface(0)
 {
     m_percentProgress = QRegExp("^\\[\\s*(\\d*)%\\]");
 }
 
-MakeStep::MakeStep(MakeStep *bs, BuildConfiguration *bc)
-    : AbstractMakeStep(bs, bc),
+MakeStep::MakeStep(MakeStep *bs, BuildConfiguration *bc) :
+    AbstractProcessStep(bs, bc),
     m_clean(bs->m_clean),
     m_futureInterface(0),
     m_buildTargets(bs->m_buildTargets),
@@ -78,7 +79,7 @@ void MakeStep::restoreFromGlobalMap(const QMap<QString, QVariant> &map)
 {
     if (map.value("clean").isValid() && map.value("clean").toBool())
         m_clean = true;
-    AbstractMakeStep::restoreFromGlobalMap(map);
+    AbstractProcessStep::restoreFromGlobalMap(map);
 }
 
 void MakeStep::restoreFromLocalMap(const QMap<QString, QVariant> &map)
@@ -87,7 +88,7 @@ void MakeStep::restoreFromLocalMap(const QMap<QString, QVariant> &map)
     m_additionalArguments = map["additionalArguments"].toStringList();
     if (map.value("clean").isValid() && map.value("clean").toBool())
         m_clean = true;
-    AbstractMakeStep::restoreFromLocalMap(map);
+    AbstractProcessStep::restoreFromLocalMap(map);
 }
 
 void MakeStep::storeIntoLocalMap(QMap<QString, QVariant> &map)
@@ -96,13 +97,12 @@ void MakeStep::storeIntoLocalMap(QMap<QString, QVariant> &map)
     map["additionalArguments"] = m_additionalArguments;
     if (m_clean)
         map["clean"] = true;
-    AbstractMakeStep::storeIntoLocalMap(map);
+    AbstractProcessStep::storeIntoLocalMap(map);
 }
 
 bool MakeStep::init()
 {
     CMakeBuildConfiguration *bc = cmakeBuildConfiguration();
-    setBuildParser(bc->buildParser());
 
     setEnabled(true);
     setWorkingDirectory(bc->buildDirectory());
@@ -115,14 +115,18 @@ bool MakeStep::init()
     setEnvironment(bc->environment());
     setIgnoreReturnValue(m_clean);
 
-    return AbstractMakeStep::init();
+    setOutputParser(new ProjectExplorer::GnuMakeParser(workingDirectory()));
+    if (bc->toolChain())
+        appendOutputParser(bc->toolChain()->outputParser());
+
+    return AbstractProcessStep::init();
 }
 
 void MakeStep::run(QFutureInterface<bool> &fi)
 {
     m_futureInterface = &fi;
     m_futureInterface->setProgressRange(0, 100);
-    AbstractMakeStep::run(fi);
+    AbstractProcessStep::run(fi);
     m_futureInterface->setProgressValue(100);
     m_futureInterface->reportFinished();
     m_futureInterface = 0;
@@ -135,7 +139,7 @@ QString MakeStep::name()
 
 QString MakeStep::displayName()
 {
-    return "Make";
+    return QLatin1String("Make");
 }
 
 BuildStepConfigWidget *MakeStep::createConfigWidget()
@@ -156,7 +160,7 @@ void MakeStep::stdOut(const QString &line)
         if (ok)
             m_futureInterface->setProgressValue(percent);
     }
-    AbstractMakeStep::stdOut(line);
+    AbstractProcessStep::stdOutput(line);
 }
 
 bool MakeStep::buildsTarget(const QString &target) const
diff --git a/src/plugins/cmakeprojectmanager/makestep.h b/src/plugins/cmakeprojectmanager/makestep.h
index 9242e545b3e65f59c9a44473c3b77ce318050f72..6859915fd1e449694d7d3c1c128b9277e5bb7f1e 100644
--- a/src/plugins/cmakeprojectmanager/makestep.h
+++ b/src/plugins/cmakeprojectmanager/makestep.h
@@ -30,7 +30,7 @@
 #ifndef MAKESTEP_H
 #define MAKESTEP_H
 
-#include <projectexplorer/abstractmakestep.h>
+#include <projectexplorer/abstractprocessstep.h>
 
 QT_BEGIN_NAMESPACE
 class QLineEdit;
@@ -43,7 +43,7 @@ namespace Internal {
 
 class CMakeBuildConfiguration;
 
-class MakeStep : public ProjectExplorer::AbstractMakeStep
+class MakeStep : public ProjectExplorer::AbstractProcessStep
 {
     Q_OBJECT
     friend class MakeStepConfigWidget; // TODO remove
diff --git a/src/plugins/genericprojectmanager/genericmakestep.cpp b/src/plugins/genericprojectmanager/genericmakestep.cpp
index 4f10924cce1818e2ba98701fb1526b6e5577011a..3c75bde174275671e0d95861ec7e1623c17b3fad 100644
--- a/src/plugins/genericprojectmanager/genericmakestep.cpp
+++ b/src/plugins/genericprojectmanager/genericmakestep.cpp
@@ -36,7 +36,7 @@
 #include <extensionsystem/pluginmanager.h>
 #include <projectexplorer/toolchain.h>
 #include <projectexplorer/projectexplorer.h>
-#include <utils/qtcassert.h>
+#include <projectexplorer/gnumakeparser.h>
 #include <coreplugin/variablemanager.h>
 
 #include <QtGui/QFormLayout>
@@ -48,13 +48,13 @@
 using namespace GenericProjectManager;
 using namespace GenericProjectManager::Internal;
 
-GenericMakeStep::GenericMakeStep(ProjectExplorer::BuildConfiguration *bc)
-    : AbstractMakeStep(bc)
+GenericMakeStep::GenericMakeStep(ProjectExplorer::BuildConfiguration *bc) :
+    AbstractProcessStep(bc)
 {
 }
 
-GenericMakeStep::GenericMakeStep(GenericMakeStep *bs, ProjectExplorer::BuildConfiguration *bc)
-    : AbstractMakeStep(bs, bc)
+GenericMakeStep::GenericMakeStep(GenericMakeStep *bs, ProjectExplorer::BuildConfiguration *bc) :
+    AbstractProcessStep(bs, bc)
 {
     m_buildTargets = bs->m_buildTargets;
     m_makeArguments = bs->m_makeArguments;
@@ -73,9 +73,6 @@ GenericBuildConfiguration *GenericMakeStep::genericBuildConfiguration() const
 bool GenericMakeStep::init()
 {
     GenericBuildConfiguration *bc = genericBuildConfiguration();
-    //TODO
-    const QString buildParser = genericBuildConfiguration()->genericProject()->buildParser(bc);
-    setBuildParser(buildParser);
 
     setEnabled(true);
     Core::VariableManager *vm = Core::VariableManager::instance();
@@ -87,7 +84,12 @@ bool GenericMakeStep::init()
     setArguments(replacedArguments());
 
     setEnvironment(bc->environment());
-    return AbstractMakeStep::init();
+
+    setOutputParser(new ProjectExplorer::GnuMakeParser(buildDir));
+    if (bc->genericProject()->toolChain())
+        appendOutputParser(bc->genericProject()->toolChain()->outputParser());
+
+    return AbstractProcessStep::init();
 }
 
 void GenericMakeStep::restoreFromLocalMap(const QMap<QString, QVariant> &map)
@@ -95,7 +97,7 @@ void GenericMakeStep::restoreFromLocalMap(const QMap<QString, QVariant> &map)
     m_buildTargets = map.value("buildTargets").toStringList();
     m_makeArguments = map.value("makeArguments").toStringList();
     m_makeCommand = map.value("makeCommand").toString();
-    ProjectExplorer::AbstractMakeStep::restoreFromLocalMap(map);
+    ProjectExplorer::AbstractProcessStep::restoreFromLocalMap(map);
 }
 
 void GenericMakeStep::storeIntoLocalMap(QMap<QString, QVariant> &map)
@@ -103,7 +105,7 @@ void GenericMakeStep::storeIntoLocalMap(QMap<QString, QVariant> &map)
     map["buildTargets"] = m_buildTargets;
     map["makeArguments"] = m_makeArguments;
     map["makeCommand"] = m_makeCommand;
-    ProjectExplorer::AbstractMakeStep::storeIntoLocalMap(map);
+    ProjectExplorer::AbstractProcessStep::storeIntoLocalMap(map);
 }
 
 QStringList GenericMakeStep::replacedArguments() const
diff --git a/src/plugins/genericprojectmanager/genericmakestep.h b/src/plugins/genericprojectmanager/genericmakestep.h
index 57a8ee4a11a699e9d895283b6c9488b76762f733..7d392b25ad0cd7eeae5a78092255d38a9a026ae5 100644
--- a/src/plugins/genericprojectmanager/genericmakestep.h
+++ b/src/plugins/genericprojectmanager/genericmakestep.h
@@ -30,7 +30,7 @@
 #ifndef GENERICMAKESTEP_H
 #define GENERICMAKESTEP_H
 
-#include <projectexplorer/abstractmakestep.h>
+#include <projectexplorer/abstractprocessstep.h>
 
 QT_BEGIN_NAMESPACE
 class QListWidgetItem;
@@ -51,7 +51,7 @@ struct GenericMakeStepSettings
 
 };
 
-class GenericMakeStep : public ProjectExplorer::AbstractMakeStep
+class GenericMakeStep : public ProjectExplorer::AbstractProcessStep
 {
     Q_OBJECT
     friend class GenericMakeStepConfigWidget; // TODO remove again?
diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp
index ec9723fccc49a0be9d2cd712d14259230c73a260..d4197cc5c480f0d9e050864f604ef0b9a7bc6357 100644
--- a/src/plugins/genericprojectmanager/genericproject.cpp
+++ b/src/plugins/genericprojectmanager/genericproject.cpp
@@ -424,28 +424,6 @@ void GenericProject::setToolChainType(ProjectExplorer::ToolChain::ToolChainType
     }
 }
 
-QString GenericProject::buildParser(BuildConfiguration *configuration) const
-{
-    Q_UNUSED(configuration)
-    if (m_toolChain) {
-        switch (m_toolChain->type()) {
-        case ProjectExplorer::ToolChain::GCC:
-        //case ProjectExplorer::ToolChain::LinuxICC:
-        case ProjectExplorer::ToolChain::MinGW:
-            return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_GCC);
-
-        case ProjectExplorer::ToolChain::MSVC:
-        case ProjectExplorer::ToolChain::WINCE:
-            return ProjectExplorer::Constants::BUILD_PARSER_MSVC;
-
-        default:
-            break;
-        } // switch
-    }
-
-    return QString();
-}
-
 ProjectExplorer::ToolChain *GenericProject::toolChain() const
 {
     return m_toolChain;
diff --git a/src/plugins/genericprojectmanager/genericproject.h b/src/plugins/genericprojectmanager/genericproject.h
index bbbbc059fe8953ced4996e68e4f54affaf1f1a18..176927a82e4a2a5a29863bde547a5937709ab4e8 100644
--- a/src/plugins/genericprojectmanager/genericproject.h
+++ b/src/plugins/genericprojectmanager/genericproject.h
@@ -103,7 +103,6 @@ public:
     virtual QStringList files(FilesMode fileMode) const;
 
     QStringList targets() const;
-    QString buildParser(ProjectExplorer::BuildConfiguration *configuration) const;
     ProjectExplorer::ToolChain *toolChain() const;
 
     bool setFiles(const QStringList &filePaths);
diff --git a/src/plugins/projectexplorer/abstractmakestep.cpp b/src/plugins/projectexplorer/abstractmakestep.cpp
deleted file mode 100644
index 6a3573ba83984ff8871a590f6cbae6d47fef863f..0000000000000000000000000000000000000000
--- a/src/plugins/projectexplorer/abstractmakestep.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** Commercial Usage
-**
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at http://qt.nokia.com/contact.
-**
-**************************************************************************/
-
-#include "abstractmakestep.h"
-
-#include "projectexplorerconstants.h"
-#include "project.h"
-#include "buildconfiguration.h"
-
-#include <extensionsystem/pluginmanager.h>
-#include <utils/qtcassert.h>
-
-#include <QtCore/QDir>
-#include <QtCore/QFileInfo>
-
-using ExtensionSystem::PluginManager;
-
-using namespace ProjectExplorer;
-
-namespace {
-bool debug = false;
-}
-
-AbstractMakeStep::AbstractMakeStep(BuildConfiguration *bc)
-    : AbstractProcessStep(bc),
-      m_buildParser(0)
-{
-}
-
-AbstractMakeStep::AbstractMakeStep(AbstractMakeStep *bs, BuildConfiguration *bc)
-    : AbstractProcessStep(bs, bc),
-    m_buildParser(0)
-{
-
-}
-
-AbstractMakeStep::~AbstractMakeStep()
-{
-    delete m_buildParser;
-    m_buildParser = 0;
-}
-
-bool AbstractMakeStep::init()
-{
-    m_openDirectories.clear();
-    addDirectory(workingDirectory());
-
-    return AbstractProcessStep::init();
-}
-
-QString AbstractMakeStep::buildParser() const
-{
-    return m_buildParserName;
-}
-
-void AbstractMakeStep::setBuildParser(const QString &parser)
-{
-    // Nothing to do?
-    if (m_buildParserName == parser)
-        return;
-
-    // Clean up
-    delete m_buildParser;
-    m_buildParser = 0;
-    m_buildParserName = QString::null;
-
-    // Now look for new parser
-    QList<IBuildParserFactory *> buildParserFactories =
-            ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>();
-
-    foreach (IBuildParserFactory * factory, buildParserFactories)
-        if (factory->canCreate(parser)) {
-            m_buildParser = factory->create(parser);
-            break;
-        }
-
-    if (m_buildParser) {
-        m_buildParserName = parser;
-        connect(m_buildParser, SIGNAL(addToOutputWindow(QString)),
-                this, SIGNAL(addToOutputWindow(QString)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(addToTaskWindow(ProjectExplorer::TaskWindow::Task)),
-                this, SLOT(slotAddToTaskWindow(ProjectExplorer::TaskWindow::Task)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(enterDirectory(QString)),
-                this, SLOT(addDirectory(QString)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(leaveDirectory(QString)),
-                this, SLOT(removeDirectory(QString)),
-                Qt::DirectConnection);
-    }
-}
-
-void AbstractMakeStep::slotAddToTaskWindow(const TaskWindow::Task &task)
-{
-    TaskWindow::Task editable(task);
-    QString filePath = QDir::cleanPath(task.file.trimmed());
-    if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) {
-        // We have no save way to decide which file in which subfolder
-        // is meant. Therefore we apply following heuristics:
-        // 1. Search for unique file in directories currently indicated as open by GNU make
-        //    (Enter directory xxx, Leave directory xxx...) + current directory
-        // 3. Check if file is unique in whole project
-        // 4. Otherwise give up
-
-        QList<QFileInfo> possibleFiles;
-        foreach (const QString &dir, m_openDirectories) {
-            QFileInfo candidate(dir + QLatin1Char('/') + filePath);
-            if (debug)
-                qDebug() << "Checking path " << candidate.filePath();
-            if (candidate.exists()
-                    && !possibleFiles.contains(candidate)) {
-                if (debug)
-                    qDebug() << candidate.filePath() << "exists!";
-                possibleFiles << candidate;
-            }
-        }
-        if (possibleFiles.count() == 0) {
-            if (debug)
-                qDebug() << "No success. Trying all files in project ...";
-            QString fileName = QFileInfo(filePath).fileName();
-            foreach (const QString &file, buildConfiguration()->project()->files(ProjectExplorer::Project::AllFiles)) {
-                QFileInfo candidate(file);
-                if (candidate.fileName() == fileName) {
-                    if (debug)
-                        qDebug() << "Found " << file;
-                    possibleFiles << candidate;
-                }
-            }
-        }
-        if (possibleFiles.count() == 1) {
-            editable.file = possibleFiles.first().filePath();
-        } else {
-            // More then one filename, so do a better compare
-            // Chop of any "../"
-            while (filePath.startsWith("../"))
-                filePath = filePath.mid(3);
-            int count = 0;
-            QString possibleFilePath;
-            foreach(const QFileInfo & fi, possibleFiles) {
-                if (fi.filePath().endsWith(filePath)) {
-                    possibleFilePath = fi.filePath();
-                    ++count;
-                }
-            }
-            if (count == 1)
-                editable.file = possibleFilePath;
-            else
-                qWarning() << "Could not find absolute location of file " << filePath;
-        }
-    }
-    emit addToTaskWindow(editable);
-}
-
-void AbstractMakeStep::addDirectory(const QString &dir)
-{
-    if (!m_openDirectories.contains(dir))
-        m_openDirectories.insert(dir);
-}
-
-void AbstractMakeStep::removeDirectory(const QString &dir)
-{
-    if (m_openDirectories.contains(dir))
-        m_openDirectories.remove(dir);
-}
-
-void AbstractMakeStep::run(QFutureInterface<bool> & fi)
-{
-    AbstractProcessStep::run(fi);
-}
-
-void AbstractMakeStep::stdOut(const QString &line)
-{
-    if (m_buildParser)
-        m_buildParser->stdOutput(line);
-    AbstractProcessStep::stdOut(line);
-}
-
-void AbstractMakeStep::stdError(const QString &line)
-{
-    if (m_buildParser)
-        m_buildParser->stdError(line);
-    AbstractProcessStep::stdError(line);
-}
diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp
index af92a62ec676289eecef5198d771f3d36b7497b2..45ff9f27fcf9b9538278cd28324d53f8e78b428f 100644
--- a/src/plugins/projectexplorer/abstractprocessstep.cpp
+++ b/src/plugins/projectexplorer/abstractprocessstep.cpp
@@ -28,29 +28,45 @@
 **************************************************************************/
 
 #include "abstractprocessstep.h"
+#include "buildconfiguration.h"
 #include "buildstep.h"
+#include "ioutputparser.h"
 #include "project.h"
 
+#include <utils/qtcassert.h>
+
 #include <QtCore/QProcess>
 #include <QtCore/QEventLoop>
-#include <QtCore/QDebug>
 #include <QtCore/QTimer>
 #include <QtGui/QTextDocument>
 
 using namespace ProjectExplorer;
 
-AbstractProcessStep::AbstractProcessStep(BuildConfiguration *bc)
-  : BuildStep(bc), m_timer(0), m_futureInterface(0), m_process(0), m_eventLoop(0)
+AbstractProcessStep::AbstractProcessStep(BuildConfiguration *bc) :
+    BuildStep(bc), m_timer(0), m_futureInterface(0),
+    m_enabled(true), m_ignoreReturnValue(false),
+    m_process(0), m_eventLoop(0), m_outputParserChain(0)
 {
 
 }
 
-AbstractProcessStep::AbstractProcessStep(AbstractProcessStep *bs, BuildConfiguration *bc)
-    : BuildStep(bs, bc), m_timer(0), m_futureInterface(0), m_process(0), m_eventLoop(0)
+AbstractProcessStep::AbstractProcessStep(AbstractProcessStep *bs,
+                                         BuildConfiguration *bc) :
+    BuildStep(bs, bc), m_timer(0), m_futureInterface(0),
+    m_enabled(bs->m_enabled), m_ignoreReturnValue(bs->m_ignoreReturnValue),
+    m_process(0), m_eventLoop(0), m_outputParserChain(0)
 {
 
 }
 
+AbstractProcessStep::~AbstractProcessStep()
+{
+    delete m_process;
+    delete m_timer;
+    // do not delete m_futureInterface, we do not own it.
+    delete m_outputParserChain;
+}
+
 void AbstractProcessStep::setCommand(const QString &cmd)
 {
     m_command = cmd;
@@ -61,6 +77,34 @@ QString AbstractProcessStep::workingDirectory() const
     return m_workingDirectory;
 }
 
+void AbstractProcessStep::setOutputParser(ProjectExplorer::IOutputParser *parser)
+{
+    delete m_outputParserChain;
+    m_outputParserChain = parser;
+
+    if (m_outputParserChain) {
+        connect(parser, SIGNAL(addOutput(QString)),
+                this, SLOT(outputAdded(QString)));
+        connect(parser, SIGNAL(addTask(ProjectExplorer::TaskWindow::Task)),
+                this, SLOT(taskAdded(ProjectExplorer::TaskWindow::Task)));
+    }
+}
+
+void AbstractProcessStep::appendOutputParser(ProjectExplorer::IOutputParser *parser)
+{
+    if (!parser)
+        return;
+
+    QTC_ASSERT(m_outputParserChain, return);
+    m_outputParserChain->appendOutputParser(parser);
+    return;
+}
+
+ProjectExplorer::IOutputParser *AbstractProcessStep::outputParser() const
+{
+    return m_outputParserChain;
+}
+
 void AbstractProcessStep::setWorkingDirectory(const QString &workingDirectory)
 {
     m_workingDirectory = workingDirectory;
@@ -96,7 +140,7 @@ bool AbstractProcessStep::init()
     return true;
 }
 
-void AbstractProcessStep::run(QFutureInterface<bool> & fi)
+void AbstractProcessStep::run(QFutureInterface<bool> &fi)
 {
     m_futureInterface = &fi;
     if (!m_enabled) {
@@ -155,23 +199,22 @@ void AbstractProcessStep::run(QFutureInterface<bool> & fi)
 
 void AbstractProcessStep::processStarted()
 {
-    emit addToOutputWindow(tr("<font color=\"#0000ff\">Starting: %1 %2</font>\n").arg(m_command, Qt::escape(m_arguments.join(" "))));
+    emit addOutput(tr("<font color=\"#0000ff\">Starting: %1 %2</font>\n").arg(m_command, Qt::escape(m_arguments.join(" "))));
 }
 
 bool AbstractProcessStep::processFinished(int exitCode, QProcess::ExitStatus status)
 {
     const bool ok = status == QProcess::NormalExit && (exitCode == 0 || m_ignoreReturnValue);
-    if (ok) {
-        emit addToOutputWindow(tr("<font color=\"#0000ff\">Exited with code %1.</font>").arg(m_process->exitCode()));
-    } else {
-        emit addToOutputWindow(tr("<font color=\"#ff0000\"><b>Exited with code %1.</b></font>").arg(m_process->exitCode()));
-    }
+    if (ok)
+        emit addOutput(tr("<font color=\"#0000ff\">Exited with code %1.</font>").arg(m_process->exitCode()));
+    else
+        emit addOutput(tr("<font color=\"#ff0000\"><b>Exited with code %1.</b></font>").arg(m_process->exitCode()));
     return ok;
 }
 
 void AbstractProcessStep::processStartupFailed()
 {
-   emit addToOutputWindow(tr("<font color=\"#ff0000\">Could not start process %1 </b></font>").arg(m_command));
+   emit addOutput(tr("<font color=\"#ff0000\">Could not start process %1 </b></font>").arg(m_command));
 }
 
 void AbstractProcessStep::processReadyReadStdOutput()
@@ -179,13 +222,15 @@ void AbstractProcessStep::processReadyReadStdOutput()
     m_process->setReadChannel(QProcess::StandardOutput);
     while (m_process->canReadLine()) {
         QString line = QString::fromLocal8Bit(m_process->readLine()).trimmed();
-        stdOut(line);
+        stdOutput(line);
     }
 }
 
-void AbstractProcessStep::stdOut(const QString &line)
+void AbstractProcessStep::stdOutput(const QString &line)
 {
-    emit addToOutputWindow(Qt::escape(line));
+    if (m_outputParserChain)
+        m_outputParserChain->stdOutput(line);
+    emit addOutput(Qt::escape(line));
 }
 
 void AbstractProcessStep::processReadyReadStdError()
@@ -199,7 +244,10 @@ void AbstractProcessStep::processReadyReadStdError()
 
 void AbstractProcessStep::stdError(const QString &line)
 {
-    emit addToOutputWindow(QLatin1String("<font color=\"#ff0000\">") + Qt::escape(line) + QLatin1String("</font>"));
+    if (m_outputParserChain)
+        m_outputParserChain->stdError(line);
+    else
+        emit addOutput(QLatin1String("<font color=\"#ff0000\">") + Qt::escape(line) + QLatin1String("</font>"));
 }
 
 void AbstractProcessStep::checkForCancel()
@@ -212,6 +260,54 @@ void AbstractProcessStep::checkForCancel()
     }
 }
 
+void AbstractProcessStep::taskAdded(const ProjectExplorer::TaskWindow::Task &task)
+{
+    TaskWindow::Task editable(task);
+    QString filePath = QDir::cleanPath(task.file.trimmed());
+    if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) {
+        // We have no save way to decide which file in which subfolder
+        // is meant. Therefore we apply following heuristics:
+        // 1. Check if file is unique in whole project
+        // 2. Otherwise try again without any ../
+        // 3. give up.
+
+        QList<QFileInfo> possibleFiles;
+        QString fileName = QFileInfo(filePath).fileName();
+        foreach (const QString &file, buildConfiguration()->project()->files(ProjectExplorer::Project::AllFiles)) {
+            QFileInfo candidate(file);
+            if (candidate.fileName() == fileName)
+                possibleFiles << candidate;
+        }
+
+        if (possibleFiles.count() == 1) {
+            editable.file = possibleFiles.first().filePath();
+        } else {
+            // More then one filename, so do a better compare
+            // Chop of any "../"
+            while (filePath.startsWith("../"))
+                filePath = filePath.mid(3);
+            int count = 0;
+            QString possibleFilePath;
+            foreach(const QFileInfo &fi, possibleFiles) {
+                if (fi.filePath().endsWith(filePath)) {
+                    possibleFilePath = fi.filePath();
+                    ++count;
+                }
+            }
+            if (count == 1)
+                editable.file = possibleFilePath;
+            else
+                qWarning() << "Could not find absolute location of file " << filePath;
+        }
+    }
+    emit addTask(editable);
+}
+
+void AbstractProcessStep::outputAdded(const QString &string)
+{
+    emit addOutput(string);
+}
+
 void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus)
 {
     QString line = QString::fromLocal8Bit(m_process->readAllStandardError()).trimmed();
@@ -220,7 +316,7 @@ void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus)
 
     line = QString::fromLocal8Bit(m_process->readAllStandardOutput()).trimmed();
     if (!line.isEmpty())
-        stdOut(line);
+        stdOutput(line);
 
     m_eventLoop->exit(0);
 }
diff --git a/src/plugins/projectexplorer/abstractprocessstep.h b/src/plugins/projectexplorer/abstractprocessstep.h
index 2c725f0b01a30da16e019abed98e7d0fac87c25c..df113303c87ceb19102891f11f96265528679a6d 100644
--- a/src/plugins/projectexplorer/abstractprocessstep.h
+++ b/src/plugins/projectexplorer/abstractprocessstep.h
@@ -38,10 +38,13 @@
 
 QT_BEGIN_NAMESPACE
 class QEventLoop;
+class QTimer;
 QT_END_NAMESPACE
 
 namespace ProjectExplorer {
 
+class IOutputParser;
+
 /*!
   AbstractProcessStep is a convenience class, which can be used as a base class instead of BuildStep.
   It should be used as a base class if your buildstep just needs to run a process.
@@ -67,6 +70,8 @@ class PROJECTEXPLORER_EXPORT AbstractProcessStep : public BuildStep
 public:
     AbstractProcessStep(BuildConfiguration *bc);
     AbstractProcessStep(AbstractProcessStep *bs, BuildConfiguration *bc);
+    virtual ~AbstractProcessStep();
+
     /// reimplemented from BuildStep::init()
     /// You need to call this from YourBuildStep::init()
     virtual bool init();
@@ -105,10 +110,17 @@ public:
     /// should be called from init()
     void setEnvironment(Environment env);
 
-    // TODO can I remove this?
     QString workingDirectory() const;
-protected:
 
+    // derived classes needs to call this function
+    /// Delete all existing output parsers and start a new chain with the
+    /// given parser.
+    void setOutputParser(ProjectExplorer::IOutputParser *parser);
+    /// Append the given output parser to the existing chain of parsers.
+    void appendOutputParser(ProjectExplorer::IOutputParser *parser);
+    ProjectExplorer::IOutputParser *outputParser() const;
+
+protected:
     /// Called after the process is started
     /// the default implementation adds a process started message to the output message
     virtual void processStarted();
@@ -121,18 +133,22 @@ protected:
     /// Called for each line of output on stdOut()
     /// the default implementation adds the line to the
     /// application output window
-    virtual void stdOut(const QString &line);
+    virtual void stdOutput(const QString &line);
     /// Called for each line of output on StdErrror()
     /// the default implementation adds the line to the
     /// application output window
     virtual void stdError(const QString &line);
+
 private slots:
     void processReadyReadStdOutput();
     void processReadyReadStdError();
     void slotProcessFinished(int, QProcess::ExitStatus);
     void checkForCancel();
-private:
 
+    void taskAdded(const ProjectExplorer::TaskWindow::Task &task);
+    void outputAdded(const QString &string);
+
+private:
     QTimer *m_timer;
     QFutureInterface<bool> *m_futureInterface;
     QString m_workingDirectory;
@@ -143,6 +159,7 @@ private:
     QProcess *m_process;
     QEventLoop *m_eventLoop;
     ProjectExplorer::Environment m_environment;
+    ProjectExplorer::IOutputParser *m_outputParserChain;
 };
 
 } // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp
index dde844b1fb32539f91f8fa4f50ec9c8281bcf5f5..560061eee44c74f029fe96131a21f276999b6bc0 100644
--- a/src/plugins/projectexplorer/buildmanager.cpp
+++ b/src/plugins/projectexplorer/buildmanager.cpp
@@ -132,9 +132,9 @@ void BuildManager::cancel()
         // (And we want those to be before the cancel message.)
         QTimer::singleShot(0, this, SLOT(emitCancelMessage()));
 
-        disconnect(m_currentBuildStep, SIGNAL(addToTaskWindow(ProjectExplorer::TaskWindow::Task)),
+        disconnect(m_currentBuildStep, SIGNAL(addTask(ProjectExplorer::TaskWindow::Task)),
                    this, SLOT(addToTaskWindow(ProjectExplorer::TaskWindow::Task)));
-        disconnect(m_currentBuildStep, SIGNAL(addToOutputWindow(QString)),
+        disconnect(m_currentBuildStep, SIGNAL(addOutput(QString)),
                    this, SLOT(addToOutputWindow(QString)));
         decrementActiveBuildSteps(m_currentBuildStep->buildConfiguration()->project());
 
@@ -269,9 +269,9 @@ void BuildManager::nextBuildQueue()
     if (m_canceling)
         return;
 
-    disconnect(m_currentBuildStep, SIGNAL(addToTaskWindow(ProjectExplorer::TaskWindow::Task)),
+    disconnect(m_currentBuildStep, SIGNAL(addTask(ProjectExplorer::TaskWindow::Task)),
                this, SLOT(addToTaskWindow(ProjectExplorer::TaskWindow::Task)));
-    disconnect(m_currentBuildStep, SIGNAL(addToOutputWindow(QString)),
+    disconnect(m_currentBuildStep, SIGNAL(addOutput(QString)),
                this, SLOT(addToOutputWindow(QString)));
 
     ++m_progress;
@@ -311,9 +311,9 @@ void BuildManager::nextStep()
         m_currentBuildStep = m_buildQueue.front();
         m_buildQueue.pop_front();
 
-        connect(m_currentBuildStep, SIGNAL(addToTaskWindow(ProjectExplorer::TaskWindow::Task)),
+        connect(m_currentBuildStep, SIGNAL(addTask(ProjectExplorer::TaskWindow::Task)),
                 this, SLOT(addToTaskWindow(ProjectExplorer::TaskWindow::Task)));
-        connect(m_currentBuildStep, SIGNAL(addToOutputWindow(QString)),
+        connect(m_currentBuildStep, SIGNAL(addOutput(QString)),
                 this, SLOT(addToOutputWindow(QString)));
 
         bool init = m_currentBuildStep->init();
diff --git a/src/plugins/projectexplorer/buildparserfactory.cpp b/src/plugins/projectexplorer/buildparserfactory.cpp
deleted file mode 100644
index e4b8895eaee2f35c25b5e12a763d199e291a530e..0000000000000000000000000000000000000000
--- a/src/plugins/projectexplorer/buildparserfactory.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** Commercial Usage
-**
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at http://qt.nokia.com/contact.
-**
-**************************************************************************/
-
-#include "buildparserfactory.h"
-
-#include "projectexplorerconstants.h"
-#include "gccparser.h"
-#include "msvcparser.h"
-
-using namespace ProjectExplorer::Internal;
-
-GccParserFactory::~GccParserFactory()
-{
-}
-
-bool GccParserFactory::canCreate(const QString & name) const
-{
-    return (name == Constants::BUILD_PARSER_GCC);
-}
-
-ProjectExplorer::IBuildParser * GccParserFactory::create(const QString & name) const
-{
-    Q_UNUSED(name)
-    return new GccParser();
-}
-
-MsvcParserFactory::~MsvcParserFactory()
-{
-}
-
-bool MsvcParserFactory::canCreate(const QString & name) const
-{
-    return (name == Constants::BUILD_PARSER_MSVC);
-}
-
-ProjectExplorer::IBuildParser * MsvcParserFactory::create(const QString & name) const
-{
-    Q_UNUSED(name)
-    return new MsvcParser();
-}
diff --git a/src/plugins/projectexplorer/buildparserfactory.h b/src/plugins/projectexplorer/buildparserfactory.h
deleted file mode 100644
index e29570f2baf2e3d0f0e8f2c964b8ec1bded97a17..0000000000000000000000000000000000000000
--- a/src/plugins/projectexplorer/buildparserfactory.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** Commercial Usage
-**
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at http://qt.nokia.com/contact.
-**
-**************************************************************************/
-
-#ifndef BUILDPARSERFACTORY_H
-#define BUILDPARSERFACTORY_H
-
-#include <projectexplorer/ibuildparser.h>
-
-namespace ProjectExplorer {
-namespace Internal {
-
-class GccParserFactory : public ProjectExplorer::IBuildParserFactory
-{
-    Q_OBJECT
-public:
-    GccParserFactory() {}
-    virtual ~GccParserFactory();
-    virtual bool canCreate(const QString & name) const;
-    virtual ProjectExplorer::IBuildParser * create(const QString & name) const;
-};
-
-class MsvcParserFactory : public ProjectExplorer::IBuildParserFactory
-{
-    Q_OBJECT
-public:
-    MsvcParserFactory() {}
-    virtual ~MsvcParserFactory();
-    virtual bool canCreate(const QString & name) const;
-    virtual ProjectExplorer::IBuildParser * create(const QString & name) const;
-};
-
-} // namespace Internal
-} // namespace ProjectExplorer
-
-#endif // BUILDPARSERFACTORY_H
diff --git a/src/plugins/projectexplorer/buildstep.h b/src/plugins/projectexplorer/buildstep.h
index 09fcbf55441b7433fdbb74fc14c55148aa88110c..29e77448c2c39285a71d91fd78cc92348aed1af1 100644
--- a/src/plugins/projectexplorer/buildstep.h
+++ b/src/plugins/projectexplorer/buildstep.h
@@ -30,11 +30,11 @@
 #ifndef BUILDSTEP_H
 #define BUILDSTEP_H
 
-#include "ibuildparser.h"
 #include "projectexplorer_export.h"
+#include "taskwindow.h"
 
-#include <QtGui/QWidget>
 #include <QtCore/QFutureInterface>
+#include <QtGui/QWidget>
 
 namespace ProjectExplorer {
 class BuildConfiguration;
@@ -109,11 +109,13 @@ public:
 
     BuildConfiguration *buildConfiguration() const;
 
-Q_SIGNALS:
-    void addToTaskWindow(const ProjectExplorer::TaskWindow::Task &task);
-    // The string is added to the output window
+signals:
+    // Add a task.
+    void addTask(const ProjectExplorer::TaskWindow::Task &task);
+    // The string is added to the generated output, usually in the output
+    // window.
     // It should be in html format, that is properly escaped
-    void addToOutputWindow(const QString &string);
+    void addOutput(const QString &string);
 
 private:
     BuildConfiguration *m_buildConfiguration;
diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp
index bc6fc6cadfcd904ad1b7df200e36db3048277a11..32a0b92946164087c0456202c5379a58c87ce853 100644
--- a/src/plugins/projectexplorer/gccparser.cpp
+++ b/src/plugins/projectexplorer/gccparser.cpp
@@ -43,39 +43,19 @@ GccParser::GccParser()
 
     m_regExpLinker.setPattern("^(\\S*)\\(\\S+\\):\\s(.+)$");
     m_regExpLinker.setMinimal(true);
-
-    //make[4]: Entering directory `/home/kkoehne/dev/ide-explorer/src/plugins/qtscripteditor'
-    m_makeDir.setPattern("^(?:mingw32-)?make.*: (\\w+) directory .(.+).$");
-    m_makeDir.setMinimal(true);
-}
-
-QString GccParser::name() const
-{
-    return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_GCC);
-}
-
-void GccParser::stdOutput(const QString & line)
-{
-    QString lne = line.trimmed();
-
-    if (m_makeDir.indexIn(lne) > -1) {
-        if (m_makeDir.cap(1) == "Leaving")
-                emit leaveDirectory(m_makeDir.cap(2));
-            else
-                emit enterDirectory(m_makeDir.cap(2));
-    }
 }
 
-void GccParser::stdError(const QString & line)
+void GccParser::stdError(const QString &line)
 {
     QString lne = line.trimmed();
     if (m_regExpLinker.indexIn(lne) > -1) {
         QString description = m_regExpLinker.cap(2);
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Error,
-                                              description,
-                                              m_regExpLinker.cap(1) /* filename */,
-                                              -1 /* linenumber */,
-                                              Constants::TASK_CATEGORY_COMPILE));
+        emit addTask(TaskWindow::Task(TaskWindow::Error,
+                                      description,
+                                      m_regExpLinker.cap(1) /* filename */,
+                                      -1 /* linenumber */,
+                                      Constants::TASK_CATEGORY_COMPILE));
+        return;
     } else if (m_regExp.indexIn(lne) > -1) {
         TaskWindow::Task task(TaskWindow::Unknown,
                               m_regExp.cap(6) /* description */,
@@ -87,20 +67,24 @@ void GccParser::stdError(const QString & line)
         else if (m_regExp.cap(5) == "error")
             task.type = TaskWindow::Error;
 
-        emit addToTaskWindow(task);
+        emit addTask(task);
+        return;
     } else if (m_regExpIncluded.indexIn(lne) > -1) {
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Unknown,
-                                              lne /* description */,
-                                              m_regExpIncluded.cap(1) /* filename */,
-                                              m_regExpIncluded.cap(2).toInt() /* linenumber */,
-                                              Constants::TASK_CATEGORY_COMPILE));
+        emit addTask(TaskWindow::Task(TaskWindow::Unknown,
+                                      lne /* description */,
+                                      m_regExpIncluded.cap(1) /* filename */,
+                                      m_regExpIncluded.cap(2).toInt() /* linenumber */,
+                                      Constants::TASK_CATEGORY_COMPILE));
+        return;
     } else if (lne.startsWith(QLatin1String("collect2:")) ||
                lne.startsWith(QLatin1String("ERROR:")) ||
                lne == QLatin1String("* cpp failed")) {
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Error,
-                                              lne /* description */,
-                                              QString() /* filename */,
-                                              -1 /* linenumber */,
-                                              Constants::TASK_CATEGORY_COMPILE));
+        emit addTask(TaskWindow::Task(TaskWindow::Error,
+                                      lne /* description */,
+                                      QString() /* filename */,
+                                      -1 /* linenumber */,
+                                      Constants::TASK_CATEGORY_COMPILE));
+        return;
     }
+    IOutputParser::stdError(line);
 }
diff --git a/src/plugins/projectexplorer/gccparser.h b/src/plugins/projectexplorer/gccparser.h
index d65c4854b503dc37d912524206d2da839e2d13e6..cf2de34b876530aeb93d980c7fcabed49d260108 100644
--- a/src/plugins/projectexplorer/gccparser.h
+++ b/src/plugins/projectexplorer/gccparser.h
@@ -30,26 +30,24 @@
 #ifndef GCCPARSER_H
 #define GCCPARSER_H
 
-#include "ibuildparser.h"
+#include "ioutputparser.h"
 
 #include <QtCore/QRegExp>
 
 namespace ProjectExplorer {
 
-class GccParser : public ProjectExplorer::IBuildParser
+class GccParser : public ProjectExplorer::IOutputParser
 {
     Q_OBJECT
 
 public:
     GccParser();
-    QString name() const;
-    virtual void stdOutput(const QString & line);
-    virtual void stdError(const QString & line);
+    virtual void stdError(const QString &line);
+
 private:
     QRegExp m_regExp;
     QRegExp m_regExpIncluded;
     QRegExp m_regExpLinker;
-    QRegExp m_makeDir;
 };
 
 } // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/gnumakeparser.cpp b/src/plugins/projectexplorer/gnumakeparser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..65958c04cedc95b4a27f32b052af6bfb383910ef
--- /dev/null
+++ b/src/plugins/projectexplorer/gnumakeparser.cpp
@@ -0,0 +1,95 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "gnumakeparser.h"
+#include "taskwindow.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+
+using namespace ProjectExplorer;
+
+GnuMakeParser::GnuMakeParser(const QString &dir)
+{
+    //make[4]: Entering directory `/some/dir'
+    m_makeDir.setPattern("^(?:mingw32-)?make.*: (\\w+) directory .(.+).$");
+    m_makeDir.setMinimal(true);
+    addDirectory(dir);
+}
+
+void GnuMakeParser::stdOutput(const QString &line)
+{
+    QString lne = line.trimmed();
+
+    if (m_makeDir.indexIn(lne) > -1) {
+        if (m_makeDir.cap(1) == "Leaving")
+            removeDirectory(m_makeDir.cap(2));
+        else
+            addDirectory(m_makeDir.cap(2));
+        return;
+    }
+
+    IOutputParser::stdOutput(line);
+}
+
+void GnuMakeParser::addDirectory(const QString &dir)
+{
+    if (dir.isEmpty() || m_directories.contains(dir))
+        return;
+    m_directories.append(dir);
+}
+
+void GnuMakeParser::removeDirectory(const QString &dir)
+{
+    m_directories.removeAll(dir);
+}
+
+void GnuMakeParser::taskAdded(const ProjectExplorer::TaskWindow::Task &task)
+{
+    ProjectExplorer::TaskWindow::Task editable(task);
+    QString filePath(QDir::cleanPath(task.file.trimmed()));
+
+    if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) {
+        QList<QFileInfo> possibleFiles;
+        foreach (const QString &dir, m_directories) {
+            QFileInfo candidate(dir + QLatin1Char('/') + filePath);
+            if (candidate.exists()
+                && !possibleFiles.contains(candidate)) {
+                possibleFiles << candidate;
+            }
+        }
+        if (possibleFiles.size() == 1)
+            editable.file = possibleFiles.first().filePath();
+        // Let the Makestep apply additional heuristics (based on
+        // files in ther project) if we can not uniquely
+        // identify the file!
+    }
+
+    IOutputParser::taskAdded(editable);
+}
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.h b/src/plugins/projectexplorer/gnumakeparser.h
similarity index 67%
rename from src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.h
rename to src/plugins/projectexplorer/gnumakeparser.h
index fd162bfbfe1e5b0af26b1237b6cc504998c73612..7a07a3bafb080b555282fda8aa19a7823dc2e44b 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.h
+++ b/src/plugins/projectexplorer/gnumakeparser.h
@@ -27,25 +27,36 @@
 **
 **************************************************************************/
 
-#ifndef S60BUILDPARSERFACTORY_H
-#define S60BUILDPARSERFACTORY_H
+#ifndef GNUMAKEPARSER_H
+#define GNUMAKEPARSER_H
 
-#include <projectexplorer/ibuildparser.h>
+#include "ioutputparser.h"
 
-namespace Qt4ProjectManager {
-namespace Internal {
+#include <QtCore/QRegExp>
+#include <QtCore/QStringList>
 
-class S60ParserFactory : public ProjectExplorer::IBuildParserFactory
+namespace ProjectExplorer {
+
+class PROJECTEXPLORER_EXPORT GnuMakeParser : public ProjectExplorer::IOutputParser
 {
     Q_OBJECT
+
 public:
-    S60ParserFactory() {}
-    virtual ~S60ParserFactory();
-    virtual bool canCreate(const QString & name) const;
-    virtual ProjectExplorer::IBuildParser * create(const QString & name) const;
+    explicit GnuMakeParser(const QString &dir = QString());
+
+    virtual void stdOutput(const QString &line);
+
+public slots:
+    virtual void taskAdded(const ProjectExplorer::TaskWindow::Task &task);
+
+private:
+    void addDirectory(const QString &dir);
+    void removeDirectory(const QString &dir);
+
+    QRegExp m_makeDir;
+    QStringList m_directories;
 };
 
-} // namespace Internal
 } // namespace ProjectExplorer
 
-#endif // S60BUILDPARSERFACTORY_H
+#endif // GNUMAKEPARSER_H
diff --git a/src/plugins/projectexplorer/ibuildparser.cpp b/src/plugins/projectexplorer/ibuildparser.cpp
deleted file mode 100644
index e60d5aaa1feb2dbe80ab524430a340a8508c2638..0000000000000000000000000000000000000000
--- a/src/plugins/projectexplorer/ibuildparser.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** Commercial Usage
-**
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at http://qt.nokia.com/contact.
-**
-**************************************************************************/
-
-#include "ibuildparser.h"
-
-using namespace ProjectExplorer;
-
-IBuildParserFactory::~IBuildParserFactory()
-{
-}
-
-
diff --git a/src/plugins/projectexplorer/ibuildparser.h b/src/plugins/projectexplorer/ioutputparser.cpp
similarity index 55%
rename from src/plugins/projectexplorer/ibuildparser.h
rename to src/plugins/projectexplorer/ioutputparser.cpp
index c1e60afa653465a9b1fdf7f36e817d93965ffaa8..a57340d342249ea221a54224ad0c4e88f9a6c2a6 100644
--- a/src/plugins/projectexplorer/ibuildparser.h
+++ b/src/plugins/projectexplorer/ioutputparser.cpp
@@ -27,46 +27,56 @@
 **
 **************************************************************************/
 
-#ifndef IBUILDPARSER_H
-#define IBUILDPARSER_H
+#include "ioutputparser.h"
+#include "utils/qtcassert.h"
 
-#include "projectexplorer_export.h"
-#include "taskwindow.h"
+namespace ProjectExplorer {
+
+IOutputParser::IOutputParser() : m_parser(0)
+{
 
-#include <QtCore/QObject>
-#include <QtCore/QString>
+}
 
-namespace ProjectExplorer {
+IOutputParser::~IOutputParser()
+{
+    delete m_parser;
+}
 
-class PROJECTEXPLORER_EXPORT IBuildParser : public QObject
+void IOutputParser::appendOutputParser(IOutputParser *parser)
 {
-    Q_OBJECT
-public:
-    virtual ~IBuildParser() {}
-    virtual QString name() const = 0;
+    QTC_ASSERT(parser, return);
+    if (m_parser) {
+        m_parser->appendOutputParser(parser);
+        return;
+    }
 
-    virtual void stdOutput(const QString & line) = 0;
-    virtual void stdError(const QString & line) = 0;
+    m_parser = parser;
+    connect(parser, SIGNAL(addOutput(QString)),
+            this, SLOT(outputAdded(QString)));
+    connect(parser, SIGNAL(addTask(ProjectExplorer::TaskWindow::Task)),
+            this, SLOT(taskAdded(ProjectExplorer::TaskWindow::Task)));
+}
 
-Q_SIGNALS:
-    void enterDirectory(const QString &dir);
-    void leaveDirectory(const QString &dir);
-    void addToOutputWindow(const QString & string);
-    void addToTaskWindow(const ProjectExplorer::TaskWindow::Task &task);
-};
+void IOutputParser::stdOutput(const QString &line)
+{
+    if (m_parser)
+        m_parser->stdOutput(line);
+}
 
-class PROJECTEXPLORER_EXPORT IBuildParserFactory
-    : public QObject
+void IOutputParser::stdError(const QString &line)
 {
-    Q_OBJECT
+    if (m_parser)
+        m_parser->stdError(line);
+}
 
-public:
-    IBuildParserFactory() {}
-    virtual ~IBuildParserFactory();
-    virtual bool canCreate(const QString & name) const = 0;
-    virtual IBuildParser * create(const QString & name) const = 0;
-};
+void IOutputParser::outputAdded(const QString &string)
+{
+    emit addOutput(string);
+}
 
-} // namespace ProjectExplorer
+void IOutputParser::taskAdded(const ProjectExplorer::TaskWindow::Task &task)
+{
+    emit addTask(task);
+}
 
-#endif // IBUILDPARSER_H
+}
diff --git a/src/plugins/projectexplorer/abstractmakestep.h b/src/plugins/projectexplorer/ioutputparser.h
similarity index 50%
rename from src/plugins/projectexplorer/abstractmakestep.h
rename to src/plugins/projectexplorer/ioutputparser.h
index 4d8f9268bfa192e9613f2eae586529b209514cb4..0ed15aea940cc6f1ac5a7b6e2ad452a52a3c21f5 100644
--- a/src/plugins/projectexplorer/abstractmakestep.h
+++ b/src/plugins/projectexplorer/ioutputparser.h
@@ -27,50 +27,54 @@
 **
 **************************************************************************/
 
-#ifndef ABSTRACTMAKESTEP_H
-#define ABSTRACTMAKESTEP_H
+#ifndef IOUTPUTPARSER_H
+#define IOUTPUTPARSER_H
 
 #include "projectexplorer_export.h"
-#include "abstractprocessstep.h"
 #include "taskwindow.h"
 
-namespace ProjectExplorer {
-class BuildStep;
-class IBuildStepFactory;
-class Project;
-}
+#include <QtCore/QObject>
+#include <QtCore/QString>
 
 namespace ProjectExplorer {
 
-class PROJECTEXPLORER_EXPORT AbstractMakeStep : public ProjectExplorer::AbstractProcessStep
+class PROJECTEXPLORER_EXPORT IOutputParser : public QObject
 {
     Q_OBJECT
 public:
-    AbstractMakeStep(BuildConfiguration *bc);
-    AbstractMakeStep(AbstractMakeStep *bs, BuildConfiguration *bc);
-    ~AbstractMakeStep();
-    virtual bool init();
-    virtual void run(QFutureInterface<bool> &);
+    IOutputParser();
+    virtual ~IOutputParser();
+
+    /// Append a subparser to this parser.
+    /// IOutputParser will take ownership.
+    void appendOutputParser(IOutputParser *parser);
 
-protected:
-    // derived classes needs to call these functions
-    virtual void stdOut(const QString &line);
+    /// Called once for each line if standard output to parse.
+    virtual void stdOutput(const QString &line);
+    /// Called once for each line if standard error to parse.
     virtual void stdError(const QString &line);
 
-    // derived classes needs to call this function
-    void setBuildParser(const QString &parser);
-    QString buildParser() const;
-private slots:
-    void slotAddToTaskWindow(const ProjectExplorer::TaskWindow::Task &task);
-    void addDirectory(const QString &dir);
-    void removeDirectory(const QString &dir);
+signals:
+    /// Should be emitted whenever some additional information should be
+    /// added to the output.
+    /// Note: This is additional information. There is no need to add each
+    /// line!
+    void addOutput(const QString &string);
+    /// Should be emitted for each task seen in the output.
+    void addTask(const ProjectExplorer::TaskWindow::Task &task);
+
+public slots:
+    /// Subparsers have their addOutput signal connected to this slot.
+    /// This method can be overwritten to change the string.
+    virtual void outputAdded(const QString &string);
+    /// Subparsers have their addTask signal connected to this slot.
+    /// This method can be overwritten to change the task.
+    virtual void taskAdded(const ProjectExplorer::TaskWindow::Task &task);
+
 private:
-    QString m_buildParserName;
-    ProjectExplorer::IBuildParser *m_buildParser;
-    QString m_buildConfiguration;
-    QSet<QString> m_openDirectories;
+    IOutputParser *m_parser;
 };
 
-} // ProjectExplorer
+} // namespace ProjectExplorer
 
-#endif // ABSTRACTMAKESTEP_H
+#endif // IOUTPUTPARSER_H
diff --git a/src/plugins/projectexplorer/metatypedeclarations.h b/src/plugins/projectexplorer/metatypedeclarations.h
index 2749c15cc84eec286eb02ddb9efaed7c46f62ec6..57fccb55067a98fe17e62da23d3ce25f050b19e7 100644
--- a/src/plugins/projectexplorer/metatypedeclarations.h
+++ b/src/plugins/projectexplorer/metatypedeclarations.h
@@ -38,7 +38,7 @@ class ProjectInterface;
 class IProjectManager;
 class SessionManager;
 class IApplicationOutput;
-class IBuildParser;
+class IOutputParser;
 class GlobalConfigManagerInterface;
 
 namespace Internal {
@@ -53,7 +53,7 @@ Q_DECLARE_METATYPE(ProjectExplorer::IProjectManager*)
 Q_DECLARE_METATYPE(ProjectExplorer::IApplicationOutput*)
 Q_DECLARE_METATYPE(ProjectExplorer::Internal::CommandQObject*)
 Q_DECLARE_METATYPE(QList<ProjectExplorer::Internal::CommandQObject*>)
-Q_DECLARE_METATYPE(ProjectExplorer::IBuildParser*)
+Q_DECLARE_METATYPE(ProjectExplorer::IOutputParser*)
 
 Q_DECLARE_METATYPE(ProjectExplorer::GlobalConfigManagerInterface*)
 Q_DECLARE_METATYPE(ProjectExplorer::TaskWindow::Task)
diff --git a/src/plugins/projectexplorer/msvcparser.cpp b/src/plugins/projectexplorer/msvcparser.cpp
index df8996f9688543986ced5c9670589ba2b82b94d4..9d8110725c2c770653ec477946a8eaa1755642a7 100644
--- a/src/plugins/projectexplorer/msvcparser.cpp
+++ b/src/plugins/projectexplorer/msvcparser.cpp
@@ -30,9 +30,6 @@
 #include "msvcparser.h"
 #include "projectexplorerconstants.h"
 
-#include <QtCore/QStringList>
-#include <QtCore/QDir>
-
 using namespace ProjectExplorer;
 
 MsvcParser::MsvcParser()
@@ -43,26 +40,15 @@ MsvcParser::MsvcParser()
     m_linkRegExp.setMinimal(true);
 }
 
-QString MsvcParser::name() const
-{
-    return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_MSVC);
-}
-
-void MsvcParser::stdError(const QString & line)
-{
-    Q_UNUSED(line)
-    //do nothing
-}
-
-void MsvcParser::stdOutput(const QString & line)
+void MsvcParser::stdOutput(const QString &line)
 {
     QString lne = line.trimmed();
     if (m_compileRegExp.indexIn(lne) > -1 && m_compileRegExp.numCaptures() == 4) {
-        emit addToTaskWindow(TaskWindow::Task(toType(m_compileRegExp.cap(3).toInt()) /* task type */,
-                                              m_compileRegExp.cap(4) /* description */,
-                                              m_compileRegExp.cap(1) /* filename */,
-                                              m_compileRegExp.cap(2).toInt() /* linenumber */,
-                                              Constants::TASK_CATEGORY_COMPILE));
+        emit addTask(TaskWindow::Task(toType(m_compileRegExp.cap(3).toInt()) /* task type */,
+                                      m_compileRegExp.cap(4) /* description */,
+                                      m_compileRegExp.cap(1) /* filename */,
+                                      m_compileRegExp.cap(2).toInt() /* linenumber */,
+                                      Constants::TASK_CATEGORY_COMPILE));
         return;
     }
     if (m_linkRegExp.indexIn(lne) > -1 && m_linkRegExp.numCaptures() == 3) {
@@ -70,13 +56,14 @@ void MsvcParser::stdOutput(const QString & line)
         if (fileName.contains(QLatin1String("LINK"), Qt::CaseSensitive))
             fileName.clear();
 
-        emit addToTaskWindow(TaskWindow::Task(toType(m_linkRegExp.cap(2).toInt()) /* task type */,
-                                              m_linkRegExp.cap(3) /* description */,
-                                              fileName /* filename */,
-                                              -1 /* line number */,
-                                              Constants::TASK_CATEGORY_COMPILE));
+        emit addTask(TaskWindow::Task(toType(m_linkRegExp.cap(2).toInt()) /* task type */,
+                                      m_linkRegExp.cap(3) /* description */,
+                                      fileName /* filename */,
+                                      -1 /* line number */,
+                                      Constants::TASK_CATEGORY_COMPILE));
         return;
     }
+    IOutputParser::stdError(line);
 }
 
 TaskWindow::TaskType MsvcParser::toType(int number)
diff --git a/src/plugins/projectexplorer/msvcparser.h b/src/plugins/projectexplorer/msvcparser.h
index d3e718a79aecb40ff857d976de407e8291c3d0e9..6b90a81c22f7e990dff83e7bd3b5b87318cad8fa 100644
--- a/src/plugins/projectexplorer/msvcparser.h
+++ b/src/plugins/projectexplorer/msvcparser.h
@@ -30,23 +30,23 @@
 #ifndef MSVCPARSER_H
 #define MSVCPARSER_H
 
-#include "ibuildparser.h"
+#include "ioutputparser.h"
 #include "taskwindow.h"
 
 #include <QtCore/QRegExp>
+#include <QtCore/QString>
 
 namespace ProjectExplorer {
 
-class MsvcParser :  public ProjectExplorer::IBuildParser
+class MsvcParser :  public ProjectExplorer::IOutputParser
 {
     Q_OBJECT
 
 public:
     MsvcParser();
-    QString name() const;
 
-    virtual void stdOutput(const QString & line);
-    virtual void stdError(const QString & line);
+    virtual void stdOutput(const QString &line);
+
 private:
     TaskWindow::TaskType toType(int number);
     QRegExp m_compileRegExp;
diff --git a/src/plugins/projectexplorer/processstep.cpp b/src/plugins/projectexplorer/processstep.cpp
index d579ebe9511022a9dea0fc5f36064172d5f4c512..85e8b8570efa0e9e027de9967b3c466f28e21f2e 100644
--- a/src/plugins/projectexplorer/processstep.cpp
+++ b/src/plugins/projectexplorer/processstep.cpp
@@ -74,6 +74,7 @@ bool ProcessStep::init()
     AbstractProcessStep::setCommand(m_command);
     AbstractProcessStep::setEnabled(m_enabled);
     AbstractProcessStep::setArguments(m_arguments);
+    setOutputParser(0);
     return AbstractProcessStep::init();
 }
 
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index dd4020baaa16b1ca8e9b077f91ee732f1fd8f2ca..fcb3fc9ee1af415b8aeff0f3c6d03c4a3c6f58e1 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -57,7 +57,6 @@
 #include "scriptwrappers.h"
 #include "session.h"
 #include "sessiondialog.h"
-#include "buildparserfactory.h"
 #include "projectexplorersettingspage.h"
 #include "projectwelcomepage.h"
 #include "projectwelcomepagewidget.h"
@@ -304,10 +303,6 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
 
     addAutoReleasedObject(new ProjectFileWizardExtension);
 
-    // Build parsers
-    addAutoReleasedObject(new GccParserFactory);
-    addAutoReleasedObject(new MsvcParserFactory);
-
     // Settings page
     addAutoReleasedObject(new ProjectExplorerSettingsPage);
 
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index 325f624a321b4a4a99e6388511b13fb5a04b7773..32a3e1baf22e3449b7bfe2f5a836243a524dd425 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -19,7 +19,8 @@ HEADERS += projectexplorer.h \
     session.h \
     dependenciespanel.h \
     allprojectsfilter.h \
-    ibuildparser.h \
+    ioutputparser.h \
+    gnumakeparser.h \
     projectexplorerconstants.h \
     projectexplorersettings.h \
     corelistenercheckingforrunningbuild.h \
@@ -57,12 +58,10 @@ HEADERS += projectexplorer.h \
     currentprojectfind.h \
     toolchain.h \
     cesdkhandler.h \
-    buildparserfactory.h \
     gccparser.h \
     msvcparser.h \
     filewatcher.h \
     debugginghelper.h \
-    abstractmakestep.h \
     projectexplorersettingspage.h \
     projectwelcomepage.h \
     projectwelcomepagewidget.h \
@@ -71,6 +70,8 @@ SOURCES += projectexplorer.cpp \
     projectwindow.cpp \
     buildmanager.cpp \
     compileoutputwindow.cpp \
+    ioutputparser.cpp \
+    gnumakeparser.cpp \
     taskwindow.cpp \
     outputwindow.cpp \
     persistentsettings.cpp \
@@ -85,7 +86,6 @@ SOURCES += projectexplorer.cpp \
     pluginfilefactory.cpp \
     buildstep.cpp \
     buildconfiguration.cpp \
-    ibuildparser.cpp \
     environment.cpp \
     buildsettingspropertiespage.cpp \
     environmenteditmodel.cpp \
@@ -110,12 +110,10 @@ SOURCES += projectexplorer.cpp \
     currentprojectfind.cpp \
     toolchain.cpp \
     cesdkhandler.cpp \
-    buildparserfactory.cpp \
     gccparser.cpp \
     msvcparser.cpp \
     filewatcher.cpp \
     debugginghelper.cpp \
-    abstractmakestep.cpp \
     projectexplorersettingspage.cpp \
     projectwelcomepage.cpp \
     projectwelcomepagewidget.cpp \
diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h
index 958391e6371011e45f6075ef899d05084e701c53..ab7258d1a9ae3c1a1d88204a32d24023e7a90986 100644
--- a/src/plugins/projectexplorer/projectexplorerconstants.h
+++ b/src/plugins/projectexplorer/projectexplorerconstants.h
@@ -178,15 +178,6 @@ const char * const CPP_HEADER_MIMETYPE = "text/x-c++hdr";
 const char * const FORM_MIMETYPE = "application/x-designer";
 const char * const RESOURCE_MIMETYPE = "application/vnd.nokia.xml.qt.resource";
 
-// build parsers
-const char * const BUILD_PARSER_MSVC        = "BuildParser.MSVC";
-const char * const BUILD_PARSER_GCC         = "BuildParser.Gcc";
-const char * const BUILD_PARSER_RVCT        = "BuildParser.Rvct";
-const char * const BUILD_PARSER_WINSCW      = "BuildParser.Winscw";
-const char * const BUILD_PARSER_ABLD_GCCE   = "BuildParser.ABLD.Gcce";
-const char * const BUILD_PARSER_ABLD_WINSCW = "BuildParser.ABLD.Winscw";
-const char * const BUILD_PARSER_ABLD_RVCT   = "BuildParser.ABLD.Rvct";
-
 // settings page
 const char * const PROJECTEXPLORER_SETTINGS_CATEGORY  = "K.ProjectExplorer";
 const char * const PROJECTEXPLORER_SETTINGS_ID = "ProjectExplorer.ProjectExplorer";
diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp
index c7cbe9e3cdbfb68baf49d4ee4997be824f6dde77..5134035a003baeb69b0416ad7aaff51bdfd847ca 100644
--- a/src/plugins/projectexplorer/taskwindow.cpp
+++ b/src/plugins/projectexplorer/taskwindow.cpp
@@ -151,7 +151,6 @@ protected:
     bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
 
 private:
-    // These correspond to ProjectExplorer::BuildParserInterface::PatternType.
     bool m_includeUnknowns;
     bool m_includeWarnings;
     bool m_includeErrors;
diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp
index d70bdcd2481761ec3e739e28a0e9eeb03e671797..c085f93aed346f8788f1510430966ecd8804ea25 100644
--- a/src/plugins/projectexplorer/toolchain.cpp
+++ b/src/plugins/projectexplorer/toolchain.cpp
@@ -31,10 +31,12 @@
 #include "project.h"
 #include "cesdkhandler.h"
 #include "projectexplorersettings.h"
+#include "gccparser.h"
+#include "msvcparser.h"
 
+#include <QtCore/QDebug>
 #include <QtCore/QFileInfo>
 #include <QtCore/QProcess>
-#include <QtCore/QDebug>
 #include <QtCore/QSettings>
 #include <QtCore/QDir>
 #include <QtCore/QTemporaryFile>
@@ -93,7 +95,6 @@ QStringList ToolChain::availableMSVCVersions()
 {
     QSettings registry(MSVC_RegKey, QSettings::NativeFormat);
     QStringList versions = registry.allKeys();
-    // qDebug() << "AVAILABLE MSVC VERSIONS:" << versions << "at" << MSVC_RegKey;
     return versions;
 }
 
@@ -241,7 +242,12 @@ void GccToolChain::addToEnvironment(ProjectExplorer::Environment &env)
 
 QString GccToolChain::makeCommand() const
 {
-    return "make";
+    return QLatin1String("make");
+}
+
+IOutputParser *GccToolChain::outputParser() const
+{
+    return new GccParser;
 }
 
 bool GccToolChain::equals(ToolChain *other) const
@@ -268,21 +274,22 @@ bool MinGWToolChain::equals(ToolChain *other) const
 
 void MinGWToolChain::addToEnvironment(ProjectExplorer::Environment &env)
 {
-    //qDebug()<<"MinGWToolChain::addToEnvironment";
     if (m_mingwPath.isEmpty())
         return;
     QString binDir = m_mingwPath + "/bin";
     if (QFileInfo(binDir).exists())
         env.prependOrSetPath(binDir);
-//    if (QFileInfo(binDir).exists())
-//        qDebug()<<"Adding "<<binDir<<" to the PATH";
 }
 
 QString MinGWToolChain::makeCommand() const
 {
-    return "mingw32-make.exe";
+    return QLatin1String("mingw32-make.exe");
 }
 
+IOutputParser *MinGWToolChain::outputParser() const
+{
+    return new GccParser;
+}
 
 MSVCToolChain::MSVCToolChain(const QString &name, bool amd64)
     : m_name(name), m_valuesSet(false), m_amd64(amd64)
@@ -382,7 +389,6 @@ QByteArray MSVCToolChain::predefinedMacros()
         }
         QFile::remove(tmpFilePath);
     }
-    //qDebug() << m_predefinedMacros;
     return m_predefinedMacros;
 }
 
@@ -412,7 +418,6 @@ void MSVCToolChain::addToEnvironment(ProjectExplorer::Environment &env)
             varsbat = path + "bin\\amd64\\vcvarsamd64.bat";
         else
             varsbat = path + "bin\\vcvars32.bat";
-        //        qDebug() << varsbat;
         if (QFileInfo(varsbat).exists()) {
             QTemporaryFile tf(QDir::tempPath() + "\\XXXXXX.bat");
             if (!tf.open())
@@ -465,9 +470,14 @@ QString MSVCToolChain::makeCommand() const
         if (QFileInfo(jom).exists())
             return jom;
         else
-            return "jom.exe";
+            return QLatin1String("jom.exe");
     }
-    return "nmake.exe";
+    return QLatin1String("nmake.exe");
+}
+
+IOutputParser *MSVCToolChain::outputParser() const
+{
+    return new MsvcParser;
 }
 
 WinCEToolChain::WinCEToolChain(const QString &name, const QString &platform)
@@ -521,14 +531,8 @@ void WinCEToolChain::addToEnvironment(ProjectExplorer::Environment &env)
 
     path += "/";
 
-//        qDebug()<<"MSVC path"<<path;
-//        qDebug()<<"looking for platform name in"<< path() + "/mkspecs/" + mkspec() +"/qmake.conf";
     // Find Platform name
-//        qDebug()<<"Platform Name"<<m_platform;
-
     CeSdkHandler cesdkhandler;
     cesdkhandler.parse(path);
     cesdkhandler.find(m_platform).addToEnvironment(env);
-    //qDebug()<<"WinCE Final Environment:";
-    //qDebug()<<env.toStringList();
 }
diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h
index 7af97d36cf18e0100629cf7d930f7b75c21abbf9..6efdc647b9483a7b0a71ce279464dc6c25c17f3e 100644
--- a/src/plugins/projectexplorer/toolchain.h
+++ b/src/plugins/projectexplorer/toolchain.h
@@ -40,6 +40,7 @@
 namespace ProjectExplorer {
 
 class Environment;
+class IOutputParser;
 class Project;
 
 class PROJECTEXPLORER_EXPORT HeaderPath
@@ -97,6 +98,7 @@ public:
     virtual void addToEnvironment(ProjectExplorer::Environment &env) = 0;
     virtual ToolChainType type() const = 0;
     virtual QString makeCommand() const = 0;
+    virtual IOutputParser *outputParser() const = 0;
 
     ToolChain();
     virtual ~ToolChain();
@@ -125,11 +127,13 @@ public:
     virtual void addToEnvironment(ProjectExplorer::Environment &env);
     virtual ToolChainType type() const;
     virtual QString makeCommand() const;
+    virtual IOutputParser *outputParser() const;
 
 protected:
     virtual bool equals(ToolChain *other) const;
     QByteArray m_predefinedMacros;
     QList<HeaderPath> m_systemHeaderPaths;
+
 private:
     QString m_gcc;
 };
@@ -142,8 +146,11 @@ public:
     virtual void addToEnvironment(ProjectExplorer::Environment &env);
     virtual ToolChainType type() const;
     virtual QString makeCommand() const;
+    virtual IOutputParser *outputParser() const;
+
 protected:
     virtual bool equals(ToolChain *other) const;
+
 private:
     QString m_mingwPath;
 };
@@ -158,10 +165,13 @@ public:
     virtual void addToEnvironment(ProjectExplorer::Environment &env);
     virtual ToolChainType type() const;
     virtual QString makeCommand() const;
+    virtual IOutputParser *outputParser() const;
+
 protected:
     virtual bool equals(ToolChain *other) const;
     QByteArray m_predefinedMacros;
     QString m_name;
+
 private:
     mutable QList<QPair<QString, QString> > m_values;
     mutable bool m_valuesSet;
@@ -178,8 +188,10 @@ public:
     virtual QList<HeaderPath> systemHeaderPaths();
     virtual void addToEnvironment(ProjectExplorer::Environment &env);
     virtual ToolChainType type() const;
+
 protected:
     virtual bool equals(ToolChain *other) const;
+
 private:
     QString m_platform;
 };
diff --git a/src/plugins/qt4projectmanager/makestep.cpp b/src/plugins/qt4projectmanager/makestep.cpp
index fb942baa84249a35b5f2109e37823fad598b36cd..2ff62bb025c91b1059dd4cc7c26dfe0e027fa6c6 100644
--- a/src/plugins/qt4projectmanager/makestep.cpp
+++ b/src/plugins/qt4projectmanager/makestep.cpp
@@ -33,26 +33,24 @@
 #include "qt4buildconfiguration.h"
 #include "qt4projectmanagerconstants.h"
 
-#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/gnumakeparser.h>
 
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
 
-using ProjectExplorer::IBuildParserFactory;
-using ProjectExplorer::IBuildParser;
 using ProjectExplorer::Environment;
 using ExtensionSystem::PluginManager;
 using namespace Qt4ProjectManager;
 using namespace Qt4ProjectManager::Internal;
 
-MakeStep::MakeStep(ProjectExplorer::BuildConfiguration *bc)
-    : AbstractMakeStep(bc), m_clean(false)
+MakeStep::MakeStep(ProjectExplorer::BuildConfiguration *bc) :
+    AbstractProcessStep(bc), m_clean(false)
 {
 
 }
 
-MakeStep::MakeStep(MakeStep *bs, ProjectExplorer::BuildConfiguration *bc)
-    : AbstractMakeStep(bs, bc),
+MakeStep::MakeStep(MakeStep *bs, ProjectExplorer::BuildConfiguration *bc) :
+    AbstractProcessStep(bs, bc),
     m_clean(bs->m_clean),
     m_userArgs(bs->m_userArgs),
     m_makeCmd(bs->m_makeCmd)
@@ -79,7 +77,7 @@ void MakeStep::restoreFromGlobalMap(const QMap<QString, QVariant> &map)
 {
     if (map.value("clean").isValid() && map.value("clean").toBool())
         m_clean = true;
-    ProjectExplorer::AbstractMakeStep::restoreFromGlobalMap(map);
+    ProjectExplorer::AbstractProcessStep::restoreFromGlobalMap(map);
 }
 
 void MakeStep::restoreFromLocalMap(const QMap<QString, QVariant> &map)
@@ -88,7 +86,7 @@ void MakeStep::restoreFromLocalMap(const QMap<QString, QVariant> &map)
     m_makeCmd = map.value("makeCmd").toString();
     if (map.value("clean").isValid() && map.value("clean").toBool())
         m_clean = true;
-    ProjectExplorer::AbstractMakeStep::restoreFromLocalMap(map);
+    ProjectExplorer::AbstractProcessStep::restoreFromLocalMap(map);
 }
 
 void MakeStep::storeIntoLocalMap(QMap<QString, QVariant> &map)
@@ -97,7 +95,7 @@ void MakeStep::storeIntoLocalMap(QMap<QString, QVariant> &map)
     map["makeCmd"] = m_makeCmd;
     if (m_clean)
         map["clean"] = true;
-    ProjectExplorer::AbstractMakeStep::storeIntoLocalMap(map);
+    ProjectExplorer::AbstractProcessStep::storeIntoLocalMap(map);
 }
 
 bool MakeStep::init()
@@ -116,8 +114,8 @@ bool MakeStep::init()
         // Try to detect command in environment
         QString tmp = environment.searchInPath(makeCmd);
         if (tmp == QString::null) {
-            emit addToOutputWindow(tr("<font color=\"#ff0000\">Could not find make command: %1 "\
-                                      "in the build environment</font>").arg(makeCmd));
+            emit addOutput(tr("<font color=\"#ff0000\">Could not find make command: %1 "\
+                              "in the build environment</font>").arg(makeCmd));
             return false;
         }
         makeCmd = tmp;
@@ -140,30 +138,22 @@ bool MakeStep::init()
     // but for now this is the least invasive change
     ProjectExplorer::ToolChain *toolchain = bc->toolChain();
 
-    ProjectExplorer::ToolChain::ToolChainType type =  ProjectExplorer::ToolChain::UNKNOWN;
-    if (toolchain)
-        type = toolchain->type();
-    if (type != ProjectExplorer::ToolChain::MSVC && type != ProjectExplorer::ToolChain::WINCE) {
-        if (m_makeCmd.isEmpty())
-            args << "-w";
+    if (toolchain) {
+        if (toolchain->type() != ProjectExplorer::ToolChain::MSVC &&
+            toolchain->type() != ProjectExplorer::ToolChain::WINCE) {
+            if (m_makeCmd.isEmpty())
+                args << "-w";
+        }
     }
 
     setEnabled(true);
     setArguments(args);
 
-    if (type == ProjectExplorer::ToolChain::MSVC || type == ProjectExplorer::ToolChain::WINCE)
-        setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_MSVC);
-    else if (ProjectExplorer::ToolChain::GCCE == type)
-        setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_ABLD_GCCE);
-    else if (ProjectExplorer::ToolChain::WINSCW == type)
-        setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_ABLD_WINSCW);
-    else if (ProjectExplorer::ToolChain::RVCT_ARMV5 == type ||
-             ProjectExplorer::ToolChain::RVCT_ARMV6 == type)
-        setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_ABLD_RVCT);
-    else
-        setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_GCC);
+    setOutputParser(new ProjectExplorer::GnuMakeParser(workingDirectory));
+    if (toolchain)
+        appendOutputParser(toolchain->outputParser());
 
-    return AbstractMakeStep::init();
+    return AbstractProcessStep::init();
 }
 
 void MakeStep::run(QFutureInterface<bool> & fi)
@@ -173,7 +163,7 @@ void MakeStep::run(QFutureInterface<bool> & fi)
         return;
     }
 
-    AbstractMakeStep::run(fi);
+    AbstractProcessStep::run(fi);
 }
 
 QString MakeStep::name()
@@ -183,7 +173,7 @@ QString MakeStep::name()
 
 QString MakeStep::displayName()
 {
-    return "Make";
+    return QLatin1String("Make");
 }
 
 bool MakeStep::immutable() const
diff --git a/src/plugins/qt4projectmanager/makestep.h b/src/plugins/qt4projectmanager/makestep.h
index 5a9390a8cb3ca46a3c958fbcc929a83b82c9a165..b18bca6ef21a38cbb7b446b8c92c47a1b4d9675d 100644
--- a/src/plugins/qt4projectmanager/makestep.h
+++ b/src/plugins/qt4projectmanager/makestep.h
@@ -33,7 +33,7 @@
 #include "ui_makestep.h"
 #include "qtversionmanager.h"
 
-#include <projectexplorer/abstractmakestep.h>
+#include <projectexplorer/abstractprocessstep.h>
 #include <projectexplorer/projectexplorer.h>
 
 namespace ProjectExplorer {
@@ -62,7 +62,7 @@ public:
 
 class Qt4Project;
 
-class MakeStep : public ProjectExplorer::AbstractMakeStep
+class MakeStep : public ProjectExplorer::AbstractProcessStep
 {
     Q_OBJECT
     friend class MakeStepConfigWidget; // TODO remove this
diff --git a/src/plugins/qt4projectmanager/qmakeparser.cpp b/src/plugins/qt4projectmanager/qmakeparser.cpp
index 767b86921af18888ca8112d25c909c07b917aa18..804a5672917a27dac30840c899ab5ffd0a1a696a 100644
--- a/src/plugins/qt4projectmanager/qmakeparser.cpp
+++ b/src/plugins/qt4projectmanager/qmakeparser.cpp
@@ -29,53 +29,30 @@
 
 #include "qmakeparser.h"
 #include "qt4projectmanagerconstants.h"
+
 #include <projectexplorer/taskwindow.h>
 #include <projectexplorer/projectexplorerconstants.h>
+#include <utils/qtcassert.h>
 
 using namespace Qt4ProjectManager;
 using namespace Qt4ProjectManager::Internal;
 using ProjectExplorer::TaskWindow;
 
-QMakeParserFactory::~QMakeParserFactory()
-{
-}
-
-bool QMakeParserFactory::canCreate(const QString & name) const
-{
-    return (name == Constants::BUILD_PARSER_QMAKE);
-}
-
-ProjectExplorer::IBuildParser * QMakeParserFactory::create(const QString & name) const
-{
-    Q_UNUSED(name)
-    return new QMakeParser();
-}
-
 QMakeParser::QMakeParser()
 {
 }
 
-QString QMakeParser::name() const
-{
-    return QLatin1String(Qt4ProjectManager::Constants::BUILD_PARSER_QMAKE);
-}
-
-void QMakeParser::stdOutput(const QString & line)
-{
-    Q_UNUSED(line)
-}
-
-void QMakeParser::stdError(const QString & line)
+void QMakeParser::stdError(const QString &line)
 {
     QString lne(line.trimmed());
-    if (lne.startsWith("Project ERROR:"))
-    {
-        lne = lne.mid(15);
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Error,
-                                              lne /* description */,
-                                              QString() /* filename */,
-                                              -1 /* linenumber */,
-                                              ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
+    if (lne.startsWith("Project ERROR:")) {
+        const QString description = lne.mid(15);
+        emit addTask(TaskWindow::Task(TaskWindow::Error,
+                                      description,
+                                      QString() /* filename */,
+                                      -1 /* linenumber */,
+                                      ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
         return;
     }
+    IOutputParser::stdError(line);
 }
diff --git a/src/plugins/qt4projectmanager/qmakeparser.h b/src/plugins/qt4projectmanager/qmakeparser.h
index e3bdf950a9d48ddc212b73adfe934747b0e7fe34..75b6684b1c1e4a05e27da25b2ac57987bb3b0ae8 100644
--- a/src/plugins/qt4projectmanager/qmakeparser.h
+++ b/src/plugins/qt4projectmanager/qmakeparser.h
@@ -30,37 +30,23 @@
 #ifndef QMAKEPARSER_H
 #define QMAKEPARSER_H
 
-#include <projectexplorer/ibuildparser.h>
+#include <projectexplorer/ioutputparser.h>
 
 #include <QtCore/QRegExp>
 
 namespace Qt4ProjectManager {
 namespace Internal {
 
-class QMakeParserFactory : public ProjectExplorer::IBuildParserFactory
-{
-    Q_OBJECT
-public:
-    QMakeParserFactory() {}
-    virtual ~QMakeParserFactory();
-    virtual bool canCreate(const QString & name) const;
-    virtual ProjectExplorer::IBuildParser * create(const QString & name) const;
-};
-
-
-class QMakeParser : public ProjectExplorer::IBuildParser
+class QMakeParser : public ProjectExplorer::IOutputParser
 {
     Q_OBJECT
 
 public:
     QMakeParser();
-    QString name() const;
-    virtual void stdOutput(const QString & line);
-    virtual void stdError(const QString & line);
-private:
+    virtual void stdError(const QString &line);
 };
 
-} // namesapce Interanal
+} // namesapce Internal
 } // namespace ProjectExplorer
 
 #endif // QMAKEPARSER_H
diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp
index f6806428246fe0fa46c1c3081498ff354cdd47ab..545ecd0a2ecbac9668e28a7ed7e83664e0e1aa9a 100644
--- a/src/plugins/qt4projectmanager/qmakestep.cpp
+++ b/src/plugins/qt4projectmanager/qmakestep.cpp
@@ -29,36 +29,33 @@
 
 #include "qmakestep.h"
 
+#include "qmakeparser.h"
+#include "qt4buildconfiguration.h"
 #include "qt4project.h"
 #include "qt4projectmanagerconstants.h"
 #include "qt4projectmanager.h"
-#include "makestep.h"
 #include "qtversionmanager.h"
-#include "qt4buildconfiguration.h"
 
 #include <coreplugin/icore.h>
 #include <utils/qtcassert.h>
 
-#include <QFileDialog>
-#include <QDir>
-#include <QFile>
-#include <QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
 
 using namespace Qt4ProjectManager;
 using namespace Qt4ProjectManager::Internal;
 using namespace ProjectExplorer;
 
-QMakeStep::QMakeStep(ProjectExplorer::BuildConfiguration *bc)
-    : AbstractMakeStep(bc), m_forced(false)
+QMakeStep::QMakeStep(ProjectExplorer::BuildConfiguration *bc) :
+    AbstractProcessStep(bc), m_forced(false)
 {
 }
 
-QMakeStep::QMakeStep(QMakeStep *bs, ProjectExplorer::BuildConfiguration *bc)
-    : AbstractMakeStep(bs, bc),
+QMakeStep::QMakeStep(QMakeStep *bs, ProjectExplorer::BuildConfiguration *bc) :
+    AbstractProcessStep(bs, bc),
     m_forced(false),
     m_userArgs(bs->m_userArgs)
 {
-
 }
 
 QMakeStep::~QMakeStep()
@@ -112,9 +109,9 @@ bool QMakeStep::init()
 
     if (!qtVersion->isValid()) {
 #if defined(Q_WS_MAC)
-        emit addToOutputWindow(tr("\n<font color=\"#ff0000\"><b>No valid Qt version set. Set one in Preferences </b></font>\n"));
+        emit addOutput(tr("\n<font color=\"#ff0000\"><b>No valid Qt version set. Set one in Preferences </b></font>\n"));
 #else
-        emit addToOutputWindow(tr("\n<font color=\"#ff0000\"><b>No valid Qt version set. Set one in Tools/Options </b></font>\n"));
+        emit addOutput(tr("\n<font color=\"#ff0000\"><b>No valid Qt version set. Set one in Tools/Options </b></font>\n"));
 #endif
         return false;
     }
@@ -124,7 +121,7 @@ bool QMakeStep::init()
 
     QString program = qtVersion->qmakeCommand();
 
-    // Check wheter we need to run qmake
+    // Check whether we need to run qmake
     m_needToRunQMake = true;
     if (QDir(workingDirectory).exists(QLatin1String("Makefile"))) {
         QString qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(workingDirectory);
@@ -144,8 +141,8 @@ bool QMakeStep::init()
     setArguments(args);
     setEnvironment(qt4bc->environment());
 
-    setBuildParser(Qt4ProjectManager::Constants::BUILD_PARSER_QMAKE);
-    return AbstractMakeStep::init();
+    setOutputParser(new QMakeParser);
+    return AbstractProcessStep::init();
 }
 
 void QMakeStep::run(QFutureInterface<bool> &fi)
@@ -157,21 +154,21 @@ void QMakeStep::run(QFutureInterface<bool> &fi)
     }
 
     if (!m_needToRunQMake) {
-        emit addToOutputWindow(tr("<font color=\"#0000ff\">Configuration unchanged, skipping QMake step.</font>"));
+        emit addOutput(tr("<font color=\"#0000ff\">Configuration unchanged, skipping QMake step.</font>"));
         fi.reportResult(true);
         return;
     }
-    AbstractMakeStep::run(fi);
+    AbstractProcessStep::run(fi);
 }
 
 QString QMakeStep::name()
 {
-    return Constants::QMAKESTEP;
+    return QLatin1String(Constants::QMAKESTEP);
 }
 
 QString QMakeStep::displayName()
 {
-    return "QMake";
+    return QLatin1String("QMake");
 }
 
 void QMakeStep::setForced(bool b)
diff --git a/src/plugins/qt4projectmanager/qmakestep.h b/src/plugins/qt4projectmanager/qmakestep.h
index f620c9b8681f127a7429b131fd99813d66731b7f..acee94ad52557cbfb76d1c534c6a79780c4936be 100644
--- a/src/plugins/qt4projectmanager/qmakestep.h
+++ b/src/plugins/qt4projectmanager/qmakestep.h
@@ -32,7 +32,7 @@
 
 #include "ui_qmakestep.h"
 
-#include <projectexplorer/abstractmakestep.h>
+#include <projectexplorer/abstractprocessstep.h>
 
 #include <QStringList>
 
@@ -64,7 +64,7 @@ public:
 } // namespace Internal
 
 
-class QMakeStep : public ProjectExplorer::AbstractMakeStep
+class QMakeStep : public ProjectExplorer::AbstractProcessStep
 {
     Q_OBJECT
 public:
diff --git a/src/plugins/qt4projectmanager/qt-s60/abldparser.cpp b/src/plugins/qt4projectmanager/qt-s60/abldparser.cpp
index 93c8c53b8cbe56653c77d2866219eb7aeea81844..b2e6000f4583b97fc3c96e566f010ea65f9626b8 100644
--- a/src/plugins/qt4projectmanager/qt-s60/abldparser.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/abldparser.cpp
@@ -28,18 +28,16 @@
 **************************************************************************/
 
 #include "abldparser.h"
-#include <utils/qtcassert.h>
 
+#include <projectexplorer/gnumakeparser.h>
 #include <projectexplorer/projectexplorerconstants.h>
 #include <projectexplorer/taskwindow.h>
 
-#include <extensionsystem/pluginmanager.h>
-
 using namespace Qt4ProjectManager;
 using namespace ProjectExplorer;
+using namespace ProjectExplorer::Constants;
 
-AbldParser::AbldParser(const QString &name) :
-    m_name(name),
+AbldParser::AbldParser() :
     m_currentLine(-1),
     m_waitingForStdErrContinuation(false),
     m_waitingForStdOutContinuation(false)
@@ -47,47 +45,7 @@ AbldParser::AbldParser(const QString &name) :
     m_perlIssue.setPattern("^(WARNING|ERROR):\\s([^\\(\\)]+[^\\d])\\((\\d+)\\) : (.+)$");
     m_perlIssue.setMinimal(true);
 
-    // Now look for new parser
-    QList<IBuildParserFactory *> buildParserFactories =
-            ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>();
-
-    QString subparser_name;
-
-    if ((m_name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_GCCE)))
-        subparser_name = QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_GCC);
-    else if ((m_name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_WINSCW)))
-        subparser_name = QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_WINSCW);
-    else if (m_name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_RVCT))
-        subparser_name = QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_RVCT);
-
-    QTC_ASSERT(!subparser_name.isNull(), return);
-
-    foreach (IBuildParserFactory * factory, buildParserFactories) {
-        if (factory->canCreate(subparser_name)) {
-            m_subparser = factory->create(subparser_name);
-            break;
-        }
-    }
-    QTC_ASSERT(0 != m_subparser, return);
-
-    connect(m_subparser, SIGNAL(enterDirectory(QString)),
-            this, SIGNAL(enterDirectory(QString)));
-    connect(m_subparser, SIGNAL(leaveDirectory(QString)),
-            this, SIGNAL(leaveDirectory(QString)));
-    connect(m_subparser, SIGNAL(addToOutputWindow(QString)),
-            this, SIGNAL(addToOutputWindow(QString)));
-    connect(m_subparser, SIGNAL(addToTaskWindow(ProjectExplorer::TaskWindow::Task)),
-            this, SIGNAL(addToTaskWindow(ProjectExplorer::TaskWindow::Task)));
-}
-
-AbldParser::~AbldParser()
-{
-    delete m_subparser;
-}
-
-QString AbldParser::name() const
-{
-    return m_name;
+    appendOutputParser(new GnuMakeParser);
 }
 
 void AbldParser::stdOutput(const QString &line)
@@ -97,19 +55,19 @@ void AbldParser::stdOutput(const QString &line)
     QString lne = line.trimmed();
     // possible ABLD.bat errors:
     if (lne.startsWith("Is Perl, version ")) {
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Error,
-                                              lne /* description */,
-                                              QString() /* filename */,
-                                              -1 /* linenumber */,
-                                              Constants::TASK_CATEGORY_BUILDSYSTEM));
+        emit addTask(TaskWindow::Task(TaskWindow::Error,
+                                      lne /* description */,
+                                      QString() /* filename */,
+                                      -1 /* linenumber */,
+                                      TASK_CATEGORY_BUILDSYSTEM));
         return;
     }
     if (lne.startsWith("FATAL ERROR:")) {
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Error,
-                                              lne /* description */,
-                                              QString() /* filename */,
-                                              -1 /* linenumber */,
-                                              Constants::TASK_CATEGORY_BUILDSYSTEM));
+        emit addTask(TaskWindow::Task(TaskWindow::Error,
+                                      lne /* description */,
+                                      QString() /* filename */,
+                                      -1 /* linenumber */,
+                                      TASK_CATEGORY_BUILDSYSTEM));
         m_waitingForStdOutContinuation = false;
         return;
     }
@@ -122,14 +80,14 @@ void AbldParser::stdOutput(const QString &line)
         TaskWindow::Task task(TaskWindow::Unknown,
                               m_perlIssue.cap(4) /* description */,
                               m_currentFile, m_currentLine,
-                              Constants::TASK_CATEGORY_BUILDSYSTEM);
+                              TASK_CATEGORY_BUILDSYSTEM);
 
         if (m_perlIssue.cap(1) == QLatin1String("WARNING"))
             task.type = TaskWindow::Warning;
         else if (m_perlIssue.cap(1) == QLatin1String("ERROR"))
             task.type = TaskWindow::Error;
 
-        emit addToTaskWindow(task);
+        emit addTask(task);
         return;
     }
 
@@ -139,17 +97,14 @@ void AbldParser::stdOutput(const QString &line)
     }
 
     if (m_waitingForStdOutContinuation) {
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Unknown,
-                                              lne /* description */,
-                                              m_currentFile, m_currentLine,
-                                              Constants::TASK_CATEGORY_BUILDSYSTEM));
+        emit addTask(TaskWindow::Task(TaskWindow::Unknown,
+                                      lne /* description */,
+                                      m_currentFile, m_currentLine,
+                                      TASK_CATEGORY_BUILDSYSTEM));
         m_waitingForStdOutContinuation = true;
         return;
     }
-
-    QTC_ASSERT(0 != m_subparser, return);
-    // pass on to compiler output parser:
-    m_subparser->stdOutput(lne);
+    IOutputParser::stdOutput(line);
 }
 
 void AbldParser::stdError(const QString &line)
@@ -162,20 +117,20 @@ void AbldParser::stdError(const QString &line)
     if (lne.startsWith("ABLD ERROR:") ||
         lne.startsWith("This project does not support ") ||
         lne.startsWith("Platform ")) {
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Error,
-                                              lne /* description */,
-                                              QString() /* filename */,
-                                              -1 /* linenumber */,
-                                              Constants::TASK_CATEGORY_BUILDSYSTEM));
+        emit addTask(TaskWindow::Task(TaskWindow::Error,
+                                      lne /* description */,
+                                      QString() /* filename */,
+                                      -1 /* linenumber */,
+                                      TASK_CATEGORY_BUILDSYSTEM));
         return;
     }
 
     if (lne.startsWith("Died at ")) {
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Error,
-                                              lne /* description */,
-                                              QString() /* filename */,
-                                              -1 /* linenumber */,
-                                              Constants::TASK_CATEGORY_BUILDSYSTEM));
+        emit addTask(TaskWindow::Task(TaskWindow::Error,
+                                      lne /* description */,
+                                      QString() /* filename */,
+                                      -1 /* linenumber */,
+                                      TASK_CATEGORY_BUILDSYSTEM));
         m_waitingForStdErrContinuation = false;
         return;
     }
@@ -191,34 +146,31 @@ void AbldParser::stdError(const QString &line)
     }
     if (lne.startsWith("WARNING: ")) {
         QString description = lne.mid(9);
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Warning, description,
-                                              m_currentFile,
-                                              -1 /* linenumber */,
-                                              Constants::TASK_CATEGORY_BUILDSYSTEM));
+        emit addTask(TaskWindow::Task(TaskWindow::Warning, description,
+                                      m_currentFile,
+                                      -1 /* linenumber */,
+                                      TASK_CATEGORY_BUILDSYSTEM));
         m_waitingForStdErrContinuation = true;
         return;
     }
     if (lne.startsWith("ERROR: ")) {
         QString description = lne.mid(7);
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Error, description,
-                                              m_currentFile,
-                                              -1 /* linenumber */,
-                                              Constants::TASK_CATEGORY_BUILDSYSTEM));
+        emit addTask(TaskWindow::Task(TaskWindow::Error, description,
+                                      m_currentFile,
+                                      -1 /* linenumber */,
+                                      TASK_CATEGORY_BUILDSYSTEM));
         m_waitingForStdErrContinuation = true;
         return;
     }
     if (m_waitingForStdErrContinuation)
     {
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Unknown,
-                                              lne /* description */,
-                                              m_currentFile,
-                                              -1 /* linenumber */,
-                                              Constants::TASK_CATEGORY_BUILDSYSTEM));
+        emit addTask(TaskWindow::Task(TaskWindow::Unknown,
+                                      lne /* description */,
+                                      m_currentFile,
+                                      -1 /* linenumber */,
+                                      TASK_CATEGORY_BUILDSYSTEM));
         m_waitingForStdErrContinuation = true;
         return;
     }
-
-    QTC_ASSERT(0 != m_subparser, return);
-    // pass on to compiler output parser:
-    m_subparser->stdError(lne);
+    IOutputParser::stdError(line);
 }
diff --git a/src/plugins/qt4projectmanager/qt-s60/abldparser.h b/src/plugins/qt4projectmanager/qt-s60/abldparser.h
index fad5511e4ab6a44280f9f37fa4cfc2384e9816a2..3ccacf7620c7c78b222066a5257a0c15109fcfb3 100644
--- a/src/plugins/qt4projectmanager/qt-s60/abldparser.h
+++ b/src/plugins/qt4projectmanager/qt-s60/abldparser.h
@@ -30,27 +30,23 @@
 #ifndef ABLDPARSER_H
 #define ABLDPARSER_H
 
-#include <projectexplorer/ibuildparser.h>
+#include <projectexplorer/ioutputparser.h>
 
 #include <QtCore/QRegExp>
 
 namespace Qt4ProjectManager {
 
-class AbldParser : public ProjectExplorer::IBuildParser
+class AbldParser : public ProjectExplorer::IOutputParser
 {
     Q_OBJECT
 
 public:
-    AbldParser(const QString & name);
-    ~AbldParser();
+    AbldParser();
 
-    QString name() const;
     virtual void stdOutput(const QString & line);
     virtual void stdError(const QString & line);
-private:
-    ProjectExplorer::IBuildParser * m_subparser;
-    const QString m_name;
 
+private:
     QRegExp m_perlIssue;
 
     QString m_currentFile;
diff --git a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
index c0fd1d72f86b1b2b4cbd7ccddcd92efb77473b8b..a489d95a065fd4f7712b3b1cdfac6d9cd3398b99 100644
--- a/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
+++ b/src/plugins/qt4projectmanager/qt-s60/qt-s60.pri
@@ -12,7 +12,6 @@
         $$PWD/serialdevicelister.cpp \
         $$PWD/rvcttoolchain.cpp \
         $$PWD/s60runconfigbluetoothstarter.cpp \
-        $$PWD/s60buildparserfactory.cpp \
         $$PWD/abldparser.cpp \
         $$PWD/rvctparser.cpp \
         $$PWD/winscwparser.cpp
@@ -27,7 +26,6 @@
         $$PWD/serialdevicelister.h \
         $$PWD/rvcttoolchain.h \
         $$PWD/s60runconfigbluetoothstarter.h \
-        $$PWD/s60buildparserfactory.h \
         $$PWD/abldparser.h \
         $$PWD/rvctparser.h \
         $$PWD/winscwparser.h
diff --git a/src/plugins/qt4projectmanager/qt-s60/rvctparser.cpp b/src/plugins/qt4projectmanager/qt-s60/rvctparser.cpp
index 0b671f811384446e3c39e5ec972a9f6847378294..76824ad2c5e2543c22f66b86e3ce9d9a61d8e193 100644
--- a/src/plugins/qt4projectmanager/qt-s60/rvctparser.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/rvctparser.cpp
@@ -32,6 +32,7 @@
 #include <projectexplorer/taskwindow.h>
 
 using namespace ProjectExplorer;
+using namespace ProjectExplorer::Constants;
 using namespace Qt4ProjectManager;
 
 RvctParser::RvctParser() :
@@ -48,46 +49,28 @@ RvctParser::RvctParser() :
     // linker problems:
     m_linkerProblem.setPattern("^(\\S*)\\(\\S+\\):\\s(.+)$");
     m_linkerProblem.setMinimal(true);
-
-    //make[4]: Entering directory `/home/kkoehne/dev/ide-explorer/src/plugins/qtscripteditor'
-    m_makeDir.setPattern("^make.*: (\\w+) directory .(.+).$");
-    m_makeDir.setMinimal(true);
-}
-
-QString RvctParser::name() const
-{
-    return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_RVCT);
-}
-
-void RvctParser::stdOutput(const QString &line)
-{
-    QString lne = line.trimmed();
-
-    if (m_makeDir.indexIn(lne) > -1) {
-        if (m_makeDir.cap(1) == "Leaving")
-            emit leaveDirectory(m_makeDir.cap(2));
-        else
-            emit enterDirectory(m_makeDir.cap(2));
-    }
 }
 
 void RvctParser::stdError(const QString &line)
 {
     QString lne = line.trimmed();
     if (m_linkerProblem.indexIn(lne) > -1) {
-       emit addToTaskWindow(TaskWindow::Task(TaskWindow::Error,
-                                             m_linkerProblem.cap(2) /* description */,
-                                             m_linkerProblem.cap(1) /* filename */,
-                                             -1 /* linenumber */,
-                                             Constants::TASK_CATEGORY_COMPILE));
-   } else if (m_warningOrError.indexIn(lne) > -1) {
+       emit addTask(TaskWindow::Task(TaskWindow::Error,
+                                     m_linkerProblem.cap(2) /* description */,
+                                     m_linkerProblem.cap(1) /* filename */,
+                                     -1 /* linenumber */,
+                                     TASK_CATEGORY_COMPILE));
+       return;
+   }
+
+   if (m_warningOrError.indexIn(lne) > -1) {
        m_lastFile = m_warningOrError.cap(1);
        m_lastLine = m_warningOrError.cap(2).toInt();
 
        TaskWindow::Task task(TaskWindow::Unknown,
                              m_warningOrError.cap(5) /* description */,
                              m_lastFile, m_lastLine,
-                             Constants::TASK_CATEGORY_COMPILE);
+                             TASK_CATEGORY_COMPILE);
        if (m_warningOrError.cap(4) == "Warning")
            task.type = TaskWindow::Warning;
        else if (m_warningOrError.cap(4) == "Error")
@@ -95,14 +78,21 @@ void RvctParser::stdError(const QString &line)
 
        m_additionalInfo = true;
 
-       emit addToTaskWindow(task);
-   } else if (m_doneWithFile.indexIn(lne) > -1) {
+       emit addTask(task);
+       return;
+   }
+
+   if (m_doneWithFile.indexIn(lne) > -1) {
        m_additionalInfo = false;
-   } else if (m_additionalInfo) {
+       return;
+   }
+   if (m_additionalInfo) {
        // Report any lines after a error/warning message as these contain
        // additional information on the problem.
-       emit addToTaskWindow(TaskWindow::Task(TaskWindow::Unknown, lne,
-                                             m_lastFile,  m_lastLine,
-                                             Constants::TASK_CATEGORY_COMPILE));
+       emit addTask(TaskWindow::Task(TaskWindow::Unknown, lne,
+                                     m_lastFile,  m_lastLine,
+                                     TASK_CATEGORY_COMPILE));
+       return;
    }
+   IOutputParser::stdError(line);
 }
diff --git a/src/plugins/qt4projectmanager/qt-s60/rvctparser.h b/src/plugins/qt4projectmanager/qt-s60/rvctparser.h
index b1d545a9c4f3dd205892d9138f15ea405c09437b..d1396c45813b27418b0e75cdb3c3e5a916c8508b 100644
--- a/src/plugins/qt4projectmanager/qt-s60/rvctparser.h
+++ b/src/plugins/qt4projectmanager/qt-s60/rvctparser.h
@@ -30,26 +30,24 @@
 #ifndef RVCTPARSER_H
 #define RVCTPARSER_H
 
-#include <projectexplorer/ibuildparser.h>
+#include <projectexplorer/ioutputparser.h>
 
 #include <QtCore/QRegExp>
 
 namespace Qt4ProjectManager {
 
-class RvctParser : public ProjectExplorer::IBuildParser
+class RvctParser : public ProjectExplorer::IOutputParser
 {
     Q_OBJECT
 
 public:
     RvctParser();
-    QString name() const;
-    virtual void stdOutput(const QString & line);
     virtual void stdError(const QString & line);
+
 private:
     QRegExp m_warningOrError;
     QRegExp m_doneWithFile;
     QRegExp m_linkerProblem;
-    QRegExp m_makeDir;
 
     bool m_additionalInfo;
     QString m_lastFile;
diff --git a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp
index efa54dfb858edb38cfe27e5831eb98778ed79196..852180677a97b4829d1b392eb7f41951012ddfc3 100644
--- a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.cpp
@@ -28,6 +28,8 @@
 **************************************************************************/
 
 #include "rvcttoolchain.h"
+#include "rvctparser.h"
+
 #include <QtCore/QProcess>
 
 using namespace ProjectExplorer;
@@ -139,6 +141,11 @@ QString RVCTToolChain::makeCommand() const
     return QLatin1String("make");
 }
 
+ProjectExplorer::IOutputParser *RVCTToolChain::outputParser() const
+{
+    return new RvctParser;
+}
+
 bool RVCTToolChain::equals(ToolChain *otherIn) const
 {
     if (otherIn->type() != type())
diff --git a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h
index 93cf80235ff25da0d0b8ea5dc13fdb96ac48031d..01ab0a444b3620095376fb98c6730ace545f2868 100644
--- a/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h
+++ b/src/plugins/qt4projectmanager/qt-s60/rvcttoolchain.h
@@ -47,6 +47,8 @@ public:
     void addToEnvironment(ProjectExplorer::Environment &env);
     ProjectExplorer::ToolChain::ToolChainType type() const;
     QString makeCommand() const;
+    ProjectExplorer::IOutputParser *outputParser() const;
+
 protected:
     bool equals(ToolChain *other) const;
 
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.cpp b/src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.cpp
deleted file mode 100644
index 70befb3a5978f96589d332a0c08626ed1d99932a..0000000000000000000000000000000000000000
--- a/src/plugins/qt4projectmanager/qt-s60/s60buildparserfactory.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** Commercial Usage
-**
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-**
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file.  Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at http://qt.nokia.com/contact.
-**
-**************************************************************************/
-
-#include "s60buildparserfactory.h"
-#include "abldparser.h"
-#include "rvctparser.h"
-#include "winscwparser.h"
-
-#include <projectexplorer/projectexplorerconstants.h>
-
-using namespace Qt4ProjectManager::Internal;
-
-S60ParserFactory::~S60ParserFactory()
-{
-}
-
-bool S60ParserFactory::canCreate(const QString & name) const
-{
-    return ((name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_GCCE)) ||
-            (name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_WINSCW)) ||
-            (name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_ABLD_RVCT)) ||
-            (name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_RVCT)) ||
-            (name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_WINSCW)));
-}
-
-ProjectExplorer::IBuildParser * S60ParserFactory::create(const QString & name) const
-{
-    if (name ==  QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_RVCT))
-        return new RvctParser();
-    if (name == QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_WINSCW))
-        return new WinscwParser();
-
-    return new AbldParser(name);
-}
-
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
index d1a58755ebb8131176151a06c13701d69606467a..72857cbfcfcd6ef0a03be710b45c95d875c96547 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp
@@ -36,7 +36,6 @@
 #include "rvcttoolchain.h"
 #include "s60emulatorrunconfiguration.h"
 #include "s60devicerunconfiguration.h"
-#include "s60buildparserfactory.h"
 
 #include <coreplugin/icore.h>
 #include <extensionsystem/pluginmanager.h>
@@ -118,9 +117,6 @@ S60Manager::S60Manager(QObject *parent)
                                                 (QLatin1String(ProjectExplorer::Constants::RUNMODE),
                                                  tr("Run on Device"), parent));
 
-    // Build parsers
-    addAutoReleasedObject(new S60ParserFactory);
-
     if (Debugger::DebuggerManager::instance())
         addAutoReleasedObject(new RunControlFactory<S60DeviceDebugRunControl,
                                                 S60DeviceRunConfiguration>
diff --git a/src/plugins/qt4projectmanager/qt-s60/winscwparser.cpp b/src/plugins/qt4projectmanager/qt-s60/winscwparser.cpp
index 6b8d4a0a721a072245e09bbfe37b79c502bddc55..ba01ac7b93485fe39db4a2b05045096c7838fb32 100644
--- a/src/plugins/qt4projectmanager/qt-s60/winscwparser.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/winscwparser.cpp
@@ -33,6 +33,7 @@
 
 using namespace Qt4ProjectManager;
 using namespace ProjectExplorer;
+using namespace ProjectExplorer::Constants;
 
 WinscwParser::WinscwParser()
 {
@@ -43,41 +44,26 @@ WinscwParser::WinscwParser()
     // WINSCW issue:
     m_compilerProblem.setPattern("^([^\\(\\)]+[^\\d]):(\\d+):\\s(.+)$");
     m_compilerProblem.setMinimal(true);
-
-    //make[4]: Entering directory `/home/kkoehne/dev/ide-explorer/src/plugins/qtscripteditor'
-    m_makeDir.setPattern("^make.*: (\\w+) directory .(.+).$");
-    m_makeDir.setMinimal(true);
-}
-
-QString WinscwParser::name() const
-{
-    return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_WINSCW);
 }
 
 void WinscwParser::stdOutput(const QString &line)
 {
     QString lne = line.trimmed();
 
-    if (m_makeDir.indexIn(lne) > -1) {
-        if (m_makeDir.cap(1) == "Leaving")
-            emit leaveDirectory(m_makeDir.cap(2));
-        else
-            emit enterDirectory(m_makeDir.cap(2));
-        return;
-    }
-
     if (m_compilerProblem.indexIn(lne) > -1) {
         TaskWindow::Task task(TaskWindow::Error,
                               m_compilerProblem.cap(3) /* description */,
                               m_compilerProblem.cap(1) /* filename */,
                               m_compilerProblem.cap(2).toInt() /* linenumber */,
-                              Constants::TASK_CATEGORY_COMPILE);
+                              TASK_CATEGORY_COMPILE);
         if (task.description.startsWith("warning: ")) {
             task.type = TaskWindow::Warning;
             task.description = task.description.mid(9);
         }
-        emit addToTaskWindow(task);
+        emit addTask(task);
+        return;
     }
+    IOutputParser::stdOutput(line);
 }
 
 void WinscwParser::stdError(const QString &line)
@@ -85,10 +71,12 @@ void WinscwParser::stdError(const QString &line)
     QString lne = line.trimmed();
 
     if (m_linkerProblem.indexIn(lne) > -1) {
-        emit addToTaskWindow(TaskWindow::Task(TaskWindow::Error,
-                                              m_linkerProblem.cap(2) /* description */,
-                                              m_linkerProblem.cap(1) /* filename */,
-                                              -1 /* linenumber */,
-                                              Constants::TASK_CATEGORY_COMPILE));
+        emit addTask(TaskWindow::Task(TaskWindow::Error,
+                                      m_linkerProblem.cap(2) /* description */,
+                                      m_linkerProblem.cap(1) /* filename */,
+                                      -1 /* linenumber */,
+                                      TASK_CATEGORY_COMPILE));
+        return;
     }
+    IOutputParser::stdError(line);
 }
diff --git a/src/plugins/qt4projectmanager/qt-s60/winscwparser.h b/src/plugins/qt4projectmanager/qt-s60/winscwparser.h
index 5b41db18594bb880ed56d27f2e8e65d0018c00ff..8c5b485aabba3fc77206c36934563623120478ba 100644
--- a/src/plugins/qt4projectmanager/qt-s60/winscwparser.h
+++ b/src/plugins/qt4projectmanager/qt-s60/winscwparser.h
@@ -30,25 +30,25 @@
 #ifndef WINSCWPARSER_H
 #define WINSCWPARSER_H
 
-#include <projectexplorer/ibuildparser.h>
+#include <projectexplorer/ioutputparser.h>
 
 #include <QtCore/QRegExp>
 
 namespace Qt4ProjectManager {
 
-class WinscwParser : public ProjectExplorer::IBuildParser
+class WinscwParser : public ProjectExplorer::IOutputParser
 {
     Q_OBJECT
 
 public:
     WinscwParser();
-    QString name() const;
-    virtual void stdOutput(const QString & line);
-    virtual void stdError(const QString & line);
+
+    virtual void stdOutput(const QString &line);
+    virtual void stdError(const QString &line);
+
 private:
     QRegExp m_compilerProblem;
     QRegExp m_linkerProblem;
-    QRegExp m_makeDir;
 };
 
 } // namespace Qt4ProjectManager
diff --git a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp
index 618623e1aad57586f8bdc96edc27c2079c104ac5..46350c219d20a95deb0ef6c7fa7d209989db7e4a 100644
--- a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.cpp
@@ -29,9 +29,10 @@
 
 #include "winscwtoolchain.h"
 
+#include "winscwparser.h"
+
 #include <QtCore/QByteArray>
 #include <QtCore/QString>
-#include <QtDebug>
 
 using namespace ProjectExplorer;
 using namespace Qt4ProjectManager::Internal;
@@ -108,7 +109,12 @@ void WINSCWToolChain::addToEnvironment(ProjectExplorer::Environment &env)
 
 QString WINSCWToolChain::makeCommand() const
 {
-    return "make";
+    return QLatin1String("make");
+}
+
+IOutputParser *WINSCWToolChain::outputParser() const
+{
+    return new WinscwParser;
 }
 
 bool WINSCWToolChain::equals(ToolChain *other) const
diff --git a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h
index c38870f6be4fb7890262720ddaca8245d481a040..cb2bbda8951a4973cd944e062a30339e9c558fe4 100644
--- a/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h
+++ b/src/plugins/qt4projectmanager/qt-s60/winscwtoolchain.h
@@ -47,6 +47,7 @@ public:
     void addToEnvironment(ProjectExplorer::Environment &env);
     ProjectExplorer::ToolChain::ToolChainType type() const;
     QString makeCommand() const;
+    ProjectExplorer::IOutputParser *outputParser() const;
 
 protected:
     bool equals(ToolChain *other) const;
diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h b/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h
index 6af9bbb0f6ab2eb18a79c8368d9dc76607bc931b..3e940b9e74f8ab2d4a3e88f81e277d219512bc27 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h
+++ b/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h
@@ -78,8 +78,6 @@ const char * const QT_SETTINGS_TR_CATEGORY    = QT_TRANSLATE_NOOP("Qt4ProjectMan
 const char * const QTVERSION_SETTINGS_PAGE_ID = "Qt Versions";
 const char * const QTVERSION_SETTINGS_PAGE_NAME = QT_TRANSLATE_NOOP("Qt4ProjectManager", "Qt Versions");
 
-// BuildParser
-const char * const BUILD_PARSER_QMAKE       = "BuildParser.QMake";
 } // namespace Constants
 } // namespace Qt4ProjectManager
 
diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp
index 5261ee74e02904ae6cda091cc157b9ec2e2d94e9..e5b0e4e4e47deb8ec14f6abfc8c5069c60ec8867 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp
+++ b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp
@@ -45,14 +45,13 @@
 #include "externaleditors.h"
 #include "gettingstartedwelcomepage.h"
 #include "gettingstartedwelcomepagewidget.h"
-#include "qmakeparser.h"
 
 #ifdef QTCREATOR_WITH_S60
-#include "qt-s60/s60manager.h"
+#    include "qt-s60/s60manager.h"
 #endif
 
 #ifdef QTCREATOR_WITH_MAEMO
-#include "qt-maemo/maemomanager.h"
+#    include "qt-maemo/maemomanager.h"
 #endif
 
 #include <coreplugin/icore.h>
@@ -68,14 +67,12 @@
 #include <coreplugin/actionmanager/actionmanager.h>
 #include <texteditor/texteditoractionhandler.h>
 
-#include <QtCore/QDebug>
-#include <QtCore/QtPlugin>
-#include <QtGui/QMenu>
-
 #ifdef WITH_TESTS
-#include <QTest>
+#    include <QTest>
 #endif
 
+#include <QtCore/QtPlugin>
+
 using namespace Qt4ProjectManager::Internal;
 using namespace Qt4ProjectManager;
 using ProjectExplorer::Project;
@@ -92,17 +89,6 @@ Qt4ProjectManagerPlugin::~Qt4ProjectManagerPlugin()
     removeObject(m_welcomePage);
     delete m_welcomePage;
 }
-/*
-static Core::Command *createSeparator(Core::ActionManager *am,
-                                       QObject *parent,
-                                       const QString &name,
-                                       const QList<int> &context)
-{
-    QAction *tmpaction = new QAction(parent);
-    tmpaction->setSeparator(true);
-    return am->registerAction(tmpaction, name, context);
-}
-*/
 
 bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
 {
@@ -150,7 +136,6 @@ bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString *
 
     addAutoReleasedObject(new QMakeStepFactory);
     addAutoReleasedObject(new MakeStepFactory);
-    addAutoReleasedObject(new QMakeParserFactory);
 
     addAutoReleasedObject(new Qt4RunConfigurationFactory);
 
diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h
index 03c3d6e70ae590bf1d73c6319fd2cc1890913c0d..3d1a265ff8e485e551bea42a064e961deccbf6ad 100644
--- a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h
+++ b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h
@@ -46,8 +46,6 @@ class GuiAppWizard;
 class EmptyProjectWizard;
 class QMakeStepFactory;
 class MakeStepFactory;
-class GccParserFactory;
-class MsvcParserFactory;
 class EmbeddedPropertiesPage;
 class GettingStartedWelcomePage;