diff --git a/src/plugins/cmakeprojectmanager/makestep.cpp b/src/plugins/cmakeprojectmanager/makestep.cpp
index 90fcc25924d483637cd6cad817f3e4f66e4c8f9a..6b173b30819105e7ac43af98f8738f361652f04a 100644
--- a/src/plugins/cmakeprojectmanager/makestep.cpp
+++ b/src/plugins/cmakeprojectmanager/makestep.cpp
@@ -31,64 +31,29 @@
 #include "cmakeprojectconstants.h"
 #include "cmakeproject.h"
 
-#include <extensionsystem/pluginmanager.h>
-#include <utils/qtcassert.h>
-
 #include <QtGui/QFormLayout>
 #include <QtGui/QGroupBox>
 #include <QtGui/QCheckBox>
 #include <QtGui/QLineEdit>
 #include <QtGui/QListWidget>
 
-namespace {
-bool debug = false;
-}
-
 using namespace CMakeProjectManager;
 using namespace CMakeProjectManager::Internal;
 
 MakeStep::MakeStep(CMakeProject *pro)
-    : AbstractProcessStep(pro), m_pro(pro), m_buildParser(0)
+    : AbstractMakeStep(pro), m_pro(pro)
 {
     m_percentProgress = QRegExp("^\\[\\s*(\\d*)%\\]");
 }
 
 MakeStep::~MakeStep()
 {
-    delete m_buildParser;
-    m_buildParser = 0;
+
 }
 
 bool MakeStep::init(const QString &buildConfiguration)
 {
-    delete m_buildParser;
-    m_buildParser = 0;
-    QString buildParser = m_pro->buildParser(buildConfiguration);
-    QList<ProjectExplorer::IBuildParserFactory *> buildParserFactories =
-            ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>();
-
-    foreach (ProjectExplorer::IBuildParserFactory * factory, buildParserFactories)
-        if (factory->canCreate(buildParser)) {
-            m_buildParser = factory->create(buildParser);
-            break;
-        }
-    if (m_buildParser) {
-        connect(m_buildParser, SIGNAL(addToOutputWindow(const QString &)),
-                this, SIGNAL(addToOutputWindow(const QString &)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)),
-                this, SLOT(slotAddToTaskWindow(const QString &, int, int, const QString &)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(enterDirectory(const QString &)),
-                this, SLOT(addDirectory(const QString &)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(leaveDirectory(const QString &)),
-                this, SLOT(removeDirectory(const QString &)),
-                Qt::DirectConnection);
-    }
-
-    m_openDirectories.clear();
-    addDirectory(m_pro->buildDirectory(buildConfiguration));
+    setBuildParser(m_pro->buildParser(buildConfiguration));
 
     setEnabled(buildConfiguration, true);
     setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration));
@@ -106,14 +71,14 @@ bool MakeStep::init(const QString &buildConfiguration)
         setArguments(buildConfiguration, arguments); // TODO
         setEnvironment(buildConfiguration, m_pro->environment(buildConfiguration));
     }
-    return AbstractProcessStep::init(buildConfiguration);
+    return AbstractMakeStep::init(buildConfiguration);
 }
 
 void MakeStep::run(QFutureInterface<bool> &fi)
 {
     m_futureInterface = &fi;
     m_futureInterface->setProgressRange(0, 100);
-    AbstractProcessStep::run(fi);
+    AbstractMakeStep::run(fi);
     m_futureInterface = 0;
 }
 
@@ -139,80 +104,13 @@ bool MakeStep::immutable() const
 
 void MakeStep::stdOut(const QString &line)
 {
-    if (m_buildParser)
-        m_buildParser->stdOutput(line);
     if (m_percentProgress.indexIn(line) != -1) {
         bool ok = false;
         int percent = m_percentProgress.cap(1).toInt(&ok);;
         if (ok)
             m_futureInterface->setProgressValue(percent);
     }
-    AbstractProcessStep::stdOut(line);
-}
-
-void MakeStep::stdError(const QString &line)
-{
-    if (m_buildParser)
-        m_buildParser->stdError(line);
-    AbstractProcessStep::stdError(line);
-}
-
-void MakeStep::slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description)
-{
-    QString filePath = fn;
-    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
-
-        filePath = filePath.trimmed();
-
-        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, project()->files(ProjectExplorer::Project::AllFiles)) {
-                QFileInfo candidate(file);
-                if (candidate.fileName() == fileName) {
-                    if (debug)
-                        qDebug() << "Found " << file;
-                    possibleFiles << candidate;
-                }
-            }
-        }
-        if (possibleFiles.count() == 1)
-            filePath = possibleFiles.first().filePath();
-        else
-            qWarning() << "Could not find absolute location of file " << filePath;
-    }
-    emit addToTaskWindow(filePath, type, linenumber, description);
-}
-
-void MakeStep::addDirectory(const QString &dir)
-{
-    if (!m_openDirectories.contains(dir))
-        m_openDirectories.insert(dir);
-}
-
-void MakeStep::removeDirectory(const QString &dir)
-{
-    if (m_openDirectories.contains(dir))
-        m_openDirectories.remove(dir);
+    AbstractMakeStep::stdOut(line);
 }
 
 CMakeProject *MakeStep::project() const
diff --git a/src/plugins/cmakeprojectmanager/makestep.h b/src/plugins/cmakeprojectmanager/makestep.h
index f43977820aebc0835ecee3f28934d9921a587a16..8f99dcdb4ff75d51c585a471f30e30bf8ab27757 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/abstractprocessstep.h>
+#include <projectexplorer/abstractmakestep.h>
 
 QT_BEGIN_NAMESPACE
 class QLineEdit;
@@ -43,7 +43,7 @@ namespace Internal {
 
 class CMakeProject;
 
-class MakeStep : public ProjectExplorer::AbstractProcessStep
+class MakeStep : public ProjectExplorer::AbstractMakeStep
 {
     Q_OBJECT
 public:
@@ -62,17 +62,11 @@ public:
     void setBuildTarget(const QString &buildConfiguration, const QString &target, bool on);
     QStringList additionalArguments(const QString &buildConfiguration) const;
     void setAdditionalArguments(const QString &buildConfiguration, const QStringList &list);
-private slots:
-    void slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description);
-    void addDirectory(const QString &dir);
-    void removeDirectory(const QString &dir);
 protected:
+    // For parsing [ 76%]
     virtual void stdOut(const QString &line);
-    virtual void stdError(const QString &line);
 private:
     CMakeProject *m_pro;
-    ProjectExplorer::BuildParserInterface *m_buildParser;
-    QSet<QString> m_openDirectories;
     QRegExp m_percentProgress;
     QFutureInterface<bool> *m_futureInterface;
 };
diff --git a/src/plugins/genericprojectmanager/genericmakestep.cpp b/src/plugins/genericprojectmanager/genericmakestep.cpp
index 65ae59f8358c34e1c1dbe0dba17d22a60c704ae2..586f10f3c5d3864fe810aedb264aae631d565e29 100644
--- a/src/plugins/genericprojectmanager/genericmakestep.cpp
+++ b/src/plugins/genericprojectmanager/genericmakestep.cpp
@@ -42,61 +42,24 @@
 #include <QtGui/QLineEdit>
 #include <QtGui/QListWidget>
 
-namespace {
-bool debug = false;
-}
-
 using namespace GenericProjectManager;
 using namespace GenericProjectManager::Internal;
 
 GenericMakeStep::GenericMakeStep(GenericProject *pro)
-    : AbstractProcessStep(pro), m_pro(pro), m_buildParser(0)
+    : AbstractMakeStep(pro), m_pro(pro)
 {
 }
 
 GenericMakeStep::~GenericMakeStep()
 {
-    delete m_buildParser;
-    m_buildParser = 0;
 }
 
 bool GenericMakeStep::init(const QString &buildConfiguration)
 {
-    // TODO figure out the correct build parser
-    delete m_buildParser;
-    m_buildParser = 0;
-
     const QString buildParser = m_pro->buildParser(buildConfiguration);
+    setBuildParser(buildParser);
     qDebug() << "*** build parser:" << buildParser;
 
-    QList<ProjectExplorer::IBuildParserFactory *> buildParserFactories =
-            ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>();
-
-    foreach (ProjectExplorer::IBuildParserFactory *factory, buildParserFactories) {
-        if (factory->canCreate(buildParser)) {
-            m_buildParser = factory->create(buildParser);
-            break;
-        }
-    }
-
-    if (m_buildParser) {
-        connect(m_buildParser, SIGNAL(addToOutputWindow(const QString &)),
-                this, SIGNAL(addToOutputWindow(const QString &)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)),
-                this, SLOT(slotAddToTaskWindow(const QString &, int, int, const QString &)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(enterDirectory(const QString &)),
-                this, SLOT(addDirectory(const QString &)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(leaveDirectory(const QString &)),
-                this, SLOT(removeDirectory(const QString &)),
-                Qt::DirectConnection);
-    }
-
-    m_openDirectories.clear();
-    addDirectory(m_pro->buildDirectory(buildConfiguration));
-
     setEnabled(buildConfiguration, true);
     setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration));
 
@@ -115,7 +78,7 @@ bool GenericMakeStep::init(const QString &buildConfiguration)
     setArguments(buildConfiguration, arguments);
 
     setEnvironment(buildConfiguration, m_pro->environment(buildConfiguration));
-    return AbstractProcessStep::init(buildConfiguration);
+    return AbstractMakeStep::init(buildConfiguration);
 }
 
 void GenericMakeStep::run(QFutureInterface<bool> &fi)
@@ -143,79 +106,6 @@ bool GenericMakeStep::immutable() const
     return true;
 }
 
-void GenericMakeStep::stdOut(const QString &line)
-{
-    if (m_buildParser)
-        m_buildParser->stdOutput(line);
-    AbstractProcessStep::stdOut(line);
-}
-
-void GenericMakeStep::stdError(const QString &line)
-{
-    if (m_buildParser)
-        m_buildParser->stdError(line);
-    AbstractProcessStep::stdError(line);
-}
-
-void GenericMakeStep::slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description)
-{
-    QString filePath = fn;
-    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
-
-        filePath = filePath.trimmed();
-
-        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, project()->files(ProjectExplorer::Project::AllFiles)) {
-                QFileInfo candidate(file);
-                if (candidate.fileName() == fileName) {
-                    if (debug)
-                        qDebug() << "Found " << file;
-                    possibleFiles << candidate;
-                }
-            }
-        }
-        if (possibleFiles.count() == 1)
-            filePath = possibleFiles.first().filePath();
-        else
-            qWarning() << "Could not find absolute location of file " << filePath;
-    }
-    emit addToTaskWindow(filePath, type, linenumber, description);
-}
-
-void GenericMakeStep::addDirectory(const QString &dir)
-{
-    if (!m_openDirectories.contains(dir))
-        m_openDirectories.insert(dir);
-}
-
-void GenericMakeStep::removeDirectory(const QString &dir)
-{
-    if (m_openDirectories.contains(dir))
-        m_openDirectories.remove(dir);
-}
-
-
 GenericProject *GenericMakeStep::project() const
 {
     return m_pro;
diff --git a/src/plugins/genericprojectmanager/genericmakestep.h b/src/plugins/genericprojectmanager/genericmakestep.h
index c103fa1ba9343bc394a48a1e0349e1661e694cff..96e71c8589140f1fc8ad843b0a870cf46426b62e 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/abstractprocessstep.h>
+#include <projectexplorer/abstractmakestep.h>
 
 QT_BEGIN_NAMESPACE
 class QListWidgetItem;
@@ -45,7 +45,7 @@ namespace Internal {
 
 class GenericProject;
 
-class GenericMakeStep : public ProjectExplorer::AbstractProcessStep
+class GenericMakeStep : public ProjectExplorer::AbstractMakeStep
 {
     Q_OBJECT
 public:
@@ -62,17 +62,8 @@ public:
     GenericProject *project() const;
     bool buildsTarget(const QString &buildConfiguration, const QString &target) const;
     void setBuildTarget(const QString &buildConfiguration, const QString &target, bool on);
-private slots:
-    void slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description);
-    void addDirectory(const QString &dir);
-    void removeDirectory(const QString &dir);
-protected:
-    virtual void stdOut(const QString &line);
-    virtual void stdError(const QString &line);
 private:
     GenericProject *m_pro;
-    ProjectExplorer::BuildParserInterface *m_buildParser;
-    QSet<QString> m_openDirectories;
 };
 
 class GenericMakeStepConfigWidget :public ProjectExplorer::BuildStepConfigWidget
diff --git a/src/plugins/projectexplorer/abstractmakestep.cpp b/src/plugins/projectexplorer/abstractmakestep.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cde9e5719c6953b6abe12b0d5a616583b82af970
--- /dev/null
+++ b/src/plugins/projectexplorer/abstractmakestep.cpp
@@ -0,0 +1,188 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#include "abstractmakestep.h"
+
+#include "projectexplorerconstants.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(Project *project)
+    : AbstractProcessStep(project),
+      m_project(project),
+      m_buildParser(0)
+{
+}
+
+AbstractMakeStep::~AbstractMakeStep()
+{
+    delete m_buildParser;
+    m_buildParser = 0;
+}
+
+bool AbstractMakeStep::init(const QString &buildConfiguration)
+{
+    m_buildConfiguration = buildConfiguration;
+
+    m_openDirectories.clear();
+    addDirectory(workingDirectory(buildConfiguration));
+
+    return AbstractProcessStep::init(buildConfiguration);
+}
+
+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) {
+        connect(m_buildParser, SIGNAL(addToOutputWindow(const QString &)),
+                this, SIGNAL(addToOutputWindow(const QString &)),
+                Qt::DirectConnection);
+        connect(m_buildParser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)),
+                this, SLOT(slotAddToTaskWindow(const QString &, int, int, const QString &)),
+                Qt::DirectConnection);
+        connect(m_buildParser, SIGNAL(enterDirectory(const QString &)),
+                this, SLOT(addDirectory(const QString &)),
+                Qt::DirectConnection);
+        connect(m_buildParser, SIGNAL(leaveDirectory(const QString &)),
+                this, SLOT(removeDirectory(const QString &)),
+                Qt::DirectConnection);
+    }
+}
+
+void AbstractMakeStep::slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description)
+{
+    QString filePath = fn;
+    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
+
+        filePath = filePath.trimmed();
+
+        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, m_project->files(ProjectExplorer::Project::AllFiles)) {
+                QFileInfo candidate(file);
+                if (candidate.fileName() == fileName) {
+                    if (debug)
+                        qDebug() << "Found " << file;
+                    possibleFiles << candidate;
+                }
+            }
+        }
+        if (possibleFiles.count() == 1)
+            filePath = possibleFiles.first().filePath();
+        else
+            qWarning() << "Could not find absolute location of file " << filePath;
+    }
+    emit addToTaskWindow(filePath, type, linenumber, description);
+}
+
+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/abstractmakestep.h b/src/plugins/projectexplorer/abstractmakestep.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e5e2e9ef6fdf13c801e6bc8203b22b1cff0e60f
--- /dev/null
+++ b/src/plugins/projectexplorer/abstractmakestep.h
@@ -0,0 +1,74 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact:  Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#ifndef ABSTRACTMAKESTEP_H
+#define ABSTRACTMAKESTEP_H
+
+#include "abstractprocessstep.h"
+#include "projectexplorer.h"
+
+namespace ProjectExplorer {
+class BuildStep;
+class IBuildStepFactory;
+class Project;
+}
+
+namespace ProjectExplorer {
+
+class AbstractMakeStep : public ProjectExplorer::AbstractProcessStep
+{
+    Q_OBJECT
+public:
+    AbstractMakeStep(Project * project);
+    ~AbstractMakeStep();
+    virtual bool init(const QString & name);
+    virtual void run(QFutureInterface<bool> &);
+
+protected:
+    virtual void stdOut(const QString &line);
+    virtual void stdError(const QString &line);
+
+    // derived classes need to call those functions
+    void setBuildParser(const QString &parser);
+    QString buildParser() const;
+private slots:
+    void slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description);
+    void addDirectory(const QString &dir);
+    void removeDirectory(const QString &dir);
+private:
+    Project *m_project;
+    QString m_buildParserName;
+    ProjectExplorer::BuildParserInterface *m_buildParser;
+    QString m_buildConfiguration;
+    QSet<QString> m_openDirectories;
+};
+
+} // ProjectExplorer
+
+#endif // ABSTRACTMAKESTEP_H
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index ac021e8976efb37f0c47957478b02c32cd3d7156..e6a04cf83d9c551f11a90e19512a8fb8886ffe25 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -59,7 +59,8 @@ HEADERS += projectexplorer.h \
     gccparser.h \
     msvcparser.h \
     filewatcher.h \
-    debugginghelper.h
+    debugginghelper.h\
+    abstractmakestep.h
 SOURCES += projectexplorer.cpp \
     projectwindow.cpp \
     buildmanager.cpp \
@@ -107,7 +108,8 @@ SOURCES += projectexplorer.cpp \
     gccparser.cpp \
     msvcparser.cpp \
     filewatcher.cpp \
-    debugginghelper.cpp
+    debugginghelper.cpp \
+    abstractmakestep.cpp
 FORMS += dependenciespanel.ui \
     buildsettingspropertiespage.ui \
     processstep.ui \
diff --git a/src/plugins/qt4projectmanager/makestep.cpp b/src/plugins/qt4projectmanager/makestep.cpp
index b972142925bd954ac4587bf59b136471150a8ac9..c12c880b42a2f3d9656aee399c0713938838f267 100644
--- a/src/plugins/qt4projectmanager/makestep.cpp
+++ b/src/plugins/qt4projectmanager/makestep.cpp
@@ -34,9 +34,6 @@
 
 #include <projectexplorer/projectexplorerconstants.h>
 
-#include <extensionsystem/pluginmanager.h>
-#include <utils/qtcassert.h>
-
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
 
@@ -47,39 +44,15 @@ using ExtensionSystem::PluginManager;
 using namespace Qt4ProjectManager;
 using namespace Qt4ProjectManager::Internal;
 
-namespace {
-bool debug = false;
-}
-
 MakeStep::MakeStep(Qt4Project * project)
-    : AbstractProcessStep(project),
-      m_project(project),
-      m_buildParser(0)
+    : AbstractMakeStep(project)
 {
-}
 
-MakeStep::~MakeStep()
-{
-    delete m_buildParser;
-    m_buildParser = 0;
 }
 
-ProjectExplorer::BuildParserInterface *MakeStep::buildParser(const QtVersion *const version)
+MakeStep::~MakeStep()
 {
-    QString buildParser;
-    ProjectExplorer::ToolChain::ToolChainType type = version->toolchainType();
-    if ( type == ProjectExplorer::ToolChain::MSVC || type == ProjectExplorer::ToolChain::WINCE)
-        buildParser = ProjectExplorer::Constants::BUILD_PARSER_MSVC;
-    else
-        buildParser = ProjectExplorer::Constants::BUILD_PARSER_GCC;
-
-    QList<IBuildParserFactory *> buildParserFactories =
-            ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>();
 
-    foreach (IBuildParserFactory * factory, buildParserFactories)
-        if (factory->canCreate(buildParser))
-            return factory->create(buildParser);
-    return 0;
 }
 
 bool MakeStep::init(const QString &name)
@@ -135,87 +108,13 @@ bool MakeStep::init(const QString &name)
     setEnabled(name, !skipMakeClean);
     setArguments(name, args);
 
-    m_openDirectories.clear();
-    addDirectory(workingDirectory);
-
-    delete m_buildParser;
-    m_buildParser = 0;
-
-    m_buildParser = buildParser(qobject_cast<Qt4Project *>(project())->qtVersion(name));
-    if (m_buildParser) {
-        connect(m_buildParser, SIGNAL(addToOutputWindow(const QString &)),
-                this, SIGNAL(addToOutputWindow(const QString &)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)),
-                this, SLOT(slotAddToTaskWindow(const QString &, int, int, const QString &)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(enterDirectory(const QString &)),
-                this, SLOT(addDirectory(const QString &)),
-                Qt::DirectConnection);
-        connect(m_buildParser, SIGNAL(leaveDirectory(const QString &)),
-                this, SLOT(removeDirectory(const QString &)),
-                Qt::DirectConnection);
-    }
-
-    return AbstractProcessStep::init(name);
-}
-
-void MakeStep::slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description)
-{
-    QString filePath = fn;
-    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
-
-        filePath = filePath.trimmed();
-
-        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, m_project->files(ProjectExplorer::Project::AllFiles)) {
-                QFileInfo candidate(file);
-                if (candidate.fileName() == fileName) {
-                    if (debug)
-                        qDebug() << "Found " << file;
-                    possibleFiles << candidate;
-                }
-            }
-        }
-        if (possibleFiles.count() == 1)
-            filePath = possibleFiles.first().filePath();
-        else
-            qWarning() << "Could not find absolute location of file " << filePath;
-    }
-    emit addToTaskWindow(filePath, type, linenumber, description);
-}
+    ProjectExplorer::ToolChain::ToolChainType type = qobject_cast<Qt4Project *>(project())->qtVersion(name)->toolchainType();
+    if ( type == ProjectExplorer::ToolChain::MSVC || type == ProjectExplorer::ToolChain::WINCE)
+        setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_MSVC);
+    else
+        setBuildParser(ProjectExplorer::Constants::BUILD_PARSER_GCC);
 
-void MakeStep::addDirectory(const QString &dir)
-{
-    if (!m_openDirectories.contains(dir))
-        m_openDirectories.insert(dir);
-}
-
-void MakeStep::removeDirectory(const QString &dir)
-{
-    if (m_openDirectories.contains(dir))
-        m_openDirectories.remove(dir);
+    return AbstractMakeStep::init(name);
 }
 
 void MakeStep::run(QFutureInterface<bool> & fi)
@@ -231,21 +130,7 @@ void MakeStep::run(QFutureInterface<bool> & fi)
         return;
     }
 
-    AbstractProcessStep::run(fi);
-}
-
-void MakeStep::stdOut(const QString &line)
-{
-    if (m_buildParser)
-        m_buildParser->stdOutput(line);
-    AbstractProcessStep::stdOut(line);
-}
-
-void MakeStep::stdError(const QString &line)
-{
-    if (m_buildParser)
-        m_buildParser->stdError(line);
-    AbstractProcessStep::stdError(line);
+    AbstractMakeStep::run(fi);
 }
 
 QString MakeStep::name()
diff --git a/src/plugins/qt4projectmanager/makestep.h b/src/plugins/qt4projectmanager/makestep.h
index 4276ea770980636c62a839d0a16bd4cd3e59903a..36e1f703dd67ac0d88f1f068266f9b3cca306a5e 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/abstractprocessstep.h>
+#include <projectexplorer/abstractmakestep.h>
 #include <projectexplorer/projectexplorer.h>
 
 namespace ProjectExplorer {
@@ -60,8 +60,7 @@ public:
 
 class Qt4Project;
 
-// NBS move this class to an own plugin? So that there can be a make project at a future time
-class MakeStep : public ProjectExplorer::AbstractProcessStep
+class MakeStep : public ProjectExplorer::AbstractMakeStep
 {
     Q_OBJECT
 public:
@@ -73,20 +72,8 @@ public:
     virtual QString displayName();
     virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
     virtual bool immutable() const;
-protected:
-    virtual void stdOut(const QString &line);
-    virtual void stdError(const QString &line);
-private slots:
-    void slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description);
-    void addDirectory(const QString &dir);
-    void removeDirectory(const QString &dir);
 private:
-    ProjectExplorer::BuildParserInterface *buildParser(const QtVersion *const version);
-    Qt4Project *m_project;
-    ProjectExplorer::BuildParserInterface *m_buildParser;
-    bool m_skipMakeClean;
     QString m_buildConfiguration;
-    QSet<QString> m_openDirectories;
 };
 
 class MakeStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget