diff --git a/bin/qtcreator b/bin/qtcreator
index d00cfa0f582d6b4d6bc175fc516259f7a2b7505b..f66b08778a6692513342d706daf82102b0c884b4 100755
--- a/bin/qtcreator
+++ b/bin/qtcreator
@@ -1,9 +1,9 @@
 #!/bin/sh
 
-bindir=$(dirname $(readlink -nf $0))
+bindir=$(dirname "$(readlink -nf $0)")
 if test "$(uname -m)" = "x86_64" ; then
-    libdir=$(cd ${bindir}/../lib64 ; pwd)
+    libdir=$(cd "${bindir}/../lib64" ; pwd)
 else
-    libdir=$(cd ${bindir}/../lib ; pwd)
+    libdir=$(cd "${bindir}/../lib" ; pwd)
 fi
 LD_LIBRARY_PATH="${libdir}/qtcreator:${LD_LIBRARY_PATH}" exec "${bindir}/qtcreator.bin" ${1+"$@"}
diff --git a/src/plugins/debugger/breakwindow.cpp b/src/plugins/debugger/breakwindow.cpp
index a571fafae506cdd1d1f34c16786e99fb1ca493fd..a93885abcb1ffb5dad2147eaf1702f21e824e2d1 100644
--- a/src/plugins/debugger/breakwindow.cpp
+++ b/src/plugins/debugger/breakwindow.cpp
@@ -84,16 +84,17 @@ void BreakWindow::resizeEvent(QResizeEvent *ev)
 void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
 {
     QMenu menu;
-    QModelIndex index = indexAt(ev->pos());
+    const QModelIndex index = indexAt(ev->pos());
+    const bool indexIsValid = index.isValid();
     QAction *act0 = new QAction(tr("Delete breakpoint"), &menu);
-    act0->setEnabled(index.isValid());
+    act0->setEnabled(indexIsValid);
     QAction *act1 = new QAction(tr("Adjust column widths to contents"), &menu);
     QAction *act2 = new QAction(tr("Always adjust column widths to contents"), &menu);
     act2->setCheckable(true);
     act2->setChecked(m_alwaysResizeColumnsToContents);
     QAction *act3 = new QAction(tr("Edit condition..."), &menu);
-    act0->setEnabled(index.isValid());
-    QAction *act4 = new QAction(tr("Syncronize breakpoints"), &menu);
+    act3->setEnabled(indexIsValid);    
+    QAction *act4 = new QAction(tr("Synchronize breakpoints"), &menu);
 
     menu.addAction(act0);
     menu.addAction(act3);
diff --git a/src/plugins/debugger/cdb/cdb.pri b/src/plugins/debugger/cdb/cdb.pri
index a9e9a5cddfa7c4ff3cd646cdd00ce46004f56bb1..97932b310269369ca654d94e36de9c92a03d57f6 100644
--- a/src/plugins/debugger/cdb/cdb.pri
+++ b/src/plugins/debugger/cdb/cdb.pri
@@ -6,6 +6,10 @@ contains(QMAKE_CXX, cl) {
 
 CDB_PATH="$$(ProgramFiles)/Debugging Tools For Windows/sdk"
 
+!exists ($$CDB_PATH) {
+  CDB_PATH="$$(ProgramFiles)/Debugging Tools For Windows (x86)/sdk"
+}
+
 exists ($$CDB_PATH) {
 message("Experimental: Adding support for $$CDB_PATH")
 
@@ -25,7 +29,9 @@ HEADERS += \
     $$PWD/cdbdebugoutput.h \
     $$PWD/cdbsymbolgroupcontext.h \
     $$PWD/cdbstacktracecontext.h \
-    $$PWD/cdbbreakpoint.h
+    $$PWD/cdbbreakpoint.h \
+    $$PWD/cdbmodules.h \
+    $$PWD/cdbassembler.h
 
 SOURCES += \
     $$PWD/cdbdebugengine.cpp \
@@ -33,7 +39,9 @@ SOURCES += \
     $$PWD/cdbdebugoutput.cpp \
     $$PWD/cdbsymbolgroupcontext.cpp \
     $$PWD/cdbstacktracecontext.cpp \
-    $$PWD/cdbbreakpoint.cpp
+    $$PWD/cdbbreakpoint.cpp \
+    $$PWD/cdbmodules.cpp \
+    $$PWD/cdbassembler.cpp
 
 } else {
    message("Debugging Tools for Windows could not be found in $$CDB_PATH")
diff --git a/src/plugins/debugger/cdb/cdbassembler.cpp b/src/plugins/debugger/cdb/cdbassembler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4cb59c7d69f018d7d9f721c8b17cc5a3fa267e45
--- /dev/null
+++ b/src/plugins/debugger/cdb/cdbassembler.cpp
@@ -0,0 +1,234 @@
+/**************************************************************************
+**
+** 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 "cdbassembler.h"
+#include "cdbdebugoutput.h"
+#include "cdbdebugengine_p.h"
+#include "cdbsymbolgroupcontext.h"
+
+#include "disassemblerhandler.h"
+#include "registerhandler.h"
+
+#include <QtCore/QVector>
+
+namespace Debugger {
+namespace Internal {
+
+typedef QList<DisassemblerLine> DisassemblerLineList;
+
+bool getRegisters(IDebugControl4 *ctl,
+                  IDebugRegisters2 *ireg,
+                  QList<Register> *registers,
+                  QString *errorMessage, int base)
+{
+    registers->clear();
+    ULONG count;
+    HRESULT hr = ireg->GetNumberRegisters(&count);
+    if (FAILED(hr)) {
+        *errorMessage= msgComFailed("GetNumberRegisters", hr);
+        return false;
+    }
+    if (!count)
+        return true;
+    // Retrieve names
+    WCHAR wszBuf[MAX_PATH];
+    for (ULONG r = 0; r < count; r++) {
+        hr = ireg->GetDescriptionWide(r, wszBuf, MAX_PATH - 1, 0, 0);
+        if (FAILED(hr)) {
+            *errorMessage= msgComFailed("GetDescriptionWide", hr);
+            return false;
+        }
+        Register reg;
+        reg.name = QString::fromUtf16(wszBuf);
+        registers->push_back(reg);
+    }
+    // get values
+    QVector<DEBUG_VALUE> values(count);
+    DEBUG_VALUE *valuesPtr = &(*values.begin());
+    memset(valuesPtr, 0, count * sizeof(DEBUG_VALUE));
+    hr = ireg->GetValues(count, 0, 0, valuesPtr);
+    if (FAILED(hr)) {
+        *errorMessage= msgComFailed("GetValues", hr);
+        return false;
+    }
+    if (base < 2)
+        base = 10;
+    for (ULONG r = 0; r < count; r++)
+        (*registers)[r].value = CdbSymbolGroupContext::debugValueToString(values.at(r), ctl, 0, base);
+    return true;
+}
+
+// Output parser for disassembler lines.
+// It uses the source file lines as symbol until it encounters
+// a C++ symbol (function entered), from which then on
+// it uses that symbol.
+class DisassemblerOutputParser
+{
+public:
+    explicit DisassemblerOutputParser(DisassemblerLineList *list);
+
+    void parse(const QStringList &l);
+
+private:
+    enum ParseResult { ParseOk, ParseIgnore, ParseFailed };
+    ParseResult parseDisassembled(const QString &in, DisassemblerLine* l);
+
+    DisassemblerLineList *m_list;
+    QString m_sourceSymbol;
+    int m_sourceSymbolOffset;
+};
+
+DisassemblerOutputParser::DisassemblerOutputParser(DisassemblerLineList *list) :
+    m_list(list),
+    m_sourceSymbolOffset(0)
+{
+}
+
+// Parse a disassembler line:
+//  module!class::foo:
+//                          004017cf cc int 3
+//  77 mainwindow.cpp       004018ff 8d4da8           lea     ecx,[ebp-0x58]
+DisassemblerOutputParser::ParseResult
+    DisassemblerOutputParser::parseDisassembled(const QString &in, DisassemblerLine* l)
+{
+    l->clear();
+
+    // Check if there is a source file
+    if (in.size() < 7)
+        return ParseIgnore;
+    const bool hasSourceFile = !in.at(6).isSpace();
+
+    // Sometimes, empty lines occur
+    const QString simplified = in.simplified();
+    if (simplified.isEmpty())
+        return ParseIgnore;
+
+    QStringList tokens = simplified.split(QLatin1Char(' '), QString::SkipEmptyParts);
+    // Check for symbols as 'module!class::foo:' (start of function encountered)
+    if (tokens.size() == 1) {
+        QString symbol = tokens.front();
+        if (symbol.endsWith(QLatin1Char(':'))  && symbol.contains(QLatin1Char('!'))) {
+            symbol.truncate(symbol.size() - 1);
+            m_sourceSymbol = symbol;
+            m_sourceSymbolOffset = 0;
+        }
+        return ParseIgnore;
+    }
+    if (tokens.size() < 2)
+        return ParseIgnore;
+    // Symbol display: Do we know a symbol?
+    if (!m_sourceSymbol.isEmpty()) {
+        l->symbol = QString(QLatin1Char('<'));
+        l->symbol += m_sourceSymbol;
+        if (m_sourceSymbolOffset) {
+            l->symbol += QLatin1Char('+');
+            l->symbol += QString::number(m_sourceSymbolOffset);
+        }
+        l->symbol += QLatin1Char('>');
+        m_sourceSymbolOffset++;
+    }
+    // Read source file information: If we don't know a symbol yet,
+    // use the source file.
+    if (hasSourceFile) {
+        if (l->symbol.isEmpty()) {
+            l->symbol = tokens.at(1);
+            l->symbol += QLatin1Char('+');
+            l->symbol += tokens.front();
+        }
+        tokens.pop_front();
+        tokens.pop_front();
+    }
+    l->symbolDisplay = l->symbol;
+    // Get offset address and instruction
+    if (tokens.size() < 3)
+        return ParseFailed;
+    l->addressDisplay = l->address = tokens.front();    
+    tokens.pop_front();
+    // The rest is effective address & instructions
+    if (tokens.size() > 1)
+        tokens.pop_front();
+    l->mnemonic = tokens.join(QString(QLatin1Char(' ')));     
+    return ParseOk;
+}
+
+void DisassemblerOutputParser::parse(const QStringList &l)
+{
+    DisassemblerLine dLine;
+    foreach(const QString &line, l) {
+        switch (parseDisassembled(line, &dLine)) {
+        case ParseOk:
+            m_list->push_back(dLine);
+            break;
+        case ParseIgnore:
+            break;
+        case ParseFailed:
+            qWarning("Failed to parse '%s'\n", qPrintable(line));
+            break;
+        }
+    }
+}
+
+bool dissassemble(IDebugClient5 *client,
+                  IDebugControl4 *ctl,
+                  ULONG64 offset,
+                  unsigned long beforeLines,
+                  unsigned long afterLines,
+                  QList<DisassemblerLine> *lines,
+                  QString *errorMessage)
+{
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO << offset;
+    lines->clear();
+    const ULONG flags = DEBUG_DISASM_MATCHING_SYMBOLS|DEBUG_DISASM_SOURCE_LINE_NUMBER|DEBUG_DISASM_SOURCE_FILE_NAME;
+    // Catch the output by temporarily setting another handler.
+    // We use the method that outputs to the output handler as it
+    // conveniently provides the 'beforeLines' context (stepping back
+    // 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);
+    // 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));
+        return false;
+    }
+    DisassemblerOutputParser parser(lines);
+    parser.parse(stringHandler.result().split(QLatin1Char('\n')));
+    return true;
+}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdbassembler.h b/src/plugins/debugger/cdb/cdbassembler.h
new file mode 100644
index 0000000000000000000000000000000000000000..e43492ebaf2dccb0a16aa5581e237728bf8a3003
--- /dev/null
+++ b/src/plugins/debugger/cdb/cdbassembler.h
@@ -0,0 +1,64 @@
+/**************************************************************************
+**
+** 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 CDBASSEMBLER_H
+#define CDBASSEMBLER_H
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+
+#include <windows.h>
+#include <inc/dbgeng.h>
+
+namespace Debugger {
+namespace Internal {
+
+class DisassemblerLine;
+
+// Utilities related to assembler code.
+class Register;
+
+bool getRegisters(IDebugControl4 *ctl,
+                  IDebugRegisters2 *ireg,
+                  QList<Register> *registers,
+                  QString *errorMessage,
+                  int base = 10 /* 16 for hex, etc */);
+
+bool dissassemble(IDebugClient5 *client,
+                  IDebugControl4 *ctl,
+                  ULONG64 offset,
+                  unsigned long beforeLines,
+                  unsigned long afterLines,
+                  QList<DisassemblerLine> *lines,
+                  QString *errorMessage);
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // CDBASSEMBLER_H
diff --git a/src/plugins/debugger/cdb/cdbbreakpoint.cpp b/src/plugins/debugger/cdb/cdbbreakpoint.cpp
index 035c5d76fca5dc19baaf6f0449cae2dbe518cd1d..6ef96f5597ad9fe31a1c6134c8e7228018c4dccf 100644
--- a/src/plugins/debugger/cdb/cdbbreakpoint.cpp
+++ b/src/plugins/debugger/cdb/cdbbreakpoint.cpp
@@ -28,6 +28,7 @@
 **************************************************************************/
 
 #include "cdbbreakpoint.h"
+#include "cdbmodules.h"
 #include "breakhandler.h"
 #include "cdbdebugengine_p.h"
 
@@ -279,20 +280,48 @@ bool CDBBreakPoint::getBreakPoints(IDebugControl4* debugControl, QList<CDBBreakP
     return true;
 }
 
+
 // Synchronize (halted) engine breakpoints with those of the BreakHandler.
 bool CDBBreakPoint::synchronizeBreakPoints(IDebugControl4* debugControl,
+                                           IDebugSymbols3 *syms,
                                            BreakHandler *handler,
                                            QString *errorMessage)
 {    
     typedef QMap<CDBBreakPoint, int> BreakPointIndexMap;
-    BreakPointIndexMap breakPointIndexMap;
-    // convert BreakHandler's bps into a map of BreakPoint->BreakHandler->Index
     if (debugCDB)
         qDebug() << Q_FUNC_INFO;
 
+    BreakPointIndexMap breakPointIndexMap;
+    // convert BreakHandler's bps into a map of BreakPoint->BreakHandler->Index
+    // Ignore invalid functions (that could not be found) as they make
+    // the debugger hang.
     const int handlerCount = handler->size();
-    for (int i=0; i < handlerCount; ++i)
-        breakPointIndexMap.insert(CDBBreakPoint(*handler->at(i)), i);
+    const QChar moduleDelimiter = QLatin1Char('!');
+    for (int i=0; i < handlerCount; ++i) {
+        BreakpointData *bd = handler->at(i);
+        // Function breakpoints: Are the module names specified?
+        bool breakPointOk = false;
+        if (bd->funcName.isEmpty()) {
+            breakPointOk = true;
+        } else {
+            switch (resolveSymbol(syms, &bd->funcName, errorMessage)) {
+            case ResolveSymbolOk:
+                breakPointOk = true;
+                break;
+            case ResolveSymbolAmbiguous:
+                qWarning("Warning: %s\n", qPrintable(*errorMessage));
+                breakPointOk = true;
+                break;
+            case ResolveSymbolNotFound:
+            case ResolveSymbolError:
+                qWarning("Warning: %s\n", qPrintable(*errorMessage));
+                break;
+            };
+        } // function breakpoint
+        if (breakPointOk)
+            breakPointIndexMap.insert(CDBBreakPoint(*bd), i);
+    }
+    errorMessage->clear();
     // get number of engine breakpoints
     ULONG engineCount;
     if (!getBreakPointCount(debugControl, &engineCount, errorMessage))
@@ -356,5 +385,5 @@ bool CDBBreakPoint::synchronizeBreakPoints(IDebugControl4* debugControl,
     return true;
 }
 
-}
-}
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdbbreakpoint.h b/src/plugins/debugger/cdb/cdbbreakpoint.h
index 2abdddcb94273e211e4dfe80de4b497eb5ebecd5..3d925b2577e2bc251bfd803300d15d979310db7c 100644
--- a/src/plugins/debugger/cdb/cdbbreakpoint.h
+++ b/src/plugins/debugger/cdb/cdbbreakpoint.h
@@ -49,7 +49,8 @@ class BreakpointData;
 /* CDB Break point data structure with utilities to
  * apply to engine and to retrieve them from the engine and comparison. */
 
-struct CDBBreakPoint {
+struct CDBBreakPoint
+{
     CDBBreakPoint();
     CDBBreakPoint(const BreakpointData &bpd);
 
@@ -72,7 +73,8 @@ struct CDBBreakPoint {
     static bool getBreakPointCount(IDebugControl4* debugControl, ULONG *count, QString *errorMessage = 0);
     static bool getBreakPoints(IDebugControl4* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage);
     // Synchronize (halted) engine with BreakHandler.
-    static bool synchronizeBreakPoints(IDebugControl4* ctl, BreakHandler *bh, QString *errorMessage);
+    static bool synchronizeBreakPoints(IDebugControl4* ctl, IDebugSymbols3 *syms,
+                                       BreakHandler *bh, QString *errorMessage);
 
     // Return a 'canonical' file (using '/' and capitalized drive letter)
     static QString canonicalSourceFile(const QString &f);
@@ -93,7 +95,7 @@ inline bool operator!=(const CDBBreakPoint& b1, const CDBBreakPoint& b2)
 inline bool operator<(const CDBBreakPoint& b1, const CDBBreakPoint& b2)
     { return b1.compare(b2) <  0; }
 
-}
-}
+} // namespace Internal
+} // namespace Debugger
 
 #endif // CDBBREAKPOINTS_H
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index a85069cc0ef7572af87e1a4fc18afcbafc8e4e96..a71aa2ac721553f596f1de9c6d835de54380a397 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -32,11 +32,17 @@
 #include "cdbsymbolgroupcontext.h"
 #include "cdbstacktracecontext.h"
 #include "cdbbreakpoint.h"
+#include "cdbmodules.h"
+#include "cdbassembler.h"
 
+#include "debuggeractions.h"
 #include "debuggermanager.h"
 #include "breakhandler.h"
 #include "stackhandler.h"
 #include "watchhandler.h"
+#include "registerhandler.h"
+#include "moduleshandler.h"
+#include "disassemblerhandler.h"
 #include "watchutils.h"
 
 #include <utils/qtcassert.h>
@@ -51,6 +57,7 @@
 #include <QtCore/QCoreApplication>
 #include <QtGui/QMessageBox>
 #include <QtGui/QMainWindow>
+#include <QtGui/QApplication>
 
 #define DBGHELP_TRANSLATE_TCHAR
 #include <inc/Dbghelp.h>
@@ -190,7 +197,6 @@ CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEn
     m_breakEventMode(BreakEventHandle),
     m_watchTimer(-1),
     m_debugEventCallBack(engine),
-    m_debugOutputCallBack(engine),    
     m_pDebugClient(0),
     m_pDebugControl(0),
     m_pDebugSystemObjects(0),
@@ -202,7 +208,7 @@ CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEn
     m_currentStackTrace(0),
     m_firstActivatedFrame(true),
     m_mode(AttachCore)
-{   
+{
 }
 
 bool CdbDebugEnginePrivate::init(QString *errorMessage)
@@ -220,7 +226,7 @@ bool CdbDebugEnginePrivate::init(QString *errorMessage)
         return false;
     }
 
-    m_pDebugClient->SetOutputCallbacks(&m_debugOutputCallBack);
+    m_pDebugClient->SetOutputCallbacksWide(&m_debugOutputCallBack);
     m_pDebugClient->SetEventCallbacks(&m_debugEventCallBack);
 
     hr = lib.debugCreate( __uuidof(IDebugControl4), reinterpret_cast<void**>(&m_pDebugControl));
@@ -246,7 +252,7 @@ bool CdbDebugEnginePrivate::init(QString *errorMessage)
     hr = lib.debugCreate( __uuidof(IDebugRegisters2), reinterpret_cast<void**>(&m_pDebugRegisters));
     if (FAILED(hr)) {
         *errorMessage = QString::fromLatin1("Creation of IDebugRegisters2 failed: %1").arg(msgDebugEngineComResult(hr));
-        return false;    
+        return false;
     }
     if (debugCDB)
         qDebug() << QString::fromLatin1("CDB Initialization succeeded, interrupt time out %1s.").arg(getInterruptTimeOutSecs(m_pDebugControl));
@@ -293,7 +299,7 @@ void CdbDebugEnginePrivate::clearForRun()
 }
 
 void CdbDebugEnginePrivate::cleanStackTrace()
-{    
+{
     if (m_currentStackTrace) {
         delete m_currentStackTrace;
         m_currentStackTrace = 0;
@@ -308,6 +314,14 @@ CdbDebugEngine::CdbDebugEngine(DebuggerManager *parent) :
     connect(&m_d->m_consoleStubProc, SIGNAL(processError(QString)), this, SLOT(slotConsoleStubError(QString)));
     connect(&m_d->m_consoleStubProc, SIGNAL(processStarted()), this, SLOT(slotConsoleStubStarted()));
     connect(&m_d->m_consoleStubProc, SIGNAL(wrapperStopped()), this, SLOT(slotConsoleStubTerminated()));
+    connect(&m_d->m_debugOutputCallBack, SIGNAL(debuggerOutput(QString,QString)),
+            m_d->m_debuggerManager, SLOT(showDebuggerOutput(QString,QString)));
+    connect(&m_d->m_debugOutputCallBack, SIGNAL(debuggerInputPrompt(QString,QString)),
+            m_d->m_debuggerManager, SLOT(showDebuggerInput(QString,QString)));
+    connect(&m_d->m_debugOutputCallBack, SIGNAL(debuggeeOutput(QString)),
+            m_d->m_debuggerManager, SLOT(showApplicationOutput(QString)));
+    connect(&m_d->m_debugOutputCallBack, SIGNAL(debuggeeInputPrompt(QString)),
+            m_d->m_debuggerManager, SLOT(showApplicationOutput(QString)));
 }
 
 CdbDebugEngine::~CdbDebugEngine()
@@ -344,8 +358,16 @@ void CdbDebugEngine::setToolTipExpression(const QPoint & /*pos*/, const QString
 {
 }
 
+void CdbDebugEnginePrivate::clearDisplay()
+{
+    m_debuggerManagerAccess->threadsHandler()->removeAll();
+    m_debuggerManagerAccess->modulesHandler()->removeAll();
+    m_debuggerManagerAccess->registerHandler()->removeAll();
+}
+
 bool CdbDebugEngine::startDebugger()
-{    
+{
+    m_d->clearDisplay();
     m_d->m_debuggerManager->showStatusMessage("Starting Debugger", -1);
     QString errorMessage;
     bool rc = false;
@@ -467,7 +489,7 @@ void CdbDebugEngine::exitDebugger()
         // Terminate or detach if we are running
         HRESULT hr;
         switch (m_d->m_mode) {
-        case AttachExternal:            
+        case AttachExternal:
             wasRunning = m_d->isDebuggeeRunning();
             if (wasRunning) { // Process must be stopped in order to detach
                 m_d->interruptInterferiorProcess(&errorMessage);
@@ -480,7 +502,7 @@ void CdbDebugEngine::exitDebugger()
                 qDebug() << Q_FUNC_INFO << "detached" << msgDebugEngineComResult(hr);
             break;
         case StartExternal:
-        case StartInternal:            
+        case StartInternal:
             wasRunning = m_d->isDebuggeeRunning();
             if (wasRunning) { // Process must be stopped in order to terminate
                 m_d->interruptInterferiorProcess(&errorMessage);
@@ -547,7 +569,7 @@ bool CdbDebugEnginePrivate::updateLocals(int frameIndex,
         qDebug() << Q_FUNC_INFO << "\n    " << frameIndex << formatWatchList(incompletes);
 
     m_engine->filterEvaluateWatchers(&incompletes, wh);
-    if (!incompletes.empty()) {        
+    if (!incompletes.empty()) {
         const QString msg = QLatin1String("Warning: Locals left in incomplete list: ") + formatWatchList(incompletes);
         qWarning("%s\n", qPrintable(msg));
     }
@@ -591,7 +613,7 @@ void CdbDebugEngine::filterEvaluateWatchers(QList<WatchData> *wd, WatchHandler *
     bool placeHolderSeen = false;
     for (WatchList::iterator it = wd->begin(); it != wd->end(); ) {
         if (it->iname.startsWith(watcherPrefix)) {
-            const bool isPlaceHolder = it->exp.startsWith(lessThan) && it->exp.endsWith(greaterThan);            
+            const bool isPlaceHolder = it->exp.startsWith(lessThan) && it->exp.endsWith(greaterThan);
             if (isPlaceHolder) {
                 if (!placeHolderSeen) { // Max one place holder
                     it->setChildCount(0);
@@ -602,7 +624,7 @@ void CdbDebugEngine::filterEvaluateWatchers(QList<WatchData> *wd, WatchHandler *
             } else {
                 evaluateWatcher(&(*it));
                 wh->insertData(*it);
-            }            
+            }
             it = wd->erase(it);
         } else {
             ++it;
@@ -756,7 +778,7 @@ bool CdbDebugEnginePrivate::continueInferiorProcess(QString *errorMessage)
 
 // Continue process with notifications
 bool CdbDebugEnginePrivate::continueInferior(QString *errorMessage)
-{   
+{
     ULONG executionStatus;
     if (!getExecutionStatus(m_pDebugControl, &executionStatus, errorMessage))
         return false;
@@ -795,7 +817,7 @@ bool CdbDebugEnginePrivate::interruptInterferiorProcess(QString *errorMessage)
         *errorMessage = QString::fromLatin1("DebugBreakProcess failed: %1").arg(Core::Utils::winErrorMessage(GetLastError()));
         return false;
     }
-#if 0    
+#if 0
     const HRESULT hr = m_pDebugControl->SetInterrupt(DEBUG_INTERRUPT_ACTIVE|DEBUG_INTERRUPT_EXIT);
     if (FAILED(hr)) {
         *errorMessage = QString::fromLatin1("Unable to interrupt debuggee after %1s: %2").
@@ -842,7 +864,7 @@ void CdbDebugEngine::assignValueInDebugger(const QString &expr, const QString &v
     if (debugCDB)
         qDebug() << Q_FUNC_INFO << expr << value;
     const int frameIndex = m_d->m_debuggerManagerAccess->stackHandler()->currentIndex();
-    QString errorMessage;    
+    QString errorMessage;
     bool success = false;
     do {
         QString newValue;
@@ -850,7 +872,7 @@ void CdbDebugEngine::assignValueInDebugger(const QString &expr, const QString &v
         if (!sg)
             break;
         if (!sg->assignValue(expr, value, &newValue, &errorMessage))
-            break;        
+            break;
         // Update view
         WatchHandler *watchHandler = m_d->m_debuggerManagerAccess->watchHandler();
         if (WatchData *fwd = watchHandler->findData(expr)) {
@@ -1010,6 +1032,7 @@ bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessa
     }
 
     return CDBBreakPoint::synchronizeBreakPoints(m_pDebugControl,
+                                                 m_pDebugSymbols,
                                                  m_debuggerManagerAccess->breakHandler(),
                                                  errorMessage);
 }
@@ -1024,6 +1047,30 @@ void CdbDebugEngine::saveSessionData()
 
 void CdbDebugEngine::reloadDisassembler()
 {
+    enum { ContextLines = 40 };
+    // Do we have a top stack frame?
+    const ULONG64 offset = m_d->m_currentStackTrace ? m_d->m_currentStackTrace->instructionOffset() : ULONG64(0);
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO << offset;
+
+    DisassemblerHandler *dh = m_d->m_debuggerManagerAccess->disassemblerHandler();
+    if (offset) {
+        QList<DisassemblerLine> lines;
+        QString errorMessage;
+        QApplication::setOverrideCursor(Qt::WaitCursor);
+        const bool drc = dissassemble(m_d->m_pDebugClient, m_d->m_pDebugControl, offset,
+                         ContextLines, ContextLines, &lines, &errorMessage);
+        QApplication::restoreOverrideCursor();
+        if (drc) {
+            dh->setLines(lines);
+            if (lines.size() > ContextLines)
+                dh->setCurrentLine(ContextLines);
+        } else {
+            qWarning("reloadDisassembler: %s\n", qPrintable(errorMessage));
+        }
+    } else {
+        dh->setLines(QList<DisassemblerLine>());
+    }
 }
 
 void CdbDebugEngine::reloadModules()
@@ -1042,8 +1089,54 @@ void CdbDebugEngine::loadAllSymbols()
         qDebug() << Q_FUNC_INFO;
 }
 
+QList<Symbol> CdbDebugEngine::moduleSymbols(const QString &moduleName)
+{
+    QList<Symbol> rc;
+    QString errorMessage;
+    bool success = false;
+    do {
+        if (m_d->isDebuggeeRunning()) {
+            errorMessage = tr("Cannot retrieve symbols while the debuggee is running.");
+            break;
+        }
+        if (!getModuleSymbols(m_d->m_pDebugSymbols, moduleName, &rc, &errorMessage))
+            break;
+        success = true;
+    } while (false);
+    if (!success)
+        qWarning("%s\n", qPrintable(errorMessage));
+    return rc;
+}
+
+static inline int registerFormatBase()
+{
+    switch(checkedRegisterFormatAction()) {
+    case FormatHexadecimal:
+        return 16;
+    case FormatDecimal:
+        return 10;
+    case FormatOctal:
+        return 8;
+    case FormatBinary:
+        return 2;
+        break;
+    case FormatRaw:
+    case FormatNatural:
+        break;
+    }
+    return 10;
+}
+
 void CdbDebugEngine::reloadRegisters()
 {
+    const int intBase = registerFormatBase();
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO << intBase;
+    QList<Register> registers;
+    QString errorMessage;
+    if (!getRegisters(m_d->m_pDebugControl, m_d->m_pDebugRegisters, &registers, &errorMessage, intBase))
+        qWarning("reloadRegisters() failed: %s\n", qPrintable(errorMessage));
+    m_d->m_debuggerManagerAccess->registerHandler()->setRegisters(registers);
 }
 
 void CdbDebugEngine::timerEvent(QTimerEvent* te)
@@ -1067,7 +1160,7 @@ void CdbDebugEngine::timerEvent(QTimerEvent* te)
             break;
         case E_UNEXPECTED: // Occurs on ExitProcess.
             killWatchTimer();
-            break;        
+            break;
     }
 }
 
@@ -1142,21 +1235,34 @@ void CdbDebugEnginePrivate::updateThreadList()
 
     ThreadsHandler* th = m_debuggerManagerAccess->threadsHandler();
     QList<ThreadData> threads;
+    bool success = false;
+    QString errorMessage;
+    do {
+        ULONG numberOfThreads;
+        HRESULT hr= m_pDebugSystemObjects->GetNumberThreads(&numberOfThreads);
+        if (FAILED(hr)) {
+            errorMessage= msgComFailed("GetNumberThreads", hr);
+            break;
+        }
+        const ULONG maxThreadIds = 256;
+        ULONG threadIds[maxThreadIds];
+        ULONG biggestThreadId = qMin(maxThreadIds, numberOfThreads - 1);
+        hr = m_pDebugSystemObjects->GetThreadIdsByIndex(0, biggestThreadId, threadIds, 0);
+        if (FAILED(hr)) {
+            errorMessage= msgComFailed("GetThreadIdsByIndex", hr);
+            break;
+        }
+        for (ULONG threadId = 0; threadId <= biggestThreadId; ++threadId) {
+            ThreadData thread;
+            thread.id = threadId;
+            threads.append(thread);
+        }
 
-    HRESULT hr;
-    ULONG numberOfThreads;
-    hr = m_pDebugSystemObjects->GetNumberThreads(&numberOfThreads);
-    const ULONG maxThreadIds = 256;
-    ULONG threadIds[maxThreadIds];
-    ULONG biggestThreadId = qMin(maxThreadIds, numberOfThreads - 1);
-    hr = m_pDebugSystemObjects->GetThreadIdsByIndex(0, biggestThreadId, threadIds, 0);
-    for (ULONG threadId = 0; threadId <= biggestThreadId; ++threadId) {
-        ThreadData thread;
-        thread.id = threadId;
-        threads.append(thread);
-    }
-
-    th->setThreads(threads);
+        th->setThreads(threads);
+        success = true;
+    } while (false);
+    if (!success)
+        qWarning("updateThreadList() failed: %s\n", qPrintable(errorMessage));
 }
 
 void CdbDebugEnginePrivate::updateStackTrace()
@@ -1166,6 +1272,7 @@ void CdbDebugEnginePrivate::updateStackTrace()
     // Create a new context
     clearForRun();
     QString errorMessage;
+    m_engine->reloadRegisters();
     m_currentStackTrace =
             CdbStackTraceContext::create(m_pDebugControl, m_pDebugSystemObjects,
                                          m_pDebugSymbols, m_currentThreadId, &errorMessage);
@@ -1173,6 +1280,10 @@ void CdbDebugEnginePrivate::updateStackTrace()
         qWarning("%s: failed to create trace context: %s", Q_FUNC_INFO, qPrintable(errorMessage));
         return;
     }
+    // Disassembling slows things down a bit. Assembler is still available via menu.
+#if 0
+    m_engine->reloadDisassembler(); // requires stack trace
+#endif
     const QList<StackFrame> stackFrames = m_currentStackTrace->frames();
     // find the first usable frame and select it
     int current = -1;
@@ -1188,14 +1299,17 @@ void CdbDebugEnginePrivate::updateStackTrace()
     if (current >= 0) {
         m_debuggerManagerAccess->stackHandler()->setCurrentIndex(current);
         m_engine->activateFrame(current);
-    }    
+    }
 }
 
-void CdbDebugEnginePrivate::handleDebugOutput(const char *szOutputString)
+
+void CdbDebugEnginePrivate::updateModules()
 {
-    if (debugCDB && strstr(szOutputString, "ModLoad:") == 0)
-        qDebug() << Q_FUNC_INFO << szOutputString;
-    m_debuggerManagerAccess->showApplicationOutput(QString::fromLocal8Bit(szOutputString));
+    QList<Module> modules;
+    QString errorMessage;
+    if (!getModuleList(m_pDebugSymbols, &modules, &errorMessage))
+        qWarning("updateModules() failed: %s\n", qPrintable(errorMessage));
+    m_debuggerManagerAccess->modulesHandler()->setModules(modules);
 }
 
 void CdbDebugEnginePrivate::handleBreakpointEvent(PDEBUG_BREAKPOINT pBP)
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h
index f37bade1cd3db6850bb36e1f1ccc53c174d9cd21..fe91fef5df8a150bf5e240d15e3a22c6cefbfd28 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine.h
@@ -87,6 +87,7 @@ public:
     virtual void reloadModules();
     virtual void loadSymbols(const QString &moduleName);
     virtual void loadAllSymbols();
+    virtual QList<Symbol> moduleSymbols(const QString &moduleName);
 
     virtual void reloadRegisters();
     virtual void reloadSourceFiles();
diff --git a/src/plugins/debugger/cdb/cdbdebugengine_p.h b/src/plugins/debugger/cdb/cdbdebugengine_p.h
index 98e725cfbfd40a963a8ab2f1d2ead76ae9fb8efa..ce9c2e381bf9082c9bd7dade9c3cf1712f5e7ae5 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine_p.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine_p.h
@@ -48,7 +48,8 @@ class CdbStackTraceContext;
 // Thin wrapper around the 'DBEng' debugger engine shared library
 // which is loaded at runtime.
 
-class DebuggerEngineLibrary {
+class DebuggerEngineLibrary
+{
 public:
     DebuggerEngineLibrary();
     bool init(QString *errorMessage);
@@ -79,14 +80,16 @@ struct CdbDebugEnginePrivate
 
     bool isDebuggeeRunning() const { return m_watchTimer != -1; }
     void handleDebugEvent();
-    void updateThreadList();
+    void updateThreadList();    
     void updateStackTrace();
     bool updateLocals(int frameIndex, WatchHandler *wh, QString *errorMessage);
-    void handleDebugOutput(const char* szOutputString);
+    void updateModules();
+
     void handleBreakpointEvent(PDEBUG_BREAKPOINT pBP);
     void cleanStackTrace();
     void clearForRun();
     CdbSymbolGroupContext *getStackFrameSymbolGroupContext(int frameIndex, QString *errorMessage) const;
+    void clearDisplay();
 
     bool interruptInterferiorProcess(QString *errorMessage);
 
diff --git a/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp b/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
index 14325f8ed5561499dc17ec8aa5493483627335e4..526902e2c3d8e3603925178335c648c082b33d89 100644
--- a/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
@@ -76,8 +76,9 @@ STDMETHODIMP_(ULONG) CdbDebugEventCallback::Release(THIS)
 
 STDMETHODIMP CdbDebugEventCallback::GetInterestMask(THIS_ __out PULONG mask)
 {
-    *mask = DEBUG_EVENT_CREATE_PROCESS | DEBUG_EVENT_EXIT_PROCESS
-            //| DEBUG_EVENT_CREATE_THREAD | DEBUG_EVENT_EXIT_THREAD
+    *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
             ;
@@ -125,13 +126,9 @@ STDMETHODIMP CdbDebugEventCallback::CreateThread(
     Q_UNUSED(Handle)
     Q_UNUSED(DataOffset)
     Q_UNUSED(StartOffset)
-
     if (debugCDB)
         qDebug() << Q_FUNC_INFO;
-    //Debugger::ThreadInfo ti;
-    //ti.handle = Handle;
-    //ti.dataOffset = DataOffset;
-    //ti.startOffset = StartOffset;
+    m_pEngine->m_d->updateThreadList();
     return S_OK;
 }
 
@@ -142,7 +139,8 @@ STDMETHODIMP CdbDebugEventCallback::ExitThread(
 {
     if (debugCDB)
         qDebug() << Q_FUNC_INFO << ExitCode;
-
+    // @TODO: It seems the terminated thread is still in the list...
+    m_pEngine->m_d->updateThreadList();
     return S_OK;
 }
 
@@ -211,14 +209,14 @@ STDMETHODIMP CdbDebugEventCallback::LoadModule(
 {
     Q_UNUSED(ImageFileHandle)
     Q_UNUSED(BaseOffset)
-    Q_UNUSED(ModuleSize)
     Q_UNUSED(ModuleName)
+    Q_UNUSED(ModuleSize)
     Q_UNUSED(ImageName)
     Q_UNUSED(CheckSum)
     Q_UNUSED(TimeDateStamp)
-    if (debugCDB)
+    if (debugCDB > 1)
         qDebug() << Q_FUNC_INFO << ModuleName;
-
+    m_pEngine->m_d->updateModules();
     return S_OK;
 }
 
@@ -230,9 +228,9 @@ STDMETHODIMP CdbDebugEventCallback::UnloadModule(
 {
     Q_UNUSED(ImageBaseName)
     Q_UNUSED(BaseOffset)
-    if (debugCDB)
+    if (debugCDB > 1)
         qDebug() << Q_FUNC_INFO << ImageBaseName;
-
+    m_pEngine->m_d->updateModules();
     return S_OK;
 }
 
diff --git a/src/plugins/debugger/cdb/cdbdebugoutput.cpp b/src/plugins/debugger/cdb/cdbdebugoutput.cpp
index 0bfa568fc707650ef76d555d452a1b84a251d847..114c59c7712b31733d3ae99f6e85c6434e8ef1a4 100644
--- a/src/plugins/debugger/cdb/cdbdebugoutput.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugoutput.cpp
@@ -27,7 +27,6 @@
 **
 **************************************************************************/
 
-
 #include "cdbdebugoutput.h"
 #include "cdbdebugengine.h"
 #include "cdbdebugengine_p.h"
@@ -38,12 +37,11 @@
 namespace Debugger {
 namespace Internal {
 
-CdbDebugOutput::CdbDebugOutput(CdbDebugEngine* engine)  :
-    m_pEngine(engine)
+CdbDebugOutputBase::CdbDebugOutputBase()
 {
 }
 
-STDMETHODIMP CdbDebugOutput::QueryInterface(
+STDMETHODIMP CdbDebugOutputBase::QueryInterface(
     THIS_
     IN REFIID InterfaceId,
     OUT PVOID* Interface
@@ -52,9 +50,9 @@ STDMETHODIMP CdbDebugOutput::QueryInterface(
     *Interface = NULL;
 
     if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
-        IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks)))
+        IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacksWide)))
     {
-        *Interface = (IDebugOutputCallbacks *)this;
+        *Interface = (IDebugOutputCallbacksWide*)this;
         AddRef();
         return S_OK;
     } else {
@@ -62,30 +60,100 @@ STDMETHODIMP CdbDebugOutput::QueryInterface(
     }
 }
 
-STDMETHODIMP_(ULONG) CdbDebugOutput::AddRef(THIS)
+STDMETHODIMP_(ULONG) CdbDebugOutputBase::AddRef(THIS)
 {
     // This class is designed to be static so
     // there's no true refcount.
     return 1;
 }
 
-STDMETHODIMP_(ULONG) CdbDebugOutput::Release(THIS)
+STDMETHODIMP_(ULONG) CdbDebugOutputBase::Release(THIS)
 {
     // This class is designed to be static so
     // there's no true refcount.
     return 0;
 }
 
-STDMETHODIMP CdbDebugOutput::Output(
+STDMETHODIMP CdbDebugOutputBase::Output(
     THIS_
     IN ULONG mask,
-    IN PCSTR text
+    IN PCWSTR text
     )
 {
-    UNREFERENCED_PARAMETER(mask);
-    m_pEngine->m_d->handleDebugOutput(text);
+    output(mask, QString::fromUtf16(text));
     return S_OK;
 }
 
+IDebugOutputCallbacksWide *CdbDebugOutputBase::getOutputCallback(IDebugClient5 *client)
+{
+    IDebugOutputCallbacksWide *rc;
+     if (FAILED(client->GetOutputCallbacksWide(&rc)))
+         return 0;
+     return rc;
+}
+
+// ------------------------- CdbDebugOutput
+
+// Return a prefix for debugger messages
+static QString prefix(ULONG mask)
+{
+    if (mask & (DEBUG_OUTPUT_PROMPT_REGISTERS)) {
+        static const QString p = QLatin1String("registers:");
+        return p;
+    }
+    if (mask & (DEBUG_OUTPUT_EXTENSION_WARNING|DEBUG_OUTPUT_WARNING)) {
+        static const QString p = QLatin1String("warning:");
+        return p;
+    }
+    if (mask & (DEBUG_OUTPUT_ERROR)) {
+        static const QString p = QLatin1String("error:");
+        return p;
+    }
+    if (mask & DEBUG_OUTPUT_SYMBOLS) {
+        static const QString p = QLatin1String("symbols:");
+        return p;
+    }
+    static const QString commonPrefix = QLatin1String("cdb:");
+    return commonPrefix;
+}
+
+enum OutputKind { DebuggerOutput, DebuggerPromptOutput, DebuggeeOutput, DebuggeePromptOutput };
+
+static inline OutputKind outputKind(ULONG mask)
+{
+    if (mask & DEBUG_OUTPUT_DEBUGGEE)
+        return DebuggeeOutput;
+    if (mask & DEBUG_OUTPUT_DEBUGGEE_PROMPT)
+        return DebuggeePromptOutput;
+    if (mask & DEBUG_OUTPUT_PROMPT)
+        return DebuggerPromptOutput;
+    return DebuggerOutput;
+}
+
+CdbDebugOutput::CdbDebugOutput()
+{
+}
+
+void CdbDebugOutput::output(ULONG mask, const QString &msg)
+{
+    if (debugCDB > 1)
+        qDebug() << Q_FUNC_INFO << "\n    " << msg;
+
+    switch (outputKind(mask)) {
+    case DebuggerOutput:
+        debuggerOutput(prefix(mask), msg);
+        break;
+    case DebuggerPromptOutput:
+        emit debuggerInputPrompt(prefix(mask), msg);
+        break;
+    case DebuggeeOutput:
+        emit debuggeeOutput(msg);
+        break;
+    case DebuggeePromptOutput:
+        emit debuggeeInputPrompt(msg);
+        break;
+    }
+}
+
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdbdebugoutput.h b/src/plugins/debugger/cdb/cdbdebugoutput.h
index ea36fb6c42bd1fa1e60209b87ef8b18fade49807..f13fedac35e57f1fc17444361daffeef0966ad11 100644
--- a/src/plugins/debugger/cdb/cdbdebugoutput.h
+++ b/src/plugins/debugger/cdb/cdbdebugoutput.h
@@ -33,16 +33,17 @@
 #include <windows.h>
 #include <inc/dbgeng.h>
 
+#include <QtCore/QObject>
+
 namespace Debugger {
 namespace Internal {
 
-class CdbDebugEngine;
+// CdbDebugOutputBase is a base class for output handlers
+// that takes care of the Active X magic and conversion to QString.
 
-class CdbDebugOutput : public IDebugOutputCallbacks
+class CdbDebugOutputBase : public IDebugOutputCallbacksWide
 {
 public:
-    explicit CdbDebugOutput(CdbDebugEngine* engine);
-
     // IUnknown.
     STDMETHOD(QueryInterface)(
         THIS_
@@ -60,11 +61,48 @@ public:
     STDMETHOD(Output)(
         THIS_
         IN ULONG mask,
-        IN PCSTR text
+        IN PCWSTR text
         );
 
+    // Helpers to retrieve the output callbacks IF
+    static IDebugOutputCallbacksWide *getOutputCallback(IDebugClient5 *client);
+
+protected:
+    CdbDebugOutputBase();
+    virtual void output(ULONG mask, const QString &message) = 0;
+};
+
+// Standard CDB output handler
+class CdbDebugOutput : public QObject, public CdbDebugOutputBase
+{
+    Q_OBJECT
+public:
+    CdbDebugOutput();
+
+protected:
+    virtual void output(ULONG mask, const QString &message);
+
+signals:
+    void debuggerOutput(const QString &prefix, const QString &message);
+    void debuggerInputPrompt(const QString &prefix, const QString &message);
+    void debuggeeOutput(const QString &message);
+    void debuggeeInputPrompt(const QString &message);
+};
+
+// An output handler that adds lines to a string (to be
+// used for cases in which linebreaks occur in-between calls
+// to output).
+class StringOutputHandler : public CdbDebugOutputBase
+{
+public:
+    StringOutputHandler() {}
+    QString result() const { return m_result; }
+
+protected:
+    virtual void output(ULONG, const QString &message) { m_result += message; }
+
 private:
-    CdbDebugEngine* m_pEngine;
+    QString m_result;
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/cdb/cdbmodules.cpp b/src/plugins/debugger/cdb/cdbmodules.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..237ead9331226b1b9848f0f1e9da07295fc5c1df
--- /dev/null
+++ b/src/plugins/debugger/cdb/cdbmodules.cpp
@@ -0,0 +1,163 @@
+/**************************************************************************
+**
+** 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 "cdbmodules.h"
+#include "moduleshandler.h"
+#include "cdbdebugengine_p.h"
+
+#include <QtCore/QFileInfo>
+
+namespace Debugger {
+namespace Internal {
+
+bool getModuleList(IDebugSymbols3 *syms, QList<Module> *modules, QString *errorMessage)
+{    
+    modules->clear();
+    ULONG loadedCount, unloadedCount;
+    HRESULT hr = syms->GetNumberModules(&loadedCount, &unloadedCount);
+    if (FAILED(hr)) {
+        *errorMessage= msgComFailed("GetNumberModules", hr);
+        return false;
+    }
+    // retrieve array of parameters
+    const ULONG count = loadedCount + unloadedCount;
+    QVector<DEBUG_MODULE_PARAMETERS> parameters(count);
+    DEBUG_MODULE_PARAMETERS *parmPtr = &(*parameters.begin());
+    memset(parmPtr, 0, sizeof(DEBUG_MODULE_PARAMETERS) * count);
+    hr = syms->GetModuleParameters(count, 0, 0u, parmPtr);
+    // E_INVALIDARG indicates 'Partial results' according to docu
+    if (FAILED(hr) && hr != E_INVALIDARG) {
+        *errorMessage= msgComFailed("GetModuleParameters", hr);
+        return false;
+    }
+    // fill array
+    const QString hexPrefix = QLatin1String("0x");
+    WCHAR wszBuf[MAX_PATH];
+    for (ULONG m = 0; m < count; m++) {
+        const DEBUG_MODULE_PARAMETERS &p = parameters.at(m);
+        if (p.Base != DEBUG_INVALID_OFFSET) { // Partial results?
+            Module module;
+            module.symbolsRead = (p.Flags & DEBUG_MODULE_USER_MODE)
+                            && (p.SymbolType != DEBUG_SYMTYPE_NONE);
+            module.startAddress = hexPrefix + QString::number(p.Base, 16);
+            module.endAddress = hexPrefix + QString::number((p.Base + p.Size), 16);
+            hr = syms ->GetModuleNameStringWide(DEBUG_MODNAME_IMAGE, m, 0, wszBuf, MAX_PATH - 1, 0);
+            if (FAILED(hr) && hr != E_INVALIDARG) {
+                *errorMessage= msgComFailed("GetModuleNameStringWide", hr);
+                return false;
+            }
+            module.moduleName = QString::fromUtf16(wszBuf);
+            modules->push_back(module);
+        }
+    }
+    return true;
+}
+
+// Search symbols matching a pattern
+bool searchSymbols(IDebugSymbols3 *syms, const QString &pattern,
+                   QStringList *matches, QString *errorMessage)
+{
+    matches->clear();    
+    ULONG64 handle = 0;
+    // E_NOINTERFACE means "no match". Apparently, it does not always
+    // set handle.
+    HRESULT hr = syms->StartSymbolMatchWide(pattern.utf16(), &handle);
+    if (hr == E_NOINTERFACE) {
+        if (handle)
+            syms->EndSymbolMatch(handle);
+        return true;
+    }
+    if (FAILED(hr)) {
+        *errorMessage= msgComFailed("StartSymbolMatchWide", hr);
+        return false;
+    }
+    WCHAR wszBuf[MAX_PATH];
+    while (true) {
+        hr = syms->GetNextSymbolMatchWide(handle, wszBuf, MAX_PATH - 1, 0, 0);
+        if (hr == E_NOINTERFACE)
+            break;
+        if (hr == S_OK)
+            matches->push_back(QString::fromUtf16(wszBuf));
+    }
+    syms->EndSymbolMatch(handle);
+    if (matches->empty())
+        *errorMessage = QString::fromLatin1("No symbol matches '%1'.").arg(pattern);
+    return true;
+}
+
+// Add missing the module specifier: "main" -> "project!main"
+
+ResolveSymbolResult resolveSymbol(IDebugSymbols3 *syms, QString *symbol,
+                                  QString *errorMessage)
+{
+    // Is it an incomplete symbol?
+    if (symbol->contains(QLatin1Char('!')))
+        return ResolveSymbolOk;
+    // 'main' is a #define for gdb, but not for VS
+    if (*symbol == QLatin1String("qMain"))
+        *symbol = QLatin1String("main");
+    // resolve
+    QStringList matches;
+    if (!searchSymbols(syms, *symbol, &matches, errorMessage))
+        return ResolveSymbolError;
+    if (matches.empty())
+        return ResolveSymbolNotFound;
+    *symbol = matches.front();
+    if (matches.size() > 1) {
+        *errorMessage = QString::fromLatin1("Ambiguous symbol '%1': %2").
+                        arg(*symbol, matches.join(QString(QLatin1Char(' '))));
+        return ResolveSymbolAmbiguous;
+    }
+    return ResolveSymbolOk;
+}
+
+// List symbols of a module
+bool getModuleSymbols(IDebugSymbols3 *syms, const QString &moduleName,
+                      QList<Symbol> *symbols, QString *errorMessage)
+{
+    // Search all symbols and retrieve addresses
+    symbols->clear();
+    QStringList matches;
+    const QString pattern = QFileInfo(moduleName).baseName() + QLatin1String("!*");
+    if (!searchSymbols(syms, pattern, &matches, errorMessage))
+        return false;
+    const QString hexPrefix = QLatin1String("0x");
+    foreach (const QString &name, matches) {
+        Symbol symbol;
+        symbol.name = name;
+        ULONG64 offset = 0;
+        if (SUCCEEDED(syms->GetOffsetByNameWide(name.utf16(), &offset)))
+            symbol.address = hexPrefix + QString::number(offset, 16);
+        symbols->push_back(symbol);
+    }
+    return true;
+}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdbmodules.h b/src/plugins/debugger/cdb/cdbmodules.h
new file mode 100644
index 0000000000000000000000000000000000000000..9a375cdb031bf1465ddfe64bdec745693c7dc026
--- /dev/null
+++ b/src/plugins/debugger/cdb/cdbmodules.h
@@ -0,0 +1,65 @@
+/**************************************************************************
+**
+** 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 CDBMODULES_H
+#define CDBMODULES_H
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+
+#include <windows.h>
+#include <inc/dbgeng.h>
+
+namespace Debugger {
+namespace Internal {
+
+class Module;
+class Symbol;
+
+bool getModuleList(IDebugSymbols3 *syms, QList<Module> *modules, QString *errorMessage);
+// Search symbols matching a pattern
+bool searchSymbols(IDebugSymbols3 *syms, const QString &pattern,
+                   QStringList *matches, QString *errorMessage);
+
+// ResolveSymbol: For symbols that are missing the module specifier,
+// find the module and expand: "main" -> "project!main".
+
+enum ResolveSymbolResult { ResolveSymbolOk, ResolveSymbolAmbiguous,
+                           ResolveSymbolNotFound, ResolveSymbolError };
+
+ResolveSymbolResult resolveSymbol(IDebugSymbols3 *syms, QString *symbol, QString *errorMessage);
+
+// List symbols of a module
+bool getModuleSymbols(IDebugSymbols3 *syms, const QString &moduleName,
+                      QList<Symbol> *symbols, QString *errorMessage);
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // CDBMODULES_H
diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
index 0500657dc44b12f7d05cb996a97a8cb46b4113fe..07bf81c5bd47fd4e3eda673b3b8f2d3423c8223d 100644
--- a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
@@ -40,7 +40,8 @@ namespace Internal {
 CdbStackTraceContext::CdbStackTraceContext(IDebugSystemObjects4* pDebugSystemObjects,
                                            IDebugSymbols3* pDebugSymbols) :
         m_pDebugSystemObjects(pDebugSystemObjects),
-        m_pDebugSymbols(pDebugSymbols)
+        m_pDebugSymbols(pDebugSymbols),
+        m_instructionOffset(0)
 {
 }
 
@@ -95,6 +96,8 @@ bool CdbStackTraceContext::init(unsigned long frameCount, QString * /*errorMessa
     for (ULONG i=0; i < frameCount; ++i) {
         StackFrame frame(i);
         const ULONG64 instructionOffset = m_cdbFrames[i].InstructionOffset;
+        if (i == 0)
+            m_instructionOffset = instructionOffset;
         frame.address = QString::fromLatin1("0x%1").arg(instructionOffset, 0, 16);
 
         m_pDebugSymbols->GetNameByOffsetWide(instructionOffset, wszBuf, MAX_PATH, 0, 0);
@@ -163,5 +166,5 @@ IDebugSymbolGroup2 *CdbStackTraceContext::createSymbolGroup(int index, QString *
     return sg;
 }
 
-}
-}
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.h b/src/plugins/debugger/cdb/cdbstacktracecontext.h
index bb8286859ef2ed3ade602808f5729a1be37a3511..efbd1c1e816cfd78c5b67cd5d858f0efb3281bd6 100644
--- a/src/plugins/debugger/cdb/cdbstacktracecontext.h
+++ b/src/plugins/debugger/cdb/cdbstacktracecontext.h
@@ -66,6 +66,9 @@ public:
     QList<StackFrame> frames() const { return m_frames; }
     inline int frameCount() const { return m_frames.size(); }
 
+    // Top-Level instruction offset for disassembler
+    ULONG64 instructionOffset() const { return m_instructionOffset; }
+
     CdbSymbolGroupContext *symbolGroupContextAt(int index, QString *errorMessage);
 
 private:
@@ -78,9 +81,10 @@ private:
     DEBUG_STACK_FRAME m_cdbFrames[maxFrames];
     QVector <CdbSymbolGroupContext*> m_symbolContexts;
     QList<StackFrame> m_frames;
+    ULONG64 m_instructionOffset;
 };
 
-}
-}
+} // namespace Internal
+} // namespace Debugger
 
 #endif // CDBSTACKTRACECONTEXT_H
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
index e381a5aa86d3ce544040e2b110e615eca2476de6..5f23419278544f27327afa920406843f4ac088be 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
@@ -58,13 +58,13 @@ static inline void debugSymbolFlags(unsigned long f, QTextStream &str)
         str << "|DEBUG_SYMBOL_IS_LOCAL";
 }
 
- QTextStream &operator<<(QTextStream &str, const DEBUG_SYMBOL_PARAMETERS& p)
+QTextStream &operator<<(QTextStream &str, const DEBUG_SYMBOL_PARAMETERS &p)
 {
     str << " Type=" << p.TypeId << " parent=";
     if (isTopLevelSymbol(p)) {
         str << "<ROOT>";
     } else {
-       str << p.ParentSymbol;
+        str << p.ParentSymbol;
     }
     str << " Subs=" << p.SubElements << " flags=" << p.Flags << '/';
     debugSymbolFlags(p.Flags, str);
@@ -403,45 +403,67 @@ bool CdbSymbolGroupContext::assignValue(const QString &iname, const QString &val
 
 // format an array of integers as "0x323, 0x2322, ..."
 template <class Integer>
-static QString hexFormatArrayHelper(const Integer *array, int size)
+static QString formatArrayHelper(const Integer *array, int size, int base = 10)
 {
     QString rc;
     const QString hexPrefix = QLatin1String("0x");
     const QString separator= QLatin1String(", ");
+    const bool hex = base == 16;
     for (int i = 0; i < size; i++) {
         if (i)
             rc += separator;
-        rc += hexPrefix;
-        rc += QString::number(array[i], 16);
+        if (hex)
+            rc += hexPrefix;
+        rc += QString::number(array[i], base);
     }
     return rc;
 }
 
 QString CdbSymbolGroupContext::hexFormatArray(const unsigned short *array, int size)
 {
-    return hexFormatArrayHelper(array, size);
+    return formatArrayHelper(array, size, 16);
 }
 
-QString CdbSymbolGroupContext::debugValueToString(const DEBUG_VALUE &dv, IDebugControl4 *ctl, QString *type)
+// Helper to format an integer with
+// a hex prefix in case base = 16
+template <class Integer>
+        inline QString formatInteger(Integer value, int base)
+{
+    QString rc;
+    if (base == 16)
+        rc = QLatin1String("0x");
+    rc += QString::number(value, base);
+    return rc;
+}
+
+QString CdbSymbolGroupContext::debugValueToString(const DEBUG_VALUE &dv, IDebugControl4 *ctl,
+                                                  QString *qType,
+                                                  int integerBase)
 {
     switch (dv.Type) {
     case DEBUG_VALUE_INT8:
-        *type = QLatin1String("char");
-        return QString::number(dv.I8);
+        if (qType)
+            *qType = QLatin1String("char");
+        return formatInteger(dv.I8, integerBase);
     case DEBUG_VALUE_INT16:
-        *type = QLatin1String("short");
-        return QString::number(static_cast<short>(dv.I16));
+        if (qType)
+            *qType = QLatin1String("short");
+        return formatInteger(static_cast<short>(dv.I16), integerBase);
     case DEBUG_VALUE_INT32:
-        *type = QLatin1String("long");
-        return QString::number(static_cast<long>(dv.I32));
+        if (qType)
+            *qType = QLatin1String("long");
+        return formatInteger(static_cast<long>(dv.I32), integerBase);
     case DEBUG_VALUE_INT64:
-        *type = QLatin1String("long long");
-        return QString::number(static_cast<long long>(dv.I64));
+        if (qType)
+            *qType = QLatin1String("long long");
+        return formatInteger(static_cast<long long>(dv.I64), integerBase);
     case DEBUG_VALUE_FLOAT32:
-        *type = QLatin1String("float");
+        if (qType)
+            *qType = QLatin1String("float");
         return QString::number(dv.F32);
     case DEBUG_VALUE_FLOAT64:
-        *type = QLatin1String("double");
+        if (qType)
+            *qType = QLatin1String("double");
         return QString::number(dv.F64);
     case DEBUG_VALUE_FLOAT80:
     case DEBUG_VALUE_FLOAT128: { // Convert to double
@@ -449,28 +471,32 @@ QString CdbSymbolGroupContext::debugValueToString(const DEBUG_VALUE &dv, IDebugC
             double d = 0.0;
             if (SUCCEEDED(ctl->CoerceValue(const_cast<DEBUG_VALUE*>(&dv), DEBUG_VALUE_FLOAT64, &doubleValue)))
                 d = dv.F64;
-            *type = dv.Type == DEBUG_VALUE_FLOAT80 ? QLatin1String("80bit-float") : QLatin1String("128bit-float");
+            if (qType)
+                *qType = QLatin1String(dv.Type == DEBUG_VALUE_FLOAT80 ? "80bit-float" : "128bit-float");
             return QString::number(d);
         }
     case DEBUG_VALUE_VECTOR64: {
-        *type = QLatin1String("64bit-vector");
-        QString rc = QLatin1String("bytes: ");
-        rc += hexFormatArrayHelper(dv.VI8, 8);
-        rc += QLatin1String(" long: ");
-        rc += hexFormatArrayHelper(dv.VI32, 2);
-        return rc;
-    }
+            if (qType)
+                *qType = QLatin1String("64bit-vector");
+            QString rc = QLatin1String("bytes: ");
+            rc += formatArrayHelper(dv.VI8, 8, integerBase);
+            rc += QLatin1String(" long: ");
+            rc += formatArrayHelper(dv.VI32, 2, integerBase);
+            return rc;
+        }
     case DEBUG_VALUE_VECTOR128: {
-        *type = QLatin1String("128bit-vector");
-        QString rc = QLatin1String("bytes: ");
-        rc += hexFormatArrayHelper(dv.VI8, 16);
-        rc += QLatin1String(" long long: ");
-        rc += hexFormatArrayHelper(dv.VI64, 2);
-        return rc;
-    }    
+            if (qType)
+                *qType = QLatin1String("128bit-vector");
+            QString rc = QLatin1String("bytes: ");
+            rc += formatArrayHelper(dv.VI8, 16, integerBase);
+            rc += QLatin1String(" long long: ");
+            rc += formatArrayHelper(dv.VI64, 2, integerBase);
+            return rc;
+        }
     }
-    *type = QString::fromLatin1("Unknown type #%1:").arg(dv.Type);
-    return hexFormatArrayHelper(dv.RawBytes, 24);
+    if (qType)
+        *qType = QString::fromLatin1("Unknown type #%1:").arg(dv.Type);
+    return formatArrayHelper(dv.RawBytes, 24, integerBase);
 }
 
 // - Watch model functions
@@ -613,5 +639,5 @@ bool CdbSymbolGroupContext::completeModel(CdbSymbolGroupContext *sg,
     return true;
 }
 
-}
-}
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
index 46254ce4e04b41b087f038934cdb824d2117a836..0773133c18aa2a0eb962d1b57bb5e40f36cc355a 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
@@ -41,7 +41,7 @@
 #include <QtCore/QMap>
 
 namespace Debugger {
-    namespace Internal {
+namespace Internal {
 
 class WatchData;
 class WatchHandler;
@@ -92,7 +92,7 @@ public:
     inline bool isExpanded(const QString &prefix) const { return symbolState(prefix) == ExpandedSymbol; }
 
     // Helper to convert a DEBUG_VALUE structure to a string representation
-    static QString debugValueToString(const DEBUG_VALUE &dv, IDebugControl4 *ctl, QString *type);
+    static QString debugValueToString(const DEBUG_VALUE &dv, IDebugControl4 *ctl, QString *type = 0, int integerBase = 10);
 
     // format an array of unsigned longs as "0x323, 0x2322, ..."
     static QString hexFormatArray(const unsigned short *array, int size);
@@ -145,6 +145,7 @@ bool CdbSymbolGroupContext::getChildSymbols(const QString &prefix, OutputIterato
     return true;
 }
 
-}
-}
+} // namespace Internal
+} // namespace Debugger
+
 #endif // CDBSYMBOLGROUPCONTEXT_H
diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp
index a2e2b6f06146be8cc98db6c69d9aedcaa640b89c..6ade9b34fde2652d6e21e9207c04529ea66fdc4e 100644
--- a/src/plugins/debugger/debuggeractions.cpp
+++ b/src/plugins/debugger/debuggeractions.cpp
@@ -54,7 +54,7 @@ namespace Internal {
 //////////////////////////////////////////////////////////////////////////
 
 DebuggerSettings::DebuggerSettings(QObject *parent)
-    : QObject(parent)
+    : QObject(parent), m_registerFormatGroup(0)
 {}
 
 DebuggerSettings::~DebuggerSettings()
@@ -74,25 +74,25 @@ void DebuggerSettings::readSettings(QSettings *settings)
         item->readSettings(settings);
 }
 
-void DebuggerSettings::writeSettings(QSettings *settings)
+void DebuggerSettings::writeSettings(QSettings *settings) const
 {
     foreach (SavedAction *item, m_items)
         item->writeSettings(settings);
 }
    
-SavedAction *DebuggerSettings::item(int code)
+SavedAction *DebuggerSettings::item(int code) const
 {
     QTC_ASSERT(m_items.value(code, 0), return 0);
     return m_items.value(code, 0);
 }
 
-QString DebuggerSettings::dump()
+QString DebuggerSettings::dump() const
 {
     QString out;
     QTextStream ts(&out);
     ts  << "Debugger settings: ";
     foreach (SavedAction *item, m_items)
-        ts << "\n" << item->value().toString();
+        ts << '\n' << item->value().toString();
     return out;
 }
 
@@ -153,27 +153,27 @@ DebuggerSettings *DebuggerSettings::instance()
 
     //
     // DebuggingHelper
-    //
+    const QString debugModeGroup = QLatin1String("DebugMode");
     item = new SavedAction(instance);
     instance->insertItem(UseDebuggingHelpers, item);
     item->setDefaultValue(true);
-    item->setSettingsKey("DebugMode", "UseDebuggingHelper");
+    item->setSettingsKey(debugModeGroup, QLatin1String("UseDebuggingHelper"));
     item->setText(tr("Use Debugging Helper"));
     item->setCheckable(true);
     item->setDefaultValue(true);
 
     item = new SavedAction(instance);
     instance->insertItem(UseCustomDebuggingHelperLocation, item);
-    item->setSettingsKey("DebugMode", "CustomDebuggingHelperLocation");
+    item->setSettingsKey(debugModeGroup, QLatin1String("CustomDebuggingHelperLocation"));
     item->setCheckable(true);
 
     item = new SavedAction(instance);
     instance->insertItem(CustomDebuggingHelperLocation, item);
-    item->setSettingsKey("DebugMode", "CustomDebuggingHelperLocation");
+    item->setSettingsKey(debugModeGroup, QLatin1String("CustomDebuggingHelperLocation"));
 
     item = new SavedAction(instance);
     instance->insertItem(DebugDebuggingHelpers, item);
-    item->setSettingsKey("DebugMode", "DebugDebuggingHelpers");
+    item->setSettingsKey(debugModeGroup, QLatin1String("DebugDebuggingHelpers"));
     item->setText(tr("Debug debugging helper"));
     item->setCheckable(true);
 
@@ -193,115 +193,120 @@ DebuggerSettings *DebuggerSettings::instance()
     // Registers
     //
 
-    QActionGroup *registerFormatGroup = new QActionGroup(instance);
-    registerFormatGroup->setExclusive(true);
+    instance->m_registerFormatGroup = new QActionGroup(instance);
+    instance->m_registerFormatGroup->setExclusive(true);
 
     item = new SavedAction(instance);
     item->setText(tr("Hexadecimal"));
     item->setCheckable(true);
-    item->setSettingsKey("DebugMode", "FormatHexadecimal");
+    item->setSettingsKey(debugModeGroup, QLatin1String("FormatHexadecimal"));
     item->setChecked(true);
+    item->setData(FormatHexadecimal);
     instance->insertItem(FormatHexadecimal, item);
-    registerFormatGroup->addAction(item);
+    instance->m_registerFormatGroup->addAction(item);
 
     item = new SavedAction(instance);
     item->setText(tr("Decimal"));
     item->setCheckable(true);
-    item->setSettingsKey("DebugMode", "FormatDecimal");
+    item->setSettingsKey(debugModeGroup, QLatin1String("FormatDecimal"));
+    item->setData(FormatDecimal);
     instance->insertItem(FormatDecimal, item);
-    registerFormatGroup->addAction(item);
+    instance->m_registerFormatGroup->addAction(item);
 
     item = new SavedAction(instance);
     item->setText(tr("Octal"));
     item->setCheckable(true);
-    item->setSettingsKey("DebugMode", "FormatOctal");
+    item->setSettingsKey(debugModeGroup, QLatin1String("FormatOctal"));
+    item->setData(FormatOctal);
     instance->insertItem(FormatOctal, item);
-    registerFormatGroup->addAction(item);
+    instance->m_registerFormatGroup->addAction(item);
 
     item = new SavedAction(instance);
     item->setText(tr("Binary"));
     item->setCheckable(true);
-    item->setSettingsKey("DebugMode", "FormatBinary");
+    item->setSettingsKey(debugModeGroup, QLatin1String("FormatBinary"));
+    item->setData(FormatBinary);
     instance->insertItem(FormatBinary, item);
-    registerFormatGroup->addAction(item);
+    instance->m_registerFormatGroup->addAction(item);
 
     item = new SavedAction(instance);
     item->setText(tr("Raw"));
     item->setCheckable(true);
-    item->setSettingsKey("DebugMode", "FormatRaw");
+    item->setSettingsKey(debugModeGroup, QLatin1String("FormatRaw"));
     instance->insertItem(FormatRaw, item);
-    registerFormatGroup->addAction(item);
+    item->setData(FormatRaw);
+    instance->m_registerFormatGroup->addAction(item);
 
     item = new SavedAction(instance);
     item->setText(tr("Natural"));
     item->setCheckable(true);
-    item->setSettingsKey("DebugMode", "FormatNatural");
+    item->setSettingsKey(debugModeGroup, QLatin1String("FormatNatural"));
+    item->setData(FormatNatural);
     instance->insertItem(FormatNatural, item);
-    registerFormatGroup->addAction(item);
-
+    instance->m_registerFormatGroup->addAction(item);
 
     //
     // Settings
     //
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "Location");
+    item->setSettingsKey(debugModeGroup, QLatin1String("Location"));
     instance->insertItem(GdbLocation, item);
 
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "Environment");
+    item->setSettingsKey(debugModeGroup, QLatin1String("Environment"));
     instance->insertItem(GdbEnvironment, item);
 
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "ScriptFile");
+    item->setSettingsKey(debugModeGroup, QLatin1String("ScriptFile"));
     instance->insertItem(GdbScriptFile, item);
 
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "AutoQuit");
+    item->setSettingsKey(debugModeGroup, QLatin1String("AutoQuit"));
     item->setText(tr("Automatically quit debugger"));
     item->setCheckable(true);
     instance->insertItem(AutoQuit, item);
 
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "UseToolTips");
+    item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTips"));
     item->setText(tr("Use tooltips when debugging"));
     item->setCheckable(true);
     instance->insertItem(UseToolTips, item);
 
     item = new SavedAction(instance);
-    item->setDefaultValue("xterm");
-    item->setSettingsKey("DebugMode", "Terminal");
+    item->setDefaultValue(QLatin1String("xterm"));
+    item->setSettingsKey(debugModeGroup, QLatin1String("Terminal"));
     instance->insertItem(TerminalApplication, item);
 
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "ListSourceFiles");
+    item->setSettingsKey(debugModeGroup, QLatin1String("ListSourceFiles"));
     item->setText(tr("List source files"));
     item->setCheckable(true);
     instance->insertItem(ListSourceFiles, item);
 
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "SkipKnownFrames");
+    item->setSettingsKey(debugModeGroup, QLatin1String("SkipKnownFrames"));
     item->setText(tr("Skip known frames"));
     item->setCheckable(true);
     instance->insertItem(SkipKnownFrames, item);
 
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "AllPluginBreakpoints");
+    item->setSettingsKey(debugModeGroup, QLatin1String("AllPluginBreakpoints"));
     instance->insertItem(AllPluginBreakpoints, item);
 
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "SelectedPluginBreakpoints");
+    item->setSettingsKey(debugModeGroup, QLatin1String("SelectedPluginBreakpoints"));
     instance->insertItem(SelectedPluginBreakpoints, item);
 
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "NoPluginBreakpoints");
+    item->setSettingsKey(debugModeGroup, QLatin1String("NoPluginBreakpoints"));
     instance->insertItem(NoPluginBreakpoints, item);
 
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "SelectedPluginBreakpointsPattern");
+    item->setSettingsKey(debugModeGroup, QLatin1String("SelectedPluginBreakpointsPattern"));
     instance->insertItem(SelectedPluginBreakpointsPattern, item);
 
     item = new SavedAction(instance);
-    item->setSettingsKey("DebugMode", "MaximalStackDepth");
+    item->setSettingsKey(debugModeGroup, QLatin1String("MaximalStackDepth"));
     item->setDefaultValue(20);
     instance->insertItem(MaximalStackDepth, item);
 
@@ -316,6 +321,11 @@ DebuggerSettings *DebuggerSettings::instance()
     return instance;
 }
 
+int DebuggerSettings::checkedRegisterFormatAction() const
+{
+    return m_registerFormatGroup->checkedAction()->data().toInt();
+}
+
 //////////////////////////////////////////////////////////////////////////
 //
 // DebuggerActions
@@ -327,6 +337,11 @@ SavedAction *theDebuggerAction(int code)
     return DebuggerSettings::instance()->item(code);
 }
 
+int checkedRegisterFormatAction()
+{
+    return DebuggerSettings::instance()->checkedRegisterFormatAction();
+}
+
 bool theDebuggerBoolSetting(int code)
 {
     return DebuggerSettings::instance()->item(code)->value().toBool();
diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h
index 4b0ebd66c86f71b5331b6c720921c3421a482118..6fc9366f7bf6ce9dd733f0de28e549132b85f9e4 100644
--- a/src/plugins/debugger/debuggeractions.h
+++ b/src/plugins/debugger/debuggeractions.h
@@ -34,6 +34,9 @@
 
 #include <utils/savedaction.h>
 
+QT_BEGIN_NAMESPACE
+class QActionGroup;
+QT_END_NAMESPACE
 namespace Debugger {
 namespace Internal {
 
@@ -46,18 +49,22 @@ public:
     ~DebuggerSettings();
     
     void insertItem(int code, Core::Utils::SavedAction *item);
-    Core::Utils::SavedAction *item(int code);
+    Core::Utils::SavedAction *item(int code) const;
 
-    QString dump();
+    QString dump() const;
 
     static DebuggerSettings *instance();
 
+    // Return one of FormatHexadecimal, FormatDecimal,...
+    int checkedRegisterFormatAction() const;
+
 public slots:
     void readSettings(QSettings *settings);
-    void writeSettings(QSettings *settings);
+    void writeSettings(QSettings *settings) const;
 
 private:
     QHash<int, Core::Utils::SavedAction *> m_items; 
+    QActionGroup *m_registerFormatGroup;
 };
 
 
@@ -125,7 +132,10 @@ enum DebuggerActionCode
 // singleton access
 Core::Utils::SavedAction *theDebuggerAction(int code);
 
-// convienience
+// Return one of FormatHexadecimal, FormatDecimal,...
+int checkedRegisterFormatAction();
+
+// convenience
 bool theDebuggerBoolSetting(int code);
 QString theDebuggerStringSetting(int code);
 
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index cf2066c7909ac6d7a320e771dbc6a4e976218b18..5f8f07aed0ec993e4049ddf7d2e5f763a630f2eb 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -175,7 +175,7 @@ void DebuggerManager::init()
     m_statusLabel = new QLabel;
     m_breakWindow = new BreakWindow;
     m_disassemblerWindow = new DisassemblerWindow;
-    m_modulesWindow = new ModulesWindow;
+    m_modulesWindow = new ModulesWindow(this);
     m_outputWindow = new DebuggerOutputWindow;
     m_registerWindow = new RegisterWindow;
     m_stackWindow = new StackWindow;
@@ -213,6 +213,8 @@ void DebuggerManager::init()
     QAbstractItemView *disassemblerView =
         qobject_cast<QAbstractItemView *>(m_disassemblerWindow);
     disassemblerView->setModel(m_disassemblerHandler->model());
+    connect(m_disassemblerWindow, SIGNAL(reloadDisassemblerRequested()),
+            this, SLOT(reloadDisassembler()));
 
     // Breakpoints
     m_breakHandler = new BreakHandler;
@@ -996,6 +998,12 @@ void DebuggerManager::loadSymbols(const QString &module)
     m_engine->loadSymbols(module);
 }
 
+QList<Symbol> DebuggerManager::moduleSymbols(const QString &moduleName)
+{
+    QTC_ASSERT(m_engine, return QList<Symbol>());
+    return m_engine->moduleSymbols(moduleName);
+}
+
 void DebuggerManager::stepExec()
 {
     QTC_ASSERT(m_engine, return);
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index 72c1467c52efe4243c46dc8f40bc0bbe018f23dc..b9709a68fa59f1fe498b8af4b191b2722c81b53c 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -65,7 +65,7 @@ class WatchHandler;
 class SourceFilesWindow;
 class WatchData;
 class BreakpointData;
-
+class Symbol;
 
 // Note: the Debugger process itself is referred to as 'Debugger',
 // whereas the debugged process is referred to as 'Inferior' or 'Debuggee'.
@@ -309,6 +309,8 @@ public:
     int status() const { return m_status; }
     DebuggerStartMode startMode() const { return m_startMode; }
 
+    QList<Symbol> moduleSymbols(const QString &moduleName);
+
 signals:
     void debuggingFinished();
     void inferiorPidChanged(qint64 pid);
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index ea41b9854eae2b38c0c852d0a49e5b2a199363d9..8a1cb6baca77baba3ed1206640ec2c2c11c5a9d9 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -650,6 +650,19 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
     connect(resetToSimpleAction, SIGNAL(triggered()),
         m_manager, SLOT(setSimpleDockWidgetArrangement()));
 
+    connect(theDebuggerAction(FormatHexadecimal), SIGNAL(triggered()),
+        m_manager, SLOT(reloadRegisters()));
+    connect(theDebuggerAction(FormatDecimal), SIGNAL(triggered()),
+        m_manager, SLOT(reloadRegisters()));
+    connect(theDebuggerAction(FormatOctal), SIGNAL(triggered()),
+        m_manager, SLOT(reloadRegisters()));
+    connect(theDebuggerAction(FormatBinary), SIGNAL(triggered()),
+        m_manager, SLOT(reloadRegisters()));
+    connect(theDebuggerAction(FormatRaw), SIGNAL(triggered()),
+        m_manager, SLOT(reloadRegisters()));
+    connect(theDebuggerAction(FormatNatural), SIGNAL(triggered()),
+        m_manager, SLOT(reloadRegisters()));
+
    // FIXME:
     m_generalOptionPage = new GdbOptionPage;
     addObject(m_generalOptionPage);
diff --git a/src/plugins/debugger/disassemblerhandler.cpp b/src/plugins/debugger/disassemblerhandler.cpp
index 9ef9efec9c636bba22cc46ecc407537b7f204e5d..ee03f6cfd55bf1eade7bfe6707b35e47f1822638 100644
--- a/src/plugins/debugger/disassemblerhandler.cpp
+++ b/src/plugins/debugger/disassemblerhandler.cpp
@@ -39,6 +39,14 @@
 using namespace Debugger;
 using namespace Debugger::Internal;
 
+void DisassemblerLine::clear()
+{
+    address.clear();
+    symbol.clear();
+    addressDisplay.clear();
+    symbolDisplay.clear();
+    mnemonic.clear();
+}
 
 //////////////////////////////////////////////////////////////////
 //
diff --git a/src/plugins/debugger/disassemblerhandler.h b/src/plugins/debugger/disassemblerhandler.h
index 6c0a5b37badef8febf48f9a02e85f5d41169f44e..4b73e69ddbfd4e4c92411c9d36a2e75a6c62df4d 100644
--- a/src/plugins/debugger/disassemblerhandler.h
+++ b/src/plugins/debugger/disassemblerhandler.h
@@ -41,6 +41,8 @@ namespace Internal {
 class DisassemblerLine
 {
 public:
+    void clear();
+
     QString address;
     QString symbol;
     QString addressDisplay;
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 906b38a72b1fb8398b381b3ab16e486b5fd794c8..0279c15181f724f4559f09a68dbe444fd222f52d 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -221,19 +221,6 @@ void GdbEngine::initializeConnections()
     connect(theDebuggerAction(RecheckDebuggingHelpers), SIGNAL(triggered()),
         this, SLOT(recheckDebuggingHelperAvailability()));
 
-    connect(theDebuggerAction(FormatHexadecimal), SIGNAL(triggered()),
-        this, SLOT(reloadRegisters()));
-    connect(theDebuggerAction(FormatDecimal), SIGNAL(triggered()),
-        this, SLOT(reloadRegisters()));
-    connect(theDebuggerAction(FormatOctal), SIGNAL(triggered()),
-        this, SLOT(reloadRegisters()));
-    connect(theDebuggerAction(FormatBinary), SIGNAL(triggered()),
-        this, SLOT(reloadRegisters()));
-    connect(theDebuggerAction(FormatRaw), SIGNAL(triggered()),
-        this, SLOT(reloadRegisters()));
-    connect(theDebuggerAction(FormatNatural), SIGNAL(triggered()),
-        this, SLOT(reloadRegisters()));
-
     connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
         this, SLOT(reloadFullStack()));
     connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()),
@@ -2402,6 +2389,40 @@ void GdbEngine::loadAllSymbols()
     reloadModules();
 }
 
+QList<Symbol> GdbEngine::moduleSymbols(const QString &moduleName)
+{
+    QList<Symbol> rc;
+    bool success = false;
+    QString errorMessage;
+    do {
+        const QString nmBinary = QLatin1String("nm");
+        QProcess proc;
+        proc.start(nmBinary, QStringList() << QLatin1String("-D") << moduleName);
+        if (!proc.waitForFinished()) {
+            errorMessage = tr("Unable to run '%1': %2").arg(nmBinary, proc.errorString());
+            break;
+        }
+        const QString contents = QString::fromLocal8Bit(proc.readAllStandardOutput());
+        const QRegExp re(QLatin1String("([0-9a-f]+)?\\s+([^\\s]+)\\s+([^\\s]+)"));
+        Q_ASSERT(re.isValid());
+        foreach (const QString &line, contents.split(QLatin1Char('\n'))) {
+            if (re.indexIn(line) != -1) {
+                Symbol symbol;
+                symbol.address = re.cap(1);
+                symbol.state = re.cap(2);
+                symbol.name = re.cap(3);
+                rc.push_back(symbol);
+            } else {
+                qWarning("moduleSymbols: unhandled: %s", qPrintable(line));
+            }
+        }
+        success = true;
+    } while (false);
+    if (!success)
+        qWarning("moduleSymbols: %s\n", qPrintable(errorMessage));
+    return rc;
+}
+
 void GdbEngine::reloadModules()
 {
     sendCommand("info shared", ModulesList, QVariant());
@@ -2619,22 +2640,28 @@ void GdbEngine::handleStackListThreads(const GdbResultRecord &record, int id)
 //
 //////////////////////////////////////////////////////////////////////
 
+static inline char registerFormatChar()
+{
+    switch(checkedRegisterFormatAction()) {
+    case FormatHexadecimal:
+        return 'x';
+    case FormatDecimal:
+        return 'd';
+    case FormatOctal:
+        return 'o';
+    case FormatBinary:
+        return 't';
+    case FormatRaw:
+        return 'r';
+    default:
+        break;
+    }
+    return 'N';
+}
+
 void GdbEngine::reloadRegisters()
 {
-    QString format;
-    if (theDebuggerAction(FormatHexadecimal)->isChecked())
-        format = "x";
-    else if (theDebuggerAction(FormatDecimal)->isChecked())
-        format = "d";
-    else if (theDebuggerAction(FormatOctal)->isChecked())
-        format = "o";
-    else if (theDebuggerAction(FormatBinary)->isChecked())
-        format = "t";
-    else if (theDebuggerAction(FormatRaw)->isChecked())
-        format = "r";
-    else
-        format = "N";
-    sendCommand("-data-list-register-values " + format, RegisterListValues);
+    sendCommand(QLatin1String("-data-list-register-values ") + QLatin1Char(registerFormatChar()), RegisterListValues);
 }
 
 void GdbEngine::handleRegisterListNames(const GdbResultRecord &record)
diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h
index aebb5da6373ad95f508c4a944fe4adf162330988..b5f5868dcf57566244280517690f2d8c2a82395f 100644
--- a/src/plugins/debugger/gdbengine.h
+++ b/src/plugins/debugger/gdbengine.h
@@ -129,6 +129,7 @@ private:
 
     void loadSymbols(const QString &moduleName);
     void loadAllSymbols();
+    virtual QList<Symbol> moduleSymbols(const QString &moduleName);
 
     Q_SLOT void setDebugDebuggingHelpers(const QVariant &on);
     Q_SLOT void setUseDebuggingHelpers(const QVariant &on);
diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h
index 2bb44f8e47bd851695d0a844c90ebd97d3e74a61..0d3863a34e71eec3a2bf1b01bcbfaa292e56cdaa 100644
--- a/src/plugins/debugger/idebuggerengine.h
+++ b/src/plugins/debugger/idebuggerengine.h
@@ -31,6 +31,7 @@
 #define DEBUGGER_IDEBUGGERENGINE_H
 
 #include <QtCore/QObject>
+#include <QtCore/QList>
 
 QT_BEGIN_NAMESPACE
 class QPoint;
@@ -40,6 +41,8 @@ QT_END_NAMESPACE
 namespace Debugger {
 namespace Internal {
 
+class Symbol;
+
 class IDebuggerEngine : public QObject
 {
 public:
@@ -79,6 +82,7 @@ public:
     virtual void reloadModules() = 0;
     virtual void loadSymbols(const QString &moduleName) = 0;
     virtual void loadAllSymbols() = 0;
+    virtual QList<Symbol> moduleSymbols(const QString &moduleName) = 0;
 
     virtual void reloadRegisters() = 0;
 
diff --git a/src/plugins/debugger/moduleshandler.h b/src/plugins/debugger/moduleshandler.h
index 4c555c83929da5db324aa84e3bf16e322952791f..a6d77e4a28eef7cb8bcb0cdd0149b04451ccc69e 100644
--- a/src/plugins/debugger/moduleshandler.h
+++ b/src/plugins/debugger/moduleshandler.h
@@ -51,6 +51,19 @@ enum ModulesModelRoles
     LoadAllSymbolsRole
 };
 
+//////////////////////////////////////////////////////////////////
+//
+// Symbol
+//
+//////////////////////////////////////////////////////////////////
+
+class Symbol
+{
+public:
+    QString address;
+    QString state;
+    QString name;
+};
 
 //////////////////////////////////////////////////////////////////
 //
diff --git a/src/plugins/debugger/moduleswindow.cpp b/src/plugins/debugger/moduleswindow.cpp
index 8d87709eadc0d08c8501f89894eeba85c8e82af9..6435e8b65a6ee8f01c7e841111d90397c523adeb 100644
--- a/src/plugins/debugger/moduleswindow.cpp
+++ b/src/plugins/debugger/moduleswindow.cpp
@@ -29,6 +29,7 @@
 
 #include "moduleswindow.h"
 #include "moduleshandler.h" // for model roles
+#include "debuggermanager.h"
 
 #include <QtCore/QDebug>
 #include <QtCore/QProcess>
@@ -40,7 +41,7 @@
 #include <QtGui/QResizeEvent>
 #include <QtGui/QToolButton>
 #include <QtGui/QTreeWidget>
-
+#include <QtGui/QApplication>
 
 ///////////////////////////////////////////////////////////////////////////
 //
@@ -48,10 +49,14 @@
 //
 ///////////////////////////////////////////////////////////////////////////
 
-using Debugger::Internal::ModulesWindow;
+namespace Debugger {
+namespace Internal {
 
-ModulesWindow::ModulesWindow(QWidget *parent)
-    : QTreeView(parent), m_alwaysResizeColumnsToContents(false)
+ModulesWindow::ModulesWindow(DebuggerManager *debuggerManager,
+                             QWidget *parent)  :
+    QTreeView(parent),
+    m_alwaysResizeColumnsToContents(false),
+    m_debuggerManager(debuggerManager)
 {
     setWindowTitle(tr("Modules"));
     setSortingEnabled(true);
@@ -88,9 +93,12 @@ void ModulesWindow::resizeEvent(QResizeEvent *event)
 
 void ModulesWindow::contextMenuEvent(QContextMenuEvent *ev)
 {
+    QString name;
     QModelIndex index = indexAt(ev->pos());
-    index = index.sibling(index.row(), 0);
-    QString name = model()->data(index).toString();
+    if (index.isValid())
+        index = index.sibling(index.row(), 0);
+    if (index.isValid())
+        name = model()->data(index).toString();
 
     QMenu menu;
     QAction *act0 = new QAction(tr("Update module list"), &menu);
@@ -116,9 +124,6 @@ void ModulesWindow::contextMenuEvent(QContextMenuEvent *ev)
     act5->setDisabled(name.isEmpty());
     act6->setDisabled(name.isEmpty());
     act7->setDisabled(name.isEmpty());
-    #ifndef Q_OS_LINUX
-    act7->setDisabled(true);
-    #endif
 
     menu.addAction(act0);
     menu.addAction(act4);
@@ -178,28 +183,26 @@ void ModulesWindow::showSymbols(const QString &name)
 {
     if (name.isEmpty())
         return;
-    QProcess proc;
-    proc.start("nm", QStringList() << "-D" << name);
-    proc.waitForFinished();
+    QApplication::setOverrideCursor(Qt::WaitCursor);
+    const QList<Symbol> symbols = m_debuggerManager->moduleSymbols(name);
+    QApplication::restoreOverrideCursor();
+    if (symbols.empty())
+        return;
     QTreeWidget *w = new QTreeWidget;
     w->setColumnCount(3);
     w->setRootIsDecorated(false);
     w->setAlternatingRowColors(true);
-    //w->header()->hide();
     w->setHeaderLabels(QStringList() << tr("Address") << tr("Code") << tr("Symbol"));
     w->setWindowTitle(tr("Symbols in \"%1\"").arg(name));
-    QString contents = QString::fromLocal8Bit(proc.readAllStandardOutput());
-    QRegExp re("([0-9a-f]+)?\\s+([^\\s]+)\\s+([^\\s]+)");
-    foreach (QString line, contents.split('\n')) {
-        if (re.indexIn(line) != -1) {
-            QTreeWidgetItem *it = new QTreeWidgetItem;
-            it->setData(0, Qt::DisplayRole, re.cap(1));
-            it->setData(1, Qt::DisplayRole, re.cap(2));
-            it->setData(2, Qt::DisplayRole, re.cap(3));
-            w->addTopLevelItem(it);
-        } else {
-            qDebug() << "UNHANDLED LINE" << line;
-        }
+    foreach (const Symbol &s, symbols) {
+        QTreeWidgetItem *it = new QTreeWidgetItem;
+        it->setData(0, Qt::DisplayRole, s.address);
+        it->setData(1, Qt::DisplayRole, s.state);
+        it->setData(2, Qt::DisplayRole, s.name);
+        w->addTopLevelItem(it);
     }
     emit newDockRequested(w);
 }
+
+}
+}
diff --git a/src/plugins/debugger/moduleswindow.h b/src/plugins/debugger/moduleswindow.h
index 36377fb58eeb657f5c742020391627a8be70ff0a..fc2b1af2acff4ee3f8a49fb340ad07823d7a3513 100644
--- a/src/plugins/debugger/moduleswindow.h
+++ b/src/plugins/debugger/moduleswindow.h
@@ -35,12 +35,14 @@
 namespace Debugger {
 namespace Internal {
 
+class DebuggerManager;
+
 class ModulesWindow : public QTreeView
 {
     Q_OBJECT
 
 public:
-    explicit ModulesWindow(QWidget *parent = 0);
+    explicit ModulesWindow(DebuggerManager *debuggerManager, QWidget *parent = 0);
 
 signals:
     void reloadModulesRequested();
@@ -62,6 +64,7 @@ private:
     void setModel(QAbstractItemModel *model);
 
     bool m_alwaysResizeColumnsToContents;
+    DebuggerManager *m_debuggerManager;
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/scriptengine.cpp b/src/plugins/debugger/scriptengine.cpp
index 3ee8b7f8697b7a7a5e47e45d90340baef5637c2e..4ab74e2154a399fd2229a8c24e7fcfe08d5fc93e 100644
--- a/src/plugins/debugger/scriptengine.cpp
+++ b/src/plugins/debugger/scriptengine.cpp
@@ -38,6 +38,7 @@
 #include "registerhandler.h"
 #include "stackhandler.h"
 #include "watchhandler.h"
+#include "moduleshandler.h"
 
 #include <utils/qtcassert.h>
 
@@ -405,6 +406,10 @@ void ScriptEngine::reloadModules()
 {
 }
 
+QList<Symbol> ScriptEngine::moduleSymbols(const QString & /*moduleName*/)
+{
+    return QList<Symbol>();
+}
 
 
 //////////////////////////////////////////////////////////////////////
diff --git a/src/plugins/debugger/scriptengine.h b/src/plugins/debugger/scriptengine.h
index 5e009327da7f63054ac4a551177cc59157385560..ee5612d09d84d3c59bf04f1849f36da2008d26c1 100644
--- a/src/plugins/debugger/scriptengine.h
+++ b/src/plugins/debugger/scriptengine.h
@@ -102,6 +102,7 @@ private:
 
     void loadSymbols(const QString &moduleName);
     void loadAllSymbols();
+    virtual QList<Symbol> moduleSymbols(const QString &moduleName);
     void reloadDisassembler();
     void reloadModules();
     void reloadRegisters() {}
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index f26d0ffcff491b143885be871cd3b1d25f338703..0b76cfc1de662a414fc571fc56880cba49d42593 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -96,15 +96,16 @@ namespace Internal {
 //
 ///////////////////////////////////////////////////////////////////////
 
-#define StartOfLine    QTextCursor::StartOfLine
-#define EndOfLine      QTextCursor::EndOfLine
-#define MoveAnchor     QTextCursor::MoveAnchor
-#define KeepAnchor     QTextCursor::KeepAnchor
-#define Up             QTextCursor::Up
-#define Down           QTextCursor::Down
-#define Right          QTextCursor::Right
-#define Left           QTextCursor::Left
-#define EndOfDocument  QTextCursor::End
+#define StartOfLine     QTextCursor::StartOfLine
+#define EndOfLine       QTextCursor::EndOfLine
+#define MoveAnchor      QTextCursor::MoveAnchor
+#define KeepAnchor      QTextCursor::KeepAnchor
+#define Up              QTextCursor::Up
+#define Down            QTextCursor::Down
+#define Right           QTextCursor::Right
+#define Left            QTextCursor::Left
+#define EndOfDocument   QTextCursor::End
+#define StartOfDocument QTextCursor::Start
 
 #define EDITOR(s) (m_textedit ? m_textedit->s : m_plaintextedit->s)
 
@@ -274,8 +275,6 @@ public:
     void moveToWordBoundary(bool simple, bool forward);
 
     // to reduce line noise
-    typedef QTextCursor::MoveOperation MoveOperation;
-    typedef QTextCursor::MoveMode MoveMode;
     void moveToEndOfDocument() { m_tc.movePosition(EndOfDocument, MoveAnchor); }
     void moveToStartOfLine() { m_tc.movePosition(StartOfLine, MoveAnchor); }
     void moveToEndOfLine();
@@ -1701,6 +1700,7 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
     static QRegExp reNormal("^norm(al)?( (.*))?$");
     static QRegExp reSet("^set?( (.*))?$");
     static QRegExp reWrite("^w!?( (.*))?$");
+    static QRegExp reSubstitute("^s(.)(.*)\\1(.*)\\1([gi]*)");
 
     if (cmd.isEmpty()) {
         setPosition(firstPositionInLine(beginLine));
@@ -1805,6 +1805,47 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
         enterCommandMode();
         //qDebug() << "REPLAY: " << reNormal.cap(3);
         replay(reNormal.cap(3), 1);
+    } else if (reSubstitute.indexIn(cmd) != -1) { // :substitute
+        QString needle = reSubstitute.cap(2);
+        const QString replacement = reSubstitute.cap(3);
+        QString flags = reSubstitute.cap(4);
+        const bool startOfLineOnly = needle.startsWith('^');
+        if (startOfLineOnly)
+           needle.remove(0, 1);
+        needle.replace('$', '\n');
+        needle.replace("\\\n", "\\$");
+        QRegExp pattern(needle);
+        if (flags.contains('i'))
+            pattern.setCaseSensitivity(Qt::CaseInsensitive);
+        const bool global = flags.contains('g');
+        m_tc.beginEditBlock();
+        for (int line = beginLine; line <= endLine; ++line) {
+            const int start = firstPositionInLine(line);
+            const int end = lastPositionInLine(line);
+            for (int position = start; position <= end && position >= start; ) {
+                position = pattern.indexIn(m_tc.document()->toPlainText(), position);
+                if (startOfLineOnly && position != start)
+                    break;
+                if (position != -1) {
+                    m_tc.setPosition(position);
+                    m_tc.movePosition(QTextCursor::NextCharacter,
+                        KeepAnchor, pattern.matchedLength());
+                    QString text = m_tc.selectedText();
+                    if (text.endsWith(ParagraphSeparator)) {
+                        text = replacement + "\n";
+                    } else {
+                        text.replace(ParagraphSeparator, "\n");
+                        text.replace(pattern, replacement);
+                    }
+                    m_tc.removeSelectedText();
+                    m_tc.insertText(text);
+                }
+                if (!global)
+                    break;
+            }
+        }
+        m_tc.endEditBlock();
+        enterCommandMode();
     } else if (reSet.indexIn(cmd) != -1) { // :set
         showBlackMessage(QString());
         QString arg = reSet.cap(2);
@@ -1927,7 +1968,7 @@ void FakeVimHandler::Private::highlightMatches(const QString &needle0)
 
     if (!needle0.isEmpty()) {
         QTextCursor tc = m_tc;
-        tc.movePosition(QTextCursor::Start, MoveAnchor);
+        tc.movePosition(StartOfDocument, MoveAnchor);
 
         QTextDocument::FindFlags flags = QTextDocument::FindCaseSensitively;
         QString needle = needle0;
@@ -2330,11 +2371,13 @@ void FakeVimHandler::Private::recordJump()
     UNDO_DEBUG("jumps: " << m_jumpListUndo);
 }
 
-struct UndoBreaker : public QAbstractUndoItem
+class UndoBreaker : public QAbstractUndoItem
 {
+public:
     UndoBreaker(FakeVimHandler::Private *doc) : m_doc(doc) {}
     void undo() { m_doc->m_needMoreUndo = true; }
     void redo() { m_doc->m_needMoreUndo = true; }
+private:   
     FakeVimHandler::Private *m_doc;
 };