diff --git a/src/plugins/debugger/cdb/cdb.pri b/src/plugins/debugger/cdb/cdb.pri
index 527cd0be298b8ba69a5f06abd83437218a5934f4..27186577c3041746f0c48c5952df1c72d3daba6b 100644
--- a/src/plugins/debugger/cdb/cdb.pri
+++ b/src/plugins/debugger/cdb/cdb.pri
@@ -1,5 +1,8 @@
+# Detect presence of "Debugging Tools For Windows"
+# in case VS compilers are used.      
+
 win32 {
-# ---- Detect Debugging Tools For Windows
+contains(QMAKE_CXX, cl) {
 
 CDB_PATH="$$(ProgramFiles)/Debugging Tools For Windows/sdk"
 
@@ -26,6 +29,7 @@ SOURCES += \
     $$PWD/cdbdebugeventcallback.cpp \
     $$PWD/cdbdebugoutput.cpp
 } else {
-   error("Debugging Tools for Windows could not be found in $$CDB_PATH")
+   message("Debugging Tools for Windows could not be found in $$CDB_PATH")
+}
 }
 }
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index efaa12d2b98a8e6b6c8d0a32966d6bced247bf11..af9da55976e7e768c3bcbc0b37e94f4ecce12f66 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -360,6 +360,16 @@ bool CdbDebugEngine::startDebuggerWithExecutable(DebuggerStartMode sm, QString *
     return true;
 }
 
+void CdbDebugEngine::processTerminated(unsigned long exitCode)
+{
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO << exitCode;
+
+    m_d->setDebuggeeHandles(0, 0);
+    m_d->m_debuggerManagerAccess->notifyInferiorExited();
+    m_d->m_debuggerManager->exitDebugger();
+}
+
 void CdbDebugEngine::exitDebugger()
 {
     if (debugCDB)
@@ -380,7 +390,9 @@ void CdbDebugEngine::exitDebugger()
             break;
         case StartExternal:
         case StartInternal:            
+            // Terminate and waitr for stop events.
             hr = m_d->m_pDebugClient->TerminateCurrentProcess();
+            QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
             if (debugCDB)
                 qDebug() << Q_FUNC_INFO << "terminated" << msgDebugEngineComResult(hr);
 
@@ -469,7 +481,7 @@ bool CdbDebugEnginePrivate::updateLocals(int frameIndex,
                 value = QLatin1String("<unknown>");
             }
             WatchData wd;
-            wd.iname = QLatin1String("local");
+            wd.iname = QLatin1String("local.") + name;
             wd.name = name;
             wd.value = value;
             wd.type  = type;
@@ -592,6 +604,7 @@ void CdbDebugEngine::continueInferior()
     m_d->m_debuggerManager->resetLocation();
 
     ULONG executionStatus;
+    m_d->m_debuggerManagerAccess->notifyInferiorRunningRequested();
     HRESULT hr = m_d->m_pDebugControl->GetExecutionStatus(&executionStatus);
     if (SUCCEEDED(hr) && executionStatus != DEBUG_STATUS_GO) {
         hr = m_d->m_pDebugControl->SetExecutionStatus(DEBUG_STATUS_GO);
@@ -654,8 +667,10 @@ void CdbDebugEngine::activateFrame(int frameIndex)
     if (debugCDB)
         qDebug() << Q_FUNC_INFO << frameIndex;
 
-    if (m_d->m_debuggerManager->status() != DebuggerInferiorStopped)
+    if (m_d->m_debuggerManager->status() != DebuggerInferiorStopped) {
+        qWarning("WARNING %s: invoked while debuggee is running\n", Q_FUNC_INFO);
         return;
+    }
 
     QString errorMessage;
     bool success = false;
@@ -793,7 +808,7 @@ void CdbDebugEngine::timerEvent(QTimerEvent* te)
     const HRESULT hr = m_d->m_pDebugControl->WaitForEvent(0, 1);
     if (debugCDB)
         if (debugCDB > 1 || hr != S_FALSE)
-            qDebug() << Q_FUNC_INFO << "WaitForEvent" << msgDebugEngineComResult(hr);
+            qDebug() << Q_FUNC_INFO << "WaitForEvent" << m_d->m_debuggerManager->status() <<   msgDebugEngineComResult(hr);
 
     switch (hr) {
         case S_OK:
@@ -974,9 +989,10 @@ void CdbDebugEnginePrivate::updateStackTrace()
     }
 }
 
-void CdbDebugEnginePrivate::handleDebugOutput(const char* szOutputString)
+void CdbDebugEnginePrivate::handleDebugOutput(const char *szOutputString)
 {
-    qDebug() << Q_FUNC_INFO << szOutputString;
+    if (debugCDB && strstr(szOutputString, "ModLoad:") == 0)
+        qDebug() << Q_FUNC_INFO << szOutputString;
     m_debuggerManagerAccess->showApplicationOutput(QString::fromLocal8Bit(szOutputString));
 }
 
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h
index 59ebeed571efb3145d10240490d6226d9021a626..0662a8350a091494acc71715e16fea72f65f0d4d 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine.h
@@ -104,6 +104,7 @@ private:
     bool startDebuggerWithExecutable(DebuggerStartMode sm, QString *errorMessage);
     void startWatchTimer();
     void killWatchTimer();
+    void processTerminated(unsigned long exitCode);
 
     CdbDebugEnginePrivate *m_d;
 
diff --git a/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp b/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
index c0f6cd80a40984e224ee5761cc0bb62497de8b39..ee8120f3e53c6ed767ddb1a4b03eceaa489da2fc 100644
--- a/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
@@ -192,9 +192,7 @@ STDMETHODIMP CdbDebugEventCallback::ExitProcess(
 {
     if (debugCDB)
         qDebug() << Q_FUNC_INFO << ExitCode;
-
-    m_pEngine->m_d->setDebuggeeHandles(0, 0);
-    m_pEngine->m_d->m_debuggerManagerAccess->notifyInferiorExited();
+    m_pEngine->processTerminated(ExitCode);
     return S_OK;
 }
 
diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index c86d3793014db99b92085c0ee58455d4ad4cc925..f6388fa835947b36a5fa3d9c348bad86bb1eb47c 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -26,6 +26,7 @@ HEADERS += \
     debuggerrunner.h \
     disassemblerhandler.h \
     disassemblerwindow.h \
+    watchutils.h \
     gdbengine.h \
     gdbmi.h \
     idebuggerengine.h \
@@ -56,6 +57,7 @@ SOURCES += \
     debuggerrunner.cpp \
     disassemblerhandler.cpp \
     disassemblerwindow.cpp \
+    watchutils.cpp \
     gdbengine.cpp \
     gdbmi.cpp \
     moduleshandler.cpp \
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index e68a359a31a8cf8d26246ab66afe7d9ccb12e041..561397ed36e47c34abc150a9f196f6f745d79710 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -88,6 +88,25 @@ using namespace Debugger::Constants;
 static const QString tooltipIName = "tooltip";
 
 
+static const char *stateName(int s)
+{
+    switch (s) {
+    case DebuggerProcessNotReady:
+        return "DebuggerProcessNotReady";
+    case DebuggerProcessStartingUp:
+        return "DebuggerProcessStartingUp";
+    case DebuggerInferiorRunningRequested:
+        return "DebuggerInferiorRunningRequested";
+    case DebuggerInferiorRunning:
+        return "DebuggerInferiorRunning";
+    case DebuggerInferiorStopRequested:
+        return "DebuggerInferiorStopRequested";
+    case DebuggerInferiorStopped:
+        return "DebuggerInferiorStopped";
+    }
+    return "<unknown>";
+}
+
 ///////////////////////////////////////////////////////////////////////
 //
 // BreakByFunctionDialog
@@ -1133,13 +1152,16 @@ static bool isAllowedTransition(int from, int to)
 void DebuggerManager::setStatus(int status)
 {
     if (Debugger::Constants::Internal::debug)
-        qDebug() << Q_FUNC_INFO << "STATUS CHANGE: from" << m_status << "to" << status;
+        qDebug() << Q_FUNC_INFO << "STATUS CHANGE: from" << stateName(m_status) << "to" << stateName(status);
 
     if (status == m_status)
         return;
 
-    if (!isAllowedTransition(m_status, status))
-        qDebug() << "UNEXPECTED TRANSITION:  " << m_status << status;
+    if (!isAllowedTransition(m_status, status)) {
+        const QString msg = QString::fromLatin1("%1: UNEXPECTED TRANSITION: %2 -> %3").
+                            arg(QLatin1String(Q_FUNC_INFO), QLatin1String(stateName(m_status)), QLatin1String(stateName(status)));
+        qWarning("%s", qPrintable(msg));
+    }
 
     m_status = status;
 
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 09083645474fb71cd8e32d19e5e72e1182e45032..b85b74e6c52fcc593ad64cfb8a896c889e7a614e 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -29,6 +29,7 @@
 
 #include "gdbengine.h"
 
+#include "watchutils.h"
 #include "debuggeractions.h"
 #include "debuggerconstants.h"
 #include "debuggermanager.h"
@@ -152,88 +153,12 @@ enum GdbCommandType
     WatchDumpCustomEditValue,
 };
 
-QString dotEscape(QString str)
-{
-    str.replace(' ', '.');
-    str.replace('\\', '.');
-    str.replace('/', '.');
-    return str;
-}
-
-QString currentTime()
-{
-    return QTime::currentTime().toString("hh:mm:ss.zzz");
-}
-
 static int &currentToken()
 {
     static int token = 0;
     return token;
 }
 
-static bool isSkippableFunction(const QString &funcName, const QString &fileName)
-{
-    if (fileName.endsWith("kernel/qobject.cpp"))
-        return true;
-    if (fileName.endsWith("kernel/moc_qobject.cpp"))
-        return true;
-    if (fileName.endsWith("kernel/qmetaobject.cpp"))
-        return true;
-    if (fileName.endsWith(".moc"))
-        return true;
-
-    if (funcName.endsWith("::qt_metacall"))
-        return true;
-
-    return false;
-}
-
-static bool isLeavableFunction(const QString &funcName, const QString &fileName)
-{
-    if (funcName.endsWith("QObjectPrivate::setCurrentSender"))
-        return true;
-    if (fileName.endsWith("kernel/qmetaobject.cpp")
-            && funcName.endsWith("QMetaObject::methodOffset"))
-        return true;
-    if (fileName.endsWith("kernel/qobject.h"))
-        return true;
-    if (fileName.endsWith("kernel/qobject.cpp")
-            && funcName.endsWith("QObjectConnectionListVector::at"))
-        return true;
-    if (fileName.endsWith("kernel/qobject.cpp")
-            && funcName.endsWith("~QObject"))
-        return true;
-    if (fileName.endsWith("thread/qmutex.cpp"))
-        return true;
-    if (fileName.endsWith("thread/qthread.cpp"))
-        return true;
-    if (fileName.endsWith("thread/qthread_unix.cpp"))
-        return true;
-    if (fileName.endsWith("thread/qmutex.h"))
-        return true;
-    if (fileName.contains("thread/qbasicatomic"))
-        return true;
-    if (fileName.contains("thread/qorderedmutexlocker_p"))
-        return true;
-    if (fileName.contains("arch/qatomic"))
-        return true;
-    if (fileName.endsWith("tools/qvector.h"))
-        return true;
-    if (fileName.endsWith("tools/qlist.h"))
-        return true;
-    if (fileName.endsWith("tools/qhash.h"))
-        return true;
-    if (fileName.endsWith("tools/qmap.h"))
-        return true;
-    if (fileName.endsWith("tools/qstring.h"))
-        return true;
-    if (fileName.endsWith("global/qglobal.h"))
-        return true;
-
-    return false;
-}
-
-
 ///////////////////////////////////////////////////////////////////////
 //
 // GdbEngine
@@ -364,12 +289,6 @@ void GdbEngine::gdbProcError(QProcess::ProcessError error)
     q->exitDebugger();
 }
 
-static inline bool isNameChar(char c)
-{
-    // could be 'stopped' or 'shlibs-added'
-    return (c >= 'a' && c <= 'z') || c == '-';
-}
-
 #if 0
 static void dump(const char *first, const char *middle, const QString & to)
 {
@@ -1575,7 +1494,6 @@ int GdbEngine::currentFrame() const
     return qq->stackHandler()->currentIndex();
 }
 
-
 bool GdbEngine::startDebugger()
 {
     debugMessage(theDebuggerSettings()->dump());
@@ -2743,43 +2661,6 @@ static QString m_toolTipExpression;
 static QPoint m_toolTipPos;
 static QMap<QString, WatchData> m_toolTipCache;
 
-static bool hasLetterOrNumber(const QString &exp)
-{
-    for (int i = exp.size(); --i >= 0; )
-        if (exp[i].isLetterOrNumber() || exp[i] == '_')
-            return true;
-    return false;
-}
-
-static bool hasSideEffects(const QString &exp)
-{
-    // FIXME: complete?
-    return exp.contains("-=")
-        || exp.contains("+=")
-        || exp.contains("/=")
-        || exp.contains("*=")
-        || exp.contains("&=")
-        || exp.contains("|=")
-        || exp.contains("^=")
-        || exp.contains("--")
-        || exp.contains("++");
-}
-
-static bool isKeyWord(const QString &exp)
-{
-    // FIXME: incomplete
-    return exp == QLatin1String("class")
-        || exp == QLatin1String("const")
-        || exp == QLatin1String("do")
-        || exp == QLatin1String("if")
-        || exp == QLatin1String("return")
-        || exp == QLatin1String("struct")
-        || exp == QLatin1String("template")
-        || exp == QLatin1String("void")
-        || exp == QLatin1String("volatile")
-        || exp == QLatin1String("while");
-}
-
 void GdbEngine::setToolTipExpression(const QPoint &pos, const QString &exp0)
 {
     //qDebug() << "SET TOOLTIP EXP" << pos << exp0;
@@ -2886,85 +2767,6 @@ void GdbEngine::setToolTipExpression(const QPoint &pos, const QString &exp0)
 
 static const QString strNotInScope = QLatin1String("<not in scope>");
 
-static bool isPointerType(const QString &type)
-{
-    return type.endsWith("*") || type.endsWith("* const");
-}
-
-static bool isAccessSpecifier(const QString &str)
-{
-    static const QStringList items =
-        QStringList() << "private" << "protected" << "public";
-    return items.contains(str);
-}
-
-static bool startsWithDigit(const QString &str)
-{
-    return !str.isEmpty() && str[0] >= '0' && str[0] <= '9';
-}
-
-QString stripPointerType(QString type)
-{
-    if (type.endsWith("*"))
-        type.chop(1);
-    if (type.endsWith("* const"))
-        type.chop(7);
-    if (type.endsWith(' '))
-        type.chop(1);
-    return type;
-}
-
-static QString gdbQuoteTypes(const QString &type)
-{
-    // gdb does not understand sizeof(Core::IFile*).
-    // "sizeof('Core::IFile*')" is also not acceptable,
-    // it needs to be "sizeof('Core::IFile'*)"
-    //
-    // We never will have a perfect solution here (even if we had a full blown
-    // C++ parser as we do not have information on what is a type and what is
-    // a variable name. So "a<b>::c" could either be two comparisons of values
-    // 'a', 'b' and '::c', or a nested type 'c' in a template 'a<b>'. We
-    // assume here it is the latter.
-    //return type;
-
-    // (*('myns::QPointer<myns::QObject>*'*)0x684060)" is not acceptable
-    // (*('myns::QPointer<myns::QObject>'**)0x684060)" is acceptable
-    if (isPointerType(type))
-        return gdbQuoteTypes(stripPointerType(type)) + "*";
-
-    QString accu;
-    QString result;
-    int templateLevel = 0;
-    for (int i = 0; i != type.size(); ++i) {
-        QChar c = type.at(i);
-        if (c.isLetterOrNumber() || c == '_' || c == ':' || c == ' ') {
-            accu += c;
-        } else if (c == '<') {
-            ++templateLevel;
-            accu += c;
-        } else if (c == '<') {
-            --templateLevel;
-            accu += c;
-        } else if (templateLevel > 0) {
-            accu += c;
-        } else {
-            if (accu.contains(':') || accu.contains('<'))
-                result += '\'' + accu + '\'';
-            else
-                result += accu;
-            accu.clear();
-            result += c;
-        }
-    }
-    if (accu.contains(':') || accu.contains('<'))
-        result += '\'' + accu + '\'';
-    else
-        result += accu;
-    //qDebug() << "GDB_QUOTING" << type << " TO " << result;
-
-    return result;
-}
-
 static void setWatchDataValue(WatchData &data, const GdbMi &mi,
     int encoding = 0)
 {
@@ -3048,68 +2850,6 @@ static void setWatchDataSAddress(WatchData &data, const GdbMi &mi)
         data.saddr = mi.data();
 }
 
-static bool extractTemplate(const QString &type, QString *tmplate, QString *inner)
-{
-    // Input "Template<Inner1,Inner2,...>::Foo" will return "Template::Foo" in
-    // 'tmplate' and "Inner1@Inner2@..." etc in 'inner'. Result indicates
-    // whether parsing was successful
-    int level = 0;
-    bool skipSpace = false;
-    for (int i = 0; i != type.size(); ++i) {
-        QChar c = type[i];
-        if (c == ' ' && skipSpace) {
-            skipSpace = false;
-        } else if (c == '<') {
-            *(level == 0 ? tmplate : inner) += c;
-            ++level;
-        } else if (c == '>') {
-            --level;
-            *(level == 0 ? tmplate : inner) += c;
-        } else if (c == ',') {
-            *inner += (level == 1) ? '@' : ',';
-            skipSpace = true;
-        } else {
-            *(level == 0 ? tmplate : inner) += c;
-        }
-    }
-    *tmplate = tmplate->trimmed();
-    *tmplate = tmplate->remove("<>");
-    *inner = inner->trimmed();
-    //qDebug() << "EXTRACT TEMPLATE: " << *tmplate << *inner << " FROM " << type;
-    return !inner->isEmpty();
-}
-
-static QString extractTypeFromPTypeOutput(const QString &str)
-{
-    int pos0 = str.indexOf('=');
-    int pos1 = str.indexOf('{');
-    int pos2 = str.lastIndexOf('}');
-    QString res = str;
-    if (pos0 != -1 && pos1 != -1 && pos2 != -1)
-        res = str.mid(pos0 + 2, pos1 - 1 - pos0)
-            + " ... " + str.right(str.size() - pos2);
-    return res.simplified();
-}
-
-static bool isIntOrFloatType(const QString &type)
-{
-    static const QStringList types = QStringList()
-        << "char" << "int" << "short" << "float" << "double" << "long"
-        << "bool" << "signed char" << "unsigned" << "unsigned char"
-        << "unsigned int" << "unsigned long" << "long long"
-        << "unsigned long long";
-    return types.contains(type);
-}
-
-static QString sizeofTypeExpression(const QString &type)
-{
-    if (type.endsWith('*'))
-        return "sizeof(void*)";
-    if (type.endsWith('>'))
-        return "sizeof(" + type + ")";
-    return "sizeof(" + gdbQuoteTypes(type) + ")";
-}
-
 void GdbEngine::setUseDumpers(bool on)
 {
     qDebug() << "SWITCHING ON/OFF DUMPER DEBUGGING:" << on;
@@ -4329,4 +4069,3 @@ IDebuggerEngine *createGdbEngine(DebuggerManager *parent)
 {
     return new GdbEngine(parent);
 }
-
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c679857ab88879ee43f102092b2019d1dcfde6e1
--- /dev/null
+++ b/src/plugins/debugger/watchutils.cpp
@@ -0,0 +1,303 @@
+/**************************************************************************
+**
+** 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 "watchutils.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QTime>
+#include <QtCore/QStringList>
+
+namespace Debugger {
+namespace Internal {
+
+QString dotEscape(QString str)
+{
+    const QChar dot = QLatin1Char(',');
+    str.replace(QLatin1Char(' '), dot);
+    str.replace(QLatin1Char('\\'), dot);
+    str.replace(QLatin1Char('/'), dot);
+    return str;
+}
+
+QString currentTime()
+{
+    return QTime::currentTime().toString(QLatin1String("hh:mm:ss.zzz"));
+}
+
+bool isSkippableFunction(const QString &funcName, const QString &fileName)
+{
+    if (fileName.endsWith(QLatin1String("kernel/qobject.cpp")))
+        return true;
+    if (fileName.endsWith(QLatin1String("kernel/moc_qobject.cpp")))
+        return true;
+    if (fileName.endsWith(QLatin1String("kernel/qmetaobject.cpp")))
+        return true;
+    if (fileName.endsWith(QLatin1String(".moc")))
+        return true;
+
+    if (funcName.endsWith("::qt_metacall"))
+        return true;
+
+    return false;
+}
+
+bool isLeavableFunction(const QString &funcName, const QString &fileName)
+{
+    if (funcName.endsWith(QLatin1String("QObjectPrivate::setCurrentSender")))
+        return true;
+    if (fileName.endsWith(QLatin1String("kernel/qmetaobject.cpp"))
+            && funcName.endsWith(QLatin1String("QMetaObject::methodOffset")))
+        return true;
+    if (fileName.endsWith(QLatin1String("kernel/qobject.h")))
+        return true;
+    if (fileName.endsWith(QLatin1String("kernel/qobject.cpp"))
+            && funcName.endsWith(QLatin1String("QObjectConnectionListVector::at")))
+        return true;
+    if (fileName.endsWith(QLatin1String("kernel/qobject.cpp"))
+            && funcName.endsWith(QLatin1String("~QObject")))
+        return true;
+    if (fileName.endsWith(QLatin1String("thread/qmutex.cpp")))
+        return true;
+    if (fileName.endsWith(QLatin1String("thread/qthread.cpp")))
+        return true;
+    if (fileName.endsWith(QLatin1String("thread/qthread_unix.cpp")))
+        return true;
+    if (fileName.endsWith(QLatin1String("thread/qmutex.h")))
+        return true;
+    if (fileName.contains(QLatin1String("thread/qbasicatomic")))
+        return true;
+    if (fileName.contains(QLatin1String("thread/qorderedmutexlocker_p")))
+        return true;
+    if (fileName.contains(QLatin1String("arch/qatomic")))
+        return true;
+    if (fileName.endsWith(QLatin1String("tools/qvector.h")))
+        return true;
+    if (fileName.endsWith(QLatin1String("tools/qlist.h")))
+        return true;
+    if (fileName.endsWith(QLatin1String("tools/qhash.h")))
+        return true;
+    if (fileName.endsWith(QLatin1String("tools/qmap.h")))
+        return true;
+    if (fileName.endsWith(QLatin1String("tools/qstring.h")))
+        return true;
+    if (fileName.endsWith(QLatin1String("global/qglobal.h")))
+        return true;
+
+    return false;
+}
+
+bool hasLetterOrNumber(const QString &exp)
+{
+    const QChar underscore = QLatin1Char('_');
+    for (int i = exp.size(); --i >= 0; )
+        if (exp.at(i).isLetterOrNumber() || exp.at(i) == underscore)
+            return true;
+    return false;
+}
+
+bool hasSideEffects(const QString &exp)
+{
+    // FIXME: complete?
+    return exp.contains(QLatin1String("-="))
+        || exp.contains(QLatin1String("+="))
+        || exp.contains(QLatin1String("/="))
+        || exp.contains(QLatin1String("*="))
+        || exp.contains(QLatin1String("&="))
+        || exp.contains(QLatin1String("|="))
+        || exp.contains(QLatin1String("^="))
+        || exp.contains(QLatin1String("--"))
+        || exp.contains(QLatin1String("++"));
+}
+
+bool isKeyWord(const QString &exp)
+{
+    // FIXME: incomplete
+    return exp == QLatin1String("class")
+        || exp == QLatin1String("const")
+        || exp == QLatin1String("do")
+        || exp == QLatin1String("if")
+        || exp == QLatin1String("return")
+        || exp == QLatin1String("struct")
+        || exp == QLatin1String("template")
+        || exp == QLatin1String("void")
+        || exp == QLatin1String("volatile")
+        || exp == QLatin1String("while");
+}
+
+bool isPointerType(const QString &type)
+{
+    return type.endsWith(QLatin1Char('*')) || type.endsWith(QLatin1String("* const"));
+}
+
+bool isAccessSpecifier(const QString &str)
+{
+    static const QStringList items =
+        QStringList() << QLatin1String("private") << QLatin1String("protected") << QLatin1String("public");
+    return items.contains(str);
+}
+
+bool startsWithDigit(const QString &str)
+{
+    return !str.isEmpty() && str.at(0).isDigit();
+}
+
+QString stripPointerType(QString type)
+{
+    if (type.endsWith(QLatin1Char('*')))
+        type.chop(1);
+    if (type.endsWith(QLatin1String("* const")))
+        type.chop(7);
+    if (type.endsWith(QLatin1Char(' ')))
+        type.chop(1);
+    return type;
+}
+
+QString gdbQuoteTypes(const QString &type)
+{
+    // gdb does not understand sizeof(Core::IFile*).
+    // "sizeof('Core::IFile*')" is also not acceptable,
+    // it needs to be "sizeof('Core::IFile'*)"
+    //
+    // We never will have a perfect solution here (even if we had a full blown
+    // C++ parser as we do not have information on what is a type and what is
+    // a variable name. So "a<b>::c" could either be two comparisons of values
+    // 'a', 'b' and '::c', or a nested type 'c' in a template 'a<b>'. We
+    // assume here it is the latter.
+    //return type;
+
+    // (*('myns::QPointer<myns::QObject>*'*)0x684060)" is not acceptable
+    // (*('myns::QPointer<myns::QObject>'**)0x684060)" is acceptable
+    if (isPointerType(type))
+        return gdbQuoteTypes(stripPointerType(type)) + QLatin1Char('*');
+
+    QString accu;
+    QString result;
+    int templateLevel = 0;
+
+    const QChar colon = QLatin1Char(':');
+    const QChar singleQuote = QLatin1Char('\'');
+    const QChar lessThan = QLatin1Char('<');
+    const QChar greaterThan = QLatin1Char('>');
+    for (int i = 0; i != type.size(); ++i) {
+        const QChar c = type.at(i);
+        if (c.isLetterOrNumber() || c == QLatin1Char('_') || c == colon || c == QLatin1Char(' ')) {
+            accu += c;
+        } else if (c == lessThan) {
+            ++templateLevel;
+            accu += c;
+        } else if (c == greaterThan) {
+            --templateLevel;
+            accu += c;
+        } else if (templateLevel > 0) {
+            accu += c;
+        } else {
+            if (accu.contains(colon) || accu.contains(lessThan))
+                result += singleQuote + accu + singleQuote;
+            else
+                result += accu;
+            accu.clear();
+            result += c;
+        }
+    }
+    if (accu.contains(colon) || accu.contains(lessThan))
+        result += singleQuote + accu + singleQuote;
+    else
+        result += accu;
+    //qDebug() << "GDB_QUOTING" << type << " TO " << result;
+
+    return result;
+}
+
+bool extractTemplate(const QString &type, QString *tmplate, QString *inner)
+{
+    // Input "Template<Inner1,Inner2,...>::Foo" will return "Template::Foo" in
+    // 'tmplate' and "Inner1@Inner2@..." etc in 'inner'. Result indicates
+    // whether parsing was successful
+    int level = 0;
+    bool skipSpace = false;
+
+    for (int i = 0; i != type.size(); ++i) {
+        const QChar c = type.at(i);
+        if (c == QLatin1Char(' ') && skipSpace) {
+            skipSpace = false;
+        } else if (c == QLatin1Char('<')) {
+            *(level == 0 ? tmplate : inner) += c;
+            ++level;
+        } else if (c == QLatin1Char('>')) {
+            --level;
+            *(level == 0 ? tmplate : inner) += c;
+        } else if (c == QLatin1Char(',')) {
+            *inner += (level == 1) ? QLatin1Char('@') : QLatin1Char(',');
+            skipSpace = true;
+        } else {
+            *(level == 0 ? tmplate : inner) += c;
+        }
+    }
+    *tmplate = tmplate->trimmed();
+    *tmplate = tmplate->remove(QLatin1String("<>"));
+    *inner = inner->trimmed();
+    //qDebug() << "EXTRACT TEMPLATE: " << *tmplate << *inner << " FROM " << type;
+    return !inner->isEmpty();
+}
+
+QString extractTypeFromPTypeOutput(const QString &str)
+{
+    int pos0 = str.indexOf(QLatin1Char('='));
+    int pos1 = str.indexOf(QLatin1Char('{'));
+    int pos2 = str.lastIndexOf(QLatin1Char('}'));
+    QString res = str;
+    if (pos0 != -1 && pos1 != -1 && pos2 != -1)
+        res = str.mid(pos0 + 2, pos1 - 1 - pos0)
+            + QLatin1String(" ... ") + str.right(str.size() - pos2);
+    return res.simplified();
+}
+
+bool isIntOrFloatType(const QString &type)
+{
+    static const QStringList types = QStringList()
+        << QLatin1String("char") << QLatin1String("int") << QLatin1String("short")
+        << QLatin1String("float") << QLatin1String("double") << QLatin1String("long")
+        << QLatin1String("bool") << QLatin1String("signed char") << QLatin1String("unsigned")
+        << QLatin1String("unsigned char")
+        << QLatin1String("unsigned int") << QLatin1String("unsigned long")
+        << QLatin1String("long long")  << QLatin1String("unsigned long long");
+    return types.contains(type);
+}
+
+QString sizeofTypeExpression(const QString &type)
+{
+    if (type.endsWith(QLatin1Char('*')))
+        return QLatin1String("sizeof(void*)");
+    if (type.endsWith(QLatin1Char('>')))
+        return QLatin1String("sizeof(") + type + QLatin1Char(')');
+    return QLatin1String("sizeof(") + gdbQuoteTypes(type) + QLatin1Char(')');
+}
+
+}
+}
diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h
new file mode 100644
index 0000000000000000000000000000000000000000..6c7dbb9143acc75536c66589d7a7f07391c0fb00
--- /dev/null
+++ b/src/plugins/debugger/watchutils.h
@@ -0,0 +1,70 @@
+/**************************************************************************
+**
+** 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 WATCHUTILS_H
+#define WATCHUTILS_H
+
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+class QString;
+QT_END_NAMESPACE
+
+namespace Debugger {
+namespace Internal {
+
+QString dotEscape(QString str);
+QString currentTime();
+bool isSkippableFunction(const QString &funcName, const QString &fileName);
+bool isLeavableFunction(const QString &funcName, const QString &fileName);
+
+inline bool isNameChar(char c)
+{
+    // could be 'stopped' or 'shlibs-added'
+    return (c >= 'a' && c <= 'z') || c == '-';
+}
+
+bool hasLetterOrNumber(const QString &exp);
+bool hasSideEffects(const QString &exp);
+bool isKeyWord(const QString &exp);
+bool isPointerType(const QString &type);
+bool isAccessSpecifier(const QString &str);
+bool startsWithDigit(const QString &str);
+QString stripPointerType(QString type);
+QString gdbQuoteTypes(const QString &type);
+bool extractTemplate(const QString &type, QString *tmplate, QString *inner);
+QString extractTypeFromPTypeOutput(const QString &str);
+bool isIntOrFloatType(const QString &type);
+QString sizeofTypeExpression(const QString &type);
+
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // WATCHUTILS_H