diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp
index 5cd7ed519ce9210042b5fc4cffdf997d76fff0ec..6277c5477cda6ddea509e1bd34dfdd7c981f382f 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.cpp
+++ b/share/qtcreator/gdbmacros/gdbmacros.cpp
@@ -32,6 +32,9 @@
 // this relies on contents copied from qobject_p.h
 #define PRIVATE_OBJECT_ALLOWED 1
 
+#ifdef HAS_QOBJECT_P_H
+#    include <QtCore/private/qobject_p.h>
+#endif
 #include <QtCore/QDateTime>
 #include <QtCore/QDebug>
 #include <QtCore/QDir>
@@ -146,8 +149,7 @@ int qtGhVersion = QT_VERSION;
 #   define NSY ""
 #endif
 
-
-#if PRIVATE_OBJECT_ALLOWED
+#if PRIVATE_OBJECT_ALLOWED && !HAS_QOBJECT_P_H
 
 #if defined(QT_BEGIN_NAMESPACE)
 QT_BEGIN_NAMESPACE
@@ -1532,6 +1534,13 @@ static void qDumpQObject(QDumper &d)
     const QObject *ob = reinterpret_cast<const QObject *>(d.data);
     const QMetaObject *mo = ob->metaObject();
     unsigned childrenOffset = d.extraInt[0];
+#ifdef HAS_QOBJECT_P_H
+    // QObject child offset if known
+    if (!childrenOffset) {
+        QObjectPrivate qop;
+        childrenOffset = (char*)&qop.children - (char*)&qop;
+    }
+#endif
     P(d, "value", ob->objectName());
     P(d, "valueencoded", "2");
     P(d, "type", NS"QObject");
@@ -1588,7 +1597,8 @@ static void qDumpQObject(QDumper &d)
             P(d, "numchild", slotCount);
         d.endHash();
 #endif
-        d.beginHash();
+        if (childrenOffset) {
+            d.beginHash();
             P(d, "name", "children");
             // works always, but causes additional traffic on the list
             //P(d, "exp", "((class '"NS"QObject'*)" << d.data << ")->children()");
@@ -1597,9 +1607,10 @@ static void qDumpQObject(QDumper &d)
             //P(d, "type", NS"QList<QObject *>");
             //P(d, "value", "<" << children.size() << " items>");
             qDumpInnerValue(d, NS"QList<"NS"QObject *>",
-                addOffset(dfunc(ob), childrenOffset));
+                            addOffset(dfunc(ob), childrenOffset));
             P(d, "numchild", children.size());
-        d.endHash();
+            d.endHash();
+        }
 #if 0
         // Unneeded (and not working): Connections are listes as childen
         // of the signal or slot they are connected to.
diff --git a/share/qtcreator/gdbmacros/gdbmacros.pro b/share/qtcreator/gdbmacros/gdbmacros.pro
index 00c7b2403c86cb10f52722974615476d4774e784..5aacbfb84ad759718f92dddc19d227548bd063eb 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.pro
+++ b/share/qtcreator/gdbmacros/gdbmacros.pro
@@ -5,3 +5,7 @@ CONFIG -= release
 CONFIG += debug
 }
 SOURCES=gdbmacros.cpp
+
+exists($$QMAKE_INCDIR_QT/QtCore/private/qobject_p.h) {
+   DEFINES+=HAS_QOBJECT_P_H
+}
diff --git a/share/qtcreator/gdbmacros/test/dumpertest.pro b/share/qtcreator/gdbmacros/test/dumpertest.pro
new file mode 100644
index 0000000000000000000000000000000000000000..7b5fd3e582aacb2283b2679439b70968524b020e
--- /dev/null
+++ b/share/qtcreator/gdbmacros/test/dumpertest.pro
@@ -0,0 +1,21 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2009-05-05T11:16:25
+#
+#-------------------------------------------------
+
+QT       -= gui
+
+TARGET = dumpertest
+CONFIG   += console
+CONFIG   -= app_bundle
+
+TEMPLATE = app
+
+SOURCES += main.cpp \
+../gdbmacros.cpp
+
+exists($$QMAKE_INCDIR_QT/QtCore/private/qobject_p.h) {
+   DEFINES+=HAS_QOBJECT_P_H
+}
+
diff --git a/share/qtcreator/gdbmacros/test/main.cpp b/share/qtcreator/gdbmacros/test/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f760e40aa980b9329349d5cf47a5fb65bd2cec3a
--- /dev/null
+++ b/share/qtcreator/gdbmacros/test/main.cpp
@@ -0,0 +1,263 @@
+/**************************************************************************
+**
+** 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 <QtCore/QStringList>
+#include <QtCore/QVector>
+#include <QtCore/QTimer>
+#include <QtCore/private/qobject_p.h>
+
+#include <string>
+#include <list>
+#include <vector>
+
+#include <stdio.h>
+#include <string.h>
+
+
+/* Test program for Dumper development/porting.
+ * Takes the type as first argument. */
+
+// --------------- Dumper symbols
+extern char qDumpInBuffer[10000];
+extern char qDumpOutBuffer[100000];
+
+extern "C" void *qDumpObjectData440(
+    int protocolVersion,
+    int token,
+    void *data,
+#ifdef Q_CC_MSVC // CDB cannot handle boolean parameters
+    int dumpChildren,
+#else
+    bool dumpChildren,
+#endif
+    int extraInt0, int extraInt1, int extraInt2, int extraInt3);
+
+static void prepareInBuffer(const char *outerType,
+                            const char *iname,
+                            const char *expr,
+                            const char *innerType)
+{
+    // Leave trailing '\0'
+    char *ptr = qDumpInBuffer;
+    strcpy(ptr, outerType);
+    ptr += strlen(outerType);
+    ptr++;
+    strcpy(ptr, iname);
+    ptr += strlen(iname);
+    ptr++;
+    strcpy(ptr, expr);
+    ptr += strlen(expr);
+    ptr++;
+    strcpy(ptr, innerType);
+    ptr += strlen(innerType);
+    ptr++;
+    strcpy(ptr, iname);
+}
+
+// ---------------  Qt types
+static int dumpQString()
+{
+    QString test = QLatin1String("hallo");
+    prepareInBuffer("QString", "local.qstring", "local.qstring", "");
+    qDumpObjectData440(2, 42, &test, 1, 0, 0, 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+static int dumpQStringList()
+{
+    QStringList test = QStringList() << QLatin1String("item1") << QLatin1String("item2");
+    prepareInBuffer("QList", "local.qstringlist", "local.qstringlist", "QString");
+    qDumpObjectData440(2, 42, &test, 1, sizeof(QString), 0, 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+static int dumpQIntList()
+{
+    QList<int> test = QList<int>() << 1 << 2;
+    prepareInBuffer("QList", "local.qintlist", "local.qintlist", "int");
+    qDumpObjectData440(2, 42, &test, 1, sizeof(int), 0, 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+static int dumpQIntVector()
+{
+    QVector<int> test = QVector<int>() << 1 << 2;
+    prepareInBuffer("QVector", "local.qintvector", "local.qintvector", "int");
+    qDumpObjectData440(2, 42, &test, 1, sizeof(int), 0, 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+// ---------------  std types
+
+static int dumpStdString()
+{
+    std::string test = "hallo";
+    prepareInBuffer("std::string", "local.string", "local.string", "");
+    qDumpObjectData440(2, 42, &test, 1, 0, 0, 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+static int dumpStdWString()
+{
+    std::wstring test = L"hallo";
+    prepareInBuffer("std::wstring", "local.wstring", "local.wstring", "");
+    qDumpObjectData440(2, 42, &test, 1, 0, 0, 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+
+static int dumpStdStringList()
+{
+    std::list<std::string> test;
+    test.push_back("item1");
+    test.push_back("item2");
+    prepareInBuffer("std::list", "local.stringlist", "local.stringlist", "std::string");
+    qDumpObjectData440(2, 42, &test, 1, sizeof(std::string), sizeof(std::list<std::string>::allocator_type), 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+static int dumpStdStringQList()
+{
+    QList<std::string> test;
+    test.push_back("item1");
+    test.push_back("item2");
+    prepareInBuffer("QList", "local.stringqlist", "local.stringqlist", "std::string");
+    qDumpObjectData440(2, 42, &test, 1, sizeof(std::string), 0, 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+static int dumpStdIntList()
+{
+    std::list<int> test;
+    test.push_back(1);
+    test.push_back(2);
+    prepareInBuffer("std::list", "local.intlist", "local.intlist", "int");
+    qDumpObjectData440(2, 42, &test, 1, sizeof(int), sizeof(std::list<int>::allocator_type), 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+static int dumpStdIntVector()
+{
+    std::vector<int> test;
+    test.push_back(1);
+    test.push_back(2);
+    prepareInBuffer("std::vector", "local.intvector", "local.intvector", "int");
+    qDumpObjectData440(2, 42, &test, 1, sizeof(int), sizeof(std::list<int>::allocator_type), 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+static int dumpStdStringVector()
+{
+    std::vector<std::string> test;
+    test.push_back("item1");
+    test.push_back("item2");
+    prepareInBuffer("std::vector", "local.stringvector", "local.stringvector", "std::string");
+    qDumpObjectData440(2, 42, &test, 1, sizeof(std::string), sizeof(std::list<int>::allocator_type), 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+
+static int dumpQObject()
+{
+    QTimer t;
+    QObjectPrivate *tp = reinterpret_cast<QObjectPrivate *>(&t);
+#ifdef KNOWS_OFFSET
+    const int childOffset = (char*)&tp->children - (char*)tp;
+#else
+    const int childOffset = 0;
+#endif
+    printf("Qt version %s Child offset: %d\n", QT_VERSION_STR, childOffset);
+    prepareInBuffer("QObject", "local.qobject", "local.qobject", "");
+    qDumpObjectData440(2, 42, &t, 1, childOffset, 0, 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    printf("Running query protocol\n");
+    qDumpObjectData440(1, 42, 0, 1, 0, 0, 0, 0);
+    fputs(qDumpOutBuffer, stdout);
+    fputc('\n', stdout);
+    fputc('\n', stdout);
+    if (argc < 2)
+        return 0;
+    for (int i = 1; i < argc; i++) {
+        const char *arg = argv[i];
+        printf("\nTesting %s\n", arg);
+        if (!qstrcmp(arg, "QString"))
+            dumpQString();
+        if (!qstrcmp(arg, "QStringList"))
+            dumpQStringList();
+        if (!qstrcmp(arg, "QList<int>"))
+            dumpQIntList();
+        if (!qstrcmp(arg, "QList<std::string>"))
+            dumpStdStringQList();
+        if (!qstrcmp(arg, "QVector<int>"))
+            dumpQIntVector();
+        if (!qstrcmp(arg, "string"))
+            dumpStdString();
+        if (!qstrcmp(arg, "wstring"))
+            dumpStdWString();
+        if (!qstrcmp(arg, "list<int>"))
+            dumpStdIntList();
+        if (!qstrcmp(arg, "list<string>"))
+            dumpStdStringList();
+        if (!qstrcmp(arg, "vector<int>"))
+            dumpStdIntVector();
+        if (!qstrcmp(arg, "vector<string>"))
+            dumpStdStringVector();
+        if (!qstrcmp(arg, "QObject"))
+            dumpQObject();
+    }
+    return 0;
+}
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/coreplugin/actionmanager/command.cpp b/src/plugins/coreplugin/actionmanager/command.cpp
index aab4f0fbad4e3674737fe02a648c5ae3b27f3ae7..edd7b78190e2696aa347289ac6d5ab292ac8117a 100644
--- a/src/plugins/coreplugin/actionmanager/command.cpp
+++ b/src/plugins/coreplugin/actionmanager/command.cpp
@@ -49,12 +49,6 @@
     \enum Command::CommandAttribute
 */
 
-/*!
-    \fn void Command::setCategory(const QString &name)
-
-    Sets the category to \a name.
-*/
-
 /*!
     \fn virtual void Command::setDefaultKeySequence(const QKeySequence &key)
 */
@@ -118,18 +112,6 @@ int CommandPrivate::stateFlags() const
     return (m_type & CS_Mask);
 }
 
-void CommandPrivate::setCategory(const QString &name)
-{
-    m_category = name;
-}
-
-QString CommandPrivate::category() const
-{
-    if (m_category.isEmpty())
-        return tr("Other");
-    return m_category;
-}
-
 void CommandPrivate::setDefaultKeySequence(const QKeySequence &key)
 {
     m_defaultKey = key;
diff --git a/src/plugins/coreplugin/actionmanager/command.h b/src/plugins/coreplugin/actionmanager/command.h
index 534b58429bcd1877b44e8708fe3dd5cefe0929f0..792d39902611d1f9d15458d4812b39ec5462e890 100644
--- a/src/plugins/coreplugin/actionmanager/command.h
+++ b/src/plugins/coreplugin/actionmanager/command.h
@@ -63,8 +63,6 @@ public:
     virtual void setDefaultText(const QString &text) = 0;
     virtual QString defaultText() const = 0;
 
-    virtual void setCategory(const QString &name) = 0;
-
     virtual int id() const = 0;
     virtual CommandType type() const = 0;
 
diff --git a/src/plugins/coreplugin/actionmanager/command_p.h b/src/plugins/coreplugin/actionmanager/command_p.h
index 414060168785ffe9290256c14d2622f3dafd6e69..4bbf261c0732a41d69988c20155339d84e9cf558 100644
--- a/src/plugins/coreplugin/actionmanager/command_p.h
+++ b/src/plugins/coreplugin/actionmanager/command_p.h
@@ -60,9 +60,6 @@ public:
 
     virtual QString name() const = 0;
 
-    void setCategory(const QString &name);
-    QString category() const;
-
     void setDefaultKeySequence(const QKeySequence &key);
     QKeySequence defaultKeySequence() const;
 
diff --git a/src/plugins/debugger/commonoptionspage.ui b/src/plugins/debugger/commonoptionspage.ui
index 23ac787f49fb8f89a45ab77df6428d592ce579fd..8804fa8dbd309d632e87ef3d621208bbc72523b3 100644
--- a/src/plugins/debugger/commonoptionspage.ui
+++ b/src/plugins/debugger/commonoptionspage.ui
@@ -33,7 +33,7 @@
       <item>
        <widget class="QCheckBox" name="checkBoxUseAlternatingRowColors">
         <property name="text">
-         <string>Use alternating row colors in debug views.</string>
+         <string>Use alternating row colors in debug views</string>
         </property>
        </widget>
       </item>
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index 13b1679dc8e1a7344330759002322d131357709f..ee7c653f06efeaf33282e26a5db496a89fb3fdac 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -30,6 +30,7 @@
 #include "debuggermanager.h"
 
 #include "debuggeractions.h"
+#include "debuggerrunner.h"
 #include "debuggerconstants.h"
 #include "idebuggerengine.h"
 
@@ -172,7 +173,7 @@ void DebuggerManager::init()
     m_busy = false;
 
     m_attachedPID = 0;
-    m_startMode = StartInternal;
+    m_runControl = 0;
 
     m_disassemblerHandler = 0;
     m_modulesHandler = 0;
@@ -295,21 +296,6 @@ void DebuggerManager::init()
     connect(m_watchHandler, SIGNAL(watchModelUpdateRequested()),
         this, SLOT(updateWatchModel()));
 
-    m_startExternalAction = new QAction(this);
-    m_startExternalAction->setText(tr("Start and Debug External Application..."));
-
-    m_attachExternalAction = new QAction(this);
-    m_attachExternalAction->setText(tr("Attach to Running External Application..."));
-
-    m_attachCoreAction = new QAction(this);
-    m_attachCoreAction->setText(tr("Attach to Core..."));
-    connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore()));
-
-    m_attachRemoteAction = new QAction(this);
-    m_attachRemoteAction->setText(tr("Attach to Running Remote Application..."));
-    connect(m_attachRemoteAction, SIGNAL(triggered()),
-        this, SLOT(attachRemoteApplication()));
-
     m_continueAction = new QAction(this);
     m_continueAction->setText(tr("Continue"));
     m_continueAction->setIcon(QIcon(":/gdbdebugger/images/debugger_continue_small.png"));
@@ -371,11 +357,6 @@ void DebuggerManager::init()
     connect(m_continueAction, SIGNAL(triggered()),
         this, SLOT(continueExec()));
 
-    connect(m_startExternalAction, SIGNAL(triggered()),
-        this, SLOT(startExternalApplication()));
-    connect(m_attachExternalAction, SIGNAL(triggered()),
-        this, SLOT(attachExternalApplication()));
-
     connect(m_stopAction, SIGNAL(triggered()),
         this, SLOT(interruptDebuggingRequest()));
     connect(m_resetAction, SIGNAL(triggered()),
@@ -798,30 +779,6 @@ void DebuggerManager::setConfigValue(const QString &name, const QVariant &value)
     emit setConfigValueRequested(name, value);
 }
 
-void DebuggerManager::startExternalApplication()
-{
-    if (!startNewDebugger(StartExternal))
-        emit debuggingFinished();
-}
-
-void DebuggerManager::attachExternalApplication()
-{
-    if (!startNewDebugger(AttachExternal))
-        emit debuggingFinished();
-}
-
-void DebuggerManager::attachCore()
-{
-    if (!startNewDebugger(AttachCore))
-        emit debuggingFinished();
-}
-
-void DebuggerManager::attachRemoteApplication()
-{
-    if (!startNewDebugger(AttachRemote))
-        emit debuggingFinished();
-}
-
 // Figure out the debugger type of an executable
 static bool determineDebuggerType(const QString &executable,
                                   DebuggerManager::DebuggerType *dt,
@@ -869,12 +826,13 @@ static bool determineDebuggerType(int  /* pid */,
     return true;
 }
 
-bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
+void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl)
 {
+    m_runControl = runControl;
+
     if (Debugger::Constants::Internal::debug)
-        qDebug() << Q_FUNC_INFO << mode;
+        qDebug() << Q_FUNC_INFO << startMode();
 
-    m_startMode = mode;
     // FIXME: Clean up
 
     switch  (startMode()) {
@@ -884,8 +842,10 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
             configValue(_("LastExternalExecutableFile")).toString());
         dlg.setExecutableArguments(
             configValue(_("LastExternalExecutableArguments")).toString());
-        if (dlg.exec() != QDialog::Accepted)
-            return false;
+        if (dlg.exec() != QDialog::Accepted) {
+            runControl->debuggingFinished();
+            return;
+        }
         setConfigValue(_("LastExternalExecutableFile"),
             dlg.executableFile());
         setConfigValue(_("LastExternalExecutableArguments"),
@@ -898,8 +858,10 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
     }
     case AttachExternal: {
         AttachExternalDialog dlg(mainWindow());
-        if (dlg.exec() != QDialog::Accepted)
-            return false;
+        if (dlg.exec() != QDialog::Accepted) {
+            runControl->debuggingFinished();
+            return;
+        }
         m_executable = QString();
         m_processArgs = QStringList();
         m_workingDir = QString();
@@ -907,7 +869,8 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
         if (m_attachedPID == 0) {
             QMessageBox::warning(mainWindow(), tr("Warning"),
                 tr("Cannot attach to PID 0"));
-            return false;
+            runControl->debuggingFinished();
+            return;
         }
         break;
     }
@@ -924,8 +887,10 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
             }
             StartExternalDialog dlg(mainWindow());
             dlg.setExecutableFile(startDirectory);
-            if (dlg.exec() != QDialog::Accepted)
-                return false;
+            if (dlg.exec() != QDialog::Accepted) {
+                runControl->debuggingFinished();
+                return;
+            }
             m_executable = dlg.executableFile();
             m_processArgs = dlg.executableArguments().split(' ');
             m_workingDir = QString();
@@ -943,8 +908,10 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
             configValue(_("LastExternalExecutableFile")).toString());
         dlg.setCoreFile(
             configValue(_("LastExternalCoreFile")).toString());
-        if (dlg.exec() != QDialog::Accepted)
-            return false;
+        if (dlg.exec() != QDialog::Accepted) {
+            runControl->debuggingFinished();
+            return;
+        }
         setConfigValue(_("LastExternalExecutableFile"),
             dlg.executableFile());
         setConfigValue(_("LastExternalCoreFile"),
@@ -963,8 +930,10 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
         dlg.setRemoteArchitectures(arches);
         dlg.setRemoteChannel(configValue(_("LastRemoteChannel")).toString());
         dlg.setRemoteArchitecture(configValue(_("LastRemoteArchtecture")).toString());
-        if (dlg.exec() != QDialog::Accepted)
-            return false;
+        if (dlg.exec() != QDialog::Accepted) {  
+            runControl->debuggingFinished();
+            return;
+        }
         setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel());
         setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture());
         m_remoteChannel = dlg.remoteChannel();
@@ -983,8 +952,8 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
     if (!hasDebugger) {
         QMessageBox::warning(mainWindow(), tr("Warning"),
                 tr("Cannot debug '%1': %2").arg(m_executable, errorMessage));
-        return false;
-
+        debuggingFinished();
+        return;
     }
     if (Debugger::Constants::Internal::debug)
         qDebug() << m_executable << type;
@@ -994,10 +963,11 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
     setStatus(DebuggerProcessStartingUp);
     if (!m_engine->startDebugger()) {
         setStatus(DebuggerProcessNotReady);
-        return false;
+        debuggingFinished();
+        return;
     }
 
-    return true;
+    return;
 }
 
 void DebuggerManager::cleanupViews()
@@ -1257,20 +1227,21 @@ void DebuggerManager::setStatus(int status)
         || status == DebuggerInferiorStopRequested
         || status == DebuggerInferiorStopped;
 
-    const bool starting = status == DebuggerProcessStartingUp;
+    //const bool starting = status == DebuggerProcessStartingUp;
     const bool running = status == DebuggerInferiorRunning;
 
     const bool ready = status == DebuggerInferiorStopped
             && startMode() != AttachCore;
 
-    m_startExternalAction->setEnabled(!started && !starting);
-    m_attachExternalAction->setEnabled(!started && !starting);
-#ifdef Q_OS_WIN
-    m_attachCoreAction->setEnabled(false);
-#else
-    m_attachCoreAction->setEnabled(!started && !starting);
-#endif
-    m_attachRemoteAction->setEnabled(!started && !starting);
+// FIXME
+//    m_startExternalAction->setEnabled(!started && !starting);
+//    m_attachExternalAction->setEnabled(!started && !starting);
+//#ifdef Q_OS_WIN
+//    m_attachCoreAction->setEnabled(false);
+//#else
+//    m_attachCoreAction->setEnabled(!started && !starting);
+//#endif
+//    m_attachRemoteAction->setEnabled(!started && !starting);
     m_watchAction->setEnabled(ready);
     m_breakAction->setEnabled(true);
 
@@ -1570,6 +1541,12 @@ void DebuggerManager::showQtDumperLibraryWarning(const QString &details)
     }
 }
 
+DebuggerStartMode DebuggerManager::startMode() const
+{
+    return m_runControl->startMode();
+}
+
+
 //////////////////////////////////////////////////////////////////////
 //
 // Testing
@@ -1581,8 +1558,7 @@ void DebuggerManager::runTest(const QString &fileName)
     m_executable = fileName;
     m_processArgs = QStringList() << "--run-debuggee";
     m_workingDir = QString();
-    if (!startNewDebugger(StartInternal))
-        emit debuggingFinished();
+    //startNewDebugger(StartInternal);
 }
 
 #include "debuggermanager.moc"
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index f238b148ab7ae9d1623454d864fb0abb2c9526d0..ad92a003f3b839e3d184d33a40d09b721dd91064 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -56,6 +56,7 @@ namespace Debugger {
 namespace Internal {
 
 class DebuggerOutputWindow;
+class DebuggerRunControl;
 class DebuggerPlugin;
 class DebugMode;
 
@@ -204,7 +205,7 @@ public:
     enum DebuggerType { GdbDebugger, ScriptDebugger, WinDebugger };
 
 public slots:
-    bool startNewDebugger(DebuggerStartMode mode);
+    void startNewDebugger(DebuggerRunControl *runControl);
     void exitDebugger(); 
 
     void setSimpleDockWidgetArrangement();
@@ -223,10 +224,6 @@ public slots:
     void resetLocation();
 
     void interruptDebuggingRequest();
-    void startExternalApplication();
-    void attachExternalApplication();
-    void attachCore();
-    void attachRemoteApplication();
 
     void jumpToLineExec();
     void runToLineExec();
@@ -328,7 +325,8 @@ public:
     // one of the interfaces
     QAbstractItemModel *threadsModel();
     int status() const { return m_status; }
-    DebuggerStartMode startMode() const { return m_startMode; }
+    DebuggerStartMode startMode() const;
+    DebuggerRunControl *runControl() const { return m_runControl; }
 
     QList<Symbol> moduleSymbols(const QString &moduleName);
 
@@ -377,7 +375,7 @@ private:
     BreakpointData *findBreakpoint(const QString &fileName, int lineNumber);
     void setToolTipExpression(const QPoint &pos, const QString &exp0);
 
-    DebuggerStartMode m_startMode;
+    DebuggerRunControl *m_runControl;
     DebuggerType m_debuggerType;
 
     /// Views
@@ -405,10 +403,6 @@ private:
 
     /// Actions
     friend class DebuggerPlugin;
-    QAction *m_startExternalAction;
-    QAction *m_attachExternalAction;
-    QAction *m_attachCoreAction;
-    QAction *m_attachRemoteAction;
     QAction *m_continueAction;
     QAction *m_stopAction;
     QAction *m_resetAction; // FIXME: Should not be needed in a stable release
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 0809df5ccafef742ba3d397d6b9872c169d85e46..cbb8a160cabc400a272a5f0d2716a72345ceac30 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -463,31 +463,48 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
     //Core::ActionContainer *mcppcontext =
     //    am->actionContainer(CppEditor::Constants::M_CONTEXT);
 
+    // External apps
+    m_startExternalAction = new QAction(this);
+    m_startExternalAction->setText(tr("Start and Debug External Application..."));
+    connect(m_startExternalAction, SIGNAL(triggered()),
+        this, SLOT(startExternalApplication()));
+
+    m_attachExternalAction = new QAction(this);
+    m_attachExternalAction->setText(tr("Attach to Running External Application..."));
+    connect(m_attachExternalAction, SIGNAL(triggered()),
+        this, SLOT(attachExternalApplication()));
+
+    m_attachCoreAction = new QAction(this);
+    m_attachCoreAction->setText(tr("Attach to Core..."));
+    connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore()));
+
+    m_attachRemoteAction = new QAction(this);
+    m_attachRemoteAction->setText(tr("Attach to Running Remote Application..."));
+    connect(m_attachRemoteAction, SIGNAL(triggered()),
+        this, SLOT(attachRemoteApplication()));
+
+
     Core::ActionContainer *mdebug =
         am->actionContainer(ProjectExplorer::Constants::M_DEBUG);
 
     Core::Command *cmd = 0;
-    cmd = am->registerAction(m_manager->m_startExternalAction,
+    cmd = am->registerAction(m_startExternalAction,
         Constants::STARTEXTERNAL, globalcontext);
     mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
 
-    cmd = am->registerAction(m_manager->m_attachExternalAction,
+    cmd = am->registerAction(m_attachExternalAction,
         Constants::ATTACHEXTERNAL, globalcontext);
     mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
 
-    if (m_manager->m_attachCoreAction) {
-        cmd = am->registerAction(m_manager->m_attachCoreAction,
-                                 Constants::ATTACHCORE, globalcontext);
-        mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
-    }
+    cmd = am->registerAction(m_attachCoreAction,
+        Constants::ATTACHCORE, globalcontext);
+    mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
 
-    #if 0
+    #if 1
     // FIXME: not yet functional
-    if (m_manager->m_attachRemoteAction) {
-        cmd = am->registerAction(m_manager->m_attachRemoteAction,
-                                 Constants::ATTACHREMOTE, globalcontext);
-        mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
-    }
+    cmd = am->registerAction(m_attachRemoteAction,
+        Constants::ATTACHREMOTE, globalcontext);
+    mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
     #endif
 
     cmd = am->registerAction(m_manager->m_continueAction,
@@ -642,7 +659,9 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
     m_debugMode = new DebugMode(this);
     //addAutoReleasedObject(m_debugMode);
 
-    addAutoReleasedObject(new DebuggerRunner(m_manager));
+    // register factory of DebuggerRunControl
+    m_debuggerRunner = new DebuggerRunner(m_manager);
+    addAutoReleasedObject(m_debuggerRunner);
 
     QList<int> context;
     context.append(uidm->uniqueIdentifier(Core::Constants::C_EDITORMANAGER));
@@ -1036,6 +1055,48 @@ void DebuggerPlugin::showSettingsDialog()
         QLatin1String(Debugger::Constants::DEBUGGER_COMMON_SETTINGS_PAGE));
 }
 
+static QSharedPointer<RunConfiguration> activeRunConfiguration()
+{
+    ProjectExplorer::Project *project =
+        ProjectExplorerPlugin::instance()->currentProject();
+    if (project)
+        return project->activeRunConfiguration();
+    return QSharedPointer<RunConfiguration>();
+}
+
+void DebuggerPlugin::startExternalApplication()
+{
+    QSharedPointer<RunConfiguration> rc = activeRunConfiguration();
+    if (RunControl *runControl = m_debuggerRunner
+            ->run(rc, ProjectExplorer::Constants::DEBUGMODE, StartExternal))
+        runControl->start();
+}
+
+void DebuggerPlugin::attachExternalApplication()
+{
+    QSharedPointer<RunConfiguration> rc = activeRunConfiguration();
+    if (RunControl *runControl = m_debuggerRunner
+            ->run(rc, ProjectExplorer::Constants::DEBUGMODE, AttachExternal))
+        runControl->start();
+}
+
+void DebuggerPlugin::attachCore()
+{
+    QSharedPointer<RunConfiguration> rc = activeRunConfiguration();
+    if (RunControl *runControl = m_debuggerRunner
+            ->run(rc, ProjectExplorer::Constants::DEBUGMODE, AttachCore))
+        runControl->start();
+}
+
+void DebuggerPlugin::attachRemoteApplication()
+{
+    QSharedPointer<RunConfiguration> rc = activeRunConfiguration();
+    if (RunControl *runControl = m_debuggerRunner
+            ->run(rc, ProjectExplorer::Constants::DEBUGMODE, AttachRemote))
+        runControl->start();
+}
+
+
 #include "debuggerplugin.moc"
 
 Q_EXPORT_PLUGIN(DebuggerPlugin)
diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h
index 44a5f2e7711faea96aba22293998bf942b48859b..8990a64191738f3e1c29086604a68892ca3c37bc 100644
--- a/src/plugins/debugger/debuggerplugin.h
+++ b/src/plugins/debugger/debuggerplugin.h
@@ -56,6 +56,7 @@ namespace Internal {
 
 class BreakpointData;
 class DebuggerManager;
+class DebuggerRunner;
 class DebugMode;
 class LocationMark;
 
@@ -96,6 +97,11 @@ private slots:
     void focusCurrentEditor(Core::IMode *mode);
     void showSettingsDialog();
 
+    void startExternalApplication();
+    void attachExternalApplication();
+    void attachCore();
+    void attachRemoteApplication();
+
 private:
     void readSettings();
     void writeSettings() const;
@@ -107,12 +113,18 @@ private:
 
     DebuggerManager *m_manager;
     DebugMode *m_debugMode;
+    DebuggerRunner *m_debuggerRunner;
 
     QString m_previousMode;
     LocationMark *m_locationMark;
     int m_gdbRunningContext;
 
     QAction *m_toggleLockedAction;
+
+    QAction *m_startExternalAction;
+    QAction *m_attachExternalAction;
+    QAction *m_attachCoreAction;
+    QAction *m_attachRemoteAction;
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp
index 0153ef67531aa240036ace56dbe1f937e99f517f..8739091296c8c11c156652289a7ad9e46ea841f9 100644
--- a/src/plugins/debugger/debuggerrunner.cpp
+++ b/src/plugins/debugger/debuggerrunner.cpp
@@ -57,6 +57,7 @@ using ProjectExplorer::ApplicationRunConfiguration;
 //
 ////////////////////////////////////////////////////////////////////////
 
+// A factory to create DebuggerRunControls
 DebuggerRunner::DebuggerRunner(DebuggerManager *manager)
   : m_manager(manager)
 {}
@@ -72,14 +73,23 @@ QString DebuggerRunner::displayName() const
     return tr("Debug");
 }
 
-RunControl* DebuggerRunner::run(RunConfigurationPtr runConfiguration, const QString &mode)
+RunControl* DebuggerRunner::run(RunConfigurationPtr runConfiguration,
+    const QString &mode, DebuggerStartMode startMode)
 {
     QTC_ASSERT(mode == ProjectExplorer::Constants::DEBUGMODE, return 0);
     ApplicationRunConfigurationPtr rc =
         qSharedPointerCast<ApplicationRunConfiguration>(runConfiguration);
-    QTC_ASSERT(rc, return 0);
+    //QTC_ASSERT(rc, return 0);
     //qDebug() << "***** Debugging" << rc->name() << rc->executable();
-    return new DebuggerRunControl(m_manager, rc);
+    DebuggerRunControl *runControl = new DebuggerRunControl(m_manager, rc);
+    runControl->setStartMode(startMode);
+    return runControl;
+}
+
+RunControl* DebuggerRunner::run(RunConfigurationPtr runConfiguration,
+    const QString &mode)
+{
+    return run(runConfiguration, mode, StartInternal);
 }
 
 QWidget *DebuggerRunner::configurationWidget(RunConfigurationPtr runConfiguration)
@@ -120,24 +130,25 @@ void DebuggerRunControl::start()
     m_running = true;
     ApplicationRunConfigurationPtr rc =
         qSharedPointerCast<ApplicationRunConfiguration>(runConfiguration());
-    QTC_ASSERT(rc, return);
-    ProjectExplorer::Project *project = rc->project();
-    QTC_ASSERT(project, return);
-
-    m_manager->m_executable = rc->executable();
-    m_manager->m_environment = rc->environment().toStringList();
-    m_manager->m_workingDir = rc->workingDirectory();
-    m_manager->m_processArgs = rc->commandLineArguments();
-    m_manager->m_dumperLib = rc->dumperLibrary();
-    m_manager->m_buildDir =
-        project->buildDirectory(project->activeBuildConfiguration());
-    m_manager->m_useTerminal = rc->runMode() == ApplicationRunConfiguration::Console;
+    if (rc) {
+        m_manager->m_executable = rc->executable();
+        m_manager->m_environment = rc->environment().toStringList();
+        m_manager->m_workingDir = rc->workingDirectory();
+        m_manager->m_processArgs = rc->commandLineArguments();
+        m_manager->m_dumperLib = rc->dumperLibrary();
+        ProjectExplorer::Project *project = rc->project();
+        QTC_ASSERT(project, /**/);
+        if (project) {
+            m_manager->m_buildDir =
+                project->buildDirectory(project->activeBuildConfiguration());
+        }
+        m_manager->m_useTerminal = rc->runMode() == ApplicationRunConfiguration::Console;
+    }
 
     //emit addToOutputWindow(this, tr("Debugging %1").arg(m_executable));
-    if (m_manager->startNewDebugger(StartInternal))
-        emit started();
-    else
-        debuggingFinished();
+    m_manager->startNewDebugger(this);
+    emit started();
+    //debuggingFinished();
 }
 
 void DebuggerRunControl::slotAddToOutputWindowInline(const QString &data)
diff --git a/src/plugins/debugger/debuggerrunner.h b/src/plugins/debugger/debuggerrunner.h
index 437b2c27016be0359a21c4e0d98f196c25d49c0e..619498bba6ecc374c414eea12c9d7020c7d75367 100644
--- a/src/plugins/debugger/debuggerrunner.h
+++ b/src/plugins/debugger/debuggerrunner.h
@@ -30,6 +30,8 @@
 #ifndef DEBUGGERRUNNER_H
 #define DEBUGGERRUNNER_H
 
+#include "debuggermanager.h"
+
 #include <projectexplorer/runconfiguration.h>
 
 namespace ProjectExplorer {
@@ -55,17 +57,20 @@ class DebuggerRunner : public ProjectExplorer::IRunConfigurationRunner
 public:
     explicit DebuggerRunner(DebuggerManager *manager);
 
+    // ProjectExplorer::IRunConfigurationRunner
     virtual bool canRun(RunConfigurationPtr runConfiguration, const QString &mode);
     virtual QString displayName() const;
     virtual ProjectExplorer::RunControl *run(RunConfigurationPtr runConfiguration,
         const QString &mode);
     virtual QWidget *configurationWidget(RunConfigurationPtr runConfiguration);
 
+    virtual ProjectExplorer::RunControl *run(RunConfigurationPtr runConfiguration,
+        const QString &mode, DebuggerStartMode startMode);
 private:
     DebuggerManager *m_manager;
 };
 
-
+// This is a job description
 class DebuggerRunControl : public ProjectExplorer::RunControl
 {
     Q_OBJECT
@@ -74,20 +79,25 @@ public:
     DebuggerRunControl(DebuggerManager *manager,
         ApplicationRunConfigurationPtr runConfiguration);
 
+    // ProjectExplorer::RunControl
     virtual void start();
     virtual void stop();
     virtual bool isRunning() const;
 
+    void setStartMode(DebuggerStartMode mode) { m_mode = mode; }
+    DebuggerStartMode startMode() const { return m_mode; }
+    Q_SLOT void debuggingFinished();
+    
 signals:
     void stopRequested();
 
 private slots:
-    void debuggingFinished();
     void slotAddToOutputWindowInline(const QString &output);
 
 private:
     DebuggerManager *m_manager;
     bool m_running;
+    DebuggerStartMode m_mode;
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 6085b8c0dd3b415ca7649c3b68940205af964151..653a6817b62afeb6e8c7f00cdbfd0aaff141efdc 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -92,111 +92,20 @@ Q_DECLARE_METATYPE(Debugger::Internal::GdbMi);
 #define STRINGIFY_INTERNAL(x) #x
 #define STRINGIFY(x) STRINGIFY_INTERNAL(x)
 
-struct _c
-{
-    inline _c(char c) : m_c(c) {}
-    inline operator QChar() const { return QLatin1Char(m_c); }
-    char m_c;    
-};
+#define CB(callback) &GdbEngine::callback, STRINGIFY(callback)
 
-#define _c(c) QLatin1Char(c)
-#define __(s) QLatin1String(s)
-#define _(s) QString::fromLatin1(s)
+typedef QLatin1Char _c;
+typedef QLatin1String __;
+static inline QString _(const char *s) { return QString::fromLatin1(s); }
 
 static const QString tooltipIName = _("tooltip");
 
-///////////////////////////////////////////////////////////////////////
-//
-// GdbCommandType
-//
-///////////////////////////////////////////////////////////////////////
-
-enum GdbCommandType
-{
-    GdbInvalidCommand = 0,
-
-    GdbShowVersion = 100,
-    GdbFileExecAndSymbols,
-    //GdbQueryPwd,
-    GdbQuerySources,
-    GdbAsyncOutput2,
-    GdbStart,
-    GdbExit,
-    GdbAttached,
-    GdbStubAttached,
-    GdbExecRun,
-    GdbExecRunToFunction,
-    GdbExecStep,
-    GdbExecNext,
-    GdbExecStepI,
-    GdbExecNextI,
-    GdbExecContinue,
-    GdbExecFinish,
-    //GdbExecJumpToLine,
-    GdbExecInterrupt,
-    GdbInfoShared,
-    GdbInfoProc,
-    GdbInfoThreads,
-    GdbQueryDebuggingHelper,
-    GdbTemporaryContinue,
-    GdbTargetCore,
-
-    BreakCondition = 200,
-    BreakEnablePending,
-    BreakSetAnnotate,
-    BreakDelete,
-    BreakEnable,
-    BreakDisable,
-    BreakList,
-    BreakIgnore,
-    BreakInfo,
-    BreakInsert,
-    BreakInsert1,
-
-    DisassemblerList = 300,
-
-    ModulesList = 400,
-
-    RegisterListNames = 500,
-    RegisterListValues,
-
-    StackSelectThread = 600,
-    StackListThreads,
-    StackListFrames,
-    StackListLocals,
-    StackListArguments,
-
-    WatchVarAssign = 700,             // data changed by user
-    WatchVarListChildren,
-    WatchVarCreate,
-    WatchEvaluateExpression,
-    WatchToolTip,
-    WatchDebuggingHelperSetup,
-    WatchDebuggingHelperValue1,           // waiting for gdb ack
-    WatchDebuggingHelperValue2,           // waiting for actual data
-    WatchDebuggingHelperValue3,           // macro based
-    WatchDebuggingHelperEditValue,
-};
-
 static int &currentToken()
 {
     static int token = 0;
     return token;
 }
 
-static bool isSkippable(int type)
-{
-    return type == RegisterListValues
-        && type == StackListThreads
-        && type == StackListFrames
-        && type == StackListLocals
-        && type == StackListArguments
-        && type == WatchVarAssign
-        && type == WatchVarListChildren
-        && type == WatchVarCreate
-        && type == WatchEvaluateExpression
-        && type == WatchToolTip;
-}
 
 ///////////////////////////////////////////////////////////////////////
 //
@@ -352,7 +261,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
     static QTime lastTime;
 
     emit gdbOutputAvailable(_("            "), currentTime());
-    emit gdbOutputAvailable(_("stdout:"), QString::fromLocal8Bit(buff));
+    emit gdbOutputAvailable(_("stdout:"), QString::fromLocal8Bit(buff, buff.length()));
 
 #if 0
     qDebug() // << "#### start response handling #### "
@@ -510,8 +419,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
                 if (*inner < 'a' || *inner > 'z')
                     break;
 
-            QByteArray resultClass(from, inner - from);
-
+            QByteArray resultClass = QByteArray::fromRawData(from, inner - from);
             if (resultClass == "done")
                 record.resultClass = GdbResultDone;
             else if (resultClass == "running")
@@ -567,7 +475,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
     }
 }
 
-void GdbEngine::handleStubAttached()
+void GdbEngine::handleStubAttached(const GdbResultRecord &, const QVariant &)
 {
     qq->notifyInferiorStopped();
     m_waitingForBreakpointSynchronizationToContinue = true;
@@ -578,7 +486,7 @@ void GdbEngine::stubStarted()
 {
     q->m_attachedPID = m_stubProc.applicationPID();
     qq->notifyInferiorPidChanged(q->m_attachedPID);
-    sendCommand(_("attach ") + QString::number(q->m_attachedPID), GdbStubAttached);
+    execCommand(_("attach %1").arg(q->m_attachedPID), CB(handleStubAttached));
 }
 
 void GdbEngine::stubError(const QString &msg)
@@ -653,36 +561,38 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
     qq->notifyInferiorPidChanged(pid);
 }
 
-void GdbEngine::sendSynchronizedCommand(const QString & command,
-    int type, const QVariant &cookie, StopNeeded needStop)
+void GdbEngine::execCommand(const QString &command, GdbCommandCallback callback,
+                            const char *callbackName, const QVariant &cookie)
 {
-    sendCommand(command, type, cookie, needStop, Synchronized);
+    execCommand(command, NoFlags, callback, callbackName, cookie);
 }
 
-void GdbEngine::sendCommand(const QString &command, int type,
-    const QVariant &cookie, StopNeeded needStop, Synchronization synchronized)
+void GdbEngine::execCommand(const QString &command, GdbCommandFlags flags,
+                            GdbCommandCallback callback, const char *callbackName,
+                            const QVariant &cookie)
 {
     if (m_gdbProc.state() == QProcess::NotRunning) {
         debugMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: ") + command);
         return;
     }
 
-    if (synchronized) {
+    if (flags & RebuildModel) {
         ++m_pendingRequests;
-        PENDING_DEBUG("   TYPE " << type << " INCREMENTS PENDING TO: "
+        PENDING_DEBUG("   CALLBACK " << callbackName << " INCREMENTS PENDING TO: "
             << m_pendingRequests << command);
     } else {
-        PENDING_DEBUG("   UNKNOWN TYPE " << type << " LEAVES PENDING AT: "
+        PENDING_DEBUG("   UNKNOWN CALLBACK " << callbackName << " LEAVES PENDING AT: "
             << m_pendingRequests << command);
     }
 
-    GdbCookie cmd;
-    cmd.synchronized = synchronized;
+    GdbCommand cmd;
     cmd.command = command;
-    cmd.type = type;
+    cmd.flags = flags;
+    cmd.callback = callback;
+    cmd.callbackName = callbackName;
     cmd.cookie = cookie;
 
-    if (needStop && q->status() != DebuggerInferiorStopped
+    if ((flags & NeedsStop) && q->status() != DebuggerInferiorStopped
             && q->status() != DebuggerProcessStartingUp) {
         // queue the commands that we cannot send at once
         QTC_ASSERT(q->status() == DebuggerInferiorRunning,
@@ -692,19 +602,24 @@ void GdbEngine::sendCommand(const QString &command, int type,
         m_commandsToRunOnTemporaryBreak.append(cmd);
         interruptInferior();
     } else if (!command.isEmpty()) {
-        ++currentToken();
-        m_cookieForToken[currentToken()] = cmd;
-        cmd.command = QString::number(currentToken()) + cmd.command;
-        if (cmd.command.contains(__("%1")))
-            cmd.command = cmd.command.arg(currentToken());
-
-        m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
-        //emit gdbInputAvailable(QString(), "         " +  currentTime());
-        //emit gdbInputAvailable(QString(), "[" + currentTime() + "]    " + cmd.command);
-        emit gdbInputAvailable(QString(), cmd.command);
+        flushCommand(cmd);
     }
 }
 
+void GdbEngine::flushCommand(GdbCommand &cmd)
+{
+    ++currentToken();
+    m_cookieForToken[currentToken()] = cmd;
+    cmd.command = QString::number(currentToken()) + cmd.command;
+    if (cmd.command.contains(__("%1")))
+        cmd.command = cmd.command.arg(currentToken());
+
+    m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
+    //emit gdbInputAvailable(QString(), "         " +  currentTime());
+    //emit gdbInputAvailable(QString(), "[" + currentTime() + "]    " + cmd.command);
+    emit gdbInputAvailable(QString(), cmd.command);
+}
+
 void GdbEngine::handleResultRecord(const GdbResultRecord &record)
 {
     //qDebug() << "TOKEN: " << record.token
@@ -716,9 +631,9 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
     if (token == -1)
         return;
 
-    GdbCookie cmd = m_cookieForToken.take(token);
+    GdbCommand cmd = m_cookieForToken.take(token);
 
-    if (record.token < m_oldestAcceptableToken && isSkippable(cmd.type)) {
+    if (record.token < m_oldestAcceptableToken && (cmd.flags & Discardable)) {
         //qDebug() << "### SKIPPING OLD RESULT " << record.toString();
         //QMessageBox::information(m_mainWindow, tr("Skipped"), "xxx");
         return;
@@ -733,10 +648,10 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
 
     // << "\n data: " << record.data.toString(true);
 
-    if (cmd.type != GdbInvalidCommand)
-        handleResult(record, cmd.type, cmd.cookie);
+    if (cmd.callback)
+        (this->*(cmd.callback))(record, cmd.cookie);
 
-    if (cmd.synchronized) {
+    if (cmd.flags & RebuildModel) {
         --m_pendingRequests;
         PENDING_DEBUG("   TYPE " << cmd.type << " DECREMENTS PENDING TO: "
             << m_pendingRequests << cmd.command);
@@ -750,176 +665,6 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
     }
 }
 
-void GdbEngine::handleResult(const GdbResultRecord & record, int type,
-    const QVariant & cookie)
-{
-    switch (type) {
-        case GdbStubAttached:
-            handleStubAttached();
-            break;
-        case GdbExecNext:
-        case GdbExecStep:
-        case GdbExecNextI:
-        case GdbExecStepI:
-        case GdbExecContinue:
-        case GdbExecFinish:
-            // evil code sharing
-            handleExecRun(record);
-            break;
-
-        case GdbStart:
-            handleStart(record);
-            break;
-        case GdbAttached:
-            handleAttach();
-            break;
-        case GdbInfoProc:
-            handleInfoProc(record);
-            break;
-        case GdbInfoThreads:
-            handleInfoThreads(record);
-            break;
-        case GdbExit:
-            handleExit(record);
-            break;
-
-        case GdbShowVersion:
-            handleShowVersion(record);
-            break;
-        case GdbFileExecAndSymbols:
-            handleFileExecAndSymbols(record);
-            break;
-        case GdbExecRunToFunction:
-            // that should be "^running". We need to handle the resulting
-            // "Stopped"
-            //handleExecRunToFunction(record);
-            break;
-        case GdbExecInterrupt:
-            qq->notifyInferiorStopped();
-            break;
-#if 0
-        case GdbExecJumpToLine:
-            handleExecJumpToLine(record);
-            break;
-#endif
-#if 0
-        case GdbQueryPwd:
-            handleQueryPwd(record);
-            break;
-#endif
-        case GdbQuerySources:
-            handleQuerySources(record);
-            break;
-        case GdbAsyncOutput2:
-            handleAsyncOutput2(cookie.value<GdbMi>());
-            break;
-        case GdbInfoShared:
-            handleInfoShared(record);
-            break;
-        case GdbQueryDebuggingHelper:
-            handleQueryDebuggingHelper(record);
-            break;
-        case GdbTemporaryContinue:
-            continueInferior();
-            q->showStatusMessage(tr("Continuing after temporary stop."));
-            break;
-        case GdbTargetCore:
-            handleTargetCore(record);
-            break;
-
-        case BreakList:
-            handleBreakList(record);
-            break;
-        case BreakInsert:
-            handleBreakInsert(record, cookie.toInt());
-            break;
-        case BreakInsert1:
-            handleBreakInsert1(record, cookie.toInt());
-            break;
-        case BreakInfo:
-            handleBreakInfo(record, cookie.toInt());
-            break;
-        case BreakEnablePending:
-        case BreakDelete:
-        case BreakEnable:
-        case BreakDisable:
-            // nothing
-            break;
-        case BreakIgnore:
-            handleBreakIgnore(record, cookie.toInt());
-            break;
-        case BreakCondition:
-            handleBreakCondition(record, cookie.toInt());
-            break;
-
-        case DisassemblerList:
-            handleDisassemblerList(record, cookie.toString());
-            break;
-
-        case ModulesList:
-            handleModulesList(record);
-            break;
-
-        case RegisterListNames:
-            handleRegisterListNames(record);
-            break;
-        case RegisterListValues:
-            handleRegisterListValues(record);
-            break;
-
-        case StackListFrames:
-            handleStackListFrames(record, cookie.toBool());
-            break;
-        case StackListThreads:
-            handleStackListThreads(record, cookie.toInt());
-            break;
-        case StackSelectThread:
-            handleStackSelectThread(record, cookie.toInt());
-            break;
-        case StackListLocals:
-            handleStackListLocals(record);
-            break;
-        case StackListArguments:
-            handleStackListArguments(record);
-            break;
-
-        case WatchVarListChildren:
-            handleVarListChildren(record, cookie.value<WatchData>());
-            break;
-        case WatchVarCreate:
-            handleVarCreate(record, cookie.value<WatchData>());
-            break;
-        case WatchVarAssign:
-            handleVarAssign();
-            break;
-        case WatchEvaluateExpression:
-            handleEvaluateExpression(record, cookie.value<WatchData>());
-            break;
-        case WatchToolTip:
-            handleToolTip(record, cookie.toByteArray());
-            break;
-        case WatchDebuggingHelperValue1:
-            handleDebuggingHelperValue1(record, cookie.value<WatchData>());
-            break;
-        case WatchDebuggingHelperValue2:
-            handleDebuggingHelperValue2(record, cookie.value<WatchData>());
-            break;
-
-        case WatchDebuggingHelperValue3:
-            handleDebuggingHelperValue3(record, cookie.value<WatchData>());
-            break;
-
-        case WatchDebuggingHelperSetup:
-            handleDebuggingHelperSetup(record);
-            break;
-
-        default:
-            debugMessage(_("FIXME: GdbEngine::handleResult: "
-                "should not happen %1").arg(type));
-            break;
-    }
-}
-
 void GdbEngine::executeDebuggerCommand(const QString &command)
 {
     if (m_gdbProc.state() == QProcess::NotRunning) {
@@ -927,17 +672,11 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
         return;
     }
 
-    GdbCookie cmd;
-    cmd.command = command;
-    cmd.type = -1;
-
-    m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
+    m_gdbProc.write(command.toLocal8Bit() + "\r\n");
 }
 
-void GdbEngine::handleTargetCore(const GdbResultRecord &record)
+void GdbEngine::handleTargetCore(const GdbResultRecord &, const QVariant &)
 {
-    Q_UNUSED(record);
-
     qq->notifyInferiorStopped();
     q->showStatusMessage(tr("Core file loaded."));
 
@@ -951,7 +690,7 @@ void GdbEngine::handleTargetCore(const GdbResultRecord &record)
 
     reloadStack();
     if (supportsThreads())
-        sendSynchronizedCommand(_("-thread-list-ids"), StackListThreads, 0);
+        execCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), 0);
 
     //
     // Disassembler
@@ -966,7 +705,7 @@ void GdbEngine::handleTargetCore(const GdbResultRecord &record)
     qq->reloadRegisters();
 
     // Gdb-Macro based DebuggingHelpers
-    sendCommand(_(
+    execCommand(_(
         "define qdumpqstring\n"
         "set $i = 0\n"
         "set $l = $arg0->d->size\n"
@@ -978,7 +717,7 @@ void GdbEngine::handleTargetCore(const GdbResultRecord &record)
         "end\n"
     ));
 
-    sendCommand(_(
+    execCommand(_(
         "define qdumpqstringlist\n"
         "set $i = $arg0->d->begin\n"
         "set $e = $arg0->d->end\n"
@@ -1019,7 +758,7 @@ void GdbEngine::handleQueryPwd(const GdbResultRecord &record)
 }
 #endif
 
-void GdbEngine::handleQuerySources(const GdbResultRecord &record)
+void GdbEngine::handleQuerySources(const GdbResultRecord &record, const QVariant &)
 {
     if (record.resultClass == GdbResultDone) {
         QMap<QString, QString> oldShortToFull = m_shortToFullName;
@@ -1046,7 +785,7 @@ void GdbEngine::handleQuerySources(const GdbResultRecord &record)
     }
 }
 
-void GdbEngine::handleInfoThreads(const GdbResultRecord &record)
+void GdbEngine::handleInfoThreads(const GdbResultRecord &record, const QVariant &)
 {
     if (record.resultClass == GdbResultDone) {
         // FIXME: use something more robust
@@ -1059,12 +798,12 @@ void GdbEngine::handleInfoThreads(const GdbResultRecord &record)
     }
 }
 
-void GdbEngine::handleInfoProc(const GdbResultRecord &record)
+void GdbEngine::handleInfoProc(const GdbResultRecord &record, const QVariant &)
 {
     if (record.resultClass == GdbResultDone) {
         #if defined(Q_OS_MAC)
         //^done,process-id="85075"
-        maybeHandleInferiorPidChanged(QString::fromLatin1(record.data.findChild("process-id").data()));
+        maybeHandleInferiorPidChanged(_(record.data.findChild("process-id").data()));
         #endif
 
         #if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
@@ -1077,11 +816,11 @@ void GdbEngine::handleInfoProc(const GdbResultRecord &record)
     }
 }
 
-void GdbEngine::handleInfoShared(const GdbResultRecord &record)
+void GdbEngine::handleInfoShared(const GdbResultRecord &record, const QVariant &cookie)
 {
     if (record.resultClass == GdbResultDone) {
         // let the modules handler do the parsing
-        handleModulesList(record);
+        handleModulesList(record, cookie);
     }
 }
 
@@ -1112,7 +851,7 @@ void GdbEngine::handleExecJumpToLine(const GdbResultRecord &record)
 }
 #endif
 
-void GdbEngine::handleExecRunToFunction(const GdbResultRecord &record)
+void GdbEngine::handleExecRunToFunction(const GdbResultRecord &record, const QVariant &)
 {
     // FIXME: remove this special case as soon as there's a real
     // reason given when the temporary breakpoint is hit.
@@ -1156,13 +895,13 @@ static bool isStoppedReason(const QByteArray &reason)
 void GdbEngine::handleAqcuiredInferior()
 {
     #if defined(Q_OS_WIN)
-    sendCommand(_("info thread"), GdbInfoThreads);
+    execCommand(_("info thread"), CB(handleInfoThreads));
     #endif
     #if defined(Q_OS_LINUX)
-    sendCommand(_("info proc"), GdbInfoProc);
+    execCommand(_("info proc"), CB(handleInfoProc));
     #endif
     #if defined(Q_OS_MAC)
-    sendCommand(_("info pid"), GdbInfoProc, QVariant(), NeedsStop);
+    execCommand(_("info pid"), NeedsStop, CB(handleInfoProc));
     #endif
     if (theDebuggerBoolSetting(ListSourceFiles))
         reloadSourceFiles();
@@ -1172,18 +911,18 @@ void GdbEngine::handleAqcuiredInferior()
     // intentionally after tryLoadDebuggingHelpers(),
     // otherwise we'd interupt solib loading.
     if (theDebuggerBoolSetting(AllPluginBreakpoints)) {
-        sendCommand(_("set auto-solib-add on"));
-        sendCommand(_("set stop-on-solib-events 0"));
-        sendCommand(_("sharedlibrary .*"));
+        execCommand(_("set auto-solib-add on"));
+        execCommand(_("set stop-on-solib-events 0"));
+        execCommand(_("sharedlibrary .*"));
     } else if (theDebuggerBoolSetting(SelectedPluginBreakpoints)) {
-        sendCommand(_("set auto-solib-add on"));
-        sendCommand(_("set stop-on-solib-events 1"));
-        sendCommand(_("sharedlibrary ")
+        execCommand(_("set auto-solib-add on"));
+        execCommand(_("set stop-on-solib-events 1"));
+        execCommand(_("sharedlibrary ")
           + theDebuggerStringSetting(SelectedPluginBreakpointsPattern));
     } else if (theDebuggerBoolSetting(NoPluginBreakpoints)) {
         // should be like that already
-        sendCommand(_("set auto-solib-add off"));
-        sendCommand(_("set stop-on-solib-events 0"));
+        execCommand(_("set auto-solib-add off"));
+        execCommand(_("set stop-on-solib-events 0"));
     }
     #endif
 
@@ -1192,6 +931,12 @@ void GdbEngine::handleAqcuiredInferior()
     attemptBreakpointSynchronization();
 }
 
+void GdbEngine::handleAutoContinue(const GdbResultRecord &, const QVariant &)
+{
+    continueInferior();
+    q->showStatusMessage(tr("Continuing after temporary stop."));
+}
+
 void GdbEngine::handleAsyncOutput(const GdbMi &data)
 {
     const QByteArray &reason = data.findChild("reason").data();
@@ -1209,7 +954,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
             msg = tr("Program exited normally");
         }
         q->showStatusMessage(msg);
-        sendCommand(_("-gdb-exit"), GdbExit);
+        execCommand(_("-gdb-exit"), CB(handleExit));
         return;
     }
 
@@ -1238,13 +983,13 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
         qq->notifyInferiorStopped();
         q->showStatusMessage(tr("Temporarily stopped."));
         // FIXME: racy
-        foreach (const GdbCookie &cmd, m_commandsToRunOnTemporaryBreak) {
+        while (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
+            GdbCommand cmd = m_commandsToRunOnTemporaryBreak.takeFirst();
             debugMessage(_("RUNNING QUEUED COMMAND %1 %2")
-                .arg(cmd.command).arg(cmd.type));
-            sendCommand(cmd.command, cmd.type, cmd.cookie);
+                .arg(cmd.command).arg(_(cmd.callbackName)));
+            flushCommand(cmd);
         }
-        sendCommand(_("p temporaryStop"), GdbTemporaryContinue);
-        m_commandsToRunOnTemporaryBreak.clear();
+        execCommand(_("p temporaryStop"), CB(handleAutoContinue));
         q->showStatusMessage(tr("Handling queued commands."));
         return;
     }
@@ -1256,7 +1001,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
             debugMessage(_("SHARED LIBRARY EVENT: ") + dataStr);
             QString pat = theDebuggerStringSetting(SelectedPluginBreakpointsPattern);
             debugMessage(_("PATTERN: ") + pat);
-            sendCommand(_("sharedlibrary ") + pat);
+            execCommand(_("sharedlibrary ") + pat);
             continueInferior();
             q->showStatusMessage(tr("Loading %1...").arg(dataStr));
             return;
@@ -1324,9 +1069,9 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
             QApplication::alert(q->mainWindow(), 3000);
             if (theDebuggerAction(ListSourceFiles)->value().toBool())
                 reloadSourceFiles();
-            sendCommand(_("-break-list"), BreakList);
+            execCommand(_("-break-list"), CB(handleBreakList));
             QVariant var = QVariant::fromValue<GdbMi>(data);
-            sendCommand(_("p 0"), GdbAsyncOutput2, var);  // dummy
+            execCommand(_("p 0"), CB(handleAsyncOutput2), var);  // dummy
         } else {
 #ifdef Q_OS_LINUX
             // For some reason, attaching to a stopped process causes *two* stops
@@ -1337,7 +1082,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
                 GdbMi frameData = data.findChild("frame");
                 if (frameData.findChild("func").data() == "_start"
                     && frameData.findChild("from").data() == "/lib/ld-linux.so.2") {
-                    sendCommand(_("-exec-continue"));
+                    execCommand(_("-exec-continue"));
                     return;
                 }
             }
@@ -1377,7 +1122,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
 void GdbEngine::reloadFullStack()
 {
     QString cmd = _("-stack-list-frames");
-    sendSynchronizedCommand(cmd, StackListFrames, true);
+    execCommand(cmd, WatchUpdate, CB(handleStackListFrames), true);
 }
 
 void GdbEngine::reloadStack()
@@ -1385,7 +1130,12 @@ void GdbEngine::reloadStack()
     QString cmd = _("-stack-list-frames");
     if (int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt())
         cmd += _(" 0 ") + QString::number(stackDepth);
-    sendSynchronizedCommand(cmd, StackListFrames, false);
+    execCommand(cmd, WatchUpdate, CB(handleStackListFrames), false);
+}
+
+void GdbEngine::handleAsyncOutput2(const GdbResultRecord &, const QVariant &cookie)
+{
+    handleAsyncOutput2(cookie.value<GdbMi>());
 }
 
 void GdbEngine::handleAsyncOutput2(const GdbMi &data)
@@ -1401,7 +1151,7 @@ void GdbEngine::handleAsyncOutput2(const GdbMi &data)
     int currentId = data.findChild("thread-id").data().toInt();
     reloadStack();
     if (supportsThreads())
-        sendSynchronizedCommand(_("-thread-list-ids"), StackListThreads, currentId);
+        execCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), currentId);
 
     //
     // Disassembler
@@ -1421,7 +1171,7 @@ void GdbEngine::handleAsyncOutput2(const GdbMi &data)
     qq->reloadRegisters();
 }
 
-void GdbEngine::handleShowVersion(const GdbResultRecord &response)
+void GdbEngine::handleShowVersion(const GdbResultRecord &response, const QVariant &)
 {
     //qDebug () << "VERSION 2:" << response.data.findChild("consolestreamoutput").data();
     //qDebug () << "VERSION:" << response.toString();
@@ -1460,8 +1210,7 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response)
     }
 }
 
-void GdbEngine::handleFileExecAndSymbols
-    (const GdbResultRecord &response)
+void GdbEngine::handleFileExecAndSymbols(const GdbResultRecord &response, const QVariant &)
 {
     if (response.resultClass == GdbResultDone) {
         //m_breakHandler->clearBreakMarkers();
@@ -1474,7 +1223,7 @@ void GdbEngine::handleFileExecAndSymbols
     }
 }
 
-void GdbEngine::handleExecRun(const GdbResultRecord &response)
+void GdbEngine::handleExecRun(const GdbResultRecord &response, const QVariant &)
 {
     if (response.resultClass == GdbResultRunning) {
         qq->notifyInferiorRunning();
@@ -1564,11 +1313,11 @@ void GdbEngine::exitDebugger()
                 qDebug() << "STATUS ON EXITDEBUGGER: " << q->status());
             interruptInferior();
         }
-        if (q->startMode() == AttachExternal)
-            sendCommand(_("detach"));
+        if (q->startMode() == AttachExternal || q->startMode() == AttachRemote)
+            execCommand(_("detach"));
         else
-            sendCommand(_("kill"));
-        sendCommand(_("-gdb-exit"), GdbExit);
+            execCommand(_("kill"));
+        execCommand(_("-gdb-exit"), CB(handleExit));
         // 20s can easily happen when loading webkit debug information
         m_gdbProc.waitForFinished(20000);
         if (m_gdbProc.state() != QProcess::Running) {
@@ -1657,25 +1406,25 @@ bool GdbEngine::startDebugger()
 
     q->showStatusMessage(tr("Gdb Running..."));
 
-    sendCommand(_("show version"), GdbShowVersion);
-    //sendCommand(_("-enable-timings");
-    sendCommand(_("set print static-members off")); // Seemingly doesn't work.
-    //sendCommand(_("define hook-stop\n-thread-list-ids\n-stack-list-frames\nend"));
-    //sendCommand(_("define hook-stop\nprint 4\nend"));
-    //sendCommand(_("define hookpost-stop\nprint 5\nend"));
-    //sendCommand(_("define hook-call\nprint 6\nend"));
-    //sendCommand(_("define hookpost-call\nprint 7\nend"));
-    //sendCommand(_("set print object on")); // works with CLI, but not MI
-    //sendCommand(_("set step-mode on"));  // we can't work with that yes
-    //sendCommand(_("set exec-done-display on"));
-    //sendCommand(_("set print pretty on"));
-    //sendCommand(_("set confirm off"));
-    //sendCommand(_("set pagination off"));
-    sendCommand(_("set breakpoint pending on"), BreakEnablePending);
-    sendCommand(_("set print elements 10000"));
-    sendCommand(_("-data-list-register-names"), RegisterListNames);
-
-    //sendCommand(_("set substitute-path /var/tmp/qt-x11-src-4.5.0 "
+    execCommand(_("show version"), CB(handleShowVersion));
+    //execCommand(_("-enable-timings");
+    execCommand(_("set print static-members off")); // Seemingly doesn't work.
+    //execCommand(_("define hook-stop\n-thread-list-ids\n-stack-list-frames\nend"));
+    //execCommand(_("define hook-stop\nprint 4\nend"));
+    //execCommand(_("define hookpost-stop\nprint 5\nend"));
+    //execCommand(_("define hook-call\nprint 6\nend"));
+    //execCommand(_("define hookpost-call\nprint 7\nend"));
+    //execCommand(_("set print object on")); // works with CLI, but not MI
+    //execCommand(_("set step-mode on"));  // we can't work with that yes
+    //execCommand(_("set exec-done-display on"));
+    //execCommand(_("set print pretty on"));
+    //execCommand(_("set confirm off"));
+    //execCommand(_("set pagination off"));
+    execCommand(_("set breakpoint pending on"));
+    execCommand(_("set print elements 10000"));
+    execCommand(_("-data-list-register-names"), CB(handleRegisterListNames));
+
+    //execCommand(_("set substitute-path /var/tmp/qt-x11-src-4.5.0 "
     //    "/home/sandbox/qtsdk-2009.01/qt"));
 
     // one of the following is needed to prevent crashes in gdb on code like:
@@ -1683,8 +1432,8 @@ bool GdbEngine::startDebugger()
     //  int main() { return foo<int>(); }
     //  (gdb) call 'int foo<int>'()
     //  /build/buildd/gdb-6.8/gdb/valops.c:2069: internal-error:
-    sendCommand(_("set overload-resolution off"));
-    //sendCommand(_("set demangle-style none"));
+    execCommand(_("set overload-resolution off"));
+    //execCommand(_("set demangle-style none"));
 
     // From the docs:
     //  Stop means reenter debugger if this signal happens (implies print).
@@ -1695,19 +1444,19 @@ bool GdbEngine::startDebugger()
     // We need "print" as otherwise we would get no feedback whatsoever
     // Custom DebuggingHelper crashs which happen regularily for when accessing
     // uninitialized variables.
-    sendCommand(_("handle SIGSEGV nopass stop print"));
+    execCommand(_("handle SIGSEGV nopass stop print"));
 
     // This is useful to kill the inferior whenever gdb dies.
-    //sendCommand(_("handle SIGTERM pass nostop print"));
+    //execCommand(_("handle SIGTERM pass nostop print"));
 
-    sendCommand(_("set unwindonsignal on"));
-    //sendCommand(_("pwd", GdbQueryPwd));
-    sendCommand(_("set width 0"));
-    sendCommand(_("set height 0"));
+    execCommand(_("set unwindonsignal on"));
+    //execCommand(_("pwd", handleQueryPwd));
+    execCommand(_("set width 0"));
+    execCommand(_("set height 0"));
 
     #ifdef Q_OS_MAC
-    sendCommand(_("-gdb-set inferior-auto-start-cfm off"));
-    sendCommand(_("-gdb-set sharedLibrary load-rules "
+    execCommand(_("-gdb-set inferior-auto-start-cfm off"));
+    execCommand(_("-gdb-set sharedLibrary load-rules "
             "dyld \".*libSystem.*\" all "
             "dyld \".*libauto.*\" all "
             "dyld \".*AppKit.*\" all "
@@ -1722,7 +1471,7 @@ bool GdbEngine::startDebugger()
     if (!scriptFileName.isEmpty()) {
         QFile scriptFile(scriptFileName);
         if (scriptFile.open(QIODevice::ReadOnly)) {
-            sendCommand(_("source ") + scriptFileName);
+            execCommand(_("source ") + scriptFileName);
         } else {
             QMessageBox::warning(q->mainWindow(),
             tr("Cannot find debugger initialization script"),
@@ -1734,7 +1483,7 @@ bool GdbEngine::startDebugger()
     }
 
     if (q->startMode() == AttachExternal) {
-        sendCommand(_("attach ") + QString::number(q->m_attachedPID), GdbAttached);
+        execCommand(_("attach %1").arg(q->m_attachedPID), CB(handleAttach));
         qq->breakHandler()->removeAllBreakpoints();
     } else if (q->startMode() == AttachCore) {
         QFileInfo fi(q->m_executable);
@@ -1742,37 +1491,39 @@ bool GdbEngine::startDebugger()
         QFileInfo fi2(q->m_coreFile);
         // quoting core name below fails in gdb 6.8-debian
         QString coreName = fi2.absoluteFilePath();
-        sendCommand(_("-file-exec-and-symbols ") + fileName);
-        sendCommand(_("target core %1").arg(coreName), GdbTargetCore);
+        execCommand(_("-file-exec-and-symbols ") + fileName);
+        execCommand(_("target core ") + coreName, CB(handleTargetCore));
         qq->breakHandler()->removeAllBreakpoints();
     } else if (q->startMode() == AttachRemote) {
-        sendCommand(_("set architecture %1").arg(q->m_remoteArchitecture));
-        sendCommand(_("target remote %1").arg(q->m_remoteChannel));
+        execCommand(_("set architecture %1").arg(q->m_remoteArchitecture));
         qq->breakHandler()->setAllPending();
-        //sendCommand(_("info target"), GdbStart);
-        qq->notifyInferiorRunningRequested();
-        sendCommand(_("-exec-continue"), GdbExecContinue);
+        //QFileInfo fi(q->m_executable);
+        //QString fileName = fi.absoluteFileName();
+        QString fileName = q->m_executable;
+        execCommand(_("-file-exec-and-symbols \"%1\"").arg(fileName));
+        // works only for > 6.8
+        execCommand(_("set target-async on"), CB(handleTargetAsync));
     } else if (q->m_useTerminal) {
         qq->breakHandler()->setAllPending();
     } else if (q->startMode() == StartInternal || q->startMode() == StartExternal) {
         QFileInfo fi(q->m_executable);
         QString fileName = _c('"') + fi.absoluteFilePath() + _c('"');
-        sendCommand(_("-file-exec-and-symbols ") + fileName, GdbFileExecAndSymbols);
-        //sendCommand(_("file ") + fileName, GdbFileExecAndSymbols);
+        execCommand(_("-file-exec-and-symbols ") + fileName, CB(handleFileExecAndSymbols));
+        //execCommand(_("file ") + fileName, handleFileExecAndSymbols);
         #ifdef Q_OS_MAC
-        sendCommand(_("sharedlibrary apply-load-rules all"));
+        execCommand(_("sharedlibrary apply-load-rules all"));
         #endif
         if (!q->m_processArgs.isEmpty())
-            sendCommand(_("-exec-arguments ") + q->m_processArgs.join(_(" ")));
+            execCommand(_("-exec-arguments ") + q->m_processArgs.join(_(" ")));
         #ifndef Q_OS_MAC
-        sendCommand(_("set auto-solib-add off"));
-        sendCommand(_("info target"), GdbStart);
+        execCommand(_("set auto-solib-add off"));
+        execCommand(_("info target"), CB(handleStart));
         #else
         // On MacOS, breaking in at the entry point wreaks havoc.
-        sendCommand(_("tbreak main"));
+        execCommand(_("tbreak main"));
         m_waitingForFirstBreakpointToBeHit = true;
         qq->notifyInferiorRunningRequested();
-        sendCommand(_("-exec-run"));
+        execCommand(_("-exec-run"));
         #endif
         qq->breakHandler()->setAllPending();
     }
@@ -1785,10 +1536,10 @@ void GdbEngine::continueInferior()
     q->resetLocation();
     setTokenBarrier();
     qq->notifyInferiorRunningRequested();
-    sendCommand(_("-exec-continue"), GdbExecContinue);
+    execCommand(_("-exec-continue"), CB(handleExecRun));
 }
 
-void GdbEngine::handleStart(const GdbResultRecord &response)
+void GdbEngine::handleStart(const GdbResultRecord &response, const QVariant &)
 {
 #ifdef Q_OS_MAC
     Q_UNUSED(response);
@@ -1801,10 +1552,10 @@ void GdbEngine::handleStart(const GdbResultRecord &response)
         QRegExp needle(_("\\bEntry point: (0x[0-9a-f]+)\\b"));
         if (needle.indexIn(msg) != -1) {
             //debugMessage("STREAM: " + msg + " " + needle.cap(1));
-            sendCommand(_("tbreak *") + needle.cap(1));
+            execCommand(_("tbreak *") + needle.cap(1));
             m_waitingForFirstBreakpointToBeHit = true;
             qq->notifyInferiorRunningRequested();
-            sendCommand(_("-exec-run"));
+            execCommand(_("-exec-run"));
         } else {
             debugMessage(_("PARSING START ADDRESS FAILED: ") + msg);
         }
@@ -1814,7 +1565,7 @@ void GdbEngine::handleStart(const GdbResultRecord &response)
 #endif
 }
 
-void GdbEngine::handleAttach()
+void GdbEngine::handleAttach(const GdbResultRecord &, const QVariant &)
 {
     qq->notifyInferiorStopped();
     q->showStatusMessage(tr("Attached to running process. Stopped."));
@@ -1831,7 +1582,7 @@ void GdbEngine::handleAttach()
 
     reloadStack();
     if (supportsThreads())
-        sendSynchronizedCommand(_("-thread-list-ids"), StackListThreads, 0);
+        execCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), 0);
 
     //
     // Disassembler
@@ -1846,9 +1597,24 @@ void GdbEngine::handleAttach()
     qq->reloadRegisters();
 }
 
-void GdbEngine::handleExit(const GdbResultRecord &response)
+void GdbEngine::handleTargetAsync(const GdbResultRecord &record, const QVariant &)
+{
+    if (record.resultClass == GdbResultDone) {
+        //execCommand(_("info target"), handleStart);
+        qq->notifyInferiorRunningRequested();
+        execCommand(_("target remote %1").arg(q->m_remoteChannel));
+        execCommand(_("-exec-continue"), CB(handleExecRun));
+    } else if (record.resultClass == GdbResultError) {
+        // a typical response on "old" gdb is:
+        // &"set target-async on\n"
+        //&"No symbol table is loaded.  Use the \"file\" command.\n"
+        //^error,msg="No symbol table is loaded.  Use the \"file\" command."
+        execCommand(_("detach"));
+        execCommand(_("-gdb-exit"), CB(handleExit));
+    }
+}
+void GdbEngine::handleExit(const GdbResultRecord &, const QVariant &)
 {
-    Q_UNUSED(response);
     q->showStatusMessage(tr("Debugger exited."));
 }
 
@@ -1856,50 +1622,53 @@ void GdbEngine::stepExec()
 {
     setTokenBarrier();
     qq->notifyInferiorRunningRequested();
-    sendCommand(_("-exec-step"), GdbExecStep);
+    execCommand(_("-exec-step"), CB(handleExecRun));
 }
 
 void GdbEngine::stepIExec()
 {
     setTokenBarrier();
     qq->notifyInferiorRunningRequested();
-    sendCommand(_("-exec-step-instruction"), GdbExecStepI);
+    execCommand(_("-exec-step-instruction"), CB(handleExecRun));
 }
 
 void GdbEngine::stepOutExec()
 {
     setTokenBarrier();
     qq->notifyInferiorRunningRequested();
-    sendCommand(_("-exec-finish"), GdbExecFinish);
+    execCommand(_("-exec-finish"), CB(handleExecRun));
 }
 
 void GdbEngine::nextExec()
 {
     setTokenBarrier();
     qq->notifyInferiorRunningRequested();
-    sendCommand(_("-exec-next"), GdbExecNext);
+    execCommand(_("-exec-next"), CB(handleExecRun));
 }
 
 void GdbEngine::nextIExec()
 {
     setTokenBarrier();
     qq->notifyInferiorRunningRequested();
-    sendCommand(_("-exec-next-instruction"), GdbExecNextI);
+    execCommand(_("-exec-next-instruction"), CB(handleExecRun));
 }
 
 void GdbEngine::runToLineExec(const QString &fileName, int lineNumber)
 {
     setTokenBarrier();
     qq->notifyInferiorRunningRequested();
-    sendCommand(_("-exec-until ") + fileName + _c(':') + QString::number(lineNumber));
+    execCommand(_("-exec-until %1:%2").arg(fileName).arg(lineNumber));
 }
 
 void GdbEngine::runToFunctionExec(const QString &functionName)
 {
     setTokenBarrier();
-    sendCommand(_("-break-insert -t ") + functionName);
+    execCommand(_("-break-insert -t ") + functionName);
     qq->notifyInferiorRunningRequested();
-    sendCommand(_("-exec-continue"), GdbExecRunToFunction);
+    // that should be "^running". We need to handle the resulting
+    // "Stopped"
+    execCommand(_("-exec-continue"));
+    //execCommand(_("-exec-continue"), handleExecRunToFunction);
 }
 
 void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber)
@@ -1907,8 +1676,8 @@ void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber)
 #if 1
     // not available everywhere?
     //sendCliCommand(_("tbreak ") + fileName + ':' + QString::number(lineNumber));
-    sendCommand(_("-break-insert -t ") + fileName + _c(':') + QString::number(lineNumber));
-    sendCommand(_("jump ") + fileName + _c(':') + QString::number(lineNumber));
+    execCommand(_("-break-insert -t ") + fileName + _c(':') + QString::number(lineNumber));
+    execCommand(_("jump ") + fileName + _c(':') + QString::number(lineNumber));
     // will produce something like
     //  &"jump /home/apoenitz/dev/work/test1/test1.cpp:242"
     //  ~"Continuing at 0x4058f3."
@@ -1917,11 +1686,11 @@ void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber)
     //  23^done"
     q->gotoLocation(fileName, lineNumber, true);
     //setBreakpoint();
-    //sendCommand(_("jump ") + fileName + ':' + QString::number(lineNumber));
+    //execCommand(_("jump ") + fileName + ':' + QString::number(lineNumber));
 #else
     q->gotoLocation(fileName, lineNumber, true);
     setBreakpoint(fileName, lineNumber);
-    sendCommand(_("jump ") + fileName + ':' + QString::number(lineNumber));
+    execCommand(_("jump ") + fileName + ':' + QString::number(lineNumber));
 #endif
 }
 
@@ -1937,18 +1706,9 @@ void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber)
 
 void GdbEngine::setTokenBarrier()
 {
-    foreach (const GdbCookie &cookie, m_cookieForToken) {
-        QTC_ASSERT(
-            cookie.synchronized
-                || cookie.type == GdbInvalidCommand
-                // FIXME: use something like "command classes" for these cases:
-                || cookie.type == GdbInfoProc
-                || cookie.type == GdbStubAttached
-                || cookie.type == ModulesList
-                || cookie.type == WatchDebuggingHelperSetup
-                || cookie.type == GdbQueryDebuggingHelper,
-            qDebug() << "CMD: " << cookie.command << "TYPE: " << cookie.type
-                << "SYNC: " << cookie.synchronized;
+    foreach (const GdbCommand &cookie, m_cookieForToken) {
+        QTC_ASSERT(!cookie.callback || (cookie.flags & Discardable),
+            qDebug() << "CMD: " << cookie.command << "CALLBACK: " << cookie.callbackName;
             return
         );
     }
@@ -1961,12 +1721,12 @@ void GdbEngine::setDebugDebuggingHelpers(const QVariant &on)
 {
     if (on.toBool()) {
         debugMessage(_("SWITCHING ON DUMPER DEBUGGING"));
-        sendCommand(_("set unwindonsignal off"));
+        execCommand(_("set unwindonsignal off"));
         q->breakByFunction(_("qDumpObjectData440"));
         //updateLocals();
     } else {
         debugMessage(_("SWITCHING OFF DUMPER DEBUGGING"));
-        sendCommand(_("set unwindonsignal on"));
+        execCommand(_("set unwindonsignal on"));
     }
 }
 
@@ -2092,10 +1852,10 @@ void GdbEngine::sendInsertBreakpoint(int index)
     cmd += where;
 #endif
     debugMessage(_("Current state: %1").arg(q->status()));
-    sendCommand(cmd, BreakInsert, index, NeedsStop);
+    execCommand(cmd, NeedsStop, CB(handleBreakInsert), index);
 }
 
-void GdbEngine::handleBreakList(const GdbResultRecord &record)
+void GdbEngine::handleBreakList(const GdbResultRecord &record, const QVariant &)
 {
     // 45^done,BreakpointTable={nr_rows="2",nr_cols="6",hdr=[
     // {width="3",alignment="-1",col_name="number",colhdr="Num"}, ...
@@ -2155,8 +1915,9 @@ void GdbEngine::handleBreakList(const GdbMi &table)
 }
 
 
-void GdbEngine::handleBreakIgnore(const GdbResultRecord &record, int index)
+void GdbEngine::handleBreakIgnore(const GdbResultRecord &record, const QVariant &cookie)
 {
+    int index = cookie.toInt();
     // gdb 6.8:
     // ignore 2 0:
     // ~"Will stop next time breakpoint 2 is reached.\n"
@@ -2183,8 +1944,9 @@ void GdbEngine::handleBreakIgnore(const GdbResultRecord &record, int index)
     }
 }
 
-void GdbEngine::handleBreakCondition(const GdbResultRecord &record, int index)
+void GdbEngine::handleBreakCondition(const GdbResultRecord &record, const QVariant &cookie)
 {
+    int index = cookie.toInt();
     BreakHandler *handler = qq->breakHandler();
     if (record.resultClass == GdbResultDone) {
         // we just assume it was successful. otherwise we had to parse
@@ -2208,8 +1970,9 @@ void GdbEngine::handleBreakCondition(const GdbResultRecord &record, int index)
     }
 }
 
-void GdbEngine::handleBreakInsert(const GdbResultRecord &record, int index)
+void GdbEngine::handleBreakInsert(const GdbResultRecord &record, const QVariant &cookie)
 {
+    int index = cookie.toInt();
     BreakHandler *handler = qq->breakHandler();
     if (record.resultClass == GdbResultDone) {
         //qDebug() << "HANDLE BREAK INSERT " << index;
@@ -2231,21 +1994,19 @@ void GdbEngine::handleBreakInsert(const GdbResultRecord &record, int index)
             + data->lineNumber;
         // Should not happen with -break-insert -f. gdb older than 6.8?
         QTC_ASSERT(false, /**/);
-        sendCommand(_("break ") + where, BreakInsert1, index);
 #endif
 #ifdef Q_OS_MAC
         QFileInfo fi(data->fileName);
         QString where = _c('"') + fi.fileName() + _("\":")
             + data->lineNumber;
-        sendCommand(_("break ") + where, BreakInsert1, index);
 #endif
 #ifdef Q_OS_WIN
         QFileInfo fi(data->fileName);
         QString where = _c('"') + fi.fileName() + _("\":")
             + data->lineNumber;
         //QString where = m_data->fileName + _c(':') + data->lineNumber;
-        sendCommand(_("break ") + where, BreakInsert1, index);
 #endif
+        execCommand(_("break ") + where, CB(handleBreakInsert1), index);
     }
 }
 
@@ -2294,8 +2055,9 @@ void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointData *
     }
 }
 
-void GdbEngine::handleBreakInfo(const GdbResultRecord &record, int bpNumber)
+void GdbEngine::handleBreakInfo(const GdbResultRecord &record, const QVariant &cookie)
 {
+    int bpNumber = cookie.toInt();
     BreakHandler *handler = qq->breakHandler();
     if (record.resultClass == GdbResultDone) {
         // Old-style output for multiple breakpoints, presumably in a
@@ -2310,8 +2072,9 @@ void GdbEngine::handleBreakInfo(const GdbResultRecord &record, int bpNumber)
     }
 }
 
-void GdbEngine::handleBreakInsert1(const GdbResultRecord &record, int index)
+void GdbEngine::handleBreakInsert1(const GdbResultRecord &record, const QVariant &cookie)
 {
+    int index = cookie.toInt();
     BreakHandler *handler = qq->breakHandler();
     if (record.resultClass == GdbResultDone) {
         // Pending breakpoints in dylibs on Mac only?
@@ -2341,15 +2104,13 @@ void GdbEngine::attemptBreakpointSynchronization()
     foreach (BreakpointData *data, handler->takeDisabledBreakpoints()) {
         QString bpNumber = data->bpNumber;
         if (!bpNumber.trimmed().isEmpty())
-            sendCommand(_("-break-disable ") + bpNumber, BreakDisable, QVariant(),
-                NeedsStop);
+            execCommand(_("-break-disable ") + bpNumber, NeedsStop);
     }
 
     foreach (BreakpointData *data, handler->takeEnabledBreakpoints()) {
         QString bpNumber = data->bpNumber;
         if (!bpNumber.trimmed().isEmpty())
-            sendCommand(_("-break-enable ") + bpNumber, BreakEnable, QVariant(),
-                NeedsStop);
+            execCommand(_("-break-enable ") + bpNumber, NeedsStop);
     }
 
     foreach (BreakpointData *data, handler->takeRemovedBreakpoints()) {
@@ -2357,8 +2118,7 @@ void GdbEngine::attemptBreakpointSynchronization()
         debugMessage(_("DELETING BP %1 IN %2").arg(bpNumber)
             .arg(data->markerFileName));
         if (!bpNumber.trimmed().isEmpty())
-            sendCommand(_("-break-delete ") + bpNumber, BreakDelete, QVariant(),
-                NeedsStop);
+            execCommand(_("-break-delete ") + bpNumber, NeedsStop);
         delete data;
     }
 
@@ -2368,8 +2128,8 @@ void GdbEngine::attemptBreakpointSynchronization()
         BreakpointData *data = handler->at(index);
         // multiple breakpoints?
         if (data->bpMultiple && data->bpFileName.isEmpty()) {
-            sendCommand(_("info break %1").arg(data->bpNumber),
-                BreakInfo, data->bpNumber.toInt());
+            execCommand(_("info break %1").arg(data->bpNumber),
+                CB(handleBreakInfo), data->bpNumber.toInt());
             updateNeeded = true;
             break;
         }
@@ -2393,8 +2153,8 @@ void GdbEngine::attemptBreakpointSynchronization()
             // update conditions if needed
             if (data->bpNumber.toInt() && data->condition != data->bpCondition
                    && !data->conditionsMatch()) {
-                sendCommand(_("condition %1 %2").arg(data->bpNumber)
-                    .arg(data->condition), BreakCondition, index);
+                execCommand(_("condition %1 %2").arg(data->bpNumber).arg(data->condition),
+                            CB(handleBreakCondition), index);
                 //qDebug() << "UPDATE NEEDED BECAUSE OF CONDITION"
                 //    << data->condition << data->bpCondition;
                 updateNeeded = true;
@@ -2402,8 +2162,8 @@ void GdbEngine::attemptBreakpointSynchronization()
             }
             // update ignorecount if needed
             if (data->bpNumber.toInt() && data->ignoreCount != data->bpIgnoreCount) {
-                sendCommand(_("ignore %1 %2").arg(data->bpNumber)
-                    .arg(data->ignoreCount), BreakIgnore, index);
+                execCommand(_("ignore %1 %2").arg(data->bpNumber).arg(data->ignoreCount),
+                            CB(handleBreakIgnore), index);
                 updateNeeded = true;
                 break;
             }
@@ -2437,12 +2197,13 @@ void GdbEngine::attemptBreakpointSynchronization()
 
 void GdbEngine::reloadDisassembler()
 {
-    emit sendCommand(_("disassemble"), DisassemblerList, m_address);
+    emit execCommand(_("disassemble"), CB(handleDisassemblerList), m_address);
 }
 
 void GdbEngine::handleDisassemblerList(const GdbResultRecord &record,
-    const QString &cookie)
+    const QVariant &cookie)
 {
+    QString listedLine = cookie.toString();
     QList<DisassemblerLine> lines;
     static const QString pad = _("    ");
     int currentLine = -1;
@@ -2474,7 +2235,7 @@ void GdbEngine::handleDisassemblerList(const GdbResultRecord &record,
                 line.addressDisplay.replace(2, 8, QString());
             line.symbolDisplay = line.symbol + pad;
 
-            if (line.address == cookie)
+            if (line.address == listedLine)
                 currentLine = lines.size();
 
             lines.append(line);
@@ -2500,13 +2261,13 @@ void GdbEngine::handleDisassemblerList(const GdbResultRecord &record,
 void GdbEngine::loadSymbols(const QString &moduleName)
 {
     // FIXME: gdb does not understand quoted names here (tested with 6.8)
-    sendCommand(_("sharedlibrary ") + dotEscape(moduleName));
+    execCommand(_("sharedlibrary ") + dotEscape(moduleName));
     reloadModules();
 }
 
 void GdbEngine::loadAllSymbols()
 {
-    sendCommand(_("sharedlibrary .*"));
+    execCommand(_("sharedlibrary .*"));
     reloadModules();
 }
 
@@ -2546,10 +2307,10 @@ QList<Symbol> GdbEngine::moduleSymbols(const QString &moduleName)
 
 void GdbEngine::reloadModules()
 {
-    sendCommand(_("info shared"), ModulesList, QVariant());
+    execCommand(_("info shared"), CB(handleModulesList));
 }
 
-void GdbEngine::handleModulesList(const GdbResultRecord &record)
+void GdbEngine::handleModulesList(const GdbResultRecord &record, const QVariant &)
 {
     QList<Module> modules;
     if (record.resultClass == GdbResultDone) {
@@ -2598,7 +2359,7 @@ void GdbEngine::handleModulesList(const GdbResultRecord &record)
 
 void GdbEngine::reloadSourceFiles()
 {
-    sendCommand(_("-file-list-exec-source-files"), GdbQuerySources);
+    execCommand(_("-file-list-exec-source-files"), CB(handleQuerySources));
 }
 
 
@@ -2608,17 +2369,17 @@ void GdbEngine::reloadSourceFiles()
 //
 //////////////////////////////////////////////////////////////////////
 
-void GdbEngine::handleStackSelectThread(const GdbResultRecord &record, int)
+void GdbEngine::handleStackSelectThread(const GdbResultRecord &, const QVariant &)
 {
-    Q_UNUSED(record);
     //qDebug("FIXME: StackHandler::handleOutput: SelectThread");
     q->showStatusMessage(tr("Retrieving data for stack view..."), 3000);
     reloadStack();
 }
 
 
-void GdbEngine::handleStackListFrames(const GdbResultRecord &record, bool isFull)
+void GdbEngine::handleStackListFrames(const GdbResultRecord &record, const QVariant &cookie)
 {
+    bool isFull = cookie.toBool();
     QList<StackFrame> stackFrames;
 
     const GdbMi stack = record.data.findChild("stack");
@@ -2650,13 +2411,13 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record, bool isFull
         const bool isBogus =
             // Assume this is wrong and points to some strange stl_algobase
             // implementation. Happens on Karsten's XP system with Gdb 5.50
-            (frame.file.endsWith(_("/bits/stl_algobase.h")) && frame.line == 150)
+            (frame.file.endsWith(__("/bits/stl_algobase.h")) && frame.line == 150)
             // Also wrong. Happens on Vista with Gdb 5.50
-               || (frame.function == _("operator new") && frame.line == 151);
+               || (frame.function == __("operator new") && frame.line == 151);
 
         // immediately leave bogus frames
         if (topFrame == -1 && isBogus) {
-            sendCommand(_("-exec-finish"));
+            execCommand(_("-exec-finish"));
             return;
         }
 
@@ -2695,8 +2456,7 @@ void GdbEngine::selectThread(int index)
     QTC_ASSERT(index < threads.size(), return);
     int id = threads.at(index).id;
     q->showStatusMessage(tr("Retrieving data for stack view..."), 10000);
-    sendCommand(_("-thread-select ") + QString::number(id),
-        StackSelectThread);
+    execCommand(_("-thread-select %1").arg(id), CB(handleStackSelectThread));
 }
 
 void GdbEngine::activateFrame(int frameIndex)
@@ -2721,7 +2481,7 @@ void GdbEngine::activateFrame(int frameIndex)
         // Assuming this always succeeds saves a roundtrip.
         // Otherwise the lines below would need to get triggered
         // after a response to this -stack-select-frame here.
-        sendCommand(_("-stack-select-frame ") + QString::number(frameIndex));
+        execCommand(_("-stack-select-frame ") + QString::number(frameIndex));
 
         stackHandler->setCurrentIndex(frameIndex);
         updateLocals();
@@ -2735,8 +2495,9 @@ void GdbEngine::activateFrame(int frameIndex)
         qDebug() << "FULL NAME NOT USABLE: " << frame.file;
 }
 
-void GdbEngine::handleStackListThreads(const GdbResultRecord &record, int id)
+void GdbEngine::handleStackListThreads(const GdbResultRecord &record, const QVariant &cookie)
 {
+    int id = cookie.toInt();
     // "72^done,{thread-ids={thread-id="2",thread-id="1"},number-of-threads="2"}
     const QList<GdbMi> items = record.data.findChild("thread-ids").children();
     QList<ThreadData> threads;
@@ -2783,10 +2544,11 @@ static inline char registerFormatChar()
 
 void GdbEngine::reloadRegisters()
 {
-    sendCommand(_("-data-list-register-values ") + _c(registerFormatChar()), RegisterListValues);
+    execCommand(_("-data-list-register-values ") + _c(registerFormatChar()),
+                Discardable, CB(handleRegisterListValues));
 }
 
-void GdbEngine::handleRegisterListNames(const GdbResultRecord &record)
+void GdbEngine::handleRegisterListNames(const GdbResultRecord &record, const QVariant &)
 {
     if (record.resultClass != GdbResultDone)
         return;
@@ -2798,7 +2560,7 @@ void GdbEngine::handleRegisterListNames(const GdbResultRecord &record)
     qq->registerHandler()->setRegisters(registers);
 }
 
-void GdbEngine::handleRegisterListValues(const GdbResultRecord &record)
+void GdbEngine::handleRegisterListValues(const GdbResultRecord &record, const QVariant &)
 {
     if (record.resultClass != GdbResultDone)
         return;
@@ -3058,7 +2820,7 @@ void GdbEngine::runDirectDebuggingHelper(const WatchData &data, bool dumpChildre
 
     QVariant var;
     var.setValue(data);
-    sendSynchronizedCommand(cmd, WatchDebuggingHelperValue3, var);
+    execCommand(cmd, WatchUpdate, CB(handleDebuggingHelperValue3), var);
 
     q->showStatusMessage(
         tr("Retrieving data for watch view (%1 requests pending)...")
@@ -3100,25 +2862,26 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
 
     QVariant var;
     var.setValue(data);
-    sendSynchronizedCommand(cmd, WatchDebuggingHelperValue1, var);
+    execCommand(cmd, WatchUpdate, CB(handleDebuggingHelperValue1), var);
 
     q->showStatusMessage(
         tr("Retrieving data for watch view (%1 requests pending)...")
             .arg(m_pendingRequests + 1), 10000);
 
     // retrieve response
-    sendSynchronizedCommand(_("p (char*)&qDumpOutBuffer"), WatchDebuggingHelperValue2, var);
+    execCommand(_("p (char*)&qDumpOutBuffer"), WatchUpdate,
+        CB(handleDebuggingHelperValue2), var);
 }
 
 void GdbEngine::createGdbVariable(const WatchData &data)
 {
-    sendSynchronizedCommand(_("-var-delete \"") + data.iname + _c('"'));
+    execCommand(_("-var-delete \"%1\"").arg(data.iname), WatchUpdate);
     QString exp = data.exp;
     if (exp.isEmpty() && data.addr.startsWith(__("0x")))
         exp = _("*(") + gdbQuoteTypes(data.type) + _("*)") + data.addr;
     QVariant val = QVariant::fromValue<WatchData>(data);
-    sendSynchronizedCommand(_("-var-create \"") + data.iname + _("\" * \"")
-        + exp + _c('"'), WatchVarCreate, val);
+    execCommand(_("-var-create \"%1\" * \"%2\"").arg(data.iname).arg(exp),
+        WatchUpdate, CB(handleVarCreate), val);
 }
 
 void GdbEngine::updateSubItem(const WatchData &data0)
@@ -3212,7 +2975,7 @@ void GdbEngine::updateSubItem(const WatchData &data0)
         qDebug() << "UPDATE SUBITEM: VALUE";
         #endif
         QString cmd = _("-var-evaluate-expression \"") + data.iname + _c('"');
-        sendSynchronizedCommand(cmd, WatchEvaluateExpression,
+        execCommand(cmd, WatchUpdate, CB(handleEvaluateExpression),
             QVariant::fromValue(data));
         return;
     }
@@ -3238,7 +3001,7 @@ void GdbEngine::updateSubItem(const WatchData &data0)
     if (data.isChildrenNeeded()) {
         QTC_ASSERT(!data.variable.isEmpty(), return); // tested above
         QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"');
-        sendSynchronizedCommand(cmd, WatchVarListChildren, QVariant::fromValue(data));
+        execCommand(cmd, WatchUpdate, CB(handleVarListChildren), QVariant::fromValue(data));
         return;
     }
 
@@ -3263,7 +3026,7 @@ void GdbEngine::updateSubItem(const WatchData &data0)
     if (data.isChildCountNeeded()) {
         QTC_ASSERT(!data.variable.isEmpty(), return); // tested above
         QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"');
-        sendCommand(cmd, WatchVarListChildren, QVariant::fromValue(data));
+        execCommand(cmd, Discardable, CB(handleVarListChildren), QVariant::fromValue(data));
         return;
     }
 
@@ -3327,7 +3090,7 @@ void GdbEngine::updateWatchModel2()
     }
 }
 
-void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record)
+void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record, const QVariant &)
 {
     m_dumperHelper.clear();
     //qDebug() << "DATA DUMPER TRIAL:" << record.toString();
@@ -3397,10 +3160,10 @@ void GdbEngine::sendWatchParameters(const QByteArray &params0)
     }
     encoded[encoded.size() - 1] = '}';
 
-    sendCommand(_(encoded));
+    execCommand(_(encoded));
 }
 
-void GdbEngine::handleVarAssign()
+void GdbEngine::handleVarAssign(const GdbResultRecord &, const QVariant &)
 {
     // everything might have changed, force re-evaluation
     // FIXME: Speed this up by re-using variables and only
@@ -3422,9 +3185,9 @@ void GdbEngine::setWatchDataType(WatchData &data, const GdbMi &mi)
 }
 
 void GdbEngine::handleVarCreate(const GdbResultRecord &record,
-    const WatchData &data0)
+    const QVariant &cookie)
 {
-    WatchData data = data0;
+    WatchData data = cookie.value<WatchData>();
     // happens e.g. when we already issued a var-evaluate command
     if (!data.isValid())
         return;
@@ -3463,9 +3226,9 @@ void GdbEngine::handleVarCreate(const GdbResultRecord &record,
 }
 
 void GdbEngine::handleEvaluateExpression(const GdbResultRecord &record,
-    const WatchData &data0)
+    const QVariant &cookie)
 {
-    WatchData data = data0;
+    WatchData data = cookie.value<WatchData>();
     QTC_ASSERT(data.isValid(), qDebug() << "HUH?");
     if (record.resultClass == GdbResultDone) {
         //if (col == 0)
@@ -3480,7 +3243,7 @@ void GdbEngine::handleEvaluateExpression(const GdbResultRecord &record,
     //updateWatchModel2();
 }
 
-void GdbEngine::handleDebuggingHelperSetup(const GdbResultRecord &record)
+void GdbEngine::handleDebuggingHelperSetup(const GdbResultRecord &record, const QVariant &)
 {
     //qDebug() << "CUSTOM SETUP RESULT: " << record.toString();
     if (record.resultClass == GdbResultDone) {
@@ -3492,9 +3255,9 @@ void GdbEngine::handleDebuggingHelperSetup(const GdbResultRecord &record)
 }
 
 void GdbEngine::handleDebuggingHelperValue1(const GdbResultRecord &record,
-    const WatchData &data0)
+    const QVariant &cookie)
 {
-    WatchData data = data0;
+    WatchData data = cookie.value<WatchData>();
     QTC_ASSERT(data.isValid(), return);
     if (record.resultClass == GdbResultDone) {
         // ignore this case, data will follow
@@ -3510,7 +3273,7 @@ void GdbEngine::handleDebuggingHelperValue1(const GdbResultRecord &record,
                 && msg.startsWith(__("The program being debugged stopped while"))
                 && msg.contains(__("qDumpObjectData440"))) {
             // Fake full stop
-            sendCommand(_("p 0"), GdbAsyncOutput2);  // dummy
+            execCommand(_("p 0"), CB(handleAsyncOutput2));  // dummy
             return;
         }
 #endif
@@ -3524,9 +3287,9 @@ void GdbEngine::handleDebuggingHelperValue1(const GdbResultRecord &record,
 }
 
 void GdbEngine::handleDebuggingHelperValue2(const GdbResultRecord &record,
-    const WatchData &data0)
+    const QVariant &cookie)
 {
-    WatchData data = data0;
+    WatchData data = cookie.value<WatchData>();
     QTC_ASSERT(data.isValid(), return);
     //qDebug() << "CUSTOM VALUE RESULT: " << record.toString();
     //qDebug() << "FOR DATA: " << data.toString() << record.resultClass;
@@ -3623,9 +3386,9 @@ void GdbEngine::handleDebuggingHelperValue2(const GdbResultRecord &record,
 }
 
 void GdbEngine::handleDebuggingHelperValue3(const GdbResultRecord &record,
-    const WatchData &data0)
+    const QVariant &cookie)
 {
-    WatchData data = data0;
+    WatchData data = cookie.value<WatchData>();
     QByteArray out = record.data.findChild("consolestreamoutput").data();
     while (out.endsWith(' ') || out.endsWith('\n'))
         out.chop(1);
@@ -3665,7 +3428,7 @@ void GdbEngine::handleDebuggingHelperValue3(const GdbResultRecord &record,
             QString cmd = _("qdumpqstring (") + data1.exp + _c(')');
             QVariant var;
             var.setValue(data1);
-            sendSynchronizedCommand(cmd, WatchDebuggingHelperValue3, var);
+            execCommand(cmd, WatchUpdate, CB(handleDebuggingHelperValue3), var);
         }
     } else {
         //: Value for variable
@@ -3687,12 +3450,13 @@ void GdbEngine::updateLocals()
     QString level = QString::number(currentFrame());
     // '2' is 'list with type and value'
     QString cmd = _("-stack-list-arguments 2 ") + level + _c(' ') + level;
-    sendSynchronizedCommand(cmd, StackListArguments);                 // stage 1/2
+    execCommand(cmd, WatchUpdate, CB(handleStackListArguments));
     // '2' is 'list with type and value'
-    sendSynchronizedCommand(_("-stack-list-locals 2"), StackListLocals); // stage 2/2
+    execCommand(_("-stack-list-locals 2"), WatchUpdate,
+        CB(handleStackListLocals)); // stage 2/2
 }
 
-void GdbEngine::handleStackListArguments(const GdbResultRecord &record)
+void GdbEngine::handleStackListArguments(const GdbResultRecord &record, const QVariant &)
 {
     // stage 1/2
 
@@ -3726,7 +3490,7 @@ void GdbEngine::handleStackListArguments(const GdbResultRecord &record)
     }
 }
 
-void GdbEngine::handleStackListLocals(const GdbResultRecord &record)
+void GdbEngine::handleStackListLocals(const GdbResultRecord &record, const QVariant &)
 {
     // stage 2/2
 
@@ -3868,7 +3632,7 @@ void GdbEngine::handleVarListChildrenHelper(const GdbMi &item,
         //qDebug() << "DATA" << data.toString();
         QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"');
         //iname += '.' + exp;
-        sendSynchronizedCommand(cmd, WatchVarListChildren, QVariant::fromValue(data));
+        execCommand(cmd, WatchUpdate, CB(handleVarListChildren), QVariant::fromValue(data));
     } else if (item.findChild("numchild").data() == "0") {
         // happens for structs without data, e.g. interfaces.
         WatchData data;
@@ -3886,7 +3650,7 @@ void GdbEngine::handleVarListChildrenHelper(const GdbMi &item,
         WatchData data;
         data.iname = _(name);
         QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"');
-        sendSynchronizedCommand(cmd, WatchVarListChildren, QVariant::fromValue(data));
+        execCommand(cmd, WatchUpdate, CB(handleVarListChildren), QVariant::fromValue(data));
     } else if (exp == "staticMetaObject") {
         //    && item.findChild("type").data() == "const QMetaObject")
         // FIXME: Namespaces?
@@ -3949,10 +3713,10 @@ void GdbEngine::handleVarListChildrenHelper(const GdbMi &item,
 }
 
 void GdbEngine::handleVarListChildren(const GdbResultRecord &record,
-    const WatchData &data0)
+    const QVariant &cookie)
 {
     //WatchResultCounter dummy(this, WatchVarListChildren);
-    WatchData data = data0;
+    WatchData data = cookie.value<WatchData>();
     if (!data.isValid())
         return;
     if (record.resultClass == GdbResultDone) {
@@ -3989,13 +3753,15 @@ void GdbEngine::handleVarListChildren(const GdbResultRecord &record,
 }
 
 void GdbEngine::handleToolTip(const GdbResultRecord &record,
-        const QByteArray &what)
+        const QVariant &cookie)
 {
+    const QByteArray &what = cookie.toByteArray();
     //qDebug() << "HANDLE TOOLTIP: " << what << m_toolTip.toString();
     //    << "record: " << record.toString();
     if (record.resultClass == GdbResultError) {
         if (what == "create") {
-            sendCommand(_("ptype ") + m_toolTip.exp, WatchToolTip, QByteArray("ptype"));
+            execCommand(_("ptype ") + m_toolTip.exp,
+                Discardable, CB(handleToolTip), QByteArray("ptype"));
             return;
         }
         if (what == "evaluate") {
@@ -4013,9 +3779,8 @@ void GdbEngine::handleToolTip(const GdbResultRecord &record,
                 runDebuggingHelper(m_toolTip, false);
             else
                 q->showStatusMessage(tr("Retrieving data for tooltip..."), 10000);
-                sendCommand(_("-data-evaluate-expression ") + m_toolTip.exp,
-                    WatchToolTip, QByteArray("evaluate"));
-                //sendToolTipCommand(_("-var-evaluate-expression tooltip"))
+                execCommand(_("-data-evaluate-expression ") + m_toolTip.exp,
+                    Discardable, CB(handleToolTip), QByteArray("evaluate"));
             return;
         }
         if (what == "evaluate") {
@@ -4053,9 +3818,9 @@ void GdbEngine::handleChangedItem(QStandardItem *item)
 
 void GdbEngine::assignValueInDebugger(const QString &expression, const QString &value)
 {
-    sendCommand(_("-var-delete assign"));
-    sendCommand(_("-var-create assign * ") + expression);
-    sendCommand(_("-var-assign assign ") + value, WatchVarAssign);
+    execCommand(_("-var-delete assign"));
+    execCommand(_("-var-create assign * ") + expression);
+    execCommand(_("-var-assign assign ") + value, Discardable, CB(handleVarAssign));
 }
 
 void GdbEngine::tryLoadDebuggingHelpers()
@@ -4080,41 +3845,41 @@ void GdbEngine::tryLoadDebuggingHelpers()
 
     m_debuggingHelperState = DebuggingHelperLoadTried;
 #if defined(Q_OS_WIN)
-    sendCommand(_("sharedlibrary .*")); // for LoadLibraryA
-    //sendCommand(_("handle SIGSEGV pass stop print"));
-    //sendCommand(_("set unwindonsignal off"));
-    sendCommand(_("call LoadLibraryA(\"") + lib + _("\")"),
-        WatchDebuggingHelperSetup);
-    sendCommand(_("sharedlibrary ") + dotEscape(lib));
+    execCommand(_("sharedlibrary .*")); // for LoadLibraryA
+    //execCommand(_("handle SIGSEGV pass stop print"));
+    //execCommand(_("set unwindonsignal off"));
+    execCommand(_("call LoadLibraryA(\"") + lib + _("\")"),
+        CB(handleDebuggingHelperSetup));
+    execCommand(_("sharedlibrary ") + dotEscape(lib));
 #elif defined(Q_OS_MAC)
-    //sendCommand(_("sharedlibrary libc")); // for malloc
-    //sendCommand(_("sharedlibrary libdl")); // for dlopen
-    sendCommand(_("call (void)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"),
-        WatchDebuggingHelperSetup);
-    //sendCommand(_("sharedlibrary ") + dotEscape(lib));
+    //execCommand(_("sharedlibrary libc")); // for malloc
+    //execCommand(_("sharedlibrary libdl")); // for dlopen
+    execCommand(_("call (void)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"),
+        CB(handleDebuggingHelperSetup));
+    //execCommand(_("sharedlibrary ") + dotEscape(lib));
     m_debuggingHelperState = DebuggingHelperLoadTried;
 #else
-    //sendCommand(_("p dlopen"));
+    //execCommand(_("p dlopen"));
     QString flag = QString::number(RTLD_NOW);
-    sendCommand(_("sharedlibrary libc")); // for malloc
-    sendCommand(_("sharedlibrary libdl")); // for dlopen
-    sendCommand(_("call (void*)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"),
-        WatchDebuggingHelperSetup);
+    execCommand(_("sharedlibrary libc")); // for malloc
+    execCommand(_("sharedlibrary libdl")); // for dlopen
+    execCommand(_("call (void*)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"),
+        CB(handleDebuggingHelperSetup));
     // some older systems like CentOS 4.6 prefer this:
-    sendCommand(_("call (void*)__dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"),
-        WatchDebuggingHelperSetup);
-    sendCommand(_("sharedlibrary ") + dotEscape(lib));
+    execCommand(_("call (void*)__dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"),
+        CB(handleDebuggingHelperSetup));
+    execCommand(_("sharedlibrary ") + dotEscape(lib));
 #endif
     // retreive list of dumpable classes
-    sendCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"));
-    sendCommand(_("p (char*)&qDumpOutBuffer"), GdbQueryDebuggingHelper);
+    execCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"));
+    execCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper));
 }
 
 void GdbEngine::recheckDebuggingHelperAvailability()
 {
     // retreive list of dumpable classes
-    sendCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"));
-    sendCommand(_("p (char*)&qDumpOutBuffer"), GdbQueryDebuggingHelper);
+    execCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"));
+    execCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper));
 }
 
 IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *opts)
diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h
index 7b07f5bc1833a2c9c79288ec91f813a28718b436..c053bc1c0acf364cfa799fdafbf75aa60a9a6b97 100644
--- a/src/plugins/debugger/gdbengine.h
+++ b/src/plugins/debugger/gdbengine.h
@@ -63,16 +63,6 @@ class GdbMi;
 class WatchData;
 class BreakpointData;
 
-struct GdbCookie
-{
-    GdbCookie() : type(0), synchronized(false) {}
-
-    QString command;
-    int type;
-    bool synchronized;
-    QVariant cookie;
-};
-
 enum DebuggingHelperState
 {
     DebuggingHelperUninitialized,
@@ -154,19 +144,44 @@ private:
 
     void handleResult(const GdbResultRecord &, int type, const QVariant &);
 
+public: // otherwise the Qt flag macros are unhappy
+    enum GdbCommandFlag {
+        NoFlags = 0,
+        NeedsStop = 1,
+        Discardable = 2,
+        RebuildModel = 4,
+        WatchUpdate = Discardable|RebuildModel
+    };
+    Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
+private:
+
+    typedef void (GdbEngine::*GdbCommandCallback)(const GdbResultRecord &record, const QVariant &cookie);
+
+    struct GdbCommand
+    {
+        GdbCommand() : flags(0), callback(0), callbackName(0) {}
+
+        int flags;
+        GdbCommandCallback callback;
+        const char *callbackName;
+        QString command;
+        QVariant cookie;
+    };
+
     // type and cookie are sender-internal data, opaque for the "event
     // queue". resultNeeded == true increments m_pendingResults on
     // send and decrements on receipt, effectively preventing 
     // watch model updates before everything is finished.
-    enum StopNeeded { DoesNotNeedStop, NeedsStop };
-    enum Synchronization { NotSynchronized, Synchronized };
-    void sendCommand(const QString &command,
-        int type = 0, const QVariant &cookie = QVariant(),
-        StopNeeded needStop = DoesNotNeedStop,
-        Synchronization synchronized = NotSynchronized);
-    void sendSynchronizedCommand(const QString & command,
-        int type = 0, const QVariant &cookie = QVariant(),
-        StopNeeded needStop = DoesNotNeedStop);
+    void flushCommand(GdbCommand &cmd);
+    void execCommand(const QString &command,
+                     GdbCommandFlags flags,
+                     GdbCommandCallback callback = 0,
+                     const char *callbackName = 0,
+                     const QVariant &cookie = QVariant());
+    void execCommand(const QString &command,
+                     GdbCommandCallback callback = 0,
+                     const char *callbackName = 0,
+                     const QVariant &cookie = QVariant());
 
     void setTokenBarrier();
 
@@ -183,25 +198,28 @@ private slots:
 private:
     int terminationIndex(const QByteArray &buffer, int &length);
     void handleResponse(const QByteArray &buff);
-    void handleStart(const GdbResultRecord &response);
-    void handleAttach();
-    void handleStubAttached();
+    void handleStart(const GdbResultRecord &response, const QVariant &);
+    void handleAttach(const GdbResultRecord &, const QVariant &);
+    void handleStubAttached(const GdbResultRecord &, const QVariant &);
     void handleAqcuiredInferior();
+    void handleAsyncOutput2(const GdbResultRecord &, const QVariant &cookie);
     void handleAsyncOutput2(const GdbMi &data);
     void handleAsyncOutput(const GdbMi &data);
     void handleResultRecord(const GdbResultRecord &response);
-    void handleFileExecAndSymbols(const GdbResultRecord &response);
-    void handleExecRun(const GdbResultRecord &response);
-    void handleExecJumpToLine(const GdbResultRecord &response);
-    void handleExecRunToFunction(const GdbResultRecord &response);
-    void handleInfoShared(const GdbResultRecord &response);
-    void handleInfoProc(const GdbResultRecord &response);
-    void handleInfoThreads(const GdbResultRecord &response);
-    void handleShowVersion(const GdbResultRecord &response);
-    void handleQueryPwd(const GdbResultRecord &response);
-    void handleQuerySources(const GdbResultRecord &response);
-    void handleTargetCore(const GdbResultRecord &response);
-    void handleExit(const GdbResultRecord &response);
+    void handleAutoContinue(const GdbResultRecord &, const QVariant &);
+    void handleFileExecAndSymbols(const GdbResultRecord &response, const QVariant &);
+    void handleExecRun(const GdbResultRecord &response, const QVariant &);
+    void handleExecJumpToLine(const GdbResultRecord &response, const QVariant &);
+    void handleExecRunToFunction(const GdbResultRecord &response, const QVariant &);
+    void handleInfoShared(const GdbResultRecord &response, const QVariant &);
+    void handleInfoProc(const GdbResultRecord &response, const QVariant &);
+    void handleInfoThreads(const GdbResultRecord &response, const QVariant &);
+    void handleShowVersion(const GdbResultRecord &response, const QVariant &);
+    void handleQueryPwd(const GdbResultRecord &response, const QVariant &);
+    void handleQuerySources(const GdbResultRecord &response, const QVariant &);
+    void handleTargetCore(const GdbResultRecord &, const QVariant &);
+    void handleExit(const GdbResultRecord &, const QVariant &);
+    void handleTargetAsync(const GdbResultRecord &, const QVariant &);
     void debugMessage(const QString &msg);
 
     OutputCollector m_outputCollector;
@@ -214,7 +232,7 @@ private:
 
     Core::Utils::ConsoleProcess m_stubProc;
 
-    QHash<int, GdbCookie> m_cookieForToken;
+    QHash<int, GdbCommand> m_cookieForToken;
     QHash<int, QByteArray> m_customOutputForToken;
 
     QByteArray m_pendingConsoleStreamOutput;
@@ -237,13 +255,13 @@ private:
     //
     // Breakpoint specific stuff
     //
-    void handleBreakList(const GdbResultRecord &record);
+    void handleBreakList(const GdbResultRecord &record, const QVariant &);
     void handleBreakList(const GdbMi &table);
-    void handleBreakIgnore(const GdbResultRecord &record, int index);
-    void handleBreakInsert(const GdbResultRecord &record, int index);
-    void handleBreakInsert1(const GdbResultRecord &record, int index);
-    void handleBreakCondition(const GdbResultRecord &record, int index);
-    void handleBreakInfo(const GdbResultRecord &record, int index);
+    void handleBreakIgnore(const GdbResultRecord &record, const QVariant &cookie);
+    void handleBreakInsert(const GdbResultRecord &record, const QVariant &cookie);
+    void handleBreakInsert1(const GdbResultRecord &record, const QVariant &cookie);
+    void handleBreakCondition(const GdbResultRecord &record, const QVariant &cookie);
+    void handleBreakInfo(const GdbResultRecord &record, const QVariant &cookie);
     void extractDataFromInfoBreak(const QString &output, BreakpointData *data);
     void breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt);
     void sendInsertBreakpoint(int index);
@@ -253,7 +271,7 @@ private:
     // Disassembler specific stuff
     //
     void handleDisassemblerList(const GdbResultRecord &record,
-        const QString &cookie);
+        const QVariant &cookie);
     void reloadDisassembler();
     QString m_address;
 
@@ -262,15 +280,15 @@ private:
     // Modules specific stuff
     //
     void reloadModules();
-    void handleModulesList(const GdbResultRecord &record);
+    void handleModulesList(const GdbResultRecord &record, const QVariant &);
 
 
     //
     // Register specific stuff
     // 
     Q_SLOT void reloadRegisters();
-    void handleRegisterListNames(const GdbResultRecord &record);
-    void handleRegisterListValues(const GdbResultRecord &record);
+    void handleRegisterListNames(const GdbResultRecord &record, const QVariant &);
+    void handleRegisterListValues(const GdbResultRecord &record, const QVariant &);
 
     //
     // Source file specific stuff
@@ -280,9 +298,9 @@ private:
     //
     // Stack specific stuff
     // 
-    void handleStackListFrames(const GdbResultRecord &record, bool isFull);
-    void handleStackSelectThread(const GdbResultRecord &record, int cookie);
-    void handleStackListThreads(const GdbResultRecord &record, int cookie);
+    void handleStackListFrames(const GdbResultRecord &record, const QVariant &cookie);
+    void handleStackSelectThread(const GdbResultRecord &, const QVariant &);
+    void handleStackListThreads(const GdbResultRecord &record, const QVariant &cookie);
     Q_SLOT void reloadStack();
     Q_SLOT void reloadFullStack();
 
@@ -316,25 +334,25 @@ private:
     bool hasDebuggingHelperForType(const QString &type) const;
 
     void handleVarListChildren(const GdbResultRecord &record,
-        const WatchData &cookie);
+        const QVariant &cookie);
     void handleVarCreate(const GdbResultRecord &record,
-        const WatchData &cookie);
-    void handleVarAssign();
+        const QVariant &cookie);
+    void handleVarAssign(const GdbResultRecord &, const QVariant &);
     void handleEvaluateExpression(const GdbResultRecord &record,
-        const WatchData &cookie);
+        const QVariant &cookie);
     void handleToolTip(const GdbResultRecord &record,
-        const QByteArray &cookie);
-    void handleQueryDebuggingHelper(const GdbResultRecord &record);
+        const QVariant &cookie);
+    void handleQueryDebuggingHelper(const GdbResultRecord &record, const QVariant &);
     void handleDebuggingHelperValue1(const GdbResultRecord &record,
-        const WatchData &cookie);
+        const QVariant &cookie);
     void handleDebuggingHelperValue2(const GdbResultRecord &record,
-        const WatchData &cookie);
+        const QVariant &cookie);
     void handleDebuggingHelperValue3(const GdbResultRecord &record,
-        const WatchData &cookie);
+        const QVariant &cookie);
     void handleDebuggingHelperEditValue(const GdbResultRecord &record);
-    void handleDebuggingHelperSetup(const GdbResultRecord &record);
-    void handleStackListLocals(const GdbResultRecord &record);
-    void handleStackListArguments(const GdbResultRecord &record);
+    void handleDebuggingHelperSetup(const GdbResultRecord &record, const QVariant &);
+    void handleStackListLocals(const GdbResultRecord &record, const QVariant &);
+    void handleStackListArguments(const GdbResultRecord &record, const QVariant &);
     void handleVarListChildrenHelper(const GdbMi &child,
         const WatchData &parent);
     void setWatchDataType(WatchData &data, const GdbMi &mi);
@@ -354,7 +372,7 @@ private:
     bool m_waitingForFirstBreakpointToBeHit;
     bool m_modulesListOutdated;
 
-    QList<GdbCookie> m_commandsToRunOnTemporaryBreak;
+    QList<GdbCommand> m_commandsToRunOnTemporaryBreak;
 
     DebuggerManager *q;
     IDebuggerManagerAccessForEngines *qq;
@@ -363,4 +381,6 @@ private:
 } // namespace Internal
 } // namespace Debugger
 
+Q_DECLARE_OPERATORS_FOR_FLAGS(Debugger::Internal::GdbEngine::GdbCommandFlags)
+
 #endif // DEBUGGER_GDBENGINE_H
diff --git a/src/plugins/debugger/gdbmi.cpp b/src/plugins/debugger/gdbmi.cpp
index e7d0434d8fd8381244b3ec3ca5caef240ae63761..4cbd53ab1fed4bd2e6476d5bba5151314ad8af8a 100644
--- a/src/plugins/debugger/gdbmi.cpp
+++ b/src/plugins/debugger/gdbmi.cpp
@@ -42,16 +42,8 @@ QTextStream &operator<<(QTextStream &os, const GdbMi &mi)
     return os << mi.toString();
 }
 
-//static void skipSpaces(const char *&from, const char *to)
-//{
-//    while (from != to && QChar(*from).isSpace())
-//        ++from;
-//}
-
-
 void GdbMi::parseResultOrValue(const char *&from, const char *to)
 {
-    //skipSpaces(from, to);
     while (from != to && QChar(*from).isSpace())
         ++from;
 
diff --git a/src/plugins/debugger/moduleswindow.cpp b/src/plugins/debugger/moduleswindow.cpp
index 40ffcee7fb62db8fd433fc21be0a9a006893f692..a67b8dd0d75742e10702a67762d2c482d88ebac1 100644
--- a/src/plugins/debugger/moduleswindow.cpp
+++ b/src/plugins/debugger/moduleswindow.cpp
@@ -209,5 +209,5 @@ void ModulesWindow::showSymbols(const QString &name)
     emit newDockRequested(w);
 }
 
-}
-}
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index 3a5b891533b11caa9cac07ddd9083244ff183bab..5693c2c2159adfa034117f184ca3df28b498b724 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -367,7 +367,9 @@ QString decodeData(const QByteArray &ba, int encoding)
 // --------------- QtDumperResult
 
 QtDumperResult::Child::Child() :
-   valueEncoded(0)
+   valueEncoded(0),
+   childCount(0),
+   valuedisabled(false)
 {
 }
 
@@ -385,6 +387,7 @@ void QtDumperResult::clear()
     value.clear();
     address.clear();
     type.clear();
+    displayedType.clear();
     valueEncoded = 0;
     valuedisabled = false;
     childCount = 0;
@@ -403,7 +406,7 @@ QList<WatchData> QtDumperResult::toWatchData(int source) const
     const int lastDotIndex = root.iname.lastIndexOf(dot);
     root.exp = root.name = lastDotIndex == -1 ? iname : iname.mid(lastDotIndex + 1);
     root.setValue(decodeData(value, valueEncoded));
-    root.setType(type);
+    root.setType(displayedType.isEmpty() ? type : displayedType);
     root.valuedisabled = valuedisabled;
     root.setAddress(address);
     root.source = source;
@@ -419,8 +422,10 @@ QList<WatchData> QtDumperResult::toWatchData(int source) const
                 wchild.iname = iname;
                 wchild.iname += dot;
                 wchild.iname += dchild.name;                
-                wchild.exp = wchild.name = dchild.name;
-                wchild.setType(childType);
+                wchild.name = dchild.name;
+                wchild.exp = dchild.exp;
+                wchild.valuedisabled = dchild.valuedisabled;
+                wchild.setType(dchild.type.isEmpty() ? childType : dchild.type);
                 wchild.setAddress(dchild.address);
                 wchild.setValue(decodeData(dchild.value, dchild.valueEncoded));
                 wchild.setChildCount(0);
@@ -436,19 +441,23 @@ QList<WatchData> QtDumperResult::toWatchData(int source) const
 QDebug operator<<(QDebug in, const QtDumperResult &d)
 {
     QDebug nospace = in.nospace();
-    nospace << " iname=" << d.iname << " type=" << d.type << " address=" << d.address
+    nospace << " iname=" << d.iname << " type=" << d.type << " displayed=" << d.displayedType
+            << " address=" << d.address
             << " value="  << d.value
             << " disabled=" << d.valuedisabled
             << " encoded=" << d.valueEncoded << " internal=" << d.internal;
-    if (d.childCount) {
-        nospace << " childCount=" << d.childCount
+    const int realChildCount = d.children.size();
+    if (d.childCount || realChildCount) {
+        nospace << " childCount=" << d.childCount << '/' << realChildCount
                 << " childType=" << d.childType << '\n';
-        const int childCount = d.children.size();
-        for (int i = 0; i < childCount; i++) {
+        for (int i = 0; i < realChildCount; i++) {
             const QtDumperResult::Child &c = d.children.at(i);
             nospace << "   #" << i << " addr=" << c.address
+                    << " disabled=" << c.valuedisabled
+                    << " type=" << c.type
                     << " name=" << c.name << " encoded=" << c.valueEncoded
-                    << " value=" << c.value << '\n';
+                    << " value=" << c.value
+                    << "childcount=" << c.childCount << '\n';
         }
     }
     return in;
@@ -602,8 +611,6 @@ QtDumperHelper::Type QtDumperHelper::specialType(QString s)
 bool QtDumperHelper::needsExpressionSyntax(Type t)
 {
     switch (t) {
-        case QObjectType:
-        case QWidgetType:
         case QObjectSlotType:
         case QObjectSignalType:
         case QMapType:
@@ -1064,12 +1071,14 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
     switch (td.type) {
     case QObjectType:
     case QWidgetType:
-        extraArgs[0] = QLatin1String("(char*)&((('");
-        extraArgs[0] += m_qtNamespace;
-        extraArgs[0] += QLatin1String("QObjectPrivate'*)&");
-        extraArgs[0] += data.exp;
-        extraArgs[0] += QLatin1String(")->children)-(char*)&");
-        extraArgs[0] += data.exp;
+        if (debugger == GdbDebugger) {
+            extraArgs[0] = QLatin1String("(char*)&((('");
+            extraArgs[0] += m_qtNamespace;
+            extraArgs[0] += QLatin1String("QObjectPrivate'*)&");
+            extraArgs[0] += data.exp;
+            extraArgs[0] += QLatin1String(")->children)-(char*)&");
+            extraArgs[0] += data.exp;
+        }
         break;
     case QVectorType:
         extraArgs[1] = QLatin1String("(char*)&((");
@@ -1201,13 +1210,16 @@ protected:
 
 private:
     enum Mode { None, ExpectingIName, ExpectingAddress, ExpectingValue,
-                ExpectingType, ExpectingInternal,
+                ExpectingType, ExpectingDisplayedType, ExpectingInternal,
                 ExpectingValueDisabled,  ExpectingValueEncoded,
-                ExpectingChildType, ExpectingChildCount,
+                ExpectingCommonChildType, ExpectingChildCount,
                 IgnoreNext,
                 ChildModeStart,
                 ExpectingChildren,ExpectingChildName, ExpectingChildAddress,
-                ExpectingChildValue, ExpectingChildValueEncoded  };
+                ExpectingChildExpression, ExpectingChildType,
+                ExpectingChildValue, ExpectingChildValueEncoded,
+                ExpectingChildValueDisabled, ExpectingChildChildCount
+              };
 
     static inline Mode nextMode(Mode in, const char *keyword, int size);
 
@@ -1226,11 +1238,15 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword
 {
     // Careful with same prefix
     switch (size) {
+    case 3:
+        if (!qstrncmp(keyword, "exp", size))
+            return ExpectingChildExpression;
+        break;
     case 4:
         if (!qstrncmp(keyword, "addr", size))
             return in > ChildModeStart ? ExpectingChildAddress : ExpectingAddress;
         if (!qstrncmp(keyword, "type", size))
-            return ExpectingType;
+            return in > ChildModeStart ? ExpectingChildType : ExpectingType;
         if (!qstrncmp(keyword, "name", size))
             return ExpectingChildName;
         break;
@@ -1244,13 +1260,13 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword
         if (!qstrncmp(keyword, "children", size))
             return ExpectingChildren;
         if (!qstrncmp(keyword, "numchild", size))
-            return ExpectingChildCount;
+            return in > ChildModeStart ?  ExpectingChildChildCount : ExpectingChildCount;
         if (!qstrncmp(keyword, "internal", size))
             return ExpectingInternal;
         break;
     case 9:
         if (!qstrncmp(keyword, "childtype", size))
-            return ExpectingChildType;
+            return ExpectingCommonChildType;
         break;    
     case 12:
         if (!qstrncmp(keyword, "valueencoded", size))
@@ -1258,7 +1274,9 @@ ValueDumperParser::Mode ValueDumperParser::nextMode(Mode in, const char *keyword
         break;
     case 13:
         if (!qstrncmp(keyword, "valuedisabled", size))
-            return ExpectingValueDisabled;
+            return in > ChildModeStart ? ExpectingChildValueDisabled : ExpectingValueDisabled;
+        if (!qstrncmp(keyword, "displayedtype", size))
+            return ExpectingDisplayedType;
         if (!qstrncmp(keyword, "childnumchild", size))
             return IgnoreNext;
         break;
@@ -1306,10 +1324,13 @@ bool ValueDumperParser::handleValue(const char *k, int size)
     case ExpectingType:
         m_result.type = QString::fromLatin1(valueBA);
         break;
+    case ExpectingDisplayedType:
+        m_result.displayedType = QString::fromLatin1(valueBA);
+        break;
     case ExpectingInternal:
         m_result.internal = valueBA == "true";
         break;
-    case ExpectingChildType:
+    case ExpectingCommonChildType:
         m_result.childType = QString::fromLatin1(valueBA);
         break;
     case ExpectingChildCount:
@@ -1327,9 +1348,21 @@ bool ValueDumperParser::handleValue(const char *k, int size)
     case ExpectingChildValue:
         m_result.children.back().value = valueBA;
         break;
+    case ExpectingChildExpression:
+        m_result.children.back().exp = QString::fromLatin1(valueBA);
+        break;
     case ExpectingChildValueEncoded:
         m_result.children.back().valueEncoded = QString::fromLatin1(valueBA).toInt();
         break;
+    case ExpectingChildValueDisabled:
+        m_result.children.back().valuedisabled = valueBA == "true";
+        break;
+    case ExpectingChildType:
+        m_result.children.back().type = QString::fromLatin1(valueBA);
+        break;
+    case ExpectingChildChildCount:
+        m_result.children.back().childCount = QString::fromLatin1(valueBA).toInt();
+        break;
     }
     return true;
 }
@@ -1340,6 +1373,9 @@ bool QtDumperHelper::parseValue(const char *data, QtDumperResult *r)
     if (!parser.run())
         return false;
     *r = parser.result();
+    // Sanity
+    if (r->childCount < r->children.size())
+        r->childCount  = r->children.size();
     return true;
 }
 
@@ -1352,5 +1388,5 @@ QDebug operator<<(QDebug in, const QtDumperHelper::TypeData &d)
     return in;
 }
 
-}
-}
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h
index 47f73a8bb79cf8e1fbf418887c961d1d782bb0bf..af0a20c3b7c66299f5eba4112996b6fa883517c7 100644
--- a/src/plugins/debugger/watchutils.h
+++ b/src/plugins/debugger/watchutils.h
@@ -76,8 +76,12 @@ struct QtDumperResult
         Child();
 
         int valueEncoded;
+        int childCount;
+        bool valuedisabled;
         QString name;
         QString address;
+        QString exp;
+        QString type;
         QByteArray value;
     };
 
@@ -88,6 +92,7 @@ struct QtDumperResult
     QString iname;
     QString address;
     QString type;
+    QString displayedType;
     QByteArray value;
     int valueEncoded;
     bool valuedisabled;
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/git/settingspage.cpp b/src/plugins/git/settingspage.cpp
index cc6d06d9b53a402d12a7ddfd8728a68be77d774d..7765dee3304e0c1f473d20d0c1599bca1faf077c 100644
--- a/src/plugins/git/settingspage.cpp
+++ b/src/plugins/git/settingspage.cpp
@@ -97,16 +97,13 @@ QString SettingsPage::trCategory() const
 
 QWidget *SettingsPage::createPage(QWidget *parent)
 {
-    if (!m_widget)
-        m_widget = new SettingsPageWidget(parent);
+    m_widget = new SettingsPageWidget(parent);
     m_widget->setSettings(GitPlugin::instance()->settings());
     return m_widget;
 }
 
 void SettingsPage::apply()
 {
-    if (!m_widget)
-        return;
     const GitSettings newSettings = m_widget->settings();
     // Warn if git cannot be found in path if the widget is on top
     if (m_widget->isVisible()) {
diff --git a/src/plugins/git/settingspage.h b/src/plugins/git/settingspage.h
index ec247d8a8967d5398f50e5693d064cb612d954ec..2bb9c0a8d300dbdd4f1688349a3ee86a6d9befaf 100644
--- a/src/plugins/git/settingspage.h
+++ b/src/plugins/git/settingspage.h
@@ -78,7 +78,7 @@ public:
     void finish() { }
 
 private:
-    QPointer<SettingsPageWidget> m_widget;
+    SettingsPageWidget* m_widget;
 };
 
 } // namespace Internal
diff --git a/src/plugins/perforce/settingspage.cpp b/src/plugins/perforce/settingspage.cpp
index 1672186e9b7fbf210cb2794bd9ee17c90c32f0e3..024c2ac01fab2385c6e0d3b7bb886a4bb0af2fb9 100644
--- a/src/plugins/perforce/settingspage.cpp
+++ b/src/plugins/perforce/settingspage.cpp
@@ -108,16 +108,12 @@ QString SettingsPage::trCategory() const
 
 QWidget *SettingsPage::createPage(QWidget *parent)
 {
-    if (!m_widget)
-        m_widget = new SettingsPageWidget(parent);
+    m_widget = new SettingsPageWidget(parent);
     m_widget->setSettings(PerforcePlugin::perforcePluginInstance()->settings());
     return m_widget;
 }
 
 void SettingsPage::apply()
 {
-    if (!m_widget)
-        return;
-
     PerforcePlugin::perforcePluginInstance()->setSettings(m_widget->p4Command(), m_widget->p4Port(), m_widget->p4Client(), m_widget->p4User(), m_widget->defaultEnv());
 }
diff --git a/src/plugins/perforce/settingspage.h b/src/plugins/perforce/settingspage.h
index 5f54c5c53812c07d90dca4cd40e15b50aaa6c2f0..f4c6d028af36b4be1062b818ca64d22775ccaf72 100644
--- a/src/plugins/perforce/settingspage.h
+++ b/src/plugins/perforce/settingspage.h
@@ -76,7 +76,7 @@ public:
     void finish() { }
 
 private:
-    QPointer<SettingsPageWidget> m_widget;
+    SettingsPageWidget* m_widget;
 };
 
 } // namespace Internal
diff --git a/src/plugins/projectexplorer/abstractmakestep.cpp b/src/plugins/projectexplorer/abstractmakestep.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..19b9aa1db742629f02b6eda4b2ac2a02d48a90ef
--- /dev/null
+++ b/src/plugins/projectexplorer/abstractmakestep.cpp
@@ -0,0 +1,189 @@
+/**************************************************************************
+**
+** 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) {
+        m_buildParserName = parser;
+        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..3f60c3217c816131c2c1d3b41f226617394f667f
--- /dev/null
+++ b/src/plugins/projectexplorer/abstractmakestep.h
@@ -0,0 +1,76 @@
+/**************************************************************************
+**
+** 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"
+#include "projectexplorer_export.h"
+
+namespace ProjectExplorer {
+class BuildStep;
+class IBuildStepFactory;
+class Project;
+}
+
+namespace ProjectExplorer {
+
+class PROJECTEXPLORER_EXPORT AbstractMakeStep : public ProjectExplorer::AbstractProcessStep
+{
+    Q_OBJECT
+public:
+    AbstractMakeStep(Project * project);
+    ~AbstractMakeStep();
+    virtual bool init(const QString & name);
+    virtual void run(QFutureInterface<bool> &);
+
+protected:
+    // derived classes needs to call these functions
+    virtual void stdOut(const QString &line);
+    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 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
diff --git a/src/plugins/quickopen/settingspage.cpp b/src/plugins/quickopen/settingspage.cpp
index bd900e6bba0debb82f0656d23215b03993c6f384..dbb69b44273fbd72a20357e47720918c64b30652 100644
--- a/src/plugins/quickopen/settingspage.cpp
+++ b/src/plugins/quickopen/settingspage.cpp
@@ -71,20 +71,20 @@ QString SettingsPage::trCategory() const
 
 QWidget *SettingsPage::createPage(QWidget *parent)
 {
-    if (!m_page) {
-        m_page = new QWidget(parent);
-        m_ui.setupUi(m_page);
-        connect(m_ui.filterList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
-                this, SLOT(updateButtonStates()));
-        connect(m_ui.filterList, SIGNAL(itemActivated(QListWidgetItem *)),
-                this, SLOT(configureFilter(QListWidgetItem *)));
-        connect(m_ui.editButton, SIGNAL(clicked()),
-                this, SLOT(configureFilter()));
-        connect(m_ui.addButton, SIGNAL(clicked()),
-                this, SLOT(addCustomFilter()));
-        connect(m_ui.removeButton, SIGNAL(clicked()),
-                this, SLOT(removeCustomFilter()));
-    }
+
+    m_page = new QWidget(parent);
+    m_ui.setupUi(m_page);
+    connect(m_ui.filterList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
+            this, SLOT(updateButtonStates()));
+    connect(m_ui.filterList, SIGNAL(itemActivated(QListWidgetItem *)),
+            this, SLOT(configureFilter(QListWidgetItem *)));
+    connect(m_ui.editButton, SIGNAL(clicked()),
+            this, SLOT(configureFilter()));
+    connect(m_ui.addButton, SIGNAL(clicked()),
+            this, SLOT(addCustomFilter()));
+    connect(m_ui.removeButton, SIGNAL(clicked()),
+            this, SLOT(removeCustomFilter()));
+
     m_ui.refreshInterval->setValue(m_plugin->refreshInterval());
     m_filters = m_plugin->filters();
     m_customFilters = m_plugin->customFilters();
diff --git a/src/plugins/quickopen/settingspage.h b/src/plugins/quickopen/settingspage.h
index 6bb3a2984abaea393380a5c340d9db04306da0e9..936ecd082b2a09eae1300e5f5243358e064b48eb 100644
--- a/src/plugins/quickopen/settingspage.h
+++ b/src/plugins/quickopen/settingspage.h
@@ -78,7 +78,7 @@ private:
 
     Ui::SettingsWidget m_ui;
     QuickOpenPlugin *m_plugin;
-    QPointer<QWidget> m_page;
+    QWidget* m_page;
     QList<IQuickOpenFilter *> m_filters;
     QList<IQuickOpenFilter *> m_addedFilters;
     QList<IQuickOpenFilter *> m_removedFilters;
diff --git a/src/plugins/subversion/settingspage.cpp b/src/plugins/subversion/settingspage.cpp
index e06560feddc260704f2f2fdb52a729d124aae346..b099b8715ce0caed79c6d9bc107faf5a9ac73e4a 100644
--- a/src/plugins/subversion/settingspage.cpp
+++ b/src/plugins/subversion/settingspage.cpp
@@ -96,15 +96,12 @@ QString SettingsPage::trCategory() const
 
 QWidget *SettingsPage::createPage(QWidget *parent)
 {
-    if (!m_widget)
-        m_widget = new SettingsPageWidget(parent);
+    m_widget = new SettingsPageWidget(parent);
     m_widget->setSettings(SubversionPlugin::subversionPluginInstance()->settings());
     return m_widget;
 }
 
 void SettingsPage::apply()
 {
-    if (!m_widget)
-        return;
     SubversionPlugin::subversionPluginInstance()->setSettings(m_widget->settings());
 }
diff --git a/src/plugins/subversion/settingspage.h b/src/plugins/subversion/settingspage.h
index 7808920e04e046bb5f773c6cc262e14e4e51e6b1..1fc5e8e3350c588567b303a78c99ba98d61122e4 100644
--- a/src/plugins/subversion/settingspage.h
+++ b/src/plugins/subversion/settingspage.h
@@ -77,7 +77,7 @@ public:
     void finish() { }
 
 private:
-    QPointer<SettingsPageWidget> m_widget;
+    SettingsPageWidget* m_widget;
 };
 
 } // namespace Subversion
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index cd683f7990b625ab95b1c14a3f38a6359cf04907..d01cc3f1d6ec67665b92584d41bc13cd759be413 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -2348,10 +2348,10 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e)
                 bool active = blockNumber == extraAreaHighlightCollapseBlockNumber;
                 bool drawStart = drawBox && active;
                 bool drawEnd = blockNumber == extraAreaHighlightCollapseEndBlockNumber || (drawStart && !endIsVisible);
+                bool hovered = blockNumber >= extraAreaHighlightCollapseBlockNumber
+                               && blockNumber <= extraAreaHighlightCollapseEndBlockNumber;
 
-                if (   blockNumber >= extraAreaHighlightCollapseBlockNumber
-                    && blockNumber <= extraAreaHighlightCollapseEndBlockNumber) {
-
+                if (hovered) {
                     QRect box = QRect(extraAreaWidth + 1, top, collapseBoxWidth - 2, collapseBoxWidth);
                     drawRectBox(&painter, box, drawStart, drawEnd, pal);
                 }
@@ -2360,7 +2360,7 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e)
                     bool expanded = nextBlock.isVisible();
                     QRect box(extraAreaWidth + collapseBoxWidth/4, top + collapseBoxWidth/4,
                               2 * (collapseBoxWidth/4) + 1, 2 * (collapseBoxWidth/4) + 1);
-                    drawFoldingMarker(&painter, box, expanded, active);
+                    drawFoldingMarker(&painter, pal, box, expanded, active, hovered);
                 }
             }
 
@@ -2404,8 +2404,11 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e)
     }
 }
 
-void BaseTextEditor::drawFoldingMarker(QPainter *painter, const QRect &rect,
-                                       bool expanded, bool hovered) const
+void BaseTextEditor::drawFoldingMarker(QPainter *painter, const QPalette &pal,
+                                       const QRect &rect,
+                                       bool expanded,
+                                       bool active,
+                                       bool hovered) const
 {
     QStyleOptionViewItemV2 opt;
     opt.rect = rect;
@@ -2414,9 +2417,12 @@ void BaseTextEditor::drawFoldingMarker(QPainter *painter, const QRect &rect,
     if (expanded)
         opt.state |= QStyle::State_Open;
 
-    if (hovered)
+    if (active)
         opt.state |= QStyle::State_MouseOver | QStyle::State_Enabled | QStyle::State_Selected;
 
+    if (hovered)
+        opt.palette.setBrush(QPalette::Window, pal.highlight());
+
     style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this);
 }
 
diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h
index bc4e8c208759c925d3fa2e30ae12662cd695f86a..c93cd86123b81ae671973ef135f510793c37e20b 100644
--- a/src/plugins/texteditor/basetexteditor.h
+++ b/src/plugins/texteditor/basetexteditor.h
@@ -511,8 +511,11 @@ private:
     void moveLineUpDown(bool up);
     void saveCurrentCursorPositionForNavigation();
 
-    void drawFoldingMarker(QPainter *painter, const QRect &rect,
-                           bool expanded, bool hovered) const;
+    void drawFoldingMarker(QPainter *painter, const QPalette &pal,
+                           const QRect &rect,
+                           bool expanded,
+                           bool active,
+                           bool hovered) const;
 
     void toggleBlockVisible(const QTextBlock &block);
     QRect collapseBox();
diff --git a/src/plugins/vcsbase/vcsbasesettingspage.h b/src/plugins/vcsbase/vcsbasesettingspage.h
index 9c271c561e9dcb710eb0fddc472e8c0143e1695a..a81daf5f35211d3f3ba006fbd6469d0e5a0e5d44 100644
--- a/src/plugins/vcsbase/vcsbasesettingspage.h
+++ b/src/plugins/vcsbase/vcsbasesettingspage.h
@@ -80,7 +80,7 @@ signals:
 
 private:
     void updateNickNames();
-    QPointer<VCSBaseSettingsWidget> m_widget;
+    VCSBaseSettingsWidget* m_widget;
     VCSBaseSettings m_settings;
 };