diff --git a/src/plugins/coreplugin/outputpane.cpp b/src/plugins/coreplugin/outputpane.cpp
index 3ead39e6a0167f2526e261d08d7b2e7dd3fc0e3a..c1cb59462ccb6948733221504149d5bd3690a2a6 100644
--- a/src/plugins/coreplugin/outputpane.cpp
+++ b/src/plugins/coreplugin/outputpane.cpp
@@ -206,6 +206,12 @@ QWidget *OutputPaneManager::buttonsWidget()
     return m_buttonsWidget;
 }
 
+// Return shortcut as Ctrl+<number>
+static inline int paneShortCut(int modifier, int number)
+{
+    return modifier | (Qt::Key_0 + number);
+}
+
 void OutputPaneManager::init()
 {
     ActionManager *am = Core::ICore::instance()->actionManager();
@@ -254,9 +260,9 @@ void OutputPaneManager::init()
         Command *cmd = am->registerAction(action, actionId, QList<int>() << Constants::C_GLOBAL_ID);
         if (outPane->priorityInStatusBar() != -1) {
 #ifdef Q_OS_MAC
-            cmd->setDefaultKeySequence(QKeySequence("Ctrl+" + QString::number(shortcutNumber)));
+            cmd->setDefaultKeySequence(QKeySequence(paneShortCut(Qt::CTRL, shortcutNumber)));
 #else
-            cmd->setDefaultKeySequence(QKeySequence("Alt+" + QString::number(shortcutNumber)));
+            cmd->setDefaultKeySequence(QKeySequence(paneShortCut(Qt::ALT, shortcutNumber)));
 #endif
         }
         mpanes->addAction(cmd);
diff --git a/src/plugins/debugger/cdb/cdb.pri b/src/plugins/debugger/cdb/cdb.pri
index 8ba7d3a68650872f537992b0c9fd5fd50b18a6c2..a9e9a5cddfa7c4ff3cd646cdd00ce46004f56bb1 100644
--- a/src/plugins/debugger/cdb/cdb.pri
+++ b/src/plugins/debugger/cdb/cdb.pri
@@ -24,14 +24,17 @@ HEADERS += \
     $$PWD/cdbdebugeventcallback.h \
     $$PWD/cdbdebugoutput.h \
     $$PWD/cdbsymbolgroupcontext.h \
-    $$PWD/cdbstacktracecontext.h
+    $$PWD/cdbstacktracecontext.h \
+    $$PWD/cdbbreakpoint.h
 
 SOURCES += \
     $$PWD/cdbdebugengine.cpp \
     $$PWD/cdbdebugeventcallback.cpp \
     $$PWD/cdbdebugoutput.cpp \
     $$PWD/cdbsymbolgroupcontext.cpp \
-    $$PWD/cdbstacktracecontext.cpp
+    $$PWD/cdbstacktracecontext.cpp \
+    $$PWD/cdbbreakpoint.cpp
+
 } else {
    message("Debugging Tools for Windows could not be found in $$CDB_PATH")
 }
diff --git a/src/plugins/debugger/cdb/cdbbreakpoint.cpp b/src/plugins/debugger/cdb/cdbbreakpoint.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fcde01e276ba2a5512e6daea047ba44e9b2e245f
--- /dev/null
+++ b/src/plugins/debugger/cdb/cdbbreakpoint.cpp
@@ -0,0 +1,345 @@
+/**************************************************************************
+**
+** 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 "cdbbreakpoint.h"
+#include "breakhandler.h"
+#include "cdbdebugengine_p.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QMap>
+
+namespace Debugger {
+namespace Internal {
+
+// The CDB breakpoint expression syntax is:
+//    `foo.cpp:523`[ "condition"]
+//    module!function[ "condition"]
+
+static const char sourceFileQuoteC = '`';
+
+CDBBreakPoint::CDBBreakPoint() :
+    ignoreCount(0),
+    lineNumber(-1)
+{
+}
+
+CDBBreakPoint::CDBBreakPoint(const BreakpointData &bpd) :
+     fileName(bpd.fileName),
+     condition(bpd.condition),
+     ignoreCount(0),
+     funcName(bpd.funcName),
+     lineNumber(-1)
+{
+    if (!bpd.ignoreCount.isEmpty())
+        ignoreCount = bpd.ignoreCount.toInt();
+    if (!bpd.lineNumber.isEmpty())
+        lineNumber = bpd.lineNumber.toInt();
+}
+
+int CDBBreakPoint::compare(const CDBBreakPoint& rhs) const
+{
+    if (ignoreCount > rhs.ignoreCount)
+        return 1;
+    if (ignoreCount < rhs.ignoreCount)
+        return -1;
+    if (lineNumber > rhs.lineNumber)
+        return 1;
+    if (lineNumber < rhs.lineNumber)
+        return -1;
+    if (const int fileCmp = fileName.compare(rhs.fileName))
+        return fileCmp;
+    if (const int  funcCmp = funcName.compare(rhs.funcName))
+        return funcCmp;
+    if (const int condCmp = condition.compare(rhs.condition))
+        return condCmp;
+    return 0;
+}
+
+void CDBBreakPoint::clear()
+{
+     ignoreCount = 0;
+     clearExpressionData();
+}
+
+void CDBBreakPoint::clearExpressionData()
+{
+    fileName.clear();
+    condition.clear();
+    funcName.clear();
+    lineNumber = -1;
+}
+
+QDebug operator<<(QDebug dbg, const CDBBreakPoint &bp)
+{
+    dbg.nospace() << "fileName='" << bp.fileName << "' condition='"
+                  << bp.condition << "' ignoreCount=" << bp.ignoreCount
+                  << " lineNumber=" << bp.lineNumber
+                  << " funcName='" << bp.funcName << '\'';
+    return dbg;
+}
+
+QString CDBBreakPoint::expression() const
+{
+    // format the breakpoint expression (file/function and condition)
+    QString rc;
+    QTextStream str(&rc);
+    if (funcName.isEmpty()) {
+        const QChar sourceFileQuote = QLatin1Char(sourceFileQuoteC);
+        str << sourceFileQuote << QDir::toNativeSeparators(fileName) << QLatin1Char(':') << lineNumber << sourceFileQuote;
+    } else {
+        str << funcName;
+    }
+    if (!condition.isEmpty()) {
+        const QChar doubleQuote = QLatin1Char('"');
+        str << QLatin1Char(' ') << doubleQuote << condition << doubleQuote;
+    }
+    return rc;
+}
+
+bool CDBBreakPoint::apply(IDebugBreakpoint2 *ibp, QString *errorMessage) const
+{
+    const QString expr = expression();
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO << *this << expr;
+    const HRESULT hr = ibp->SetOffsetExpressionWide(expr.utf16());
+    if (FAILED(hr)) {
+        *errorMessage = QString::fromLatin1("Unable to set breakpoint '%1' : %2").
+                        arg(expr, msgComFailed("SetOffsetExpressionWide", hr));
+        return false;
+    }
+    // Pass Count is ignoreCount + 1
+    ibp->SetPassCount(ignoreCount + 1u);
+    ibp->AddFlags(DEBUG_BREAKPOINT_ENABLED);
+    return true;
+}
+
+bool CDBBreakPoint::add(IDebugControl4* debugControl, QString *errorMessage) const
+{
+    IDebugBreakpoint2* ibp = 0;
+    const HRESULT hr = debugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &ibp);
+    if (FAILED(hr)) {
+        *errorMessage = QString::fromLatin1("Unable to add breakpoint: %1").
+                        arg(msgComFailed("AddBreakpoint2", hr));
+        return false;
+    }
+    if (!ibp) {
+        *errorMessage = QString::fromLatin1("Unable to add breakpoint: <Unknown error>");
+        return false;
+    }
+    return apply(ibp, errorMessage);
+}
+
+// Make sure file can be found in editor manager and text markers
+// Use '/' and capitalize drive letter
+QString CDBBreakPoint::canonicalSourceFile(const QString &f)
+{
+    if (f.isEmpty())
+        return f;
+    QString rc = QDir::fromNativeSeparators(f);
+    if (rc.size() > 2 && rc.at(1) == QLatin1Char(':'))
+        rc[0] = rc.at(0).toUpper();
+    return rc;
+}
+
+bool CDBBreakPoint::retrieve(IDebugBreakpoint2 *ibp, QString *errorMessage)
+{
+    clear();
+    WCHAR wszBuf[MAX_PATH];
+    const HRESULT hr =ibp->GetOffsetExpressionWide(wszBuf, MAX_PATH, 0);
+    if (FAILED(hr)) {
+        *errorMessage = QString::fromLatin1("Cannot retrieve breakpoint: %1").
+                        arg(msgComFailed("GetOffsetExpressionWide", hr));
+        return false;
+    }
+    // Pass Count is ignoreCount + 1
+    ibp->GetPassCount(&ignoreCount);
+    if (ignoreCount)
+        ignoreCount--;
+    const QString expr = QString::fromUtf16(wszBuf);
+    if (!parseExpression(expr)) {
+        *errorMessage = QString::fromLatin1("Parsing of '%1' failed.").arg(expr);
+        return false;
+    }
+    return true;
+}
+
+bool CDBBreakPoint::parseExpression(const QString &expr)
+{
+    clearExpressionData();
+    const QChar sourceFileQuote = QLatin1Char(sourceFileQuoteC);
+    // Check for file or function
+    int conditionPos = 0;
+    if (expr.startsWith(sourceFileQuote)) { // `c:\foo.cpp:523`[ "condition"]
+        // Do not fall for the drive letter colon here
+        const int colonPos = expr.indexOf(QLatin1Char(':'), 3);
+        if (colonPos == -1)
+            return false;
+        conditionPos = expr.indexOf(sourceFileQuote, colonPos + 1);
+        if (conditionPos == -1)
+            return false;
+        fileName = canonicalSourceFile(expr.mid(1, colonPos - 1));
+        const QString lineNumberS = expr.mid(colonPos + 1, conditionPos - colonPos - 1);
+        bool lineNumberOk = false;
+        lineNumber = lineNumberS.toInt(&lineNumberOk);
+        if (!lineNumberOk)
+            return false;
+        conditionPos++;
+    } else {
+        // Check function token
+        conditionPos = expr.indexOf(QLatin1Char(' '));
+        if (conditionPos != -1) {
+            funcName = expr.mid(0, conditionPos);
+            conditionPos++;
+        } else {
+            funcName = expr;
+            conditionPos = expr.size();
+        }
+    }
+    // Condition? ".if bla"
+    if (conditionPos >= expr.size())
+        return true;
+    const QChar doubleQuote = QLatin1Char('"');
+    conditionPos = expr.indexOf(doubleQuote, conditionPos);
+    if (conditionPos == -1)
+        return true;
+    conditionPos++;
+    const int condEndPos = expr.lastIndexOf(doubleQuote);
+    if (condEndPos == -1)
+        return false;
+    condition = expr.mid(conditionPos, condEndPos - conditionPos);
+    return true;
+}
+
+bool CDBBreakPoint::getBreakPoints(IDebugControl4* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage)
+{
+    ULONG count = 0;
+    bps->clear();
+    // get number
+    HRESULT hr = debugControl->GetNumberBreakpoints(&count);
+    if (FAILED(hr)) {
+        *errorMessage = QString::fromLatin1("Cannot retrieve breakpoints: %1").
+                        arg(msgComFailed("GetNumberBreakpoints", hr));
+        return false;
+    }
+    // retrieve one by one and parse
+    for (ULONG b= 0; b < count; b++) {
+        IDebugBreakpoint2 *ibp = 0;
+        hr = debugControl->GetBreakpointByIndex2(b, &ibp);
+        if (FAILED(hr)) {
+            *errorMessage = QString::fromLatin1("Cannot retrieve breakpoint %1: %2").
+                            arg(b).arg(msgComFailed("GetBreakpointByIndex2", hr));
+            return false;
+        }
+        CDBBreakPoint bp;
+        if (!bp.retrieve(ibp, errorMessage))
+            return false;
+        bps->push_back(bp);
+    }
+    return true;
+}
+
+// Synchronize (halted) engine breakpoints with those of the BreakHandler.
+bool CDBBreakPoint::synchronizeBreakPoints(IDebugControl4* debugControl,
+                                           BreakHandler *handler,
+                                           QString *errorMessage)
+{    
+    typedef QMap<CDBBreakPoint, bool> BreakPointPendingMap;
+    BreakPointPendingMap breakPointPendingMap;
+    // convert BreakHandler's bps into a map of BreakPoint->Pending
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO;
+
+    const int handlerCount = handler->size();
+    for (int i=0; i < handlerCount; ++i) {
+        BreakpointData* breakpoint = handler->at(i);
+        const bool pending = breakpoint->pending;
+        breakPointPendingMap.insert(CDBBreakPoint(*breakpoint), pending);
+        if (pending)
+            breakpoint->pending = false;
+    }
+    ULONG engineCount;
+    // get number of engine breakpoints
+    HRESULT hr = debugControl->GetNumberBreakpoints(&engineCount);
+    if (FAILED(hr)) {
+        *errorMessage = QString::fromLatin1("Cannot retrieve number of breakpoints: %1").
+                        arg(msgComFailed("GetNumberBreakpoints", hr));
+        return false;
+    }
+    // Starting from end, check if engine breakpoints are still in handler.
+    // If not->remove
+    if (engineCount) {
+        for (ULONG eb = engineCount - 1u; ; eb--) {
+            // get engine breakpoint
+            IDebugBreakpoint2 *ibp = 0;
+            hr = debugControl->GetBreakpointByIndex2(eb, &ibp);
+            if (FAILED(hr)) {
+                *errorMessage = QString::fromLatin1("Cannot retrieve breakpoint %1: %2").
+                                arg(eb).arg(msgComFailed("GetBreakpointByIndex2", hr));
+                return false;
+            }
+            CDBBreakPoint engineBreakPoint;
+            if (!engineBreakPoint.retrieve(ibp, errorMessage))
+                return false;
+            // Still in handler?
+            if (!breakPointPendingMap.contains(engineBreakPoint)) {
+                if (debugCDB)
+                    qDebug() << "    Removing" << engineBreakPoint;
+                hr = debugControl->RemoveBreakpoint2(ibp);
+                if (FAILED(hr)) {
+                    *errorMessage = QString::fromLatin1("Cannot remove breakpoint %1: %2").
+                                    arg(engineBreakPoint.expression(), msgComFailed("RemoveBreakpoint2", hr));
+                    return false;
+                }
+            } // not in handler
+            if (!eb)
+                break;
+        }
+    }
+    // Add pending breakpoints
+    const BreakPointPendingMap::const_iterator pcend = breakPointPendingMap.constEnd();
+    for (BreakPointPendingMap::const_iterator it = breakPointPendingMap.constBegin(); it != pcend; ++it) {
+        if (it.value()) {
+            if (debugCDB)
+                qDebug() << "    Adding " << it.key();
+            if (!it.key().add(debugControl, errorMessage))
+                return false;
+        }
+    }
+    if (debugCDB > 1) {
+        QList<CDBBreakPoint> bps;
+        CDBBreakPoint::getBreakPoints(debugControl, &bps, errorMessage);
+        qDebug().nospace() << "### Breakpoints in engine: " << bps;
+    }
+    return true;
+}
+
+}
+}
diff --git a/src/plugins/debugger/cdb/cdbbreakpoint.h b/src/plugins/debugger/cdb/cdbbreakpoint.h
new file mode 100644
index 0000000000000000000000000000000000000000..57a40872d50a124adbdf2990c9988bea398cb2e2
--- /dev/null
+++ b/src/plugins/debugger/cdb/cdbbreakpoint.h
@@ -0,0 +1,98 @@
+/**************************************************************************
+**
+** 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 CDBBREAKPOINTS_H
+#define CDBBREAKPOINTS_H
+
+#include <windows.h>
+#include <inc/dbgeng.h>
+
+#include <QtCore/QString>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+class QDebug;
+QT_END_NAMESPACE
+
+namespace Debugger {
+namespace Internal {
+
+class BreakHandler;
+class BreakpointData;
+
+/* CDB Break point data structure with utilities to
+ * apply to engine and to retrieve them from the engine and comparison. */
+
+struct CDBBreakPoint {
+    CDBBreakPoint();
+    CDBBreakPoint(const BreakpointData &bpd);
+
+    int compare(const CDBBreakPoint& rhs) const;
+
+    void clear();
+    void clearExpressionData();
+
+    QString expression() const;
+
+    // Apply parameters
+    bool apply(IDebugBreakpoint2 *ibp, QString *errorMessage) const;
+    // Convenience to add to a IDebugControl4
+    bool add(IDebugControl4* debugControl, QString *errorMessage) const;
+
+    // Retrieve/parse breakpoints from the interfaces
+    bool retrieve(IDebugBreakpoint2 *ibp, QString *errorMessage);
+    bool parseExpression(const QString &expr);
+    // Retrieve all breakpoints from the engine
+    static bool getBreakPoints(IDebugControl4* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage);
+    // Synchronize (halted) engine with BreakHandler.
+    static bool synchronizeBreakPoints(IDebugControl4* ctl, BreakHandler *bh, QString *errorMessage);
+
+    // Return a 'canonical' file (using '/' and capitalized drive letter)
+    static QString canonicalSourceFile(const QString &f);
+
+    QString fileName;       // short name of source file
+    QString condition;      // condition associated with breakpoint
+    unsigned long ignoreCount;    // ignore count associated with breakpoint
+    int lineNumber;     // line in source file
+    QString funcName;       // name of containing function
+};
+
+QDebug operator<<(QDebug, const CDBBreakPoint &bp);
+
+inline bool operator==(const CDBBreakPoint& b1, const CDBBreakPoint& b2)
+    { return b1.compare(b2) == 0; }
+inline bool operator!=(const CDBBreakPoint& b1, const CDBBreakPoint& b2)
+    { return b1.compare(b2) != 0; }
+inline bool operator<(const CDBBreakPoint& b1, const CDBBreakPoint& b2)
+    { return b1.compare(b2) <  0; }
+
+}
+}
+
+#endif // CDBBREAKPOINTS_H
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index 7f80abcb37c0a66fc69ee853ff610bd43aa7ca57..a7baeb33ca7045ff2c9a0e4b67872e7d5d4c318a 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -31,6 +31,7 @@
 #include "cdbdebugengine_p.h"
 #include "cdbsymbolgroupcontext.h"
 #include "cdbstacktracecontext.h"
+#include "cdbbreakpoint.h"
 
 #include "debuggermanager.h"
 #include "breakhandler.h"
@@ -62,6 +63,8 @@ static const char *localSymbolRootC = "local";
 namespace Debugger {
 namespace Internal {
 
+typedef QList<WatchData> WatchList;
+
 QString msgDebugEngineComResult(HRESULT hr)
 {
     switch (hr) {
@@ -127,6 +130,34 @@ bool DebuggerEngineLibrary::init(QString *errorMessage)
     return true;
 }
 
+// A class that sets an expression syntax on the debug control while in scope.
+// Can be nested as it checks for the old value.
+class SyntaxSetter {
+    Q_DISABLE_COPY(SyntaxSetter)
+public:
+    explicit inline SyntaxSetter(IDebugControl4 *ctl, ULONG desiredSyntax);
+    inline  ~SyntaxSetter();
+private:
+    const ULONG m_desiredSyntax;
+    IDebugControl4 *m_ctl;
+    ULONG m_oldSyntax;
+};
+
+SyntaxSetter::SyntaxSetter(IDebugControl4 *ctl, ULONG desiredSyntax) :
+    m_desiredSyntax(desiredSyntax),
+    m_ctl(ctl)
+{
+    m_ctl->GetExpressionSyntax(&m_oldSyntax);
+    if (m_oldSyntax != m_desiredSyntax)
+        m_ctl->SetExpressionSyntax(m_desiredSyntax);
+}
+
+SyntaxSetter::~SyntaxSetter()
+{
+    if (m_oldSyntax != m_desiredSyntax)
+        m_ctl->SetExpressionSyntax(m_oldSyntax);
+}
+
 // --- CdbDebugEnginePrivate
 
 CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEngine* engine) :
@@ -440,13 +471,36 @@ CdbSymbolGroupContext *CdbDebugEnginePrivate::getStackFrameSymbolGroupContext(in
     return 0;
 }
 
+static inline QString formatWatchList(const WatchList &wl)
+{
+    const int count = wl.size();
+    QString rc;
+    for (int i = 0; i < count; i++) {
+        if (i)
+            rc += QLatin1String(", ");
+        rc += wl.at(i).iname;
+        rc += QLatin1String(" (");
+        rc += wl.at(i).exp;
+        rc += QLatin1Char(')');
+    }
+    return rc;
+}
+
 bool CdbDebugEnginePrivate::updateLocals(int frameIndex,
                                          WatchHandler *wh,
                                          QString *errorMessage)
 {
+    wh->reinitializeWatchers();
+
+    QList<WatchData> incompletes = wh->takeCurrentIncompletes();
     if (debugCDB)
-        qDebug() << Q_FUNC_INFO << frameIndex;
-    wh->cleanup();
+        qDebug() << Q_FUNC_INFO << "\n    " << frameIndex << formatWatchList(incompletes);
+
+    m_engine->filterEvaluateWatchers(&incompletes, wh);
+    if (!incompletes.empty()) {        
+        const QString msg = QLatin1String("Warning: Locals left in incomplete list: ") + formatWatchList(incompletes);
+        qWarning("%s\n", qPrintable(msg));
+    }
 
     bool success = false;
     if (CdbSymbolGroupContext *sgc = getStackFrameSymbolGroupContext(frameIndex, errorMessage))
@@ -456,17 +510,88 @@ bool CdbDebugEnginePrivate::updateLocals(int frameIndex,
     return success;
 }
 
+void CdbDebugEngine::evaluateWatcher(WatchData *wd)
+{
+    if (debugCDB > 1)
+        qDebug() << Q_FUNC_INFO << wd->exp;
+    QString errorMessage;
+    QString value;
+    QString type;
+    if (evaluateExpression(wd->exp, &value, &type, &errorMessage)) {
+        wd->setValue(value);
+        wd->setType(type);
+    } else {
+        wd->setValue(errorMessage);
+        wd->setTypeUnneeded();
+    }
+    wd->setChildCount(0);
+}
+
+void CdbDebugEngine::filterEvaluateWatchers(QList<WatchData> *wd, WatchHandler *wh)
+{
+    typedef QList<WatchData> WatchList;
+    if (wd->empty())
+        return;
+
+    // Filter out actual watchers. Ignore the "<Edit>" top level place holders
+    SyntaxSetter syntaxSetter(m_d->m_pDebugControl, DEBUG_EXPR_CPLUSPLUS);
+    const QString watcherPrefix = QLatin1String("watch.");
+    const QChar lessThan = QLatin1Char('<');
+    const QChar greaterThan = QLatin1Char('>');
+    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);            
+            if (isPlaceHolder) {
+                if (!placeHolderSeen) { // Max one place holder
+                    it->setChildCount(0);
+                    it->setAllUnneeded();
+                    wh->insertData(*it);
+                    placeHolderSeen = true;
+                }
+            } else {
+                evaluateWatcher(&(*it));
+                wh->insertData(*it);
+            }            
+            it = wd->erase(it);
+        } else {
+            ++it;
+        }
+    }
+}
+
 void CdbDebugEngine::updateWatchModel()
 {
+    // Stack trace exists and evaluation funcs can only be called
+    // when running
+    if (m_d->isDebuggeeRunning()) {
+        qWarning("updateWatchModel() called while debuggee is running.");
+        return;
+    }
+
     const int frameIndex = m_d->m_debuggerManagerAccess->stackHandler()->currentIndex();
+
+    WatchHandler *watchHandler = m_d->m_debuggerManagerAccess->watchHandler();
+    WatchList incomplete = watchHandler->takeCurrentIncompletes();
+    if (incomplete.empty())
+        return;
     if (debugCDB)
-        qDebug() << Q_FUNC_INFO << "fi=" << frameIndex;
+        qDebug() << Q_FUNC_INFO << "\n    fi=" << frameIndex << formatWatchList(incomplete);
 
     bool success = false;
-    QString errorMessage;    
-    if (CdbSymbolGroupContext *sg = m_d->m_currentStackTrace->symbolGroupContextAt(frameIndex, &errorMessage))
-        success = CdbSymbolGroupContext::completeModel(sg, m_d->m_debuggerManagerAccess->watchHandler(), &errorMessage);
-
+    QString errorMessage;
+    do {
+        // Filter out actual watchers
+        filterEvaluateWatchers(&incomplete, watchHandler);
+        // Do locals. We might get called while running when someone enters watchers
+        if (!incomplete.empty()) {
+            CdbSymbolGroupContext *sg = m_d->m_currentStackTrace->symbolGroupContextAt(frameIndex, &errorMessage);
+            if (!sg || !CdbSymbolGroupContext::completeModel(sg, incomplete, watchHandler, &errorMessage))
+                break;
+        }
+        watchHandler->rebuildModel();
+        success = true;
+    } while (false);
     if (!success)
         qWarning("%s : %s", Q_FUNC_INFO, qPrintable(errorMessage));
 }
@@ -476,7 +601,6 @@ void CdbDebugEngine::stepExec()
     if (debugCDB)
         qDebug() << Q_FUNC_INFO;
 
-    //m_pDebugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
     m_d->cleanStackTrace();
     const HRESULT hr = m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO);
     Q_UNUSED(hr)
@@ -646,9 +770,51 @@ void CdbDebugEngine::assignValueInDebugger(const QString &expr, const QString &v
 }
 
 void CdbDebugEngine::executeDebuggerCommand(const QString &command)
+{
+    QString errorMessage;
+    if (!executeDebuggerCommand(command, &errorMessage))
+        qWarning("%s\n", qPrintable(errorMessage));
+}
+
+bool CdbDebugEngine::executeDebuggerCommand(const QString &command, QString *errorMessage)
 {
     if (debugCDB)
         qDebug() << Q_FUNC_INFO << command;
+    const HRESULT hr = m_d->m_pDebugControl->ExecuteWide(DEBUG_OUTCTL_THIS_CLIENT, command.utf16(), 0);
+    if (FAILED(hr)) {
+        *errorMessage = QString::fromLatin1("Unable to execute '%1': %2").
+                        arg(command, msgDebugEngineComResult(hr));
+        return false;
+    }
+    return true;
+}
+
+bool CdbDebugEngine::evaluateExpression(const QString &expression,
+                                        QString *value,
+                                        QString *type,
+                                        QString *errorMessage)
+{
+    if (debugCDB > 1)
+        qDebug() << Q_FUNC_INFO << expression;
+    DEBUG_VALUE debugValue;
+    memset(&debugValue, 0, sizeof(DEBUG_VALUE));
+    // Original syntax must be restored, else setting breakpoints will fail.
+    SyntaxSetter syntaxSetter(m_d->m_pDebugControl, DEBUG_EXPR_CPLUSPLUS);
+    ULONG errorPosition = 0;
+    const HRESULT hr = m_d->m_pDebugControl->EvaluateWide(expression.utf16(),
+                                                          DEBUG_VALUE_INVALID, &debugValue,
+                                                          &errorPosition);    if (FAILED(hr)) {
+        if (HRESULT_CODE(hr) == 517) {
+            *errorMessage = QString::fromLatin1("Unable to evaluate '%1': Expression out of scope.").
+                            arg(expression);
+        } else {
+            *errorMessage = QString::fromLatin1("Unable to evaluate '%1': Error at %2: %3").
+                            arg(expression).arg(errorPosition).arg(msgDebugEngineComResult(hr));
+        }
+        return false;
+    }
+    *value = CdbSymbolGroupContext::debugValueToString(debugValue, m_d->m_pDebugControl, type);
+    return true;
 }
 
 void CdbDebugEngine::activateFrame(int frameIndex)
@@ -706,17 +872,6 @@ void CdbDebugEngine::selectThread(int index)
     m_d->updateStackTrace();
 }
 
-static inline QString breakPointExpression(const QString &fileName, const QString &lineNumber)
-{
-    QString str;
-    str += QLatin1Char('`');
-    str += QDir::toNativeSeparators(fileName);
-    str += QLatin1Char(':');
-    str += lineNumber;
-    str += QLatin1Char('`');
-    return str;
-}
-
 void CdbDebugEngine::attemptBreakpointSynchronization()
 {
     if (debugCDB)
@@ -727,36 +882,11 @@ void CdbDebugEngine::attemptBreakpointSynchronization()
         return;
     }
 
-    BreakHandler *handler = m_d->m_debuggerManagerAccess->breakHandler();
-    for (int i=0; i < handler->size(); ++i) {
-        BreakpointData* breakpoint = handler->at(i);
-        if (breakpoint->pending) {
-            const QString expr = breakPointExpression(breakpoint->fileName,  breakpoint->lineNumber);
-            IDebugBreakpoint2* pBP = 0;
-            HRESULT hr = m_d->m_pDebugControl->AddBreakpoint2(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &pBP);
-            if (FAILED(hr) || !pBP) {
-                qWarning("m_pDebugControl->AddBreakpoint2 %s failed.", qPrintable(expr));
-                continue;
-            }
-
-            hr = pBP->SetOffsetExpressionWide(expr.utf16());
-            if (FAILED(hr)) {
-                qWarning("SetOffsetExpressionWide %s failed", qPrintable(expr));
-                continue;
-            }
-
-            bool ok;
-            ULONG ul;
-            ul = breakpoint->ignoreCount.toULong(&ok);
-            if (ok) pBP->SetPassCount(ul);
-
-            //TODO: handle breakpoint->condition
-
-            pBP->AddFlags(DEBUG_BREAKPOINT_ENABLED);
-            //pBP->AddFlags(DEBUG_BREAKPOINT_GO_ONLY);
-            breakpoint->pending = false;
-        }
-    }
+    QString errorMessage;
+    if (!CDBBreakPoint::synchronizeBreakPoints(m_d->m_pDebugControl,
+                                               m_d->m_debuggerManagerAccess->breakHandler(),
+                                               &errorMessage))
+        qWarning("%s\n", qPrintable(errorMessage));
 }
 
 void CdbDebugEngine::loadSessionData()
@@ -927,8 +1057,6 @@ void CdbDebugEnginePrivate::updateStackTrace()
     m_firstActivatedFrame = true;
     if (current >= 0) {
         m_debuggerManagerAccess->stackHandler()->setCurrentIndex(current);
-        m_debuggerManager->gotoLocation(stackFrames.at(current).file,
-                                        stackFrames.at(current).line, true);
         m_engine->activateFrame(current);
     }    
 }
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h
index 0662a8350a091494acc71715e16fea72f65f0d4d..f37bade1cd3db6850bb36e1f1ccc53c174d9cd21 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine.h
@@ -105,6 +105,10 @@ private:
     void startWatchTimer();
     void killWatchTimer();
     void processTerminated(unsigned long exitCode);
+    bool executeDebuggerCommand(const QString &command, QString *errorMessage);
+    bool evaluateExpression(const QString &expression, QString *value, QString *type, QString *errorMessage);
+    void evaluateWatcher(WatchData *wd);
+    void filterEvaluateWatchers(QList<WatchData> *wd, WatchHandler *wh);
 
     CdbDebugEnginePrivate *m_d;
 
diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
index f80766941db22f7f3812b6563d28c2a8241127a9..0500657dc44b12f7d05cb996a97a8cb46b4113fe 100644
--- a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
@@ -28,9 +28,12 @@
 **************************************************************************/
 
 #include "cdbstacktracecontext.h"
+#include "cdbbreakpoint.h"
 #include "cdbsymbolgroupcontext.h"
 #include "cdbdebugengine_p.h"
 
+#include <QtCore/QDir>
+
 namespace Debugger {
 namespace Internal {
 
@@ -98,12 +101,13 @@ bool CdbStackTraceContext::init(unsigned long frameCount, QString * /*errorMessa
         frame.function = QString::fromUtf16(wszBuf);
 
         ULONG ulLine;
-        ULONG ulFileNameSize;
         ULONG64 ul64Displacement;
-        const HRESULT hr = m_pDebugSymbols->GetLineByOffsetWide(instructionOffset, &ulLine, wszBuf, MAX_PATH, &ulFileNameSize, &ul64Displacement);
+        const HRESULT hr = m_pDebugSymbols->GetLineByOffsetWide(instructionOffset, &ulLine, wszBuf, MAX_PATH, 0, &ul64Displacement);
         if (SUCCEEDED(hr)) {
             frame.line = ulLine;
-            frame.file = QString::fromUtf16(wszBuf, ulFileNameSize);
+            // Vitally important  to use canonical file that matches editormanager,
+            // else the marker will not show.
+            frame.file = CDBBreakPoint::canonicalSourceFile(QString::fromUtf16(wszBuf));
         }
         m_frames.push_back(frame);
     }
@@ -114,7 +118,7 @@ CdbSymbolGroupContext *CdbStackTraceContext::symbolGroupContextAt(int index, QSt
 {
     // Create a symbol group on demand
     if (debugCDB)
-        qDebug() << Q_FUNC_INFO << index << m_symbolContexts.at(index);
+        qDebug() << Q_FUNC_INFO << index;
 
     if (index < 0 || index >= m_symbolContexts.size()) {
         *errorMessage = QString::fromLatin1("%1: Index %2 out of range %3.").
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
index 5666fd58aa70b80eaeb00fa444351b50d37b911d..e381a5aa86d3ce544040e2b110e615eca2476de6 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
@@ -33,6 +33,8 @@
 #include "watchutils.h"
 #include <QtCore/QTextStream>
 
+enum { debug = 0 };
+
 static inline QString msgSymbolNotFound(const QString &s)
 {
     return QString::fromLatin1("The symbol '%1' could not be found.").arg(s);
@@ -146,7 +148,7 @@ bool CdbSymbolGroupContext::init(QString *errorMessage)
         return false;
     }
     populateINameIndexMap(m_prefix, DEBUG_ANY_ID, 0, count);
-    if (debugCDB)
+    if (debug)
         qDebug() << Q_FUNC_INFO << '\n'<< toString();
     return true;
 }
@@ -157,7 +159,7 @@ void CdbSymbolGroupContext::populateINameIndexMap(const QString &prefix, unsigne
     // Make the entries for iname->index mapping. We might encounter
     // already expanded subitems when doing it for top-level, recurse in that case.
     const QString symbolPrefix = prefix + m_nameDelimiter;
-    if (debugCDB)
+    if (debug)
         qDebug() << Q_FUNC_INFO << '\n'<< symbolPrefix << start << count;
     const unsigned long end = m_symbolParameters.size();
     unsigned long seenChildren = 0;
@@ -230,7 +232,7 @@ bool CdbSymbolGroupContext::getChildSymbolsPosition(const QString &prefix,
                                                     unsigned long *parentId,
                                                     QString *errorMessage)
 {
-    if (debugCDB)
+    if (debug)
         qDebug() << Q_FUNC_INFO << '\n'<< prefix;
 
     *start = *parentId = 0;
@@ -238,7 +240,7 @@ bool CdbSymbolGroupContext::getChildSymbolsPosition(const QString &prefix,
     if (prefix == m_prefix) {
         *start = 0;
         *parentId = DEBUG_ANY_ID;
-        if (debugCDB)
+        if (debug)
             qDebug() << '<' << prefix << "at" << *start;
         return true;
     }
@@ -252,7 +254,7 @@ bool CdbSymbolGroupContext::getChildSymbolsPosition(const QString &prefix,
     *start = nit.value() + 1;
     if (!expandSymbol(prefix, *parentId, errorMessage))
         return false;
-    if (debugCDB)
+    if (debug)
         qDebug() << '<' << prefix << "at" << *start;
     return true;
 }
@@ -260,7 +262,7 @@ bool CdbSymbolGroupContext::getChildSymbolsPosition(const QString &prefix,
 // Expand a symbol using the symbol group interface.
 bool CdbSymbolGroupContext::expandSymbol(const QString &prefix, unsigned long index, QString *errorMessage)
 {
-    if (debugCDB)
+    if (debug)
         qDebug() << '>' << Q_FUNC_INFO << '\n' << prefix << index;
 
     switch (symbolState(index)) {
@@ -306,7 +308,7 @@ bool CdbSymbolGroupContext::expandSymbol(const QString &prefix, unsigned long in
             it.value() += newSymbolCount;
     // insert the new symbols
     populateINameIndexMap(prefix, index, index + 1, newSymbolCount);
-    if (debugCDB > 1)
+    if (debug > 1)
         qDebug() << '<' << Q_FUNC_INFO << '\n' << prefix << index << '\n' << toString();
     return true;
 }
@@ -372,7 +374,7 @@ WatchData CdbSymbolGroupContext::symbolAt(unsigned long index) const
     } else {
         wd.setChildCount(0);
     }
-    if (debugCDB > 1)
+    if (debug > 1)
         qDebug() << Q_FUNC_INFO << index << '\n' << wd.toString();
     return wd;
 }
@@ -399,6 +401,78 @@ bool CdbSymbolGroupContext::assignValue(const QString &iname, const QString &val
     return true;
 }
 
+// format an array of integers as "0x323, 0x2322, ..."
+template <class Integer>
+static QString hexFormatArrayHelper(const Integer *array, int size)
+{
+    QString rc;
+    const QString hexPrefix = QLatin1String("0x");
+    const QString separator= QLatin1String(", ");
+    for (int i = 0; i < size; i++) {
+        if (i)
+            rc += separator;
+        rc += hexPrefix;
+        rc += QString::number(array[i], 16);
+    }
+    return rc;
+}
+
+QString CdbSymbolGroupContext::hexFormatArray(const unsigned short *array, int size)
+{
+    return hexFormatArrayHelper(array, size);
+}
+
+QString CdbSymbolGroupContext::debugValueToString(const DEBUG_VALUE &dv, IDebugControl4 *ctl, QString *type)
+{
+    switch (dv.Type) {
+    case DEBUG_VALUE_INT8:
+        *type = QLatin1String("char");
+        return QString::number(dv.I8);
+    case DEBUG_VALUE_INT16:
+        *type = QLatin1String("short");
+        return QString::number(static_cast<short>(dv.I16));
+    case DEBUG_VALUE_INT32:
+        *type = QLatin1String("long");
+        return QString::number(static_cast<long>(dv.I32));
+    case DEBUG_VALUE_INT64:
+        *type = QLatin1String("long long");
+        return QString::number(static_cast<long long>(dv.I64));
+    case DEBUG_VALUE_FLOAT32:
+        *type = QLatin1String("float");
+        return QString::number(dv.F32);
+    case DEBUG_VALUE_FLOAT64:
+        *type = QLatin1String("double");
+        return QString::number(dv.F64);
+    case DEBUG_VALUE_FLOAT80:
+    case DEBUG_VALUE_FLOAT128: { // Convert to double
+            DEBUG_VALUE doubleValue;
+            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");
+            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;
+    }
+    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;
+    }    
+    }
+    *type = QString::fromLatin1("Unknown type #%1:").arg(dv.Type);
+    return hexFormatArrayHelper(dv.RawBytes, 24);
+}
+
 // - Watch model functions
 class WatchDataBackInserter {
 public:
@@ -436,7 +510,7 @@ static bool insertSymbolRecursion(WatchData wd,
     // (Sometimes, some root children are already expanded after creating the context).
     const bool hasChildren = wd.childCount > 0 || wd.isChildrenNeeded();
     const bool recurse = hasChildren && (level < maxRecursionLevel || sg->isExpanded(wd.iname));
-    if (debugCDB)
+    if (debug)
         qDebug() << Q_FUNC_INFO << '\n' << wd.iname << "level=" << level <<  "recurse=" << recurse;
     bool rc = true;
     if (recurse) { // Determine number of children and indicate in model
@@ -453,7 +527,7 @@ static bool insertSymbolRecursion(WatchData wd,
             wd.setChildrenUnneeded();
         }
     }
-    if (debugCDB)
+    if (debug)
         qDebug() << " INSERTING: at " << level << wd.toString();
     watchHandler->insertData(wd);
     return rc;
@@ -468,7 +542,7 @@ static bool insertChildrenRecursion(const QString &iname,
                                     QString *errorMessage,
                                     int *childCountPtr)
 {
-    if (debugCDB > 1)
+    if (debug > 1)
         qDebug() << Q_FUNC_INFO << '\n' << iname << level;
 
     QList<WatchData> watchList;
@@ -516,17 +590,17 @@ bool CdbSymbolGroupContext::populateModelInitially(CdbSymbolGroupContext *sg,
 }
 
 bool CdbSymbolGroupContext::completeModel(CdbSymbolGroupContext *sg,
+                                          const QList<WatchData> &incompleteLocals,
                                           WatchHandler *watchHandler,
                                           QString *errorMessage)
 {
-    const QList<WatchData> incomplete = watchHandler->takeCurrentIncompletes();
     if (debugCDB)
-        qDebug().nospace() << "###>" << Q_FUNC_INFO << ' ' << incomplete.size() << '\n';
+        qDebug().nospace() << "###>" << Q_FUNC_INFO << ' ' << incompleteLocals.size() << '\n';
     // The view reinserts any node being expanded with flag 'ChildrenNeeded'.
     // Recurse down one level in context unless this is already the case.
-    foreach(WatchData wd, incomplete) {        
+    foreach(WatchData wd, incompleteLocals) {
         const bool contextExpanded = sg->isExpanded(wd.iname);
-        if (debugCDB)
+        if (debug)
             qDebug() << "  " << wd.iname << "CE=" << contextExpanded;
         if (contextExpanded) { // You know that already.
             wd.setChildrenUnneeded();
@@ -536,7 +610,6 @@ bool CdbSymbolGroupContext::completeModel(CdbSymbolGroupContext *sg,
                 return false;
         }
     }
-    watchHandler->rebuildModel();
     return true;
 }
 
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
index a7501128973438a219c8e25e1b5f4a1f5f327115..46254ce4e04b41b087f038934cdb824d2117a836 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
@@ -74,7 +74,11 @@ public:
                      QString *newValue /* = 0 */, QString *errorMessage);
 
     static bool populateModelInitially(CdbSymbolGroupContext *sg, WatchHandler *wh, QString *errorMessage);
-    static bool completeModel(CdbSymbolGroupContext *sg, WatchHandler *wh, QString *errorMessage);
+
+    static bool completeModel(CdbSymbolGroupContext *sg,
+                              const QList<WatchData> &incompleteLocals,
+                              WatchHandler *wh,
+                              QString *errorMessage);
 
     // Retrieve child symbols of prefix as a sequence of WatchData.
     template <class OutputIterator>
@@ -87,6 +91,12 @@ public:
     inline bool isExpanded(unsigned long index) const   { return symbolState(index) == ExpandedSymbol; }
     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);
+
+    // format an array of unsigned longs as "0x323, 0x2322, ..."
+    static QString hexFormatArray(const unsigned short *array, int size);
+
 private:
     typedef QMap<QString, unsigned long>  NameIndexMap;