diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp
index debdb12263a03e1bd9d9fb78a45230837cdadc5a..4ae65b85a77cb927bc3e7be916a2cb47384cb78a 100644
--- a/src/plugins/projectexplorer/taskwindow.cpp
+++ b/src/plugins/projectexplorer/taskwindow.cpp
@@ -29,18 +29,17 @@
 
 #include "taskwindow.h"
 
+#include "itaskhandler.h"
+#include "projectexplorerconstants.h"
 #include "task.h"
 
 #include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/actionmanager/command.h>
 #include <coreplugin/coreconstants.h>
-#include <coreplugin/vcsmanager.h>
-#include <coreplugin/iversioncontrol.h>
-#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/icontext.h>
 #include <coreplugin/icore.h>
 #include <coreplugin/uniqueidmanager.h>
-#include <coreplugin/actionmanager/command.h>
-#include <texteditor/basetexteditor.h>
-#include <texteditor/itexteditor.h>
+#include <extensionsystem/pluginmanager.h>
 
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
@@ -485,8 +484,9 @@ public:
     Internal::TaskFilterModel *m_filter;
     Internal::TaskView *m_listview;
     Internal::TaskWindowContext *m_taskWindowContext;
-    QAction *m_copyAction;
-    QAction *m_vcsAnnotateAction;
+    QMenu *m_contextMenu;
+    QModelIndex m_contextMenuIndex;
+    ITaskHandler *m_defaultHandler;
     QToolButton *m_filterWarningsButton;
     QToolButton *m_categoriesButton;
     QMenu *m_categoriesMenu;
@@ -508,7 +508,7 @@ static QToolButton *createFilterButton(QIcon icon, const QString &toolTip,
 
 TaskWindow::TaskWindow() : d(new TaskWindowPrivate)
 {
-    Core::ICore *core = Core::ICore::instance();
+    d->m_defaultHandler = 0;
 
     d->m_model = new Internal::TaskModel;
     d->m_filter = new Internal::TaskFilterModel(d->m_model);
@@ -525,31 +525,24 @@ TaskWindow::TaskWindow() : d(new TaskWindowPrivate)
     d->m_listview->setAttribute(Qt::WA_MacShowFocusRect, false);
 
     d->m_taskWindowContext = new Internal::TaskWindowContext(d->m_listview);
-    core->addContextObject(d->m_taskWindowContext);
-
-    d->m_copyAction = new QAction(QIcon(Core::Constants::ICON_COPY), tr("&Copy"), this);
-    Core::Command *command = core->actionManager()->
-            registerAction(d->m_copyAction, Core::Constants::COPY, d->m_taskWindowContext->context());
-    d->m_listview->addAction(command->action());
-    connect(d->m_copyAction, SIGNAL(triggered()), SLOT(copy()));
-
-    // Annotate using VCS: Make visible in all contexts
-    d->m_vcsAnnotateAction = new QAction(tr("&Annotate"), this);
-    d->m_vcsAnnotateAction->setToolTip("Annotate using version control system");
-    QList<int> annotateContext = d->m_taskWindowContext->context();
-    annotateContext << Core::ICore::instance()->uniqueIDManager()->uniqueIdentifier(QLatin1String(Core::Constants::C_GLOBAL));
-    command = core->actionManager()->
-            registerAction(d->m_vcsAnnotateAction, QLatin1String("ProjectExplorer.Task.VCS_Annotate"), annotateContext);
-    d->m_listview->addAction(command->action());
-    connect(d->m_vcsAnnotateAction, SIGNAL(triggered()), SLOT(vcsAnnotate()));
+    Core::ICore::instance()->addContextObject(d->m_taskWindowContext);
 
     connect(d->m_listview->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
             tld, SLOT(currentChanged(QModelIndex,QModelIndex)));
 
     connect(d->m_listview, SIGNAL(activated(QModelIndex)),
-            this, SLOT(showTaskInFile(QModelIndex)));
+            this, SLOT(triggerDefaultHandler(QModelIndex)));
     connect(d->m_listview, SIGNAL(clicked(QModelIndex)),
-            this, SLOT(showTaskInFile(QModelIndex)));
+            this, SLOT(triggerDefaultHandler(QModelIndex)));
+
+    d->m_contextMenu = new QMenu(d->m_listview);
+    connect(d->m_contextMenu, SIGNAL(triggered(QAction*)),
+            this, SLOT(contextMenuEntryTriggered(QAction*)));
+
+    d->m_listview->setContextMenuPolicy(Qt::CustomContextMenu);
+
+    connect(d->m_listview, SIGNAL(customContextMenuRequested(QPoint)),
+            this, SLOT(showContextMenu(QPoint)));
 
     d->m_filterWarningsButton = createFilterButton(taskTypeIcon(Task::Warning),
                                                 tr("Show Warnings"),
@@ -568,13 +561,12 @@ TaskWindow::TaskWindow() : d(new TaskWindowPrivate)
 
     qRegisterMetaType<ProjectExplorer::Task>("ProjectExplorer::Task");
     qRegisterMetaType<QList<ProjectExplorer::Task> >("QList<ProjectExplorer::Task>");
-
-    updateActions();
 }
 
 TaskWindow::~TaskWindow()
 {
     Core::ICore::instance()->removeContextObject(d->m_taskWindowContext);
+    cleanContextMenu();
     delete d->m_filterWarningsButton;
     delete d->m_listview;
     delete d->m_filter;
@@ -596,7 +588,6 @@ void TaskWindow::clearTasks(const QString &categoryId)
 {
     d->m_model->clearTasks(categoryId);
 
-    updateActions();
     emit tasksChanged();
     navigateStateChanged();
 }
@@ -615,7 +606,6 @@ void TaskWindow::addTask(const Task &task)
 {
     d->m_model->addTask(task);
 
-    updateActions();
     emit tasksChanged();
     navigateStateChanged();
 }
@@ -624,65 +614,73 @@ void TaskWindow::removeTask(const Task &task)
 {
     d->m_model->removeTask(task);
 
-    updateActions();
     emit tasksChanged();
     navigateStateChanged();
 }
 
-void TaskWindow::showTaskInFile(const QModelIndex &index)
+void TaskWindow::triggerDefaultHandler(const QModelIndex &index)
 {
     if (!index.isValid())
         return;
-    QString file = index.data(Internal::TaskModel::File).toString();
-    int line = index.data(Internal::TaskModel::Line).toInt();
-    if (file.isEmpty() || line == -1)
-        return;
 
-    QFileInfo fi(file);
-    if (fi.exists()) {
-        TextEditor::BaseTextEditor::openEditorAt(fi.canonicalFilePath(), line);
-        Core::EditorManager::instance()->ensureEditorManagerVisible();
+    // Find a default handler to use:
+    if (!d->m_defaultHandler) {
+        QList<ITaskHandler *> handlers = ExtensionSystem::PluginManager::instance()->getObjects<ITaskHandler>();
+        foreach(ITaskHandler *handler, handlers) {
+            if (handler->id() == QLatin1String(Constants::SHOW_TASK_IN_EDITOR)) {
+                d->m_defaultHandler = handler;
+                break;
+            }
+        }
+    }
+    Q_ASSERT(d->m_defaultHandler);
+    Task task(index.data(Internal::TaskModel::Task_t).value<Task>());
+    if (d->m_defaultHandler->canHandle(task)) {
+        d->m_defaultHandler->handle(task);
+    } else {
+        if (!QFileInfo(task.file).exists())
+            d->m_model->setFileNotFound(index, true);
     }
-    else
-        d->m_model->setFileNotFound(index, true);
-    d->m_listview->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select);
-    d->m_listview->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect);
 }
 
-// Right-click VCS annotate: Find version control and point it to line
-void TaskWindow::vcsAnnotate()
+void TaskWindow::showContextMenu(const QPoint &position)
 {
-    const QModelIndex index = d->m_listview->selectionModel()->currentIndex();
+    QModelIndex index = d->m_listview->indexAt(position);
     if (!index.isValid())
         return;
-    const QString file = index.data(Internal::TaskModel::File).toString();
-    const int line = index.data(Internal::TaskModel::Line).toInt();
-    const QFileInfo fi(file);
-    if (fi.exists())
-        if (Core::IVersionControl *vc = Core::ICore::instance()->vcsManager()->findVersionControlForDirectory(fi.absolutePath()))
-            if (vc->supportsOperation(Core::IVersionControl::AnnotateOperation))
-                vc->vcsAnnotate(fi.absoluteFilePath(), line);
+    d->m_contextMenuIndex = index;
+    cleanContextMenu();
+
+    Task task = index.data(Internal::TaskModel::Task_t).value<Task>();
+
+    QList<ITaskHandler *> handlers = ExtensionSystem::PluginManager::instance()->getObjects<ITaskHandler>();
+    foreach(ITaskHandler *handler, handlers) {
+        if (handler == d->m_defaultHandler)
+            continue;
+        QAction * action = handler->createAction(d->m_contextMenu);
+        action->setEnabled(handler->canHandle(task));
+        action->setData(qVariantFromValue(qobject_cast<QObject*>(handler)));
+        d->m_contextMenu->addAction(action);
+    }
+    d->m_contextMenu->popup(d->m_listview->mapToGlobal(position));
 }
 
-void TaskWindow::copy()
+void TaskWindow::contextMenuEntryTriggered(QAction *action)
 {
-    const QModelIndex index = d->m_listview->selectionModel()->currentIndex();
-    if (!index.isValid())
-        return;
-    const QString file = index.data(Internal::TaskModel::File).toString();
-    const QString line = index.data(Internal::TaskModel::Line).toString();
-    const QString description = index.data(Internal::TaskModel::Description).toString();
-    QString type;
-    switch (index.data(Internal::TaskModel::Type).toInt()) {
-    case Task::Error:
-        type = "error: ";
-        break;
-    case Task::Warning:
-        type = "warning: ";
-        break;
+    if (action->isEnabled()) {
+        Task task = d->m_contextMenuIndex.data(Internal::TaskModel::Task_t).value<Task>();
+        ITaskHandler *handler = qobject_cast<ITaskHandler*>(action->data().value<QObject*>());
+        if (!handler)
+            return;
+        handler->handle(task);
     }
+}
 
-    QApplication::clipboard()->setText(file + ':' + line + ": " + type + description);
+void TaskWindow::cleanContextMenu()
+{
+    QList<QAction *> actions = d->m_contextMenu->actions();
+    qDeleteAll(actions);
+    d->m_contextMenu->clear();
 }
 
 void TaskWindow::setShowWarnings(bool show)
@@ -791,7 +789,7 @@ void TaskWindow::goToNext()
         currentIndex = d->m_filter->index(0, 0);
     }
     d->m_listview->setCurrentIndex(currentIndex);
-    showTaskInFile(currentIndex);
+    triggerDefaultHandler(currentIndex);
 }
 
 void TaskWindow::goToPrev()
@@ -808,7 +806,7 @@ void TaskWindow::goToPrev()
         currentIndex = d->m_filter->index(d->m_filter->rowCount()-1, 0);
     }
     d->m_listview->setCurrentIndex(currentIndex);
-    showTaskInFile(currentIndex);
+    triggerDefaultHandler(currentIndex);
 }
 
 bool TaskWindow::canNavigate()
@@ -816,11 +814,6 @@ bool TaskWindow::canNavigate()
     return true;
 }
 
-void TaskWindow::updateActions()
-{
-    d->m_copyAction->setEnabled(d->m_model->tasks().count() > 0);
-}
-
 QIcon TaskWindow::taskTypeIcon(int t) const
 {
     return d->m_model->taskTypeIcon(static_cast<Task::TaskType>(t));
diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h
index 8152d93b4f900096f081f7844354c10fdd1898c1..086dd0502b9b552520304911b7a044d4b91ee201 100644
--- a/src/plugins/projectexplorer/taskwindow.h
+++ b/src/plugins/projectexplorer/taskwindow.h
@@ -88,15 +88,15 @@ signals:
     void tasksChanged();
 
 private slots:
-    void showTaskInFile(const QModelIndex &index);
-    void copy();
-    void vcsAnnotate();
+    void triggerDefaultHandler(const QModelIndex &index);
+    void showContextMenu(const QPoint &position);
+    void contextMenuEntryTriggered(QAction *);
     void setShowWarnings(bool);
     void updateCategoriesMenu();
     void filterCategoryTriggered(QAction *action);
 
 private:
-    void updateActions();
+    void cleanContextMenu();
     int sizeHintForColumn(int column) const;
 
     TaskWindowPrivate *d;