diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index 3c9f4558fe1bed2018c55100417350af8fbbe303..580e49c6fb465f66c3b2842e1ba9fcad85cfd51e 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -27,7 +27,6 @@ HEADERS += breakhandler.h \
     debuggerrunner.h \
     debuggertooltip.h \
     debuggerstringutils.h \
-    watchutils.h \
     idebuggerengine.h \
     moduleshandler.h \
     moduleswindow.h \
@@ -42,6 +41,7 @@ HEADERS += breakhandler.h \
     sourcefileswindow.h \
     threadswindow.h \
     watchhandler.h \
+    watchutils.h \
     watchwindow.h \
     name_demangler.h \
     debuggeruiswitcher.h \
@@ -57,7 +57,6 @@ SOURCES += breakhandler.cpp \
     debuggerplugin.cpp \
     debuggerrunner.cpp \
     debuggertooltip.cpp \
-    watchutils.cpp \
     moduleshandler.cpp \
     moduleswindow.cpp \
     outputcollector.cpp \
@@ -70,8 +69,10 @@ SOURCES += breakhandler.cpp \
     stackwindow.cpp \
     sourcefileswindow.cpp \
     threadswindow.cpp \
+    watchdata.cpp \
     watchhandler.cpp \
     watchwindow.cpp \
+    watchutils.cpp \
     name_demangler.cpp \
     debuggeruiswitcher.cpp \
     debuggermainwindow.cpp
diff --git a/src/plugins/debugger/gdb/classicgdbengine.cpp b/src/plugins/debugger/gdb/classicgdbengine.cpp
index 9baabf0923e7f7a7db32ede95802edb7896aa302..67f3a0d6f36ae44841c02eb046dbedf028e82b56 100644
--- a/src/plugins/debugger/gdb/classicgdbengine.cpp
+++ b/src/plugins/debugger/gdb/classicgdbengine.cpp
@@ -418,7 +418,8 @@ void GdbEngine::handleDebuggingHelperValue2Classic(const GdbResponse &response)
     setWatchDataType(data, response.data.findChild("type"));
     setWatchDataDisplayedType(data, response.data.findChild("displaytype"));
     QList<WatchData> list;
-    handleChildren(data, contents, &list);
+    parseWatchData(manager()->watchHandler()->expandedINames(),
+        data, contents, &list);
     //for (int i = 0; i != list.size(); ++i)
     //    qDebug() << "READ: " << list.at(i).toString();
     manager()->watchHandler()->insertBulkData(list);
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 0f8f645404e2b378ee86501bdd1ccbad3d090ea8..7432c4601f1ce7f5dab58f898a414542cf6b3f2c 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -251,7 +251,6 @@ void GdbEngine::initializeVariables()
 
     m_fullToShortName.clear();
     m_shortToFullName.clear();
-    m_varToType.clear();
 
     invalidateSourcesList();
     m_sourcesListUpdating = false;
@@ -3236,65 +3235,6 @@ void GdbEngine::setToolTipExpression(const QPoint &mousePos,
 //
 //////////////////////////////////////////////////////////////////////
 
-void GdbEngine::setWatchDataValue(WatchData &data, const GdbMi &item)
-{
-    GdbMi value = item.findChild("value");
-    if (value.isValid()) {
-        int encoding = item.findChild("valueencoded").data().toInt();
-        data.setValue(decodeData(value.data(), encoding));
-    } else {
-        data.setValueNeeded();
-    }
-}
-
-void GdbEngine::setWatchDataValueToolTip(WatchData &data, const GdbMi &mi,
-    int encoding)
-{
-    if (mi.isValid())
-        data.setValueToolTip(decodeData(mi.data(), encoding));
-}
-
-void GdbEngine::setWatchDataChildCount(WatchData &data, const GdbMi &mi)
-{
-    if (mi.isValid())
-        data.setHasChildren(mi.data().toInt() > 0);
-}
-
-void GdbEngine::setWatchDataValueEnabled(WatchData &data, const GdbMi &mi)
-{
-    if (mi.data() == "true")
-        data.valueEnabled = true;
-    else if (mi.data() == "false")
-        data.valueEnabled = false;
-}
-
-void GdbEngine::setWatchDataValueEditable(WatchData &data, const GdbMi &mi)
-{
-    if (mi.data() == "true")
-        data.valueEditable = true;
-    else if (mi.data() == "false")
-        data.valueEditable = false;
-}
-
-void GdbEngine::setWatchDataExpression(WatchData &data, const GdbMi &mi)
-{
-    if (mi.isValid())
-        data.exp = mi.data();
-}
-
-void GdbEngine::setWatchDataAddress(WatchData &data, const GdbMi &mi)
-{
-    if (mi.isValid())
-        setWatchDataAddressHelper(data, mi.data());
-}
-
-void GdbEngine::setWatchDataAddressHelper(WatchData &data, const QByteArray &addr)
-{
-    data.addr = addr;
-    if (data.exp.isEmpty() && !data.addr.startsWith("$"))
-        data.exp = "*(" + gdbQuoteTypes(data.type).toLatin1() + "*)" + data.addr;
-}
-
 void GdbEngine::setAutoDerefPointers(const QVariant &on)
 {
     Q_UNUSED(on)
@@ -3443,25 +3383,6 @@ void GdbEngine::handleVarAssign(const GdbResponse &)
     updateLocals();
 }
 
-// Find the "type" and "displayedtype" children of root and set up type.
-void GdbEngine::setWatchDataType(WatchData &data, const GdbMi &item)
-{
-    if (item.isValid()) {
-        const QString miData = _(item.data());
-        if (!data.framekey.isEmpty())
-            m_varToType[data.framekey] = miData;
-        data.setType(miData);
-    } else if (data.type.isEmpty()) {
-        data.setTypeNeeded();
-    }
-}
-
-void GdbEngine::setWatchDataDisplayedType(WatchData &data, const GdbMi &item)
-{
-    if (item.isValid())
-        data.displayedType = _(item.data());
-}
-
 void GdbEngine::handleVarCreate(const GdbResponse &response)
 {
     WatchData data = response.cookie.value<WatchData>();
@@ -3502,84 +3423,6 @@ void GdbEngine::handleDebuggingHelperSetup(const GdbResponse &response)
     }
 }
 
-void GdbEngine::handleChildren(const WatchData &data0, const GdbMi &item,
-    QList<WatchData> *list)
-{
-    //qDebug() << "HANDLE CHILDREN: " << data0.toString() << item.toString();
-    WatchData data = data0;
-    if (!manager()->watchHandler()->isExpandedIName(data.iname))
-        data.setChildrenUnneeded();
-
-    GdbMi children = item.findChild("children");
-    if (children.isValid() || !manager()->watchHandler()->isExpandedIName(data.iname))
-        data.setChildrenUnneeded();
-
-    setWatchDataType(data, item.findChild("type"));
-    GdbMi mi = item.findChild("editvalue");
-    if (mi.isValid())
-        data.editvalue = mi.data();
-    mi = item.findChild("editformat");
-    if (mi.isValid())
-        data.editformat = mi.data().toInt();
-    mi = item.findChild("typeformats");
-    if (mi.isValid())
-        data.typeFormats = QString::fromUtf8(mi.data());
-
-    setWatchDataValue(data, item);
-    setWatchDataAddress(data, item.findChild("addr"));
-    setWatchDataExpression(data, item.findChild("exp"));
-    setWatchDataValueEnabled(data, item.findChild("valueenabled"));
-    setWatchDataValueEditable(data, item.findChild("valueeditable"));
-    setWatchDataChildCount(data, item.findChild("numchild"));
-    //qDebug() << "\nAPPEND TO LIST: " << data.toString() << "\n";
-    list->append(data);
-
-    bool ok = false;
-    qulonglong addressBase = item.findChild("addrbase").data().toULongLong(&ok, 0);
-    qulonglong addressStep = item.findChild("addrstep").data().toULongLong();
-
-    // Try not to repeat data too often.
-    WatchData childtemplate;
-    setWatchDataType(childtemplate, item.findChild("childtype"));
-    setWatchDataChildCount(childtemplate, item.findChild("childnumchild"));
-    //qDebug() << "CHILD TEMPLATE:" << childtemplate.toString();
-
-    int i = 0;
-    foreach (const GdbMi &child, children.children()) {
-        WatchData data1 = childtemplate;
-        GdbMi name = child.findChild("name");
-        if (name.isValid())
-            data1.name = _(name.data());
-        else
-            data1.name = QString::number(i);
-        GdbMi iname = child.findChild("iname");
-        if (iname.isValid())
-            data1.iname = iname.data();
-        else
-            data1.iname = data.iname + '.' + data1.name.toLatin1();
-        if (!data1.name.isEmpty() && data1.name.at(0).isDigit())
-            data1.name = _c('[') + data1.name + _c(']');
-        if (addressStep) {
-            const QByteArray addr = "0x" + QByteArray::number(addressBase, 16);
-            setWatchDataAddressHelper(data1, addr);
-            addressBase += addressStep;
-        }
-        QByteArray key = child.findChild("key").data();
-        if (!key.isEmpty()) {
-            int encoding = child.findChild("keyencoded").data().toInt();
-            QString skey = decodeData(key, encoding);
-            if (skey.size() > 13) {
-                skey = skey.left(12);
-                skey += _("...");
-            }
-            //data1.name += " (" + skey + ")";
-            data1.name = skey;
-        }
-        handleChildren(data1, child, list);
-        ++i;
-    }
-}
-
 void GdbEngine::updateLocals(const QVariant &cookie)
 {
     m_pendingWatchRequests = 0;
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 345e1c23cd67282bc2cd3ee487c6837b2321f145..c1bc7b57f0e5fe147fdef0a27d45a54ce1aa36d9 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -459,8 +459,6 @@ private: ////////// View & Data Stuff //////////
 
     // FIXME: BaseClass. called to improve situation for a watch item
     void updateSubItemClassic(const WatchData &data);
-    void handleChildren(const WatchData &parent, const GdbMi &child,
-        QList<WatchData> *insertions);
 
     void virtual updateWatchData(const WatchData &data);
     Q_SLOT void updateWatchDataHelper(const WatchData &data);
@@ -503,11 +501,8 @@ private: ////////// View & Data Stuff //////////
                             QMap<QByteArray, int> *seen);
     void setLocals(const QList<GdbMi> &locals);
     void handleStackListArgumentsClassic(const GdbResponse &response);
-    void setWatchDataType(WatchData &data, const GdbMi &mi);
-    void setWatchDataDisplayedType(WatchData &data, const GdbMi &mi);
 
     QSet<QByteArray> m_processedNames;
-    QMap<QString, QString> m_varToType;
 
 private: ////////// Dumper Management //////////
     QString qtDumperLibraryName() const;
@@ -538,16 +533,6 @@ private: ////////// Convenience Functions //////////
     static QString m_toolTipExpression;
     static QPoint m_toolTipPos;
     static QByteArray tooltipINameForExpression(const QByteArray &exp);
-
-    static void setWatchDataValue(WatchData &data, const GdbMi &item);
-    static void setWatchDataValueToolTip(WatchData &data, const GdbMi &mi,
-            int encoding = 0);
-    static void setWatchDataChildCount(WatchData &data, const GdbMi &mi);
-    static void setWatchDataValueEnabled(WatchData &data, const GdbMi &mi);
-    static void setWatchDataValueEditable(WatchData &data, const GdbMi &mi);
-    static void setWatchDataExpression(WatchData &data, const GdbMi &mi);
-    static void setWatchDataAddress(WatchData &data, const GdbMi &mi);
-    static void setWatchDataAddressHelper(WatchData &data, const QByteArray &addr);
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/gdb/pythongdbengine.cpp b/src/plugins/debugger/gdb/pythongdbengine.cpp
index 3bb164365bd99573e24ea6a749df9d2cb2b80fe3..112b172d73f888b5108facee359367f3e53fea52 100644
--- a/src/plugins/debugger/gdb/pythongdbengine.cpp
+++ b/src/plugins/debugger/gdb/pythongdbengine.cpp
@@ -125,14 +125,15 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
 
         GdbMi data = all.findChild("data");
         QList<WatchData> list;
+        WatchHandler *watchHandler = manager()->watchHandler();
         foreach (const GdbMi &child, data.children()) {
             WatchData dummy;
             dummy.iname = child.findChild("iname").data();
             dummy.name = _(child.findChild("name").data());
             //qDebug() << "CHILD: " << child.toString();
-            handleChildren(dummy, child, &list);
+            parseWatchData(watchHandler->expandedINames(), dummy, child, &list);
         }
-        manager()->watchHandler()->insertBulkData(list);
+        watchHandler->insertBulkData(list);
         //for (int i = 0; i != list.size(); ++i)
         //    qDebug() << "LOCAL: " << list.at(i).toString();
 
diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7d2f8248a977f6b15010fcf0536d15cf51f45073
--- /dev/null
+++ b/src/plugins/debugger/watchdata.cpp
@@ -0,0 +1,265 @@
+
+#include "watchdata.h"
+#include "watchutils.h"
+
+#include <QtCore/QTextStream>
+#include <QtCore/QDebug>
+
+#include <QtGui/QApplication>
+#include <QtGui/QTextDocument> // Qt::escape
+
+////////////////////////////////////////////////////////////////////
+//
+// WatchData
+//
+////////////////////////////////////////////////////////////////////
+
+namespace Debugger {
+namespace Internal {
+
+WatchData::WatchData() :
+    editformat(0),
+    hasChildren(false),
+    generation(-1),
+    valueEnabled(true),
+    valueEditable(true),
+    error(false),
+    source(0),
+    state(InitialState),
+    changed(false)
+{
+}
+
+bool WatchData::isEqual(const WatchData &other) const
+{
+    return iname == other.iname
+      && exp == other.exp
+      && name == other.name
+      && value == other.value
+      && editvalue == other.editvalue
+      && valuetooltip == other.valuetooltip
+      && type == other.type
+      && displayedType == other.displayedType
+      && variable == other.variable
+      && addr == other.addr
+      && framekey == other.framekey
+      && hasChildren == other.hasChildren
+      && valueEnabled == other.valueEnabled
+      && valueEditable == other.valueEditable
+      && error == other.error;
+}
+
+void WatchData::setError(const QString &msg)
+{
+    setAllUnneeded();
+    value = msg;
+    setHasChildren(false);
+    valueEnabled = false;
+    valueEditable = false;
+    error = true;
+}
+
+void WatchData::setValue(const QString &value0)
+{
+    value = value0;
+    if (value == "{...}") {
+        value.clear();
+        hasChildren = true; // at least one...
+    }
+    // strip off quoted characters for chars.
+    if (value.endsWith(QLatin1Char('\'')) && type.endsWith(QLatin1String("char"))) {
+        const int blankPos = value.indexOf(QLatin1Char(' '));
+        if (blankPos != -1)
+            value.truncate(blankPos);
+    }
+
+    // avoid duplicated information
+    if (value.startsWith(QLatin1Char('(')) && value.contains(") 0x"))
+        value = value.mid(value.lastIndexOf(") 0x") + 2);
+
+    // doubles are sometimes displayed as "@0x6141378: 1.2".
+    // I don't want that.
+    if (/*isIntOrFloatType(type) && */ value.startsWith("@0x")
+         && value.contains(':')) {
+        value = value.mid(value.indexOf(':') + 2);
+        setHasChildren(false);
+    }
+
+    // "numchild" is sometimes lying
+    //MODEL_DEBUG("\n\n\nPOINTER: " << type << value);
+    if (isPointerType(type))
+        setHasChildren(value != "0x0" && value != "<null>"
+            && !isCharPointerType(type));
+
+    // pointer type information is available in the 'type'
+    // column. No need to duplicate it here.
+    if (value.startsWith(QLatin1Char('(') + type + ") 0x"))
+        value = value.section(QLatin1Char(' '), -1, -1);
+
+    setValueUnneeded();
+}
+
+void WatchData::setValueToolTip(const QString &tooltip)
+{
+    valuetooltip = tooltip;
+}
+
+void WatchData::setType(const QString &str, bool guessChildrenFromType)
+{
+    type = str.trimmed();
+    bool changed = true;
+    while (changed) {
+        if (type.endsWith(QLatin1String("const")))
+            type.chop(5);
+        else if (type.endsWith(QLatin1Char(' ')))
+            type.chop(1);
+        else if (type.endsWith(QLatin1Char('&')))
+            type.chop(1);
+        else if (type.startsWith(QLatin1String("const ")))
+            type = type.mid(6);
+        else if (type.startsWith(QLatin1String("volatile ")))
+            type = type.mid(9);
+        else if (type.startsWith(QLatin1String("class ")))
+            type = type.mid(6);
+        else if (type.startsWith(QLatin1String("struct ")))
+            type = type.mid(6);
+        else if (type.startsWith(QLatin1Char(' ')))
+            type = type.mid(1);
+        else
+            changed = false;
+    }
+    setTypeUnneeded();
+    if (guessChildrenFromType) {
+        switch (guessChildren(type)) {
+        case HasChildren:
+            setHasChildren(true);
+            break;
+        case HasNoChildren:
+            setHasChildren(false);
+            break;
+        case HasPossiblyChildren:
+            setHasChildren(true); // FIXME: bold assumption
+            break;
+        }
+    }
+}
+
+void WatchData::setAddress(const QByteArray &a)
+{
+    addr = a;
+}
+
+QString WatchData::toString() const
+{
+    const char *doubleQuoteComma = "\",";
+    QString res;
+    QTextStream str(&res);
+    str << QLatin1Char('{');
+    if (!iname.isEmpty())
+        str << "iname=\"" << iname << doubleQuoteComma;
+    if (!name.isEmpty() && name != iname)
+        str << "name=\"" << name << doubleQuoteComma;
+    if (error)
+        str << "error,";
+    if (!addr.isEmpty())
+        str << "addr=\"" << addr << doubleQuoteComma;
+    if (!exp.isEmpty())
+        str << "exp=\"" << exp << doubleQuoteComma;
+
+    if (!variable.isEmpty())
+        str << "variable=\"" << variable << doubleQuoteComma;
+
+    if (isValueNeeded())
+        str << "value=<needed>,";
+    if (isValueKnown() && !value.isEmpty())
+        str << "value=\"" << value << doubleQuoteComma;
+
+    if (!editvalue.isEmpty())
+        str << "editvalue=\"<...>\",";
+    //    str << "editvalue=\"" << editvalue << doubleQuoteComma;
+
+    if (isTypeNeeded())
+        str << "type=<needed>,";
+    if (isTypeKnown() && !type.isEmpty())
+        str << "type=\"" << type << doubleQuoteComma;
+
+    if (isHasChildrenNeeded())
+        str << "hasChildren=<needed>,";
+    if (isHasChildrenKnown())
+        str << "hasChildren=\"" << (hasChildren ? "true" : "false") << doubleQuoteComma;
+
+    if (isChildrenNeeded())
+        str << "children=<needed>,";
+    if (source)
+        str << "source=" << source;
+    str.flush();
+    if (res.endsWith(QLatin1Char(',')))
+        res.truncate(res.size() - 1);
+    return res + QLatin1Char('}');
+}
+
+// Format a tooltip fow with aligned colon.
+static void formatToolTipRow(QTextStream &str,
+    const QString &category, const QString &value)
+{
+    str << "<tr><td>" << category << "</td><td> : </td><td>"
+        << Qt::escape(value) << "</td></tr>";
+}
+
+static QString typeToolTip(const WatchData &wd)
+{
+    if (wd.displayedType.isEmpty())
+        return wd.type;
+    QString rc = wd.displayedType;
+    rc += QLatin1String(" (");
+    rc += wd.type;
+    rc += QLatin1Char(')');
+    return rc;
+}
+
+QString WatchData::toToolTip() const
+{
+    if (!valuetooltip.isEmpty())
+        return QString::number(valuetooltip.size());
+    QString res;
+    QTextStream str(&res);
+    str << "<html><body><table>";
+    formatToolTipRow(str, QCoreApplication::translate("Debugger::Internal::WatchHandler", "Name"), name);
+    formatToolTipRow(str, QCoreApplication::translate("Debugger::Internal::WatchHandler", "Expression"), exp);
+    formatToolTipRow(str, QCoreApplication::translate("Debugger::Internal::WatchHandler", "Type"), typeToolTip(*this));
+    QString val = value;
+    if (value.size() > 1000) {
+        val.truncate(1000);
+        val += QCoreApplication::translate("Debugger::Internal::WatchHandler", " ... <cut off>");
+    }
+    formatToolTipRow(str, QCoreApplication::translate("Debugger::Internal::WatchHandler", "Value"), val);
+    formatToolTipRow(str, QCoreApplication::translate("Debugger::Internal::WatchHandler", "Object Address"), addr);
+    formatToolTipRow(str, QCoreApplication::translate("Debugger::Internal::WatchHandler", "Internal ID"), iname);
+    formatToolTipRow(str, QCoreApplication::translate("Debugger::Internal::WatchHandler", "Generation"),
+        QString::number(generation));
+    str << "</table></body></html>";
+    return res;
+}
+
+QString WatchData::msgNotInScope()
+{
+    static const QString rc = QCoreApplication::translate("Debugger::Internal::WatchData", "<not in scope>");
+    return rc;
+}
+
+const QString &WatchData::shadowedNameFormat()
+{
+    static const QString format = QCoreApplication::translate("Debugger::Internal::WatchData", "%1 <shadowed %2>");
+    return format;
+}
+
+QString WatchData::shadowedName(const QString &name, int seen)
+{
+    if (seen <= 0)
+        return name;
+    return shadowedNameFormat().arg(name, seen);
+}
+
+} // namespace Internal
+} // namespace Debugger
+
diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h
new file mode 100644
index 0000000000000000000000000000000000000000..f8062324ef25eaf4ae2385582dedadcf069b9bac
--- /dev/null
+++ b/src/plugins/debugger/watchdata.h
@@ -0,0 +1,142 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEBUGGER_WATCHDATA_H
+#define DEBUGGER_WATCHDATA_H
+
+#include <QtCore/QMetaType>
+#include <QtCore/QtGlobal>
+#include <QtCore/QObject>
+#include <QtScript/QScriptValue>
+
+namespace Debugger {
+namespace Internal {
+
+class WatchData
+{
+public:
+    WatchData();
+
+    enum State
+    {
+        Complete = 0,
+        HasChildrenNeeded = 1,
+        ValueNeeded = 2,
+        TypeNeeded = 4,
+        ChildrenNeeded = 8,
+
+        NeededMask = ValueNeeded
+            | TypeNeeded
+            | ChildrenNeeded
+            | HasChildrenNeeded,
+
+        InitialState = ValueNeeded
+            | TypeNeeded
+            | ChildrenNeeded
+            | HasChildrenNeeded
+    };
+
+    void setValue(const QString &);
+    void setType(const QString &, bool guessChildrenFromType = true);
+    void setValueToolTip(const QString &);
+    void setError(const QString &);
+    void setAddress(const QByteArray &);
+
+    bool isSomethingNeeded() const { return state & NeededMask; }
+    void setAllNeeded() { state = NeededMask; }
+    void setAllUnneeded() { state = State(0); }
+
+    bool isTypeNeeded() const { return state & TypeNeeded; }
+    bool isTypeKnown() const { return !(state & TypeNeeded); }
+    void setTypeNeeded() { state = State(state | TypeNeeded); }
+    void setTypeUnneeded() { state = State(state & ~TypeNeeded); }
+
+    bool isValueNeeded() const { return state & ValueNeeded; }
+    bool isValueKnown() const { return !(state & ValueNeeded); }
+    void setValueNeeded() { state = State(state | ValueNeeded); }
+    void setValueUnneeded() { state = State(state & ~ValueNeeded); }
+
+    bool isChildrenNeeded() const { return state & ChildrenNeeded; }
+    bool isChildrenKnown() const { return !(state & ChildrenNeeded); }
+    void setChildrenNeeded() { state = State(state | ChildrenNeeded); }
+    void setChildrenUnneeded() { state = State(state & ~ChildrenNeeded); }
+
+    bool isHasChildrenNeeded() const { return state & HasChildrenNeeded; }
+    bool isHasChildrenKnown() const { return !(state & HasChildrenNeeded); }
+    void setHasChildrenNeeded() { state = State(state | HasChildrenNeeded); }
+    void setHasChildrenUnneeded() { state = State(state & ~HasChildrenNeeded); }
+    void setHasChildren(bool c) { hasChildren = c; setHasChildrenUnneeded();
+        if (!c) setChildrenUnneeded(); }
+
+    QString toString() const;
+    QString toToolTip() const;
+    bool isLocal() const { return iname.startsWith("local."); }
+    bool isWatcher() const { return iname.startsWith("watch."); }
+    bool isValid() const { return !iname.isEmpty(); }
+
+    bool isEqual(const WatchData &other) const;
+
+    static QString msgNotInScope();
+    static QString shadowedName(const QString &name, int seen);
+    static const QString &shadowedNameFormat();
+
+public:
+    QByteArray iname;     // Internal name sth like 'local.baz.public.a'
+    QByteArray exp;       // The expression
+    QString name;         // Displayed name
+    QString value;        // Displayed value
+    QByteArray editvalue; // Displayed value
+    int editformat;       // Format of displayed value
+    QString valuetooltip; // Tooltip in value column
+    QString typeFormats;  // Selection of formats of displayed value
+    QString type;         // Type for further processing
+    QString displayedType;// Displayed type (optional)
+    QByteArray variable;  // Name of internal Gdb variable if created
+    QByteArray addr;      // Displayed address
+    QString framekey;     // Key for type cache
+    QScriptValue scriptValue; // If needed...
+    bool hasChildren;
+    int generation;       // When updated?
+    bool valueEnabled;    // Value will be greyed out or not
+    bool valueEditable;   // Value will be editable
+    bool error;
+
+public:
+    int source;  // Originated from dumper or symbol evaluation? (CDB only)
+    int state;
+    bool changed;
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+Q_DECLARE_METATYPE(Debugger::Internal::WatchData);
+
+
+#endif // DEBUGGER_WATCHDATA_H
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index 8aab91508bb3bcc704487a05e566261c040ce92b..e4a3bb61ab699dd394492e2c3ade4feabcac3ad8 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -103,254 +103,6 @@ public:
     QList<WatchItem *> children;  // fetched children
 };
 
-////////////////////////////////////////////////////////////////////
-//
-// WatchData
-//
-////////////////////////////////////////////////////////////////////
-
-WatchData::WatchData() :
-    editformat(0),
-    hasChildren(false),
-    generation(-1),
-    valueEnabled(true),
-    valueEditable(true),
-    error(false),
-    source(0),
-    state(InitialState),
-    changed(false)
-{
-}
-
-bool WatchData::isEqual(const WatchData &other) const
-{
-    return iname == other.iname
-      && exp == other.exp
-      && name == other.name
-      && value == other.value
-      && editvalue == other.editvalue
-      && valuetooltip == other.valuetooltip
-      && type == other.type
-      && displayedType == other.displayedType
-      && variable == other.variable
-      && addr == other.addr
-      && framekey == other.framekey
-      && hasChildren == other.hasChildren
-      && valueEnabled == other.valueEnabled
-      && valueEditable == other.valueEditable
-      && error == other.error;
-}
-
-void WatchData::setError(const QString &msg)
-{
-    setAllUnneeded();
-    value = msg;
-    setHasChildren(false);
-    valueEnabled = false;
-    valueEditable = false;
-    error = true;
-}
-
-void WatchData::setValue(const QString &value0)
-{
-    value = value0;
-    if (value == "{...}") {
-        value.clear();
-        hasChildren = true; // at least one...
-    }
-    // strip off quoted characters for chars.
-    if (value.endsWith(QLatin1Char('\'')) && type.endsWith(QLatin1String("char"))) {
-        const int blankPos = value.indexOf(QLatin1Char(' '));
-        if (blankPos != -1)
-            value.truncate(blankPos);
-    }
-
-    // avoid duplicated information
-    if (value.startsWith(QLatin1Char('(')) && value.contains(") 0x"))
-        value = value.mid(value.lastIndexOf(") 0x") + 2);
-
-    // doubles are sometimes displayed as "@0x6141378: 1.2".
-    // I don't want that.
-    if (/*isIntOrFloatType(type) && */ value.startsWith("@0x")
-         && value.contains(':')) {
-        value = value.mid(value.indexOf(':') + 2);
-        setHasChildren(false);
-    }
-
-    // "numchild" is sometimes lying
-    //MODEL_DEBUG("\n\n\nPOINTER: " << type << value);
-    if (isPointerType(type))
-        setHasChildren(value != "0x0" && value != "<null>"
-            && !isCharPointerType(type));
-
-    // pointer type information is available in the 'type'
-    // column. No need to duplicate it here.
-    if (value.startsWith(QLatin1Char('(') + type + ") 0x"))
-        value = value.section(QLatin1Char(' '), -1, -1);
-
-    setValueUnneeded();
-}
-
-void WatchData::setValueToolTip(const QString &tooltip)
-{
-    valuetooltip = tooltip;
-}
-
-void WatchData::setType(const QString &str, bool guessChildrenFromType)
-{
-    type = str.trimmed();
-    bool changed = true;
-    while (changed) {
-        if (type.endsWith(QLatin1String("const")))
-            type.chop(5);
-        else if (type.endsWith(QLatin1Char(' ')))
-            type.chop(1);
-        else if (type.endsWith(QLatin1Char('&')))
-            type.chop(1);
-        else if (type.startsWith(QLatin1String("const ")))
-            type = type.mid(6);
-        else if (type.startsWith(QLatin1String("volatile ")))
-            type = type.mid(9);
-        else if (type.startsWith(QLatin1String("class ")))
-            type = type.mid(6);
-        else if (type.startsWith(QLatin1String("struct ")))
-            type = type.mid(6);
-        else if (type.startsWith(QLatin1Char(' ')))
-            type = type.mid(1);
-        else
-            changed = false;
-    }
-    setTypeUnneeded();
-    if (guessChildrenFromType) {
-        switch (guessChildren(type)) {
-        case HasChildren:
-            setHasChildren(true);
-            break;
-        case HasNoChildren:
-            setHasChildren(false);
-            break;
-        case HasPossiblyChildren:
-            setHasChildren(true); // FIXME: bold assumption
-            break;
-        }
-    }
-}
-
-void WatchData::setAddress(const QByteArray &a)
-{
-    addr = a;
-}
-
-QString WatchData::toString() const
-{
-    const char *doubleQuoteComma = "\",";
-    QString res;
-    QTextStream str(&res);
-    str << QLatin1Char('{');
-    if (!iname.isEmpty())
-        str << "iname=\"" << iname << doubleQuoteComma;
-    if (!name.isEmpty() && name != iname)
-        str << "name=\"" << name << doubleQuoteComma;
-    if (error)
-        str << "error,";
-    if (!addr.isEmpty())
-        str << "addr=\"" << addr << doubleQuoteComma;
-    if (!exp.isEmpty())
-        str << "exp=\"" << exp << doubleQuoteComma;
-
-    if (!variable.isEmpty())
-        str << "variable=\"" << variable << doubleQuoteComma;
-
-    if (isValueNeeded())
-        str << "value=<needed>,";
-    if (isValueKnown() && !value.isEmpty())
-        str << "value=\"" << value << doubleQuoteComma;
-
-    if (!editvalue.isEmpty())
-        str << "editvalue=\"<...>\",";
-    //    str << "editvalue=\"" << editvalue << doubleQuoteComma;
-
-    if (isTypeNeeded())
-        str << "type=<needed>,";
-    if (isTypeKnown() && !type.isEmpty())
-        str << "type=\"" << type << doubleQuoteComma;
-
-    if (isHasChildrenNeeded())
-        str << "hasChildren=<needed>,";
-    if (isHasChildrenKnown())
-        str << "hasChildren=\"" << (hasChildren ? "true" : "false") << doubleQuoteComma;
-
-    if (isChildrenNeeded())
-        str << "children=<needed>,";
-    if (source)
-        str << "source=" << source;
-    str.flush();
-    if (res.endsWith(QLatin1Char(',')))
-        res.truncate(res.size() - 1);
-    return res + QLatin1Char('}');
-}
-
-// Format a tooltip fow with aligned colon.
-static void formatToolTipRow(QTextStream &str,
-    const QString &category, const QString &value)
-{
-    str << "<tr><td>" << category << "</td><td> : </td><td>"
-        << Qt::escape(value) << "</td></tr>";
-}
-
-static inline QString typeToolTip(const WatchData &wd)
-{
-    if (wd.displayedType.isEmpty())
-        return wd.type;
-    QString rc = wd.displayedType;
-    rc += QLatin1String(" (");
-    rc += wd.type;
-    rc += QLatin1Char(')');
-    return rc;
-}
-
-QString WatchData::toToolTip() const
-{
-    if (!valuetooltip.isEmpty())
-        return QString::number(valuetooltip.size());
-    QString res;
-    QTextStream str(&res);
-    str << "<html><body><table>";
-    formatToolTipRow(str, WatchHandler::tr("Name"), name);
-    formatToolTipRow(str, WatchHandler::tr("Expression"), exp);
-    formatToolTipRow(str, WatchHandler::tr("Type"), typeToolTip(*this));
-    QString val = value;
-    if (value.size() > 1000) {
-        val.truncate(1000);
-        val +=  WatchHandler::tr(" ... <cut off>");
-    }
-    formatToolTipRow(str, WatchHandler::tr("Value"), val);
-    formatToolTipRow(str, WatchHandler::tr("Object Address"), addr);
-    formatToolTipRow(str, WatchHandler::tr("Internal ID"), iname);
-    formatToolTipRow(str, WatchHandler::tr("Generation"),
-        QString::number(generation));
-    str << "</table></body></html>";
-    return res;
-}
-
-QString WatchData::msgNotInScope()
-{
-    static const QString rc = QCoreApplication::translate("Debugger::Internal::WatchData", "<not in scope>");
-    return rc;
-}
-
-const QString &WatchData::shadowedNameFormat()
-{
-    static const QString format = QCoreApplication::translate("Debugger::Internal::WatchData", "%1 <shadowed %2>");
-    return format;
-}
-
-QString WatchData::shadowedName(const QString &name, int seen)
-{
-    if (seen <= 0)
-        return name;
-    return shadowedNameFormat().arg(name, seen);
-}
 
 ///////////////////////////////////////////////////////////////////////
 //
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index 2fd672fb43e95ef19cbe80a285aa57f306589243..38bb85c87d43e06f6991aeb0cf1ea2200da9d57c 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -30,6 +30,8 @@
 #ifndef DEBUGGER_WATCHHANDLER_H
 #define DEBUGGER_WATCHHANDLER_H
 
+#include "watchdata.h"
+
 #include <QtCore/QPointer>
 #include <QtCore/QObject>
 #include <QtCore/QHash>
@@ -51,101 +53,6 @@ class WatchItem;
 class WatchHandler;
 enum WatchType { LocalsWatch, WatchersWatch, TooltipsWatch };
 
-class WatchData
-{
-public:
-    WatchData();
-
-    enum State
-    {
-        Complete = 0,
-        HasChildrenNeeded = 1,
-        ValueNeeded = 2,
-        TypeNeeded = 4,
-        ChildrenNeeded = 8,
-
-        NeededMask = ValueNeeded
-            | TypeNeeded
-            | ChildrenNeeded
-            | HasChildrenNeeded,
-
-        InitialState = ValueNeeded
-            | TypeNeeded
-            | ChildrenNeeded
-            | HasChildrenNeeded
-    };
-
-    void setValue(const QString &);
-    void setType(const QString &, bool guessChildrenFromType = true);
-    void setValueToolTip(const QString &);
-    void setError(const QString &);
-    void setAddress(const QByteArray &);
-
-    bool isSomethingNeeded() const { return state & NeededMask; }
-    void setAllNeeded() { state = NeededMask; }
-    void setAllUnneeded() { state = State(0); }
-
-    bool isTypeNeeded() const { return state & TypeNeeded; }
-    bool isTypeKnown() const { return !(state & TypeNeeded); }
-    void setTypeNeeded() { state = State(state | TypeNeeded); }
-    void setTypeUnneeded() { state = State(state & ~TypeNeeded); }
-
-    bool isValueNeeded() const { return state & ValueNeeded; }
-    bool isValueKnown() const { return !(state & ValueNeeded); }
-    void setValueNeeded() { state = State(state | ValueNeeded); }
-    void setValueUnneeded() { state = State(state & ~ValueNeeded); }
-
-    bool isChildrenNeeded() const { return state & ChildrenNeeded; }
-    bool isChildrenKnown() const { return !(state & ChildrenNeeded); }
-    void setChildrenNeeded() { state = State(state | ChildrenNeeded); }
-    void setChildrenUnneeded() { state = State(state & ~ChildrenNeeded); }
-
-    bool isHasChildrenNeeded() const { return state & HasChildrenNeeded; }
-    bool isHasChildrenKnown() const { return !(state & HasChildrenNeeded); }
-    void setHasChildrenNeeded() { state = State(state | HasChildrenNeeded); }
-    void setHasChildrenUnneeded() { state = State(state & ~HasChildrenNeeded); }
-    void setHasChildren(bool c) { hasChildren = c; setHasChildrenUnneeded();
-        if (!c) setChildrenUnneeded(); }
-
-    QString toString() const;
-    QString toToolTip() const;
-    bool isLocal() const { return iname.startsWith("local."); }
-    bool isWatcher() const { return iname.startsWith("watch."); }
-    bool isValid() const { return !iname.isEmpty(); }
-
-    bool isEqual(const WatchData &other) const;
-
-    static QString msgNotInScope();
-    static QString shadowedName(const QString &name, int seen);
-    static const QString &shadowedNameFormat();
-
-public:
-    QByteArray iname;     // Internal name sth like 'local.baz.public.a'
-    QByteArray exp;       // The expression
-    QString name;         // Displayed name
-    QString value;        // Displayed value
-    QByteArray editvalue; // Displayed value
-    int editformat;       // Format of displayed value
-    QString valuetooltip; // Tooltip in value column
-    QString typeFormats;  // Selection of formats of displayed value
-    QString type;         // Type for further processing
-    QString displayedType;// Displayed type (optional)
-    QByteArray variable;  // Name of internal Gdb variable if created
-    QByteArray addr;      // Displayed address
-    QString framekey;     // Key for type cache
-    QScriptValue scriptValue; // If needed...
-    bool hasChildren;
-    int generation;       // When updated?
-    bool valueEnabled;    // Value will be greyed out or not
-    bool valueEditable;   // Value will be editable
-    bool error;
-
-public:
-    int source;  // Originated from dumper or symbol evaluation? (CDB only)
-    int state;
-    bool changed;
-};
-
 enum WatchRoles
 {
     INameRole = Qt::UserRole,
@@ -305,6 +212,4 @@ private:
 } // namespace Internal
 } // namespace Debugger
 
-Q_DECLARE_METATYPE(Debugger::Internal::WatchData);
-
 #endif // DEBUGGER_WATCHHANDLER_H
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index a25568dcec07cd100b7cfdd314dbdccdff7b41f6..46a698952062b209506b193c8799a8f264db6c8b 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -28,8 +28,10 @@
 **************************************************************************/
 
 #include "watchutils.h"
-#include "watchhandler.h"
+#include "watchdata.h"
+#include "debuggerstringutils.h"
 #include "gdb/gdbmi.h"
+
 #include <utils/qtcassert.h>
 
 #include <coreplugin/ifile.h>
@@ -1543,5 +1545,166 @@ QDebug operator<<(QDebug in, const QtDumperHelper::TypeData &d)
     return in;
 }
 
+
+//////////////////////////////////////////////////////////////////////
+//
+// GdbMi interaction
+//
+//////////////////////////////////////////////////////////////////////
+
+void setWatchDataValue(WatchData &data, const GdbMi &item)
+{
+    GdbMi value = item.findChild("value");
+    if (value.isValid()) {
+        int encoding = item.findChild("valueencoded").data().toInt();
+        data.setValue(decodeData(value.data(), encoding));
+    } else {
+        data.setValueNeeded();
+    }
+}
+
+void setWatchDataValueToolTip(WatchData &data, const GdbMi &mi,
+    int encoding)
+{
+    if (mi.isValid())
+        data.setValueToolTip(decodeData(mi.data(), encoding));
+}
+
+void setWatchDataChildCount(WatchData &data, const GdbMi &mi)
+{
+    if (mi.isValid())
+        data.setHasChildren(mi.data().toInt() > 0);
+}
+
+void setWatchDataValueEnabled(WatchData &data, const GdbMi &mi)
+{
+    if (mi.data() == "true")
+        data.valueEnabled = true;
+    else if (mi.data() == "false")
+        data.valueEnabled = false;
+}
+
+void setWatchDataValueEditable(WatchData &data, const GdbMi &mi)
+{
+    if (mi.data() == "true")
+        data.valueEditable = true;
+    else if (mi.data() == "false")
+        data.valueEditable = false;
+}
+
+void setWatchDataExpression(WatchData &data, const GdbMi &mi)
+{
+    if (mi.isValid())
+        data.exp = mi.data();
+}
+
+void setWatchDataAddress(WatchData &data, const GdbMi &mi)
+{
+    if (mi.isValid())
+        setWatchDataAddressHelper(data, mi.data());
+}
+
+void setWatchDataAddressHelper(WatchData &data, const QByteArray &addr)
+{
+    data.addr = addr;
+    if (data.exp.isEmpty() && !data.addr.startsWith("$"))
+        data.exp = "*(" + gdbQuoteTypes(data.type).toLatin1() + "*)" + data.addr;
+}
+
+// Find the "type" and "displayedtype" children of root and set up type.
+void setWatchDataType(WatchData &data, const GdbMi &item)
+{
+    if (item.isValid())
+        data.setType(_(item.data()));
+    else if (data.type.isEmpty())
+        data.setTypeNeeded();
+}
+
+void setWatchDataDisplayedType(WatchData &data, const GdbMi &item)
+{
+    if (item.isValid())
+        data.displayedType = _(item.data());
+}
+
+void parseWatchData(const QSet<QByteArray> &expandedINames,
+    const WatchData &data0, const GdbMi &item, QList<WatchData> *list)
+{
+    //qDebug() << "HANDLE CHILDREN: " << data0.toString() << item.toString();
+    WatchData data = data0;
+    bool isExpanded = expandedINames.contains(data.iname);
+    if (!isExpanded)
+        data.setChildrenUnneeded();
+
+    GdbMi children = item.findChild("children");
+    if (children.isValid() || !isExpanded)
+        data.setChildrenUnneeded();
+
+    setWatchDataType(data, item.findChild("type"));
+    GdbMi mi = item.findChild("editvalue");
+    if (mi.isValid())
+        data.editvalue = mi.data();
+    mi = item.findChild("editformat");
+    if (mi.isValid())
+        data.editformat = mi.data().toInt();
+    mi = item.findChild("typeformats");
+    if (mi.isValid())
+        data.typeFormats = QString::fromUtf8(mi.data());
+
+    setWatchDataValue(data, item);
+    setWatchDataAddress(data, item.findChild("addr"));
+    setWatchDataExpression(data, item.findChild("exp"));
+    setWatchDataValueEnabled(data, item.findChild("valueenabled"));
+    setWatchDataValueEditable(data, item.findChild("valueeditable"));
+    setWatchDataChildCount(data, item.findChild("numchild"));
+    //qDebug() << "\nAPPEND TO LIST: " << data.toString() << "\n";
+    list->append(data);
+
+    bool ok = false;
+    qulonglong addressBase = item.findChild("addrbase").data().toULongLong(&ok, 0);
+    qulonglong addressStep = item.findChild("addrstep").data().toULongLong();
+
+    // Try not to repeat data too often.
+    WatchData childtemplate;
+    setWatchDataType(childtemplate, item.findChild("childtype"));
+    setWatchDataChildCount(childtemplate, item.findChild("childnumchild"));
+    //qDebug() << "CHILD TEMPLATE:" << childtemplate.toString();
+
+    int i = 0;
+    foreach (const GdbMi &child, children.children()) {
+        WatchData data1 = childtemplate;
+        GdbMi name = child.findChild("name");
+        if (name.isValid())
+            data1.name = _(name.data());
+        else
+            data1.name = QString::number(i);
+        GdbMi iname = child.findChild("iname");
+        if (iname.isValid())
+            data1.iname = iname.data();
+        else
+            data1.iname = data.iname + '.' + data1.name.toLatin1();
+        if (!data1.name.isEmpty() && data1.name.at(0).isDigit())
+            data1.name = _c('[') + data1.name + _c(']');
+        if (addressStep) {
+            const QByteArray addr = "0x" + QByteArray::number(addressBase, 16);
+            setWatchDataAddressHelper(data1, addr);
+            addressBase += addressStep;
+        }
+        QByteArray key = child.findChild("key").data();
+        if (!key.isEmpty()) {
+            int encoding = child.findChild("keyencoded").data().toInt();
+            QString skey = decodeData(key, encoding);
+            if (skey.size() > 13) {
+                skey = skey.left(12);
+                skey += _("...");
+            }
+            //data1.name += " (" + skey + ")";
+            data1.name = skey;
+        }
+        parseWatchData(expandedINames, data1, child, list);
+        ++i;
+    }
+}
+
+
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h
index 3941fbf2473733c0af27a0d28474d8f951e21d87..67d0d732a88fdb15814ce196022fa671c9574956 100644
--- a/src/plugins/debugger/watchutils.h
+++ b/src/plugins/debugger/watchutils.h
@@ -30,6 +30,7 @@
 #ifndef WATCHUTILS_H
 #define WATCHUTILS_H
 
+#include <QtCore/QSet>
 #include <QtCore/QString>
 #include <QtCore/QMap>
 
@@ -238,6 +239,27 @@ QDebug operator<<(QDebug in, const QtDumperHelper::TypeData &d);
 // remove the default template argument in std:: containers
 QString removeDefaultTemplateArguments(QString type);
 
+
+//
+// GdbMi interaction
+//
+
+void setWatchDataValue(WatchData &data, const GdbMi &item);
+void setWatchDataValueToolTip(WatchData &data, const GdbMi &mi,
+    int encoding);
+void setWatchDataChildCount(WatchData &data, const GdbMi &mi);
+void setWatchDataValueEnabled(WatchData &data, const GdbMi &mi);
+void setWatchDataValueEditable(WatchData &data, const GdbMi &mi);
+void setWatchDataExpression(WatchData &data, const GdbMi &mi);
+void setWatchDataAddress(WatchData &data, const GdbMi &mi);
+void setWatchDataAddressHelper(WatchData &data, const QByteArray &addr);
+void setWatchDataType(WatchData &data, const GdbMi &mi);
+void setWatchDataDisplayedType(WatchData &data, const GdbMi &mi);
+
+void parseWatchData(const QSet<QByteArray> &expandedINames,
+    const WatchData &parent, const GdbMi &child,
+    QList<WatchData> *insertions);
+
 } // namespace Internal
 } // namespace Debugger