diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp
index 14ecc4bfd0bc386e86dd9d52aec710419818814b..f2d39806e4845514d411ccb180f91b7ed5611e2e 100644
--- a/src/plugins/projectexplorer/buildmanager.cpp
+++ b/src/plugins/projectexplorer/buildmanager.cpp
@@ -86,6 +86,8 @@ BuildManager::BuildManager(ProjectExplorerPlugin *parent)
     m_taskWindow = new TaskWindow;
     pm->addObject(m_taskWindow);
 
+    m_taskWindow->addCategory(Constants::TASK_CATEGORY_COMPILE, tr("Compile", "Category for compiler isses listened under 'Build Issues'"));
+
     connect(m_taskWindow, SIGNAL(tasksChanged()),
             this, SIGNAL(tasksChanged()));
 
@@ -179,7 +181,7 @@ void BuildManager::toggleTaskWindow()
 
 bool BuildManager::tasksAvailable() const
 {
-    return m_taskWindow->numberOfTasks() > 0;
+    return m_taskWindow->taskCount() > 0;
 }
 
 void BuildManager::gotoTaskWindow()
@@ -221,7 +223,7 @@ void BuildManager::startBuildQueue()
 
 void BuildManager::showBuildResults()
 {
-    if (m_taskWindow->numberOfTasks() != 0)
+    if (m_taskWindow->taskCount() != 0)
         toggleTaskWindow();
     else
         toggleOutputWindow();
@@ -230,7 +232,9 @@ void BuildManager::showBuildResults()
 
 void BuildManager::addToTaskWindow(const QString &file, int type, int line, const QString &description)
 {
-    m_taskWindow->addItem(BuildParserInterface::PatternType(type), description, file, line);
+    TaskWindow::Task task(TaskWindow::TaskType(type), description, file, line,
+                           Constants::TASK_CATEGORY_COMPILE);
+    m_taskWindow->addTask(task);
 }
 
 void BuildManager::addToOutputWindow(const QString &string)
diff --git a/src/plugins/projectexplorer/buildmanager.h b/src/plugins/projectexplorer/buildmanager.h
index 4b3f1393a27c618d75ee9825b60028a58afe57c4..58795ee5e1775de335780bfc4a71bbd6c912f78b 100644
--- a/src/plugins/projectexplorer/buildmanager.h
+++ b/src/plugins/projectexplorer/buildmanager.h
@@ -42,10 +42,10 @@ namespace ProjectExplorer {
 
 namespace Internal {
     class CompileOutputWindow;
-    class TaskWindow;
     class BuildProgressFuture;
 }
 
+class TaskWindow;
 class BuildStep;
 class Project;
 class ProjectExplorerPlugin;
@@ -109,7 +109,7 @@ private:
     void decrementActiveBuildSteps(Project *pro);
 
     Internal::CompileOutputWindow *m_outputWindow;
-    Internal::TaskWindow *m_taskWindow;
+    TaskWindow *m_taskWindow;
 
     QList<BuildStep *> m_buildQueue;
     QStringList m_configurations; // the corresponding configuration to the m_buildQueue
diff --git a/src/plugins/projectexplorer/buildparserinterface.h b/src/plugins/projectexplorer/buildparserinterface.h
index 8a15c6d469396d76ccf444b808a1df47a10b9067..7b1a55e6e2ac06b6ac06d4f54a23ce224e48dd6d 100644
--- a/src/plugins/projectexplorer/buildparserinterface.h
+++ b/src/plugins/projectexplorer/buildparserinterface.h
@@ -41,8 +41,6 @@ class PROJECTEXPLORER_EXPORT BuildParserInterface : public QObject
 {
     Q_OBJECT
 public:
-    enum PatternType { Unknown, Warning, Error };
-
     virtual ~BuildParserInterface() {}
     virtual QString name() const = 0;
 
diff --git a/src/plugins/projectexplorer/buildprogress.cpp b/src/plugins/projectexplorer/buildprogress.cpp
index edc3576b71507cff7b0323b3c7c2b85636a0f390..c3c3525028f2125fb74d2e24bda620a5f1271c39 100644
--- a/src/plugins/projectexplorer/buildprogress.cpp
+++ b/src/plugins/projectexplorer/buildprogress.cpp
@@ -82,12 +82,12 @@ void BuildProgress::updateState()
 {
     if (!m_taskWindow)
         return;
-    int errors = m_taskWindow->numberOfErrors();
+    int errors = m_taskWindow->errorTaskCount();
     bool haveErrors = (errors > 0);
     m_errorIcon->setEnabled(haveErrors);
     m_errorLabel->setEnabled(haveErrors);
     m_errorLabel->setText(QString("%1").arg(errors));
-    int warnings = m_taskWindow->numberOfTasks()-errors;
+    int warnings = m_taskWindow->taskCount()-errors;
     bool haveWarnings = (warnings > 0);
     m_warningIcon->setEnabled(haveWarnings);
     m_warningLabel->setEnabled(haveWarnings);
diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp
index a3e0e93a16c4162589249e5afb4f2029077b031f..093c436c1a5f570ba03ae74af540ae37f693bd7c 100644
--- a/src/plugins/projectexplorer/gccparser.cpp
+++ b/src/plugins/projectexplorer/gccparser.cpp
@@ -29,6 +29,7 @@
 
 #include "gccparser.h"
 #include "projectexplorerconstants.h"
+#include "taskwindow.h"
 
 using namespace ProjectExplorer;
 
@@ -72,17 +73,18 @@ void GccParser::stdError(const QString & line)
         QString description = m_regExpLinker.cap(2);
         emit addToTaskWindow(
                 m_regExpLinker.cap(1), //filename
-                ProjectExplorer::BuildParserInterface::Error,
+                TaskWindow::Error,
                 -1, //linenumber
                 description);
+        //qDebug()<<"m_regExpLinker"<<m_regExpLinker.cap(2);
     } else if (m_regExp.indexIn(lne) > -1) {
-        ProjectExplorer::BuildParserInterface::PatternType type;
+        TaskWindow::TaskType type;
         if (m_regExp.cap(5) == "warning")
-            type = ProjectExplorer::BuildParserInterface::Warning;
+            type = TaskWindow::Warning;
         else if (m_regExp.cap(5) == "error")
-            type = ProjectExplorer::BuildParserInterface::Error;
+            type = TaskWindow::Error;
         else
-            type = ProjectExplorer::BuildParserInterface::Unknown;
+            type = TaskWindow::Unknown;
 
         QString description =  m_regExp.cap(6);
 
@@ -94,7 +96,7 @@ void GccParser::stdError(const QString & line)
     } else if (m_regExpIncluded.indexIn(lne) > -1) {
         emit addToTaskWindow(
                 m_regExpIncluded.cap(1), //filename
-                ProjectExplorer::BuildParserInterface::Unknown,
+                TaskWindow::Unknown,
                 m_regExpIncluded.cap(2).toInt(), //linenumber
                 lne //description
                 );
diff --git a/src/plugins/projectexplorer/msvcparser.cpp b/src/plugins/projectexplorer/msvcparser.cpp
index f4e7c715503331662197f7f07fe2fde8dc5ffde9..c840158c023616f27c7518227432d7e82b21bc67 100644
--- a/src/plugins/projectexplorer/msvcparser.cpp
+++ b/src/plugins/projectexplorer/msvcparser.cpp
@@ -79,12 +79,12 @@ void MsvcParser::stdOutput(const QString & line)
     }
 }
 
-ProjectExplorer::BuildParserInterface::PatternType MsvcParser::toType(int number)
+TaskWindow::TaskType MsvcParser::toType(int number)
 {
     if (number == 0)
-        return ProjectExplorer::BuildParserInterface::Unknown;
+        return TaskWindow::Unknown;
     else if (number > 4000 && number < 5000)
-        return ProjectExplorer::BuildParserInterface::Warning;
+        return TaskWindow::Warning;
     else
-        return ProjectExplorer::BuildParserInterface::Error;
+        return TaskWindow::Error;
 }
diff --git a/src/plugins/projectexplorer/msvcparser.h b/src/plugins/projectexplorer/msvcparser.h
index 4ef8b5cb90d32c61ba5070c15db5f4350f5ddc6c..c6aed2886aef32b67e972a28d307a2eba5b2968b 100644
--- a/src/plugins/projectexplorer/msvcparser.h
+++ b/src/plugins/projectexplorer/msvcparser.h
@@ -31,6 +31,7 @@
 #define MSVCPARSER_H
 
 #include "buildparserinterface.h"
+#include "taskwindow.h"
 
 #include <QtCore/QRegExp>
 
@@ -47,7 +48,7 @@ public:
     virtual void stdOutput(const QString & line);
     virtual void stdError(const QString & line);
 private:
-    ProjectExplorer::BuildParserInterface::PatternType toType(int number);
+    TaskWindow::TaskType toType(int number);
     QRegExp m_compileRegExp;
     QRegExp m_linkRegExp;
 };
diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h
index 382004456f2b1728c86279a3002aa53ddbefe3e2..5f01e40482587cd984b676f3c5a7a997135b4498 100644
--- a/src/plugins/projectexplorer/projectexplorerconstants.h
+++ b/src/plugins/projectexplorer/projectexplorerconstants.h
@@ -189,6 +189,9 @@ const char * const BUILD_PARSER_ABLD_RVCT   = "BuildParser.ABLD.Rvct";
 const char * const PROJECTEXPLORER_CATEGORY            = "ProjectExplorer";
 const char * const PROJECTEXPLORER_PAGE                = "ProjectExplorer.ProjectExplorer";
 
+// task categories
+const char * const TASK_CATEGORY_COMPILE = "Task.Category.Compile";
+
 } // namespace Constants
 } // namespace ProjectExplorer
 
diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp
index 1194211018699616db404fac17ed4036499d5d3d..4cadbb4f4ffb75c09dd1510449fd910d45679935 100644
--- a/src/plugins/projectexplorer/taskwindow.cpp
+++ b/src/plugins/projectexplorer/taskwindow.cpp
@@ -29,44 +29,69 @@
 
 #include "taskwindow.h"
 
-#include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/actionmanager/actionmanager.h>
-#include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/coreconstants.h>
+#include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/icore.h>
 #include <coreplugin/uniqueidmanager.h>
-#include <extensionsystem/pluginmanager.h>
-#include <texteditor/itexteditor.h>
 #include <texteditor/basetexteditor.h>
-#include <projectexplorerconstants.h>
+#include <texteditor/itexteditor.h>
 
 #include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtGui/QApplication>
+#include <QtGui/QClipboard>
 #include <QtGui/QKeyEvent>
-#include <QtGui/QHeaderView>
 #include <QtGui/QListView>
 #include <QtGui/QPainter>
-#include <QtCore/QAbstractItemModel>
+#include <QtGui/QStyledItemDelegate>
 #include <QtGui/QSortFilterProxyModel>
-#include <QtGui/QApplication>
-#include <QtGui/QClipboard>
-#include <QtGui/QFont>
-#include <QtGui/QFontMetrics>
-#include <QtGui/QTextLayout>
+
 #include <QDebug>
 
-using namespace ProjectExplorer::Internal;
+namespace ProjectExplorer {
+namespace Internal {
+
+class TaskView : public QListView
+{
+public:
+    TaskView(QWidget *parent = 0);
+    ~TaskView();
+    void resizeEvent(QResizeEvent *e);
+    void keyPressEvent(QKeyEvent *e);
+};
 
-// Internal Struct for TaskModel
-struct TaskItem
+class TaskDelegate : public QStyledItemDelegate
 {
-    QString description;
-    QString file;
-    int line;
-    bool fileNotFound;
-    ProjectExplorer::BuildParserInterface::PatternType type;
+    Q_OBJECT
+public:
+    TaskDelegate(QObject * parent = 0);
+    ~TaskDelegate();
+    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+    // TaskView uses this method if the size of the taskview changes
+    void emitSizeHintChanged(const QModelIndex &index);
+
+public slots:
+    void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+
+private:
+    void generateGradientPixmap(int width, int height, QColor color, bool selected) const;
 };
 
-class ProjectExplorer::Internal::TaskModel : public QAbstractItemModel
+class TaskWindowContext : public Core::IContext
+{
+public:
+    TaskWindowContext(QWidget *widget);
+    virtual QList<int> context() const;
+    virtual QWidget *widget();
+private:
+    QWidget *m_taskList;
+    QList<int> m_context;
+};
+
+class TaskModel : public QAbstractItemModel
 {
 public:
     // Model stuff
@@ -76,25 +101,34 @@ public:
     int rowCount(const QModelIndex &parent = QModelIndex()) const;
     int columnCount(const QModelIndex &parent = QModelIndex()) const;
     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
-    void clear();
-    void addTask(ProjectExplorer::BuildParserInterface::PatternType type,
-                         const QString &description, const QString &file, int line);
+
+    void addCategory(const QString &categoryId, const QString &categoryName);
+
+    QList<TaskWindow::Task> tasks(const QString &categoryId = QString()) const;
+    void addTask(const TaskWindow::Task &task);
+    void clearTasks(const QString &categoryId = QString());
+
     int sizeOfFile();
     int sizeOfLineNumber();
     void setFileNotFound(const QModelIndex &index, bool b);
 
     enum Roles { File = Qt::UserRole, Line, Description, FileNotFound, Type };
 
-    QIcon iconFor(ProjectExplorer::BuildParserInterface::PatternType type);
+    QIcon iconFor(TaskWindow::TaskType type);
+
 private:
-    QList<TaskItem> m_items;
+    QHash<QString,QString> m_categories; // category id -> display name
+    QList<TaskWindow::Task> m_tasks;   // all tasks (in order of insertion)
+    QMap<QString,QList<TaskWindow::Task> > m_tasksInCategory; // categoryId->tasks
+
+    QHash<QString,bool> m_fileNotFound;
     int m_maxSizeOfFileName;
     QIcon m_errorIcon;
     QIcon m_warningIcon;
     QIcon m_unspecifiedIcon;
 };
 
-class ProjectExplorer::Internal::TaskFilterModel : public QSortFilterProxyModel
+class TaskFilterModel : public QSortFilterProxyModel
 {
 public:
     TaskFilterModel(TaskModel *sourceModel, QObject *parent = 0);
@@ -120,6 +154,14 @@ private:
     bool m_includeErrors;
 };
 
+} // Internal
+} // ProjectExplorer
+
+
+using namespace ProjectExplorer;
+using namespace ProjectExplorer::Internal;
+
+
 ////
 //  TaskView
 ////
@@ -164,17 +206,31 @@ TaskModel::TaskModel()
 
 }
 
-void TaskModel::addTask(ProjectExplorer::BuildParserInterface::PatternType type, const QString &description, const QString &file, int line)
+void TaskModel::addCategory(const QString &categoryId, const QString &categoryName)
+{
+    Q_ASSERT(!categoryId.isEmpty());
+    m_categories.insert(categoryId, categoryName);
+}
+
+QList<TaskWindow::Task> TaskModel::tasks(const QString &categoryId) const
+{
+    if (categoryId.isEmpty()) {
+        return m_tasks;
+    } else {
+        return m_tasksInCategory.value(categoryId);
+    }
+}
+
+void TaskModel::addTask(const TaskWindow::Task &task)
 {
-    TaskItem task;
-    task.description = description;
-    task.file = file;
-    task.line = line;
-    task.type = type;
-    task.fileNotFound = false;
+    Q_ASSERT(m_categories.keys().contains(task.category));
+
+    QList<TaskWindow::Task> tasksInCategory = m_tasksInCategory.value(task.category);
+    tasksInCategory.append(task);
+    m_tasksInCategory.insert(task.category, tasksInCategory);
 
-    beginInsertRows(QModelIndex(), m_items.size(), m_items.size());
-    m_items.append(task);
+    beginInsertRows(QModelIndex(), m_tasks.size(), m_tasks.size());
+    m_tasks.append(task);
     endInsertRows();
 
     QFont font;
@@ -182,18 +238,48 @@ void TaskModel::addTask(ProjectExplorer::BuildParserInterface::PatternType type,
     QString filename = task.file;
     int pos = filename.lastIndexOf("/");
     if (pos != -1)
-        filename = file.mid(pos +1);
+        filename = task.file.mid(pos +1);
+
     m_maxSizeOfFileName = qMax(m_maxSizeOfFileName, fm.width(filename));
 }
+//
+//void TaskModel::removeTask(const ITaskWindow::Task &task)
+//{
+//    Q_ASSERT(m_tasks.contains(task));
+//    int index = m_tasks.indexOf(task);
+//    beginRemoveRows(QModelIndex(), index, index);
+//    m_tasks.removeAt(index);
+//    endRemoveRows();
+//}
+
+void TaskModel::clearTasks(const QString &categoryId)
+{
+    if (categoryId.isEmpty()) {
+        if (m_tasks.size() == 0)
+            return;
+        beginRemoveRows(QModelIndex(), 0, m_tasks.size() -1);
+        m_tasks.clear();
+        m_tasksInCategory.clear();
+        endRemoveRows();
+        m_maxSizeOfFileName = 0;
+    } else {
+        // TODO: Optimize this for consecutive rows
+        foreach (const TaskWindow::Task &task, m_tasksInCategory.value(categoryId)) {
+            int index = m_tasks.indexOf(task);
+            Q_ASSERT(index >= 0);
+            beginRemoveRows(QModelIndex(), index, index);
 
-void TaskModel::clear()
-{
-    if (m_items.isEmpty())
-        return;
-    beginRemoveRows(QModelIndex(), 0, m_items.size() -1);
-    m_items.clear();
-    endRemoveRows();
-    m_maxSizeOfFileName = 0;
+            m_tasks.removeAt(index);
+
+            QList<TaskWindow::Task> tasksInCategory = m_tasksInCategory.value(categoryId);
+            tasksInCategory.removeOne(task);
+            m_tasksInCategory.insert(categoryId, tasksInCategory);
+
+            endRemoveRows();
+        }
+
+        // what to do with m_maxSizeOfFileName ?
+    }
 }
 
 
@@ -212,7 +298,7 @@ QModelIndex TaskModel::parent(const QModelIndex &child) const
 
 int TaskModel::rowCount(const QModelIndex &parent) const
 {
-    return parent.isValid() ? 0 : m_items.count();
+    return parent.isValid() ? 0 : m_tasks.count();
 }
 
 int TaskModel::columnCount(const QModelIndex &parent) const
@@ -222,27 +308,27 @@ int TaskModel::columnCount(const QModelIndex &parent) const
 
 QVariant TaskModel::data(const QModelIndex &index, int role) const
 {
-    if (!index.isValid() || index.row() >= m_items.size() || index.column() != 0)
+    if (!index.isValid() || index.row() >= m_tasks.size() || index.column() != 0)
         return QVariant();
 
     if (role == TaskModel::File)
-        return m_items.at(index.row()).file;
+        return m_tasks.at(index.row()).file;
     else if (role == TaskModel::Line)
-        return m_items.at(index.row()).line;
+        return m_tasks.at(index.row()).line;
     else if (role == TaskModel::Description)
-        return m_items.at(index.row()).description;
+        return m_tasks.at(index.row()).description;
     else if (role == TaskModel::FileNotFound)
-        return m_items.at(index.row()).fileNotFound;
+        return m_fileNotFound.value(m_tasks.at(index.row()).file);
     else if (role == TaskModel::Type)
-        return (int)m_items.at(index.row()).type;
+        return (int)m_tasks.at(index.row()).type;
     return QVariant();
 }
 
-QIcon TaskModel::iconFor(ProjectExplorer::BuildParserInterface::PatternType type)
+QIcon TaskModel::iconFor(TaskWindow::TaskType type)
 {
-    if (type == ProjectExplorer::BuildParserInterface::Error)
+    if (type == TaskWindow::Error)
         return m_errorIcon;
-    else if (type == ProjectExplorer::BuildParserInterface::Warning)
+    else if (type == TaskWindow::Warning)
         return m_warningIcon;
     else
         return m_unspecifiedIcon;
@@ -262,8 +348,8 @@ int TaskModel::sizeOfLineNumber()
 
 void TaskModel::setFileNotFound(const QModelIndex &idx, bool b)
 {
-    if (idx.isValid() && idx.row() < m_items.size()) {
-        m_items[idx.row()].fileNotFound = b;
+    if (idx.isValid() && idx.row() < m_tasks.size()) {
+        m_fileNotFound.insert(m_tasks[idx.row()].file, b);
         emit dataChanged(idx, idx);
     }
 }
@@ -288,15 +374,15 @@ TaskModel *TaskFilterModel::taskModel() const
 bool TaskFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
 {
     QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
-    ProjectExplorer::BuildParserInterface::PatternType type = ProjectExplorer::BuildParserInterface::PatternType(index.data(TaskModel::Type).toInt());
+    TaskWindow::TaskType type = TaskWindow::TaskType(index.data(TaskModel::Type).toInt());
     switch (type) {
-    case ProjectExplorer::BuildParserInterface::Unknown:
+    case TaskWindow::Unknown:
         return m_includeUnknowns;
 
-    case ProjectExplorer::BuildParserInterface::Warning:
+    case TaskWindow::Warning:
         return m_includeWarnings;
 
-    case ProjectExplorer::BuildParserInterface::Error:
+    case TaskWindow::Error:
         return m_includeErrors;
     }
 
@@ -308,7 +394,7 @@ bool TaskFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceP
 // TaskWindow
 /////
 
-static QToolButton *createFilterButton(ProjectExplorer::BuildParserInterface::PatternType type,
+static QToolButton *createFilterButton(TaskWindow::TaskType type,
                                        const QString &toolTip, TaskModel *model,
                                        QObject *receiver, const char *slot)
 {
@@ -359,12 +445,11 @@ TaskWindow::TaskWindow()
 
     connect(m_copyAction, SIGNAL(triggered()), SLOT(copy()));
 
-    m_filterWarningsButton = createFilterButton(ProjectExplorer::BuildParserInterface::Warning,
+    m_filterWarningsButton = createFilterButton(TaskWindow::Warning,
                                                 tr("Show Warnings"), m_model,
                                                 this, SLOT(setShowWarnings(bool)));
 
-    m_errorCount = 0;
-    m_currentTask = -1;
+    updateActions();
 }
 
 TaskWindow::~TaskWindow()
@@ -386,12 +471,11 @@ QWidget *TaskWindow::outputWidget(QWidget *)
     return m_listview;
 }
 
-void TaskWindow::clearContents()
+void TaskWindow::clearTasks(const QString &categoryId)
 {
-    m_errorCount = 0;
-    m_currentTask = -1;
-    m_model->clear();
-    m_copyAction->setEnabled(false);
+    m_model->clearTasks(categoryId);
+
+    updateActions();
     emit tasksChanged();
     navigateStateChanged();
 }
@@ -400,16 +484,19 @@ void TaskWindow::visibilityChanged(bool /* b */)
 {
 }
 
-void TaskWindow::addItem(ProjectExplorer::BuildParserInterface::PatternType type,
-                         const QString &description, const QString &file, int line)
+void TaskWindow::addCategory(const QString &categoryId, const QString &displayName)
+{
+    Q_ASSERT(!categoryId.isEmpty());
+    m_model->addCategory(categoryId, displayName);
+}
+
+void TaskWindow::addTask(const Task &task)
 {
-    m_model->addTask(type, description, file, line);
-    if (type == ProjectExplorer::BuildParserInterface::Error)
-        ++m_errorCount;
-    m_copyAction->setEnabled(true);
+    m_model->addTask(task);
+
+    updateActions();
     emit tasksChanged();
-    if (m_model->rowCount() == 1)
-        navigateStateChanged();
+    navigateStateChanged();
 }
 
 void TaskWindow::showTaskInFile(const QModelIndex &index)
@@ -440,10 +527,10 @@ void TaskWindow::copy()
     QString description = index.data(TaskModel::Description).toString();
     QString type;
     switch (index.data(TaskModel::Type).toInt()) {
-    case ProjectExplorer::BuildParserInterface::Error:
+    case TaskWindow::Error:
         type = "error: ";
         break;
-    case ProjectExplorer::BuildParserInterface::Warning:
+    case TaskWindow::Warning:
         type = "warning: ";
         break;
     }
@@ -457,14 +544,21 @@ void TaskWindow::setShowWarnings(bool show)
     m_filter->setFilterIncludesUnknowns(show); // "Unknowns" are often associated with warnings
 }
 
-int TaskWindow::numberOfTasks() const
+int TaskWindow::taskCount(const QString &categoryId) const
 {
-    return m_model->rowCount(QModelIndex());
+    return m_model->tasks(categoryId).count();
 }
 
-int TaskWindow::numberOfErrors() const
+int TaskWindow::errorTaskCount(const QString &categoryId) const
 {
-    return m_errorCount;
+    int errorTaskCount = 0;
+
+    foreach (const Task &task, m_model->tasks(categoryId)) {
+        if (task.type == TaskWindow::Error)
+            ++ errorTaskCount;
+    }
+
+    return errorTaskCount;
 }
 
 int TaskWindow::priorityInStatusBar() const
@@ -472,6 +566,11 @@ int TaskWindow::priorityInStatusBar() const
     return 90;
 }
 
+void TaskWindow::clearContents()
+{
+    clearTasks();
+}
+
 bool TaskWindow::hasFocus()
 {
     return m_listview->hasFocus();
@@ -541,6 +640,11 @@ bool TaskWindow::canNavigate()
     return true;
 }
 
+void TaskWindow::updateActions()
+{
+    m_copyAction->setEnabled(m_model->tasks().count() > 0);
+}
+
 /////
 // Delegate
 /////
@@ -636,7 +740,7 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
     painter->setPen(textColor);
 
     TaskModel *model = static_cast<TaskFilterModel *>(view->model())->taskModel();
-    ProjectExplorer::BuildParserInterface::PatternType type = ProjectExplorer::BuildParserInterface::PatternType(index.data(TaskModel::Type).toInt());
+    TaskWindow::TaskType type = TaskWindow::TaskType(index.data(TaskModel::Type).toInt());
     QIcon icon = model->iconFor(type);
     painter->drawPixmap(2, opt.rect.top() + 2, icon.pixmap(16, 16));
 
@@ -727,3 +831,22 @@ QWidget *TaskWindowContext::widget()
     return m_taskList;
 }
 
+
+//
+// functions
+//
+bool ProjectExplorer::operator==(const TaskWindow::Task &t1, const TaskWindow::Task &t2)
+{
+    return t1.type == t2.type
+            && t1.line == t2.line
+            && t1.description == t2.description
+            && t1.file == t2.file
+            && t1.category == t2.category;
+}
+
+uint ProjectExplorer::qHash(const TaskWindow::Task &task)
+{
+    return qHash(task.file) + task.line;
+}
+
+#include "taskwindow.moc"
diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h
index d7e7d702c662d7b7e361e56a9cbc76810b4b4732..20cd59f655678de93dfd00ddce5e7cb3033d9ddf 100644
--- a/src/plugins/projectexplorer/taskwindow.h
+++ b/src/plugins/projectexplorer/taskwindow.h
@@ -32,15 +32,15 @@
 
 #include "buildparserinterface.h"
 
-#include <coreplugin/ioutputpane.h>
 #include <coreplugin/icontext.h>
+#include <coreplugin/ioutputpane.h>
 
-#include <QtGui/QTreeWidget>
-#include <QtGui/QStyledItemDelegate>
-#include <QtGui/QListView>
+#include <QtCore/QModelIndex>
+#include <QtGui/QAction>
 #include <QtGui/QToolButton>
 
 namespace ProjectExplorer {
+
 namespace Internal {
 
 class TaskModel;
@@ -48,7 +48,9 @@ class TaskFilterModel;
 class TaskView;
 class TaskWindowContext;
 
-class TaskWindow : public Core::IOutputPane
+} // namespace Internal
+
+class PROJECTEXPLORER_EXPORT TaskWindow : public Core::IOutputPane
 {
     Q_OBJECT
 
@@ -56,6 +58,35 @@ public:
     TaskWindow();
     ~TaskWindow();
 
+    enum TaskType {
+        Unknown,
+        Error,
+        Warning
+    };
+
+    struct Task {
+        Task(TaskType type_, const QString &description_,
+             const QString &file_, int line_, const QString &category_) :
+            type(type_), description(description_), file(file_), line(line_), category(category_)
+        { }
+
+        TaskType type;
+        QString description;
+        QString file;
+        int line;
+        QString category;
+    };
+
+    void addCategory(const QString &categoryId, const QString &displayName);
+
+    void addTask(const Task &task);
+    void clearTasks(const QString &categoryId = QString());
+
+    int taskCount(const QString &categoryId = QString()) const;
+    int errorTaskCount(const QString &categoryId = QString()) const;
+
+
+    // IOutputPane
     QWidget *outputWidget(QWidget *);
     QList<QWidget*> toolBarWidgets() const;
 
@@ -64,21 +95,15 @@ public:
     void clearContents();
     void visibilityChanged(bool visible);
 
-    void addItem(BuildParserInterface::PatternType type,
-        const QString &description, const QString &file, int line);
-
-    int numberOfTasks() const;
-    int numberOfErrors() const;
-
     bool canFocus();
     bool hasFocus();
     void setFocus();
 
+    bool canNavigate();
     bool canNext();
     bool canPrevious();
     void goToNext();
     void goToPrev();
-    bool canNavigate();
 
 signals:
     void tasksChanged();
@@ -89,59 +114,20 @@ private slots:
     void setShowWarnings(bool);
 
 private:
+    void updateActions();
     int sizeHintForColumn(int column) const;
 
-    int m_errorCount;
-    int m_currentTask;
-
-    TaskModel *m_model;
-    TaskFilterModel *m_filter;
-    TaskView *m_listview;
-    TaskWindowContext *m_taskWindowContext;
+    Internal::TaskModel *m_model;
+    Internal::TaskFilterModel *m_filter;
+    Internal::TaskView *m_listview;
+    Internal::TaskWindowContext *m_taskWindowContext;
     QAction *m_copyAction;
     QToolButton *m_filterWarningsButton;
 };
 
-class TaskView : public QListView
-{
-public:
-    TaskView(QWidget *parent = 0);
-    ~TaskView();
-    void resizeEvent(QResizeEvent *e);
-    void keyPressEvent(QKeyEvent *e);
-};
-
-class TaskDelegate : public QStyledItemDelegate
-{
-    Q_OBJECT
-public:
-    TaskDelegate(QObject * parent = 0);
-    ~TaskDelegate();
-    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
-    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
-
-    // TaskView uses this method if the size of the taskview changes
-    void emitSizeHintChanged(const QModelIndex &index);
-
-public slots:
-    void currentChanged(const QModelIndex &current, const QModelIndex &previous);
-
-private:
-    void generateGradientPixmap(int width, int height, QColor color, bool selected) const;
-};
-
-class TaskWindowContext : public Core::IContext
-{
-public:
-    TaskWindowContext(QWidget *widget);
-    virtual QList<int> context() const;
-    virtual QWidget *widget();
-private:
-    QWidget *m_taskList;
-    QList<int> m_context;
-};
+bool operator==(const TaskWindow::Task &t1, const TaskWindow::Task &t2);
+uint qHash(const TaskWindow::Task &task);
 
-} //namespace Internal
 } //namespace ProjectExplorer
 
 #endif // TASKWINDOW_H