diff --git a/src/plugins/projectexplorer/gnumakeparser.cpp b/src/plugins/projectexplorer/gnumakeparser.cpp
index 929a99fa5aafc05bfdba335bddcb2e27afbdaa5e..1027b12374546dfcf7b2db9b0df4790326b697d6 100644
--- a/src/plugins/projectexplorer/gnumakeparser.cpp
+++ b/src/plugins/projectexplorer/gnumakeparser.cpp
@@ -28,6 +28,8 @@
 **************************************************************************/
 
 #include "gnumakeparser.h"
+
+#include "projectexplorerconstants.h"
 #include "taskwindow.h"
 
 #include <QtCore/QDir>
@@ -35,11 +37,17 @@
 
 using namespace ProjectExplorer;
 
+namespace {
+    const char * const MAKE_PATTERN("^(mingw(32|64)-|g)?make(\\[\\d+\\])?:\\s");
+}
+
 GnuMakeParser::GnuMakeParser(const QString &dir)
 {
-    //make[4]: Entering directory `/some/dir'
-    m_makeDir.setPattern("^(?:mingw32-)?make.*: (\\w+) directory .(.+).$");
+    m_makeDir.setPattern(QLatin1String(MAKE_PATTERN) +
+                         QLatin1String("(\\w+) directory .(.+).$"));
     m_makeDir.setMinimal(true);
+    m_makeLine.setPattern(QLatin1String(MAKE_PATTERN) + QLatin1String("(.*)$"));
+    m_makeLine.setMinimal(true);
     addDirectory(dir);
 }
 
@@ -48,10 +56,24 @@ 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));
+        if (m_makeDir.cap(4) == "Leaving")
+            removeDirectory(m_makeDir.cap(5));
         else
-            addDirectory(m_makeDir.cap(2));
+            addDirectory(m_makeDir.cap(5));
+        return;
+    }
+    if (m_makeLine.indexIn(lne) > -1) {
+        QString message = m_makeLine.cap(4);
+        Task task(Task::Warning,
+                  message,
+                  QString() /* filename */,
+                  -1, /* line */
+                  Constants::TASK_CATEGORY_BUILDSYSTEM);
+        if (message.startsWith(QLatin1String("*** "))) {
+            task.description = task.description.mid(4);
+            task.type = Task::Error;
+        }
+        addTask(task);
         return;
     }
 
@@ -70,9 +92,9 @@ void GnuMakeParser::removeDirectory(const QString &dir)
     m_directories.removeAll(dir);
 }
 
-void GnuMakeParser::taskAdded(const ProjectExplorer::Task &task)
+void GnuMakeParser::taskAdded(const Task &task)
 {
-    ProjectExplorer::Task editable(task);
+    Task editable(task);
     QString filePath(QDir::cleanPath(task.file.trimmed()));
 
     if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) {
@@ -93,3 +115,237 @@ void GnuMakeParser::taskAdded(const ProjectExplorer::Task &task)
 
     IOutputParser::taskAdded(editable);
 }
+
+#if defined WITH_TESTS
+QStringList GnuMakeParser::searchDirectories() const
+{
+    return m_directories;
+}
+#endif
+
+// Unit tests:
+
+#ifdef WITH_TESTS
+#   include <QTest>
+
+#   include <QtCore/QDebug>
+#   include <QtCore/QUuid>
+
+#   include "outputparser_test.h"
+#   include "projectexplorer.h"
+#   include "projectexplorerconstants.h"
+
+#   include "metatypedeclarations.h"
+
+void ProjectExplorerPlugin::testGnuMakeParserParsing_data()
+{
+    QTest::addColumn<QStringList>("extraSearchDirs");
+    QTest::addColumn<QString>("input");
+    QTest::addColumn<OutputParserTester::Channel>("inputChannel");
+    QTest::addColumn<QString>("childStdOutLines");
+    QTest::addColumn<QString>("childStdErrLines");
+    QTest::addColumn<QList<Task> >("tasks");
+    QTest::addColumn<QString>("outputLines");
+    QTest::addColumn<QStringList>("additionalSearchDirs");
+
+    QTest::newRow("pass-through stdout")
+            << QStringList()
+            << QString::fromLatin1("Sometext") << OutputParserTester::STDOUT
+            << QString::fromLatin1("Sometext") << QString()
+            << QList<Task>()
+            << QString()
+            << QStringList();
+    QTest::newRow("pass-through stderr")
+            << QStringList()
+            << QString::fromLatin1("Sometext") << OutputParserTester::STDERR
+            << QString() << QString::fromLatin1("Sometext")
+            << QList<Task>()
+            << QString()
+            << QStringList();
+    // make sure adding directories works (once;-)
+    QTest::newRow("entering directory")
+            << (QStringList() << QString::fromLatin1("/test/dir") )
+            << QString::fromLatin1("make[4]: Entering directory `/home/code/build/qt/examples/opengl/grabber'\n"
+                                   "make[4]: Entering directory `/home/code/build/qt/examples/opengl/grabber'\n")
+            << OutputParserTester::STDOUT
+            << QString() << QString()
+            << QList<Task>()
+            << QString()
+            << (QStringList() << QString::fromLatin1("/home/code/build/qt/examples/opengl/grabber") << QString::fromLatin1("/test/dir"));
+    QTest::newRow("leaving directory")
+            << (QStringList()  << QString::fromLatin1("/home/code/build/qt/examples/opengl/grabber") << QString::fromLatin1("/test/dir"))
+            << QString::fromLatin1("make[4]: Leaving directory `/home/code/build/qt/examples/opengl/grabber'")
+            << OutputParserTester::STDOUT
+            << QString() << QString()
+            << QList<Task>()
+            << QString()
+            << (QStringList() << QString::fromLatin1("/test/dir"));
+    QTest::newRow("make error")
+            << QStringList()
+            << QString::fromLatin1("make: *** No rule to make target `hello.c', needed by `hello.o'.  Stop.")
+            << OutputParserTester::STDOUT
+            << QString() << QString()
+            << (QList<Task>()
+                << Task(Task::Error,
+                        QString::fromLatin1("No rule to make target `hello.c', needed by `hello.o'.  Stop."),
+                        QString(), -1,
+                        Constants::TASK_CATEGORY_BUILDSYSTEM))
+            << QString()
+            << QStringList();
+    QTest::newRow("make warning")
+            << QStringList()
+            << QString::fromLatin1("make: warning: ignoring old commands for target `xxx'")
+            << OutputParserTester::STDOUT
+            << QString() << QString()
+            << (QList<Task>()
+                << Task(Task::Warning,
+                        QString::fromLatin1("warning: ignoring old commands for target `xxx'"),
+                        QString(), -1,
+                        Constants::TASK_CATEGORY_BUILDSYSTEM))
+            << QString()
+            << QStringList();
+}
+
+void ProjectExplorerPlugin::testGnuMakeParserParsing()
+{
+    OutputParserTester testbench;
+    GnuMakeParser *childParser = new GnuMakeParser;
+    testbench.appendOutputParser(childParser);
+    QFETCH(QStringList, extraSearchDirs);
+    QFETCH(QString, input);
+    QFETCH(OutputParserTester::Channel, inputChannel);
+    QFETCH(QList<Task>, tasks);
+    QFETCH(QString, childStdOutLines);
+    QFETCH(QString, childStdErrLines);
+    QFETCH(QString, outputLines);
+    QFETCH(QStringList, additionalSearchDirs);
+
+    QStringList searchDirs = childParser->searchDirectories();
+
+    // add extra directories:
+    foreach(const QString &dir, extraSearchDirs)
+        childParser->addDirectory(dir);
+
+    testbench.testParsing(input, inputChannel,
+                          tasks, childStdOutLines, childStdErrLines,
+                          outputLines);
+
+    // make sure we still have all the original dirs
+    QStringList newSearchDirs = childParser->searchDirectories();
+    foreach (const QString &dir, searchDirs) {
+        QVERIFY(newSearchDirs.contains(dir));
+        newSearchDirs.removeOne(dir);
+    }
+
+    // make sure we have all additional dirs:
+    foreach (const QString &dir, additionalSearchDirs) {
+        QVERIFY(newSearchDirs.contains(dir));
+        newSearchDirs.removeOne(dir);
+    }
+    // make sure we have no extra cruft:
+    QVERIFY(newSearchDirs.isEmpty());
+}
+
+void ProjectExplorerPlugin::testGnuMakeParserTaskMangling_data()
+{
+    QTest::addColumn<QStringList>("files");
+    QTest::addColumn<QStringList>("searchDirectories");
+    QTest::addColumn<Task>("inputTask");
+    QTest::addColumn<Task>("outputTask");
+
+    QTest::newRow("no filename")
+            << QStringList()
+            << QStringList()
+            << Task(Task::Error,
+                    QLatin1String("no filename, no mangling"),
+                    QString(),
+                    -1,
+                    Constants::TASK_CATEGORY_COMPILE)
+            << Task(Task::Error,
+                    QLatin1String("no filename, no mangling"),
+                    QString(),
+                    -1,
+                    Constants::TASK_CATEGORY_COMPILE);
+   QTest::newRow("no mangling")
+            << QStringList()
+            << QStringList()
+            << Task(Task::Error,
+                    QLatin1String("unknown filename, no mangling"),
+                    QString::fromLatin1("some/path/unknown.cpp"),
+                    -1,
+                    Constants::TASK_CATEGORY_COMPILE)
+            << Task(Task::Error,
+                    QLatin1String("unknown filename, no mangling"),
+                    QString::fromLatin1("some/path/unknown.cpp"),
+                    -1,
+                    Constants::TASK_CATEGORY_COMPILE);
+    QTest::newRow("find file")
+            << (QStringList() << "test/file.cpp")
+            << (QStringList() << "test")
+            << Task(Task::Error,
+                    QLatin1String("mangling"),
+                    QString::fromLatin1("file.cpp"),
+                    10,
+                    Constants::TASK_CATEGORY_COMPILE)
+            << Task(Task::Error,
+                    QLatin1String("mangling"),
+                    QString::fromLatin1("$TMPDIR/test/file.cpp"),
+                    10,
+                    Constants::TASK_CATEGORY_COMPILE);
+}
+
+void ProjectExplorerPlugin::testGnuMakeParserTaskMangling()
+{
+    OutputParserTester testbench;
+    GnuMakeParser *childParser = new GnuMakeParser;
+    testbench.appendOutputParser(childParser);
+
+    QFETCH(QStringList, files);
+    QFETCH(QStringList, searchDirectories);
+    QFETCH(Task, inputTask);
+    QFETCH(Task, outputTask);
+
+    // setup files:
+    QString tempdir;
+#if defined Q_OS_WIN
+    tempdir = QDir::fromNativeSeparators(qgetenv("TEMP"));
+#else
+    tempdir = QLatin1String("/tmp");
+#endif
+    tempdir.append(QChar('/'));
+    tempdir.append(QUuid::createUuid().toString());
+    tempdir.append(QChar('/'));
+
+    QDir filedir(tempdir);
+    foreach (const QString &file, files) {
+        Q_ASSERT(!file.startsWith(QChar('/')));
+        Q_ASSERT(!file.contains(QLatin1String("../")));
+
+        filedir.mkpath(file.left(file.lastIndexOf(QChar('/'))));
+
+        QFile tempfile(tempdir + file);
+        if (!tempfile.open(QIODevice::WriteOnly))
+            continue;
+        tempfile.write("Delete me again!");
+        tempfile.close();
+    }
+
+    // setup search dirs:
+    foreach (const QString &dir, searchDirectories) {
+        Q_ASSERT(!dir.startsWith(QChar('/')));
+        Q_ASSERT(!dir.contains(QLatin1String("../")));
+        childParser->addDirectory(tempdir + dir);
+    }
+
+    // fix up output task file:
+    if (outputTask.file.startsWith(QLatin1String("$TMPDIR/")))
+        outputTask.file = outputTask.file.replace(QLatin1String("$TMPDIR/"), tempdir);
+
+    // test mangling:
+    testbench.testTaskMangling(inputTask, outputTask);
+
+    // clean up:
+    foreach (const QString &file, files)
+        filedir.rmpath(tempdir + file);
+}
+#endif
diff --git a/src/plugins/projectexplorer/gnumakeparser.h b/src/plugins/projectexplorer/gnumakeparser.h
index 30f82bca8c8bb695f1c6e873115b995f96fd9404..433375622310a19f466fa4d47a44e755f1aee0bf 100644
--- a/src/plugins/projectexplorer/gnumakeparser.h
+++ b/src/plugins/projectexplorer/gnumakeparser.h
@@ -46,6 +46,8 @@ public:
 
     virtual void stdOutput(const QString &line);
 
+    QStringList searchDirectories() const;
+
 public slots:
     virtual void taskAdded(const ProjectExplorer::Task &task);
 
@@ -54,7 +56,13 @@ private:
     void removeDirectory(const QString &dir);
 
     QRegExp m_makeDir;
+    QRegExp m_makeLine;
+
     QStringList m_directories;
+
+#if defined WITH_TESTS
+    friend class ProjectExplorerPlugin;
+#endif
 };
 
 } // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index 7c13947df347622f81bfcc057cd147d10821b733..440314247419d0c29476d2cb5c03705f91ab98eb 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -223,6 +223,11 @@ private slots:
 #ifdef WITH_TESTS
     void testGccOutputParsers_data();
     void testGccOutputParsers();
+
+    void testGnuMakeParserParsing_data();
+    void testGnuMakeParserParsing();
+    void testGnuMakeParserTaskMangling_data();
+    void testGnuMakeParserTaskMangling();
 #endif
 
 private: