diff --git a/src/plugins/debugger/cdb/cdb.pri b/src/plugins/debugger/cdb/cdb.pri
index 7e78763dfe538592e3294d4f28f7026031dd6a84..c11f3846bdea8a565cdafb657dc399c0fc67ed3a 100644
--- a/src/plugins/debugger/cdb/cdb.pri
+++ b/src/plugins/debugger/cdb/cdb.pri
@@ -37,7 +37,8 @@ HEADERS += \
     $$PWD/cdbmodules.h \
     $$PWD/cdbassembler.h \
     $$PWD/cdboptions.h \
-    $$PWD/cdboptionspage.h
+    $$PWD/cdboptionspage.h \
+    $$PWD/cdbdumperhelper.h
 
 SOURCES += \
     $$PWD/cdbdebugengine.cpp \
@@ -49,7 +50,8 @@ SOURCES += \
     $$PWD/cdbmodules.cpp \
     $$PWD/cdbassembler.cpp \
     $$PWD/cdboptions.cpp \
-    $$PWD/cdboptionspage.cpp
+    $$PWD/cdboptionspage.cpp \
+    $$PWD/cdbdumperhelper.cpp
 
 FORMS += $$PWD/cdboptionspagewidget.ui
 
diff --git a/src/plugins/debugger/cdb/cdbassembler.cpp b/src/plugins/debugger/cdb/cdbassembler.cpp
index 4cb59c7d69f018d7d9f721c8b17cc5a3fa267e45..ae030578c9aba6f38e15b9dda062f47b706335fe 100644
--- a/src/plugins/debugger/cdb/cdbassembler.cpp
+++ b/src/plugins/debugger/cdb/cdbassembler.cpp
@@ -212,14 +212,11 @@ bool dissassemble(IDebugClient5 *client,
     // in assembler code). We build a complete string first as line breaks
     // may occur in-between messages.
     StringOutputHandler stringHandler;
-    IDebugOutputCallbacksWide *oldHandler = CdbDebugOutputBase::getOutputCallback(client);
-    client->SetOutputCallbacksWide(&stringHandler);
+    OutputRedirector redir(client, &stringHandler);
     // For some reason, we need to output to "all clients"
     const HRESULT hr =  ctl->OutputDisassemblyLines(DEBUG_OUTCTL_ALL_CLIENTS,
                                                     beforeLines, beforeLines + afterLines,
                                                     offset, flags, 0, 0, 0, 0);
-    client->SetOutputCallbacksWide(oldHandler);
-
     if (FAILED(hr)) {
         *errorMessage= QString::fromLatin1("Unable to dissamble at 0x%1: %2").
                        arg(QString::number(offset, 16), msgComFailed("OutputDisassemblyLines", hr));
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index b210186c0f563c8ae38d48d9f4b26fbfd10be0f6..35028561a083af58b9b66a1c51535e1a9352391c 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -188,19 +188,7 @@ bool DebuggerEngineLibrary::init(const QString &path, QString *errorMessage)
     return true;
 }
 
-// A class that sets an expression syntax on the debug control while in scope.
-// Can be nested as it checks for the old value.
-class SyntaxSetter {
-    Q_DISABLE_COPY(SyntaxSetter)
-public:
-    explicit inline SyntaxSetter(IDebugControl4 *ctl, ULONG desiredSyntax);
-    inline  ~SyntaxSetter();
-private:
-    const ULONG m_desiredSyntax;
-    IDebugControl4 *m_ctl;
-    ULONG m_oldSyntax;
-};
-
+// ----- SyntaxSetter
 SyntaxSetter::SyntaxSetter(IDebugControl4 *ctl, ULONG desiredSyntax) :
     m_desiredSyntax(desiredSyntax),
     m_ctl(ctl)
@@ -216,6 +204,17 @@ SyntaxSetter::~SyntaxSetter()
         m_ctl->SetExpressionSyntax(m_oldSyntax);
 }
 
+// CdbComInterfaces
+CdbComInterfaces::CdbComInterfaces() :
+    debugClient(0),
+    debugControl(0),
+    debugSystemObjects(0),
+    debugSymbols(0),
+    debugRegisters(0),
+    debugDataSpaces(0)
+{
+}
+
 // --- CdbDebugEnginePrivate
 
 CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent,
@@ -225,13 +224,9 @@ CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent,
     m_hDebuggeeProcess(0),
     m_hDebuggeeThread(0),
     m_breakEventMode(BreakEventHandle),
+    m_dumper(&m_cif),
     m_watchTimer(-1),
     m_debugEventCallBack(engine),
-    m_pDebugClient(0),
-    m_pDebugControl(0),
-    m_pDebugSystemObjects(0),
-    m_pDebugSymbols(0),
-    m_pDebugRegisters(0),
     m_engine(engine),
     m_debuggerManager(parent),
     m_debuggerManagerAccess(parent->engineInterface()),
@@ -250,42 +245,49 @@ bool CdbDebugEnginePrivate::init(QString *errorMessage)
 
     // Initialize the COM interfaces
     HRESULT hr;
-    hr = lib.debugCreate( __uuidof(IDebugClient5), reinterpret_cast<void**>(&m_pDebugClient));
+    hr = lib.debugCreate( __uuidof(IDebugClient5), reinterpret_cast<void**>(&m_cif.debugClient));
     if (FAILED(hr)) {
         *errorMessage = QString::fromLatin1("Creation of IDebugClient5 failed: %1").arg(msgDebugEngineComResult(hr));
         return false;
     }
 
-    m_pDebugClient->SetOutputCallbacksWide(&m_debugOutputCallBack);
-    m_pDebugClient->SetEventCallbacks(&m_debugEventCallBack);
+    m_cif.debugClient->SetOutputCallbacksWide(&m_debugOutputCallBack);
+    m_cif.debugClient->SetEventCallbacksWide(&m_debugEventCallBack);
 
-    hr = lib.debugCreate( __uuidof(IDebugControl4), reinterpret_cast<void**>(&m_pDebugControl));
+    hr = lib.debugCreate( __uuidof(IDebugControl4), reinterpret_cast<void**>(&m_cif.debugControl));
     if (FAILED(hr)) {
         *errorMessage = QString::fromLatin1("Creation of IDebugControl4 failed: %1").arg(msgDebugEngineComResult(hr));
         return false;
     }
 
-    m_pDebugControl->SetCodeLevel(DEBUG_LEVEL_SOURCE);
+    m_cif.debugControl->SetCodeLevel(DEBUG_LEVEL_SOURCE);
 
-    hr = lib.debugCreate( __uuidof(IDebugSystemObjects4), reinterpret_cast<void**>(&m_pDebugSystemObjects));
+    hr = lib.debugCreate( __uuidof(IDebugSystemObjects4), reinterpret_cast<void**>(&m_cif.debugSystemObjects));
     if (FAILED(hr)) {
         *errorMessage = QString::fromLatin1("Creation of IDebugSystemObjects4 failed: %1").arg(msgDebugEngineComResult(hr));
         return false;
     }
 
-    hr = lib.debugCreate( __uuidof(IDebugSymbols3), reinterpret_cast<void**>(&m_pDebugSymbols));
+    hr = lib.debugCreate( __uuidof(IDebugSymbols3), reinterpret_cast<void**>(&m_cif.debugSymbols));
     if (FAILED(hr)) {
         *errorMessage = QString::fromLatin1("Creation of IDebugSymbols3 failed: %1").arg(msgDebugEngineComResult(hr));
         return false;
     }
 
-    hr = lib.debugCreate( __uuidof(IDebugRegisters2), reinterpret_cast<void**>(&m_pDebugRegisters));
+    hr = lib.debugCreate( __uuidof(IDebugRegisters2), reinterpret_cast<void**>(&m_cif.debugRegisters));
     if (FAILED(hr)) {
         *errorMessage = QString::fromLatin1("Creation of IDebugRegisters2 failed: %1").arg(msgDebugEngineComResult(hr));
         return false;
     }
+
+    hr = lib.debugCreate( __uuidof(IDebugDataSpaces4), reinterpret_cast<void**>(&m_cif.debugDataSpaces));
+    if (FAILED(hr)) {
+        *errorMessage = QString::fromLatin1("Creation of IDebugDataSpaces4 failed: %1").arg(msgDebugEngineComResult(hr));
+        return false;
+    }
+
     if (debugCDB)
-        qDebug() << QString::fromLatin1("CDB Initialization succeeded, interrupt time out %1s.").arg(getInterruptTimeOutSecs(m_pDebugControl));
+        qDebug() << QString::fromLatin1("CDB Initialization succeeded, interrupt time out %1s.").arg(getInterruptTimeOutSecs(m_cif.debugControl));
     return true;
 }
 
@@ -303,16 +305,18 @@ IDebuggerEngine *CdbDebugEngine::create(DebuggerManager *parent,
 CdbDebugEnginePrivate::~CdbDebugEnginePrivate()
 {
     cleanStackTrace();
-    if (m_pDebugClient)
-        m_pDebugClient->Release();
-    if (m_pDebugControl)
-        m_pDebugControl->Release();
-    if (m_pDebugSystemObjects)
-        m_pDebugSystemObjects->Release();
-    if (m_pDebugSymbols)
-        m_pDebugSymbols->Release();
-    if (m_pDebugRegisters)
-        m_pDebugRegisters->Release();
+    if (m_cif.debugClient)
+        m_cif.debugClient->Release();
+    if (m_cif.debugControl)
+        m_cif.debugControl->Release();
+    if (m_cif.debugSystemObjects)
+        m_cif.debugSystemObjects->Release();
+    if (m_cif.debugSymbols)
+        m_cif.debugSymbols->Release();
+    if (m_cif.debugRegisters)
+        m_cif.debugRegisters->Release();
+    if (m_cif.debugDataSpaces)
+        m_cif.debugDataSpaces->Release();
 }
 
 void CdbDebugEnginePrivate::clearForRun()
@@ -395,6 +399,18 @@ void CdbDebugEnginePrivate::clearDisplay()
 bool CdbDebugEngine::startDebugger()
 {
     m_d->clearDisplay();
+    // Figure out dumper. @TODO: same in gdb...
+    bool dumperEnabled = false && m_d->m_debuggerManager->qtDumperLibraryEnabled();
+    const QString dumperLibName = QDir::toNativeSeparators(m_d->m_debuggerManager->qtDumperLibraryName());
+    if (dumperEnabled) {
+        const QFileInfo fi(dumperLibName);
+        if (!fi.isFile()) {
+            const QString msg = tr("The dumper library '%1' does not exist.").arg(dumperLibName);
+            m_d->m_debuggerManager->showQtDumperLibraryWarning(msg);
+            dumperEnabled = false;
+        }
+    }
+    m_d->m_dumper.reset(dumperLibName, dumperEnabled);
     m_d->m_debuggerManager->showStatusMessage("Starting Debugger", -1);
     QString errorMessage;
     bool rc = false;
@@ -435,7 +451,7 @@ bool CdbDebugEngine::startAttachDebugger(qint64 pid, QString *errorMessage)
 {
     // Need to aatrach invasively, otherwise, no notification signals
     // for for CreateProcess/ExitProcess occur.
-    const HRESULT hr = m_d->m_pDebugClient->AttachProcess(NULL, pid,
+    const HRESULT hr = m_d->m_cif.debugClient->AttachProcess(NULL, pid,
                                                           DEBUG_ATTACH_INVASIVE_RESUME_PROCESS);
     if (debugCDB)
         qDebug() << "Attaching to " << pid << " returns " << hr;
@@ -461,10 +477,10 @@ bool CdbDebugEngine::startDebuggerWithExecutable(DebuggerStartMode sm, QString *
         qDebug() << Q_FUNC_INFO <<filename;
 
     const QFileInfo fi(filename);
-    m_d->m_pDebugSymbols->AppendImagePathWide(QDir::toNativeSeparators(fi.absolutePath()).utf16());
-    //m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
-    m_d->m_pDebugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
-    //m_pDebugSymbols->AddSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS | SYMOPT_NO_IMAGE_SEARCH);
+    m_d->m_cif.debugSymbols->AppendImagePathWide(QDir::toNativeSeparators(fi.absolutePath()).utf16());
+    //m_cif.debugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
+    m_d->m_cif.debugSymbols->SetSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS);
+    //m_cif.debugSymbols->AddSymbolOptions(SYMOPT_CASE_INSENSITIVE | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS | SYMOPT_NO_IMAGE_SEARCH);
 
     // TODO console
     const QString cmd = Core::Utils::AbstractProcess::createWinCommandline(filename, m_d->m_debuggerManager->m_processArgs);
@@ -476,7 +492,7 @@ bool CdbDebugEngine::startDebuggerWithExecutable(DebuggerStartMode sm, QString *
         envData = Core::Utils::AbstractProcess::createWinEnvironment(Core::Utils::AbstractProcess::fixWinEnvironment(m_d->m_debuggerManager->m_environment));
         env = reinterpret_cast<PCWSTR>(envData.data());
     }
-    const HRESULT hr = m_d->m_pDebugClient->CreateProcess2Wide(NULL,
+    const HRESULT hr = m_d->m_cif.debugClient->CreateProcess2Wide(NULL,
                                                                const_cast<PWSTR>(cmd.utf16()),
                                                                &dbgopts,
                                                                sizeof(dbgopts),
@@ -490,6 +506,7 @@ bool CdbDebugEngine::startDebuggerWithExecutable(DebuggerStartMode sm, QString *
         m_d->m_mode = sm;
     }
     m_d->m_debuggerManagerAccess->notifyInferiorRunning();
+
     return true;
 }
 
@@ -522,7 +539,7 @@ void CdbDebugEngine::exitDebugger()
                 m_d->interruptInterferiorProcess(&errorMessage);
                 QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
             }
-            hr = m_d->m_pDebugClient->DetachCurrentProcess();
+            hr = m_d->m_cif.debugClient->DetachCurrentProcess();
             if (FAILED(hr))
                 errorMessage += msgComFailed("DetachCurrentProcess", hr);
             if (debugCDB)
@@ -536,11 +553,11 @@ void CdbDebugEngine::exitDebugger()
                 QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
             }
             // Terminate and wait for stop events.
-            hr = m_d->m_pDebugClient->TerminateCurrentProcess();
+            hr = m_d->m_cif.debugClient->TerminateCurrentProcess();
             if (FAILED(hr))
                 errorMessage += msgComFailed("TerminateCurrentProcess", hr);
             if (!wasRunning) {
-                hr = m_d->m_pDebugClient->TerminateProcesses();
+                hr = m_d->m_cif.debugClient->TerminateProcesses();
                 if (FAILED(hr))
                     errorMessage += msgComFailed("TerminateProcesses", hr);
             }
@@ -633,7 +650,7 @@ void CdbDebugEngine::filterEvaluateWatchers(QList<WatchData> *wd, WatchHandler *
         return;
 
     // Filter out actual watchers. Ignore the "<Edit>" top level place holders
-    SyntaxSetter syntaxSetter(m_d->m_pDebugControl, DEBUG_EXPR_CPLUSPLUS);
+    SyntaxSetter syntaxSetter(m_d->m_cif.debugControl, DEBUG_EXPR_CPLUSPLUS);
     const QString watcherPrefix = QLatin1String("watch.");
     const QChar lessThan = QLatin1Char('<');
     const QChar greaterThan = QLatin1Char('>');
@@ -701,7 +718,7 @@ void CdbDebugEngine::stepExec()
         qDebug() << Q_FUNC_INFO;
 
     m_d->clearForRun();
-    const HRESULT hr = m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO);
+    const HRESULT hr = m_d->m_cif.debugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO);
     Q_UNUSED(hr)
 
     m_d->m_breakEventMode = CdbDebugEnginePrivate::BreakEventIgnoreOnce;
@@ -733,7 +750,7 @@ void CdbDebugEngine::stepOutExec()
         }
 
         IDebugBreakpoint2* pBP;
-        HRESULT hr = m_d->m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
+        HRESULT hr = m_d->m_cif.debugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
         if (FAILED(hr) || !pBP) {
             errorMessage = QString::fromLatin1("Cannot create temporary breakpoint: %1").arg(msgDebugEngineComResult(hr));
             break;
@@ -756,7 +773,7 @@ void CdbDebugEngine::nextExec()
         qDebug() << Q_FUNC_INFO;
 
     m_d->clearForRun();
-    const HRESULT hr = m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER);
+    const HRESULT hr = m_d->m_cif.debugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER);
     if (SUCCEEDED(hr)) {
         startWatchTimer();
     } else {
@@ -775,7 +792,7 @@ void CdbDebugEngine::nextIExec()
         qDebug() << Q_FUNC_INFO;
 
     m_d->clearForRun();
-    const HRESULT hr = m_d->m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
+    const HRESULT hr = m_d->m_cif.debugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
     if (SUCCEEDED(hr)) {
         startWatchTimer();
     } else {
@@ -795,7 +812,7 @@ bool CdbDebugEnginePrivate::continueInferiorProcess(QString *errorMessage)
 {
     if (debugCDB)
         qDebug() << Q_FUNC_INFO;
-    const HRESULT hr = m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_GO);
+    const HRESULT hr = m_cif.debugControl->SetExecutionStatus(DEBUG_STATUS_GO);
     if (FAILED(hr)) {
         *errorMessage = msgComFailed("SetExecutionStatus", hr);
         return false;
@@ -807,7 +824,7 @@ bool CdbDebugEnginePrivate::continueInferiorProcess(QString *errorMessage)
 bool CdbDebugEnginePrivate::continueInferior(QString *errorMessage)
 {
     ULONG executionStatus;
-    if (!getExecutionStatus(m_pDebugControl, &executionStatus, errorMessage))
+    if (!getExecutionStatus(m_cif.debugControl, &executionStatus, errorMessage))
         return false;
 
     if (debugCDB)
@@ -836,7 +853,7 @@ bool CdbDebugEnginePrivate::interruptInterferiorProcess(QString *errorMessage)
     // Interrupt the interferior process without notifications
     if (debugCDB) {
         ULONG executionStatus;
-        getExecutionStatus(m_pDebugControl, &executionStatus, errorMessage);
+        getExecutionStatus(m_cif.debugControl, &executionStatus, errorMessage);
         qDebug() << Q_FUNC_INFO << "\n    ex=" << executionStatus;
     }
 
@@ -845,10 +862,10 @@ bool CdbDebugEnginePrivate::interruptInterferiorProcess(QString *errorMessage)
         return false;
     }
 #if 0
-    const HRESULT hr = m_pDebugControl->SetInterrupt(DEBUG_INTERRUPT_ACTIVE|DEBUG_INTERRUPT_EXIT);
+    const HRESULT hr = m_cif.debugControl->SetInterrupt(DEBUG_INTERRUPT_ACTIVE|DEBUG_INTERRUPT_EXIT);
     if (FAILED(hr)) {
         *errorMessage = QString::fromLatin1("Unable to interrupt debuggee after %1s: %2").
-                        arg(getInterruptTimeOutSecs(m_pDebugControl)).arg(msgComFailed("SetInterrupt", hr));
+                        arg(getInterruptTimeOutSecs(m_cif.debugControl)).arg(msgComFailed("SetInterrupt", hr));
         return false;
     }
 #endif
@@ -918,15 +935,16 @@ void CdbDebugEngine::assignValueInDebugger(const QString &expr, const QString &v
 void CdbDebugEngine::executeDebuggerCommand(const QString &command)
 {
     QString errorMessage;
-    if (!executeDebuggerCommand(command, &errorMessage))
+    if (!CdbDebugEnginePrivate::executeDebuggerCommand(m_d->m_cif.debugControl, command, &errorMessage))
         qWarning("%s\n", qPrintable(errorMessage));
 }
 
-bool CdbDebugEngine::executeDebuggerCommand(const QString &command, QString *errorMessage)
+bool CdbDebugEnginePrivate::executeDebuggerCommand(IDebugControl4 *ctrl, const QString &command, QString *errorMessage)
 {
     if (debugCDB)
         qDebug() << Q_FUNC_INFO << command;
-    const HRESULT hr = m_d->m_pDebugControl->ExecuteWide(DEBUG_OUTCTL_THIS_CLIENT, command.utf16(), 0);
+    // output to all clients, else we do not see anything
+    const HRESULT hr = ctrl->ExecuteWide(DEBUG_OUTCTL_ALL_CLIENTS, command.utf16(), 0);
     if (FAILED(hr)) {
         *errorMessage = QString::fromLatin1("Unable to execute '%1': %2").
                         arg(command, msgDebugEngineComResult(hr));
@@ -945,9 +963,9 @@ bool CdbDebugEngine::evaluateExpression(const QString &expression,
     DEBUG_VALUE debugValue;
     memset(&debugValue, 0, sizeof(DEBUG_VALUE));
     // Original syntax must be restored, else setting breakpoints will fail.
-    SyntaxSetter syntaxSetter(m_d->m_pDebugControl, DEBUG_EXPR_CPLUSPLUS);
+    SyntaxSetter syntaxSetter(m_d->m_cif.debugControl, DEBUG_EXPR_CPLUSPLUS);
     ULONG errorPosition = 0;
-    const HRESULT hr = m_d->m_pDebugControl->EvaluateWide(expression.utf16(),
+    const HRESULT hr = m_d->m_cif.debugControl->EvaluateWide(expression.utf16(),
                                                           DEBUG_VALUE_INVALID, &debugValue,
                                                           &errorPosition);    if (FAILED(hr)) {
         if (HRESULT_CODE(hr) == 517) {
@@ -959,7 +977,7 @@ bool CdbDebugEngine::evaluateExpression(const QString &expression,
         }
         return false;
     }
-    *value = CdbSymbolGroupContext::debugValueToString(debugValue, m_d->m_pDebugControl, type);
+    *value = CdbSymbolGroupContext::debugValueToString(debugValue, m_d->m_cif.debugControl, type);
     return true;
 }
 
@@ -1044,7 +1062,7 @@ bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessa
     // called again from the debug event handler.
 
     ULONG dummy;
-    const bool wasRunning = !CDBBreakPoint::getBreakPointCount(m_pDebugControl, &dummy);
+    const bool wasRunning = !CDBBreakPoint::getBreakPointCount(m_cif.debugControl, &dummy);
     if (debugCDB)
         qDebug() << Q_FUNC_INFO << "\n  Running=" << wasRunning;
 
@@ -1058,8 +1076,8 @@ bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessa
         return true;
     }
 
-    return CDBBreakPoint::synchronizeBreakPoints(m_pDebugControl,
-                                                 m_pDebugSymbols,
+    return CDBBreakPoint::synchronizeBreakPoints(m_cif.debugControl,
+                                                 m_cif.debugSymbols,
                                                  m_debuggerManagerAccess->breakHandler(),
                                                  errorMessage);
 }
@@ -1085,7 +1103,7 @@ void CdbDebugEngine::reloadDisassembler()
         QList<DisassemblerLine> lines;
         QString errorMessage;
         QApplication::setOverrideCursor(Qt::WaitCursor);
-        const bool drc = dissassemble(m_d->m_pDebugClient, m_d->m_pDebugControl, offset,
+        const bool drc = dissassemble(m_d->m_cif.debugClient, m_d->m_cif.debugControl, offset,
                          ContextLines, ContextLines, &lines, &errorMessage);
         QApplication::restoreOverrideCursor();
         if (drc) {
@@ -1126,7 +1144,7 @@ QList<Symbol> CdbDebugEngine::moduleSymbols(const QString &moduleName)
             errorMessage = tr("Cannot retrieve symbols while the debuggee is running.");
             break;
         }
-        if (!getModuleSymbols(m_d->m_pDebugSymbols, moduleName, &rc, &errorMessage))
+        if (!getModuleSymbols(m_d->m_cif.debugSymbols, moduleName, &rc, &errorMessage))
             break;
         success = true;
     } while (false);
@@ -1161,7 +1179,7 @@ void CdbDebugEngine::reloadRegisters()
         qDebug() << Q_FUNC_INFO << intBase;
     QList<Register> registers;
     QString errorMessage;
-    if (!getRegisters(m_d->m_pDebugControl, m_d->m_pDebugRegisters, &registers, &errorMessage, intBase))
+    if (!getRegisters(m_d->m_cif.debugControl, m_d->m_cif.debugRegisters, &registers, &errorMessage, intBase))
         qWarning("reloadRegisters() failed: %s\n", qPrintable(errorMessage));
     m_d->m_debuggerManagerAccess->registerHandler()->setRegisters(registers);
 }
@@ -1171,7 +1189,7 @@ void CdbDebugEngine::timerEvent(QTimerEvent* te)
     if (te->timerId() != m_d->m_watchTimer)
         return;
 
-    const HRESULT hr = m_d->m_pDebugControl->WaitForEvent(0, 1);
+    const HRESULT hr = m_d->m_cif.debugControl->WaitForEvent(0, 1);
     if (debugCDB)
         if (debugCDB > 1 || hr != S_FALSE)
             qDebug() << Q_FUNC_INFO << "WaitForEvent" << m_d->m_debuggerManager->status() <<   msgDebugEngineComResult(hr);
@@ -1266,7 +1284,7 @@ void CdbDebugEnginePrivate::updateThreadList()
     QString errorMessage;
     do {
         ULONG numberOfThreads;
-        HRESULT hr= m_pDebugSystemObjects->GetNumberThreads(&numberOfThreads);
+        HRESULT hr= m_cif.debugSystemObjects->GetNumberThreads(&numberOfThreads);
         if (FAILED(hr)) {
             errorMessage= msgComFailed("GetNumberThreads", hr);
             break;
@@ -1274,7 +1292,7 @@ void CdbDebugEnginePrivate::updateThreadList()
         const ULONG maxThreadIds = 256;
         ULONG threadIds[maxThreadIds];
         ULONG biggestThreadId = qMin(maxThreadIds, numberOfThreads - 1);
-        hr = m_pDebugSystemObjects->GetThreadIdsByIndex(0, biggestThreadId, threadIds, 0);
+        hr = m_cif.debugSystemObjects->GetThreadIdsByIndex(0, biggestThreadId, threadIds, 0);
         if (FAILED(hr)) {
             errorMessage= msgComFailed("GetThreadIdsByIndex", hr);
             break;
@@ -1301,8 +1319,8 @@ void CdbDebugEnginePrivate::updateStackTrace()
     QString errorMessage;
     m_engine->reloadRegisters();
     m_currentStackTrace =
-            CdbStackTraceContext::create(m_pDebugControl, m_pDebugSystemObjects,
-                                         m_pDebugSymbols, m_currentThreadId, &errorMessage);
+            CdbStackTraceContext::create(m_cif.debugControl, m_cif.debugSystemObjects,
+                                         m_cif.debugSymbols, m_currentThreadId, &errorMessage);
     if (!m_currentStackTrace) {
         qWarning("%s: failed to create trace context: %s", Q_FUNC_INFO, qPrintable(errorMessage));
         return;
@@ -1329,17 +1347,36 @@ void CdbDebugEnginePrivate::updateStackTrace()
     }
 }
 
-
 void CdbDebugEnginePrivate::updateModules()
 {
     QList<Module> modules;
     QString errorMessage;
-    if (!getModuleList(m_pDebugSymbols, &modules, &errorMessage))
+    if (!getModuleList(m_cif.debugSymbols, &modules, &errorMessage))
         qWarning("updateModules() failed: %s\n", qPrintable(errorMessage));
     m_debuggerManagerAccess->modulesHandler()->setModules(modules);
 }
 
-void CdbDebugEnginePrivate::handleBreakpointEvent(PDEBUG_BREAKPOINT pBP)
+static const char *dumperPrefixC = "dumper";
+
+void CdbDebugEnginePrivate::handleModuleLoad(const QString &name)
+{
+    if (debugCDB>2)
+        qDebug() << Q_FUNC_INFO << "\n    " << name;
+    updateModules();
+    // Call the dumper helper hook and notify about progress.
+    bool ignoreNextBreakPoint;
+    if (m_dumper.moduleLoadHook(name, &ignoreNextBreakPoint)) {
+        if (m_dumper.state() == CdbDumperHelper::Loaded)
+            m_debuggerManagerAccess->showDebuggerOutput(QLatin1String(dumperPrefixC), QString::fromLatin1("Dumpers loaded: %1").arg(m_dumper.library()));
+    } else {
+        m_debuggerManager->showQtDumperLibraryWarning(m_dumper.errorMessage());
+        m_debuggerManagerAccess->showDebuggerOutput(QLatin1String(dumperPrefixC), QString::fromLatin1("Unable to load dumpers: %1").arg(m_dumper.errorMessage()));
+    }
+    if (ignoreNextBreakPoint)
+        m_breakEventMode = BreakEventIgnoreOnce;
+}
+
+void CdbDebugEnginePrivate::handleBreakpointEvent(PDEBUG_BREAKPOINT2 pBP)
 {
     Q_UNUSED(pBP)
     if (debugCDB)
diff --git a/src/plugins/debugger/cdb/cdbdebugengine_p.h b/src/plugins/debugger/cdb/cdbdebugengine_p.h
index ae4812d7d8183cb6a0520240aee50a926c4a1502..88cbb2725c9b5b6661acec727f089bb20fa7ea2e 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine_p.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine_p.h
@@ -33,6 +33,7 @@
 #include "cdbdebugeventcallback.h"
 #include "cdbdebugoutput.h"
 #include "cdboptions.h"
+#include "cdbdumperhelper.h"
 #include "stackhandler.h"
 #include "debuggermanager.h"
 
@@ -67,6 +68,31 @@ private:
     DebugCreateFunction m_debugCreate;
 };
 
+// A class that sets an expression syntax on the debug control while in scope.
+// Can be nested as it checks for the old value.
+class SyntaxSetter {
+    Q_DISABLE_COPY(SyntaxSetter)
+public:
+    explicit inline SyntaxSetter(IDebugControl4 *ctl, ULONG desiredSyntax);
+    inline  ~SyntaxSetter();
+private:
+    const ULONG m_desiredSyntax;
+    IDebugControl4 *m_ctl;
+    ULONG m_oldSyntax;
+};
+
+// helper struct to pass interfaces around
+struct CdbComInterfaces
+{
+    CdbComInterfaces();
+    IDebugClient5*          debugClient;
+    IDebugControl4*         debugControl;
+    IDebugSystemObjects4*   debugSystemObjects;
+    IDebugSymbols3*         debugSymbols;
+    IDebugRegisters2*       debugRegisters;
+    IDebugDataSpaces4*      debugDataSpaces;
+};
+
 struct CdbDebugEnginePrivate
 {    
     enum HandleBreakEventMode { // Special modes for break event handler.
@@ -90,9 +116,10 @@ struct CdbDebugEnginePrivate
     bool updateLocals(int frameIndex, WatchHandler *wh, QString *errorMessage);
     void updateModules();
 
-    void handleBreakpointEvent(PDEBUG_BREAKPOINT pBP);
+    void handleBreakpointEvent(PDEBUG_BREAKPOINT2 pBP);
     void cleanStackTrace();
     void clearForRun();
+    void handleModuleLoad(const QString &);
     CdbSymbolGroupContext *getStackFrameSymbolGroupContext(int frameIndex, QString *errorMessage) const;
     void clearDisplay();
 
@@ -103,6 +130,8 @@ struct CdbDebugEnginePrivate
 
     bool attemptBreakpointSynchronization(QString *errorMessage);
 
+    static bool executeDebuggerCommand(IDebugControl4 *ctrl, const QString &command, QString *errorMessage);
+
     const QSharedPointer<CdbOptions>  m_options;
     HANDLE                  m_hDebuggeeProcess;
     HANDLE                  m_hDebuggeeThread;
@@ -110,13 +139,10 @@ struct CdbDebugEnginePrivate
     HandleBreakEventMode    m_breakEventMode;
 
     int                     m_watchTimer;
-    IDebugClient5*          m_pDebugClient;
-    IDebugControl4*         m_pDebugControl;
-    IDebugSystemObjects4*   m_pDebugSystemObjects;
-    IDebugSymbols3*         m_pDebugSymbols;
-    IDebugRegisters2*       m_pDebugRegisters;
+    CdbComInterfaces        m_cif;
     CdbDebugEventCallback   m_debugEventCallBack;
-    CdbDebugOutput          m_debugOutputCallBack;
+    CdbDebugOutput          m_debugOutputCallBack;    
+    CdbDumperHelper         m_dumper;
 
     CdbDebugEngine* m_engine;
     DebuggerManager *m_debuggerManager;
diff --git a/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp b/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
index 526902e2c3d8e3603925178335c648c082b33d89..2e6b2178f19ca681443fee4fe278ee6032171f4a 100644
--- a/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
@@ -38,12 +38,12 @@
 namespace Debugger {
 namespace Internal {
 
-CdbDebugEventCallback::CdbDebugEventCallback(CdbDebugEngine* dbg) :
-    m_pEngine(dbg)
+//     CdbDebugEventCallbackBase
+CdbDebugEventCallbackBase::CdbDebugEventCallbackBase()
 {
 }
 
-STDMETHODIMP CdbDebugEventCallback::QueryInterface(
+STDMETHODIMP CdbDebugEventCallbackBase::QueryInterface(
     THIS_
     IN REFIID InterfaceId,
     OUT PVOID* Interface)
@@ -60,32 +60,170 @@ STDMETHODIMP CdbDebugEventCallback::QueryInterface(
     }
 }
 
-STDMETHODIMP_(ULONG) CdbDebugEventCallback::AddRef(THIS)
+STDMETHODIMP_(ULONG) CdbDebugEventCallbackBase::AddRef(THIS)
 {
     // This class is designed to be static so
     // there's no true refcount.
     return 1;
 }
 
-STDMETHODIMP_(ULONG) CdbDebugEventCallback::Release(THIS)
+STDMETHODIMP_(ULONG) CdbDebugEventCallbackBase::Release(THIS)
 {
     // This class is designed to be static so
     // there's no true refcount.
     return 0;
 }
 
+STDMETHODIMP CdbDebugEventCallbackBase::Breakpoint(THIS_ __in PDEBUG_BREAKPOINT2)
+{
+    return S_OK;
+}
+STDMETHODIMP CdbDebugEventCallbackBase::Exception(
+    THIS_
+    __in PEXCEPTION_RECORD64,
+    __in ULONG /* FirstChance */
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP CdbDebugEventCallbackBase::CreateThread(
+    THIS_
+    __in ULONG64 /* Handle */,
+    __in ULONG64 /* DataOffset */,
+    __in ULONG64 /* StartOffset */
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP CdbDebugEventCallbackBase::ExitThread(
+    THIS_
+    __in ULONG /* ExitCode */
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP CdbDebugEventCallbackBase::CreateProcess(
+    THIS_
+    __in ULONG64 /* ImageFileHandle */,
+    __in ULONG64 /* Handle */,
+    __in ULONG64 /* BaseOffset */,
+    __in ULONG /* ModuleSize */,
+    __in_opt PCWSTR /* ModuleName */,
+    __in_opt PCWSTR /* ImageName */,
+    __in ULONG /* CheckSum */,
+    __in ULONG /* TimeDateStamp */,
+    __in ULONG64 /* InitialThreadHandle */,
+    __in ULONG64 /* ThreadDataOffset */,
+    __in ULONG64 /* StartOffset */
+    )
+{    
+    return S_OK;
+}
+
+STDMETHODIMP CdbDebugEventCallbackBase::ExitProcess(
+    THIS_
+    __in ULONG /* ExitCode */
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP CdbDebugEventCallbackBase::LoadModule(
+    THIS_
+    __in ULONG64 /* ImageFileHandle */,
+    __in ULONG64 /* BaseOffset */,
+    __in ULONG /* ModuleSize */,
+    __in_opt PCWSTR /* ModuleName */,
+    __in_opt PCWSTR /* ImageName */,
+    __in ULONG /* CheckSum */,
+    __in ULONG /* TimeDateStamp */
+    )
+{    
+    return S_OK;
+}
+
+STDMETHODIMP CdbDebugEventCallbackBase::UnloadModule(
+    THIS_
+    __in_opt PCWSTR /* ImageBaseName */,
+    __in ULONG64 /* BaseOffset */
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP CdbDebugEventCallbackBase::SystemError(
+    THIS_
+    __in ULONG /* Error */,
+    __in ULONG /* Level */
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP CdbDebugEventCallbackBase::SessionStatus(
+    THIS_
+    __in ULONG /* Status */
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP CdbDebugEventCallbackBase::ChangeDebuggeeState(
+    THIS_
+    __in ULONG /* Flags */,
+    __in ULONG64 /* Argument */
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP CdbDebugEventCallbackBase::ChangeEngineState(
+    THIS_
+    __in ULONG /* Flags */,
+    __in ULONG64 /* Argument */
+    )
+{
+    return S_OK;
+}
+
+STDMETHODIMP CdbDebugEventCallbackBase::ChangeSymbolState(
+    THIS_
+    __in ULONG /* Flags */,
+    __in ULONG64 /* Argument */
+    )
+{    
+    return S_OK;
+}
+
+IDebugEventCallbacksWide *CdbDebugEventCallbackBase::getEventCallback(IDebugClient5 *clnt)
+{
+    IDebugEventCallbacksWide *rc = 0;
+    if (SUCCEEDED(clnt->GetEventCallbacksWide(&rc)))
+        return rc;
+    return 0;
+}
+
+// ---------- CdbDebugEventCallback
+
+CdbDebugEventCallback::CdbDebugEventCallback(CdbDebugEngine* dbg) :
+    m_pEngine(dbg)
+{
+}
+
 STDMETHODIMP CdbDebugEventCallback::GetInterestMask(THIS_ __out PULONG mask)
 {
     *mask = DEBUG_EVENT_CREATE_PROCESS  | DEBUG_EVENT_EXIT_PROCESS
             | DEBUG_EVENT_LOAD_MODULE   | DEBUG_EVENT_UNLOAD_MODULE
             | DEBUG_EVENT_CREATE_THREAD | DEBUG_EVENT_EXIT_THREAD
             | DEBUG_EVENT_BREAKPOINT
-            | DEBUG_EVENT_EXCEPTION
-            ;
+            | DEBUG_EVENT_EXCEPTION;
     return S_OK;
 }
 
-STDMETHODIMP CdbDebugEventCallback::Breakpoint(THIS_ __in PDEBUG_BREAKPOINT Bp)
+STDMETHODIMP CdbDebugEventCallback::Breakpoint(THIS_ __in PDEBUG_BREAKPOINT2 Bp)
 {
     if (debugCDB)
         qDebug() << Q_FUNC_INFO;
@@ -150,8 +288,8 @@ STDMETHODIMP CdbDebugEventCallback::CreateProcess(
     __in ULONG64 Handle,
     __in ULONG64 BaseOffset,
     __in ULONG ModuleSize,
-    __in_opt PCSTR ModuleName,
-    __in_opt PCSTR ImageName,
+    __in_opt PCWSTR ModuleName,
+    __in_opt PCWSTR ImageName,
     __in ULONG CheckSum,
     __in ULONG TimeDateStamp,
     __in ULONG64 InitialThreadHandle,
@@ -175,7 +313,7 @@ STDMETHODIMP CdbDebugEventCallback::CreateProcess(
     m_pEngine->m_d->m_debuggerManagerAccess->notifyInferiorRunning();
 
     ULONG currentThreadId;
-    if (SUCCEEDED(m_pEngine->m_d->m_pDebugSystemObjects->GetThreadIdByHandle(InitialThreadHandle, &currentThreadId)))
+    if (SUCCEEDED(m_pEngine->m_d->m_cif.debugSystemObjects->GetThreadIdByHandle(InitialThreadHandle, &currentThreadId)))
         m_pEngine->m_d->m_currentThreadId = currentThreadId;
     else
         m_pEngine->m_d->m_currentThreadId = 0;
@@ -201,8 +339,8 @@ STDMETHODIMP CdbDebugEventCallback::LoadModule(
     __in ULONG64 ImageFileHandle,
     __in ULONG64 BaseOffset,
     __in ULONG ModuleSize,
-    __in_opt PCSTR ModuleName,
-    __in_opt PCSTR ImageName,
+    __in_opt PCWSTR ModuleName,
+    __in_opt PCWSTR ImageName,
     __in ULONG CheckSum,
     __in ULONG TimeDateStamp
     )
@@ -216,13 +354,13 @@ STDMETHODIMP CdbDebugEventCallback::LoadModule(
     Q_UNUSED(TimeDateStamp)
     if (debugCDB > 1)
         qDebug() << Q_FUNC_INFO << ModuleName;
-    m_pEngine->m_d->updateModules();
+    m_pEngine->m_d->handleModuleLoad(QString::fromUtf16(ModuleName));
     return S_OK;
 }
 
 STDMETHODIMP CdbDebugEventCallback::UnloadModule(
     THIS_
-    __in_opt PCSTR ImageBaseName,
+    __in_opt PCWSTR ImageBaseName,
     __in ULONG64 BaseOffset
     )
 {
@@ -245,46 +383,28 @@ STDMETHODIMP CdbDebugEventCallback::SystemError(
     return S_OK;
 }
 
-STDMETHODIMP CdbDebugEventCallback::SessionStatus(
-    THIS_
-    __in ULONG Status
-    )
+// -----------IgnoreDebugEventCallback
+IgnoreDebugEventCallback::IgnoreDebugEventCallback()
 {
-    Q_UNUSED(Status)
-    return S_OK;
 }
 
-STDMETHODIMP CdbDebugEventCallback::ChangeDebuggeeState(
-    THIS_
-    __in ULONG Flags,
-    __in ULONG64 Argument
-    )
+STDMETHODIMP IgnoreDebugEventCallback::GetInterestMask(THIS_ __out PULONG mask)
 {
-    Q_UNUSED(Flags)
-    Q_UNUSED(Argument)
+    *mask = 0;
     return S_OK;
 }
 
-STDMETHODIMP CdbDebugEventCallback::ChangeEngineState(
-    THIS_
-    __in ULONG Flags,
-    __in ULONG64 Argument
-    )
+// --------- EventCallbackRedirector
+EventCallbackRedirector::EventCallbackRedirector(IDebugClient5 *client,  IDebugEventCallbacksWide *cb) :
+        m_client(client),
+        m_oldCb(CdbDebugEventCallbackBase::getEventCallback(client))
 {
-    Q_UNUSED(Flags)
-    Q_UNUSED(Argument)
-    return S_OK;
+    client->SetEventCallbacksWide(cb);
 }
 
-STDMETHODIMP CdbDebugEventCallback::ChangeSymbolState(
-    THIS_
-    __in ULONG Flags,
-    __in ULONG64 Argument
-    )
+EventCallbackRedirector::~EventCallbackRedirector()
 {
-    Q_UNUSED(Flags)
-    Q_UNUSED(Argument)
-    return S_OK;
+    m_client->SetEventCallbacksWide(m_oldCb);
 }
 
 } // namespace Internal
diff --git a/src/plugins/debugger/cdb/cdbdebugeventcallback.h b/src/plugins/debugger/cdb/cdbdebugeventcallback.h
index d3ab4974f64c8cf497cb9a38d269f1982c6eee5c..d33aa4375547b89d8b3709dfe9733e58fc5e1032 100644
--- a/src/plugins/debugger/cdb/cdbdebugeventcallback.h
+++ b/src/plugins/debugger/cdb/cdbdebugeventcallback.h
@@ -32,17 +32,21 @@
 
 #include <windows.h>
 #include <inc/dbgeng.h>
+#include <QtCore/QtGlobal>
 
 namespace Debugger {
 namespace Internal {
 
 class CdbDebugEngine;
 
-class CdbDebugEventCallback : public IDebugEventCallbacks
+// Base class for event callbacks that takes care
+// Active X magic. Provides base implementations with
+// the exception of GetInterestMask
+class CdbDebugEventCallbackBase  : public IDebugEventCallbacksWide
 {
+protected:
+    CdbDebugEventCallbackBase();
 public:
-    explicit CdbDebugEventCallback(CdbDebugEngine* dbg);
-
     // IUnknown.
     STDMETHOD(QueryInterface)(
         THIS_
@@ -58,14 +62,9 @@ public:
 
     // IDebugEventCallbacks.
 
-    STDMETHOD(GetInterestMask)(
-        THIS_
-        __out PULONG mask
-        );
-
     STDMETHOD(Breakpoint)(
         THIS_
-        __in PDEBUG_BREAKPOINT Bp
+        __in PDEBUG_BREAKPOINT2 Bp
         );
 
     STDMETHOD(Exception)(
@@ -91,8 +90,8 @@ public:
         __in ULONG64 Handle,
         __in ULONG64 BaseOffset,
         __in ULONG ModuleSize,
-        __in_opt PCSTR ModuleName,
-        __in_opt PCSTR ImageName,
+        __in_opt PCWSTR ModuleName,
+        __in_opt PCWSTR ImageName,
         __in ULONG CheckSum,
         __in ULONG TimeDateStamp,
         __in ULONG64 InitialThreadHandle,
@@ -110,15 +109,15 @@ public:
         __in ULONG64 ImageFileHandle,
         __in ULONG64 BaseOffset,
         __in ULONG ModuleSize,
-        __in_opt PCSTR ModuleName,
-        __in_opt PCSTR ImageName,
+        __in_opt PCWSTR ModuleName,
+        __in_opt PCWSTR ImageName,
         __in ULONG CheckSum,
         __in ULONG TimeDateStamp
         );
 
     STDMETHOD(UnloadModule)(
         THIS_
-        __in_opt PCSTR ImageBaseName,
+        __in_opt PCWSTR ImageBaseName,
         __in ULONG64 BaseOffset
         );
 
@@ -151,10 +150,116 @@ public:
         __in ULONG64 Argument
         );
 
+
+    static IDebugEventCallbacksWide *getEventCallback(IDebugClient5 *clnt);
+};
+
+class CdbDebugEventCallback : public CdbDebugEventCallbackBase
+{
+public:
+    explicit CdbDebugEventCallback(CdbDebugEngine* dbg);
+
+    // IDebugEventCallbacks.
+
+    STDMETHOD(GetInterestMask)(
+        THIS_
+        __out PULONG mask
+        );
+
+    STDMETHOD(Breakpoint)(
+        THIS_
+        __in PDEBUG_BREAKPOINT2 Bp
+        );
+
+    STDMETHOD(Exception)(
+        THIS_
+        __in PEXCEPTION_RECORD64 Exception,
+        __in ULONG FirstChance
+        );
+
+    STDMETHOD(CreateThread)(
+        THIS_
+        __in ULONG64 Handle,
+        __in ULONG64 DataOffset,
+        __in ULONG64 StartOffset
+        );
+    STDMETHOD(ExitThread)(
+        THIS_
+        __in ULONG ExitCode
+        );
+
+    STDMETHOD(CreateProcess)(
+        THIS_
+        __in ULONG64 ImageFileHandle,
+        __in ULONG64 Handle,
+        __in ULONG64 BaseOffset,
+        __in ULONG ModuleSize,
+        __in_opt PCWSTR ModuleName,
+        __in_opt PCWSTR ImageName,
+        __in ULONG CheckSum,
+        __in ULONG TimeDateStamp,
+        __in ULONG64 InitialThreadHandle,
+        __in ULONG64 ThreadDataOffset,
+        __in ULONG64 StartOffset
+        );
+
+    STDMETHOD(ExitProcess)(
+        THIS_
+        __in ULONG ExitCode
+        );
+
+    STDMETHOD(LoadModule)(
+        THIS_
+        __in ULONG64 ImageFileHandle,
+        __in ULONG64 BaseOffset,
+        __in ULONG ModuleSize,
+        __in_opt PCWSTR ModuleName,
+        __in_opt PCWSTR ImageName,
+        __in ULONG CheckSum,
+        __in ULONG TimeDateStamp
+        );
+
+    STDMETHOD(UnloadModule)(
+        THIS_
+        __in_opt PCWSTR ImageBaseName,
+        __in ULONG64 BaseOffset
+        );
+
+    STDMETHOD(SystemError)(
+        THIS_
+        __in ULONG Error,
+        __in ULONG Level
+        );
+
 private:
     CdbDebugEngine *m_pEngine;
 };
 
+// Event handler that ignores everything
+class IgnoreDebugEventCallback : public CdbDebugEventCallbackBase
+{
+public:
+    explicit IgnoreDebugEventCallback();
+
+    STDMETHOD(GetInterestMask)(
+        THIS_
+        __out PULONG mask
+        );
+};
+
+// Utility class to temporarily redirect events to another handler
+// as long as in scope
+class EventCallbackRedirector {
+    Q_DISABLE_COPY(EventCallbackRedirector)
+public:
+    explicit EventCallbackRedirector(IDebugClient5 *client,  IDebugEventCallbacksWide *cb);
+    ~EventCallbackRedirector();
+private:
+    IDebugClient5 *m_client;
+    IDebugEventCallbacksWide *m_oldCb;
+};
+
+
 } // namespace Internal
 } // namespace Debugger
 
diff --git a/src/plugins/debugger/cdb/cdbdebugoutput.cpp b/src/plugins/debugger/cdb/cdbdebugoutput.cpp
index 114c59c7712b31733d3ae99f6e85c6434e8ef1a4..8517b0f220bc901b311f07b0f0bc7de1694c651e 100644
--- a/src/plugins/debugger/cdb/cdbdebugoutput.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugoutput.cpp
@@ -155,5 +155,18 @@ void CdbDebugOutput::output(ULONG mask, const QString &msg)
     }
 }
 
+// Utility class to temporarily redirect output to another handler
+// as long as in scope
+OutputRedirector::OutputRedirector(IDebugClient5 *client, IDebugOutputCallbacksWide *newHandler) :
+        m_client(client),
+        m_oldHandler(CdbDebugOutputBase::getOutputCallback(client))
+{
+    m_client->SetOutputCallbacksWide(newHandler);
+}
+OutputRedirector::~OutputRedirector()
+{
+    m_client->SetOutputCallbacksWide(m_oldHandler);
+}
+
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdbdebugoutput.h b/src/plugins/debugger/cdb/cdbdebugoutput.h
index f13fedac35e57f1fc17444361daffeef0966ad11..9deb527e9a39fff970cd67297ad85768263fce67 100644
--- a/src/plugins/debugger/cdb/cdbdebugoutput.h
+++ b/src/plugins/debugger/cdb/cdbdebugoutput.h
@@ -105,6 +105,18 @@ private:
     QString m_result;
 };
 
+// Utility class to temporarily redirect output to another handler
+// as long as in scope
+class OutputRedirector {
+    Q_DISABLE_COPY(OutputRedirector)
+public:
+    explicit OutputRedirector(IDebugClient5 *client, IDebugOutputCallbacksWide *newHandler);
+    ~OutputRedirector();
+private:
+    IDebugClient5 *m_client;
+    IDebugOutputCallbacksWide *m_oldHandler;
+};
+
 } // namespace Internal
 } // namespace Debugger
 
diff --git a/src/plugins/debugger/cdb/cdbdumperhelper.cpp b/src/plugins/debugger/cdb/cdbdumperhelper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d0b4332811bb641ebe4ef3d3e7d72d4928ead295
--- /dev/null
+++ b/src/plugins/debugger/cdb/cdbdumperhelper.cpp
@@ -0,0 +1,223 @@
+/**************************************************************************
+**
+** 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 "cdbdumperhelper.h"
+#include "cdbmodules.h"
+#include "cdbdebugengine_p.h"
+#include "cdbdebugoutput.h"
+#include "cdbdebugeventcallback.h"
+
+#include <QtCore/QRegExp>
+
+enum { loadDebug = 0 };
+
+namespace Debugger {
+namespace Internal {
+
+// Alloc memory in debuggee using the ".dvalloc" command as
+// there seems to be no API for it.
+static bool allocDebuggeeMemory(IDebugControl4 *ctl,
+                                IDebugClient5 *client,
+                                int size, ULONG64 *address, QString *errorMessage)
+{
+    *address = 0;
+    const QString allocCmd = QLatin1String(".dvalloc ") + QString::number(size);
+    StringOutputHandler stringHandler;
+    OutputRedirector redir(client, &stringHandler);
+    if (!CdbDebugEnginePrivate::executeDebuggerCommand(ctl, allocCmd, errorMessage))
+        return false;
+   // "Allocated 1000 bytes starting at 003a0000" .. hopefully never localized
+    bool ok = false;
+    const QString output = stringHandler.result();
+    const int lastBlank = output.lastIndexOf(QLatin1Char(' '));
+    if (lastBlank != -1) {
+        const qint64 addri = output.mid(lastBlank + 1).toLongLong(&ok, 16);
+        if (ok)
+            *address = addri;
+    }
+    if (!ok) {
+        *errorMessage = QString::fromLatin1("Failed to parse output '%1'").arg(output);
+        return false;
+    }
+    return true;
+}
+
+// Alloc an AscII string in debuggee
+static bool createDebuggeeAscIIString(IDebugControl4 *ctl,
+                                IDebugClient5 *client,
+                                IDebugDataSpaces4 *data,
+                                const QString &s,
+                                ULONG64 *address,
+                                QString *errorMessage)
+{
+    QByteArray sAsciiData = s.toLocal8Bit();
+    sAsciiData += '\0';
+    if (!allocDebuggeeMemory(ctl, client, sAsciiData.size(), address, errorMessage))
+        return false;
+    const HRESULT hr = data->WriteVirtual(*address, sAsciiData.data(), sAsciiData.size(), 0);
+    if (FAILED(hr)) {
+        *errorMessage= msgComFailed("WriteVirtual", hr);
+        return false;
+    }
+    return true;
+}
+
+// Locate 'qstrdup' in the (potentially namespaced) corelib. For some
+// reason, the symbol is present in QtGui as well without type information.
+static inline QString resolveStrdup(IDebugSymbols3 *syms, QString *errorMessage)
+{
+    QStringList matches;
+    const QString pattern = QLatin1String("*qstrdup");
+    const QRegExp corelibPattern(QLatin1String("QtCore[d]*4!"));
+    Q_ASSERT(corelibPattern.isValid());
+    if (!searchSymbols(syms, pattern, &matches, errorMessage))
+        return QString();
+    QStringList corelibStrdup = matches.filter(corelibPattern);
+    if (corelibStrdup.isEmpty()) {
+        *errorMessage = QString::fromLatin1("Unable to locate '%1' in '%2' (%3)").
+                        arg(pattern, corelibPattern.pattern(), matches.join(QString(QLatin1Char(','))));
+        return QString();
+    }
+    return corelibStrdup.front();
+}
+
+// Load a library into the debuggee. Currently requires
+// the QtCored4.pdb file to be present as we need "qstrdup"
+// as dummy symbol. This is ok ATM since dumpers only
+// make sense for Qt apps.
+static bool debuggeeLoadLibrary(IDebugControl4 *ctl,
+                         IDebugClient5 *client,
+                         IDebugSymbols3 *syms,
+                         IDebugDataSpaces4 *data,
+                         const QString &moduleName, QString *errorMessage)
+{
+    if (loadDebug)
+        qDebug() << Q_FUNC_INFO << moduleName;
+    // Try to ignore the breakpoints
+    IgnoreDebugEventCallback devNull;
+    EventCallbackRedirector eventRedir(client, &devNull);
+    // Make a call to LoadLibraryA. First, reserve memory in debugger
+    // and copy name over.
+    ULONG64 nameAddress;
+    if (!createDebuggeeAscIIString(ctl, client, data, moduleName, &nameAddress, errorMessage))
+        return false;
+    // We want to call "HMODULE LoadLibraryA(LPCTSTR lpFileName)"
+    // (void* LoadLibraryA(char*)). However, despite providing a symbol
+    // server, the debugger refuses to recognize it as a function.
+    // Set up the call stack with a function of same signature (qstrdup)
+    // and change the call register to LoadLibraryA() before executing "g".
+    // Prepare call.
+    const QString dummyFunc = resolveStrdup(syms, errorMessage);
+    if (dummyFunc.isEmpty())
+        return false;
+    QString callCmd = QLatin1String(".call ");
+    callCmd += dummyFunc;
+    callCmd += QLatin1String("(0x");
+    callCmd += QString::number(nameAddress, 16);
+    callCmd += QLatin1Char(')');
+    if (!CdbDebugEnginePrivate::executeDebuggerCommand(ctl, callCmd, errorMessage))
+        return false;
+    if (!CdbDebugEnginePrivate::executeDebuggerCommand(ctl, QLatin1String("r eip=Kernel32!LoadLibraryA"), errorMessage))
+        return false;
+    // This will hit a breakpoint
+    if (loadDebug)
+        qDebug() << " executing 'g'";
+    if (!CdbDebugEnginePrivate::executeDebuggerCommand(ctl, QString(QLatin1Char('g')), errorMessage))
+        return false;
+    // @Todo: We cannot evaluate output here as it is asynchronous
+    return true;
+}
+
+CdbDumperHelper::CdbDumperHelper(CdbComInterfaces *cif) :
+    m_state(NotLoaded),
+    m_cif(cif)
+{
+}
+
+void CdbDumperHelper::reset(const QString &library, bool enabled)
+{
+    m_library = library;
+    m_state = enabled ? NotLoaded : Disabled;
+    m_dumpObjectSymbol = QLatin1String("qDumpObjectData440");
+    m_errorMessage.clear();
+}
+
+bool CdbDumperHelper::moduleLoadHook(const QString &name, bool *ignoreNextBreakPoint)
+{
+    *ignoreNextBreakPoint = false;
+    bool ok = true; // report failure only once
+    switch (m_state) {
+    case Disabled:
+        break;
+    case NotLoaded:
+        // Load once QtCore is there.
+        if (name.contains(QLatin1String("QtCore"))) {
+            if (loadDebug)
+                qDebug() << Q_FUNC_INFO << '\n' << name << m_state;
+            ok = debuggeeLoadLibrary(m_cif->debugControl, m_cif->debugClient, m_cif->debugSymbols, m_cif->debugDataSpaces,
+                                     m_library, &m_errorMessage);
+            if (ok) {
+                m_state = Loading;
+                *ignoreNextBreakPoint = true;
+            } else {
+                m_state = Failed;
+            }
+        }
+        break;
+    case Loading:
+        // Hurray, loaded. Now resolve the symbols we need
+        if (name.contains(QLatin1String("gdbmacros"))) {
+            ok = resolveSymbols(&m_errorMessage);
+            if (ok) {
+                m_state = Loaded;
+            } else {
+                m_state = Failed;
+            }
+        }
+        break;
+    case Loaded:
+        break;
+    case Failed:
+        break;
+    };    
+    return ok;
+}
+
+bool CdbDumperHelper::resolveSymbols(QString *errorMessage)
+{    
+    // Resolve the symbols we need
+    m_dumpObjectSymbol = QLatin1String("qDumpObjectData440");
+    const bool rc = resolveSymbol(m_cif->debugSymbols, &m_dumpObjectSymbol, errorMessage) == ResolveSymbolOk;
+    if (loadDebug)
+        qDebug() << Q_FUNC_INFO << '\n' << rc << m_dumpObjectSymbol;
+    return rc;
+}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdbdumperhelper.h b/src/plugins/debugger/cdb/cdbdumperhelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..8947acd134cc344e347c989118ea8f53a6ccc69c
--- /dev/null
+++ b/src/plugins/debugger/cdb/cdbdumperhelper.h
@@ -0,0 +1,87 @@
+/**************************************************************************
+**
+** 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 CDBDUMPERHELPER_H
+#define CDBDUMPERHELPER_H
+
+#include <QtCore/QString>
+
+namespace Debugger {
+namespace Internal {
+
+struct CdbComInterfaces;
+
+// For code clarity, all the stuff related to custom dumpers
+// goes here.
+// "Custom dumper" is a library compiled against the current
+// Qt containing functions to evaluate values of Qt classes
+// (such as QString, taking pointers to their addresses).
+// The library must be loaded into the debuggee.
+
+class CdbDumperHelper
+{
+public:
+   enum State {
+        Disabled,
+        NotLoaded,
+        Loading,
+        Loaded,
+        Failed
+    };
+
+    explicit CdbDumperHelper(CdbComInterfaces *cif);
+
+    // Call before starting the debugger
+    void reset(const QString &library, bool enabled);
+
+    // Call from the module loaded event handler.
+    // It will load the dumper library and resolve the required symbols
+    // when appropriate.
+    bool moduleLoadHook(const QString &name, bool *ignoreNextBreakPoint);
+
+    State state() const { return m_state; }
+
+    QString errorMessage() const { return m_errorMessage; }
+    QString library() const { return m_library; }
+
+private:
+    bool resolveSymbols(QString *errorMessage);
+
+    State m_state;
+    CdbComInterfaces *m_cif;
+
+    QString m_library;
+    QString m_dumpObjectSymbol;
+    QString m_errorMessage;
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // CDBDUMPERHELPER_H
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index 6c6bb90ea0be188cc3c2b95208822cd97b492fe0..f0c36ad222d7e763aa0bae9b3e25f2640864adbf 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -56,6 +56,7 @@
 #ifdef Q_OS_WIN
 #  include "peutils.h"
 #endif
+#include <coreplugin/icore.h>
 #include <utils/qtcassert.h>
 
 #include <QtCore/QDebug>
@@ -79,6 +80,7 @@
 #include <QtGui/QTextCursor>
 #include <QtGui/QToolBar>
 #include <QtGui/QToolButton>
+#include <QtGui/QPushButton>
 #include <QtGui/QToolTip>
 
 using namespace Debugger;
@@ -1466,6 +1468,52 @@ void DebuggerManager::reloadRegisters()
     m_engine->reloadRegisters();
 }
 
+//////////////////////////////////////////////////////////////////////
+//
+// Dumpers. "Custom dumpers" are a library compiled against the current
+// Qt containing functions to evaluate values of Qt classes
+// (such as QString, taking pointers to their addresses).
+// The library must be loaded into the debuggee.
+//
+//////////////////////////////////////////////////////////////////////
+
+bool DebuggerManager::qtDumperLibraryEnabled() const
+{
+    return theDebuggerBoolSetting(UseDebuggingHelpers);
+}
+
+QString DebuggerManager::qtDumperLibraryName() const
+{
+    if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool())
+        return theDebuggerAction(CustomDebuggingHelperLocation)->value().toString();
+    return m_dumperLib;
+}
+
+void DebuggerManager::showQtDumperLibraryWarning(const QString &details)
+{
+    QMessageBox dialog(mainWindow());
+    QPushButton *qtPref = dialog.addButton(tr("Open Qt preferences"), QMessageBox::ActionRole);
+    QPushButton *helperOff = dialog.addButton(tr("Turn helper usage off"), QMessageBox::ActionRole);
+    QPushButton *justContinue = dialog.addButton(tr("Continue anyway"), QMessageBox::AcceptRole);
+    dialog.setDefaultButton(justContinue);
+    dialog.setWindowTitle(tr("Debugging helper missing"));
+    dialog.setText(tr("The debugger did not find the debugging helper library."));
+    dialog.setInformativeText(tr("The debugging helper is used to nicely format the values of Qt "
+                                 "data types and some STL data types. "
+                                 "It must be compiled for each Qt version, "
+                                 "you can do this in the Qt preferences page by selecting "
+                                 "a Qt installation and clicking on 'Rebuild' for the debugging "
+                                 "helper."));
+    if (!details.isEmpty())
+        dialog.setDetailedText(details);
+    dialog.exec();
+    if (dialog.clickedButton() == qtPref) {
+        Core::ICore::instance()->showOptionsDialog(QLatin1String("Qt4"), QLatin1String("Qt Versions"));
+    } else if (dialog.clickedButton() == helperOff) {
+        theDebuggerAction(UseDebuggingHelpers)->setValue(qVariantFromValue(false), false);
+    }
+}
+
 
 //////////////////////////////////////////////////////////////////////
 //
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index 4062be169dcd5a90e921c853d32c3cec7bd78e2a..e5117845a95ae5f44198d356b67ef507e9862ade 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -164,6 +164,8 @@ private:
     virtual SourceFilesWindow *sourceFileWindow() = 0;
 
     virtual void showApplicationOutput(const QString &data) = 0;
+    virtual void showDebuggerOutput(const QString &prefix, const QString &msg) = 0;
+    virtual void showDebuggerInput(const QString &prefix, const QString &msg) = 0;
     
     virtual void reloadDisassembler() = 0;
     virtual void reloadModules() = 0;
@@ -250,6 +252,10 @@ public slots:
 
     void showStatusMessage(const QString &msg, int timeout = -1); // -1 forever
 
+    bool qtDumperLibraryEnabled() const;
+    QString qtDumperLibraryName() const;
+    void showQtDumperLibraryWarning(const QString &details);
+
 private slots:
     void showDebuggerOutput(const QString &prefix, const QString &msg);
     void showDebuggerInput(const QString &prefix, const QString &msg);
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 7b08b13fbdb2362e08309c46df37ad8a6ca5fb06..feef41394e274e7ddd77744460c920119d74f591 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -4128,36 +4128,6 @@ void GdbEngine::assignValueInDebugger(const QString &expression, const QString &
     sendCommand("-var-assign assign " + value, WatchVarAssign);
 }
 
-QString GdbEngine::dumperLibraryName() const
-{
-    if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool())
-        return theDebuggerAction(CustomDebuggingHelperLocation)->value().toString();
-    return q->m_dumperLib;
-}
-
-void GdbEngine::showDebuggingHelperWarning()
-{
-    QMessageBox dialog(q->mainWindow());
-    QPushButton *qtPref = dialog.addButton(tr("Open Qt preferences"), QMessageBox::ActionRole);
-    QPushButton *helperOff = dialog.addButton(tr("Turn helper usage off"), QMessageBox::ActionRole);
-    QPushButton *justContinue = dialog.addButton(tr("Continue anyway"), QMessageBox::AcceptRole);
-    dialog.setDefaultButton(justContinue);
-    dialog.setWindowTitle(tr("Debugging helper missing"));
-    dialog.setText(tr("The debugger did not find the debugging helper library."));
-    dialog.setInformativeText(tr("The debugging helper is used to nicely format the values of Qt "
-                                 "data types and some STL data types. "
-                                 "It must be compiled for each Qt version, "
-                                 "you can do this in the Qt preferences page by selecting "
-                                 "a Qt installation and clicking on 'Rebuild' for the debugging "
-                                 "helper."));
-    dialog.exec();
-    if (dialog.clickedButton() == qtPref) {
-        Core::ICore::instance()->showOptionsDialog("Qt4", "Qt Versions");
-    } else if (dialog.clickedButton() == helperOff) {
-        theDebuggerAction(UseDebuggingHelpers)->setValue(qVariantFromValue(false), false);
-    }
-}
-
 void GdbEngine::tryLoadDebuggingHelpers()
 {
     if (m_debuggingHelperState != DebuggingHelperUninitialized)
@@ -4165,16 +4135,16 @@ void GdbEngine::tryLoadDebuggingHelpers()
 
     PENDING_DEBUG("TRY LOAD CUSTOM DUMPERS");
     m_debuggingHelperState = DebuggingHelperUnavailable;
-    QString lib = dumperLibraryName();
+    if (!q->qtDumperLibraryEnabled())
+        return;
+    const QString lib = q->qtDumperLibraryName();
     //qDebug() << "DUMPERLIB: " << lib;
-
-    if (!QFileInfo(lib).exists()) {
-        debugMessage(QString("DEBUG HELPER LIBRARY IS NOT USABLE: "
-            " %1  EXISTS: %2, EXECUTABLE: %3").arg(lib)
-            .arg(QFileInfo(lib).exists())
-            .arg(QFileInfo(lib).isExecutable()));
-        if (theDebuggerBoolSetting(UseDebuggingHelpers))
-            showDebuggingHelperWarning();
+    // @TODO: same in CDB engine...
+    const QFileInfo fi(lib);
+    if (!fi.exists()) {
+        const QString msg = tr("The dumper library '%1' does not exist.").arg(lib);
+        debugMessage(msg);
+        q->showQtDumperLibraryWarning(msg);
         return;
     }
 
diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h
index 4cb7dcef6590a3f263e929cb7c95b7579e020521..67a7c9a24249154bb8824811cd0467bb764a33c5 100644
--- a/src/plugins/debugger/gdbengine.h
+++ b/src/plugins/debugger/gdbengine.h
@@ -137,7 +137,7 @@ private:
     //
     // Own stuff
     //
-    void showDebuggingHelperWarning();
+
     int currentFrame() const;
     QString currentWorkingDirectory() const { return m_pwd; }
 
@@ -202,7 +202,6 @@ private:
     void handleTargetCore(const GdbResultRecord &response);
     void handleExit(const GdbResultRecord &response);
     void debugMessage(const QString &msg);
-    QString dumperLibraryName() const;
 
     OutputCollector m_outputCollector;
     QTextCodec *m_outputCodec;