diff --git a/dist/changes-1.3.0 b/dist/changes-1.3.0
index 25d8e12256c98cb5c2125010f70439fe4588d34f..0c1fa497ed5750e06fef76cb30638268de39b763 100644
--- a/dist/changes-1.3.0
+++ b/dist/changes-1.3.0
@@ -15,6 +15,8 @@ Debugging
    * CDB: Added more types to the dumpers (QSharedPointer, QVector, common
    * QMap/QSet types), dereference reference parameters
    * CDB: Simplified display of STL types in the locals window
+   * CDB: Fixed thread handling
+   * CDB: Added internal dumpers for string types for debuggee crashes
    * Improved QObject dumping, print out QRect/QSize, enumerations and flags
 
 General:
@@ -39,3 +41,4 @@ Wizards
    * Added version control checkout wizards
    * Added a license header template setting
    * Added a wizard for Qt Designer custom widgets
+   * Added a gitorious clone wizard
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index 365252f876a61688189f96c50ae7e09714bc0f40..b914986a0b4194d6b60caa751daeaf48744fe2f5 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -1177,8 +1177,11 @@ void CdbDebugEngine::selectThread(int index)
 
     ThreadsHandler *threadsHandler = m_d->m_debuggerManagerAccess->threadsHandler();
     threadsHandler->setCurrentThread(index);
-    m_d->m_currentThreadId = index;
-    m_d->updateStackTrace();
+    const int newThreadId = threadsHandler->threads().at(index).id;
+    if (newThreadId != m_d->m_currentThreadId) {
+        m_d->m_currentThreadId = threadsHandler->threads().at(index).id;
+        m_d->updateStackTrace();
+    }
 }
 
 void CdbDebugEngine::attemptBreakpointSynchronization()
@@ -1223,7 +1226,7 @@ bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessa
                                                  m_cif.debugSymbols,
                                                  m_debuggerManagerAccess->breakHandler(),
                                                  errorMessage, &warnings);
-    if (const int warningsCount = warnings.size())        
+    if (const int warningsCount = warnings.size())
         for (int w = 0; w < warningsCount; w++)
             m_engine->warning(warnings.at(w));
     return ok;
@@ -1390,6 +1393,16 @@ void CdbDebugEnginePrivate::notifyCrashed()
     m_dumper->disable();
 }
 
+static int threadIndexById(const ThreadsHandler *threadsHandler, int id)
+{
+    const QList<ThreadData> threads = threadsHandler->threads();
+    const int count = threads.count();
+    for (int i = 0; i < count; i++)
+        if (threads.at(i).id == id)
+            return i;
+    return -1;
+}
+
 void CdbDebugEnginePrivate::handleDebugEvent()
 {
     if (debugCDB)
@@ -1401,10 +1414,15 @@ void CdbDebugEnginePrivate::handleDebugEvent()
     m_breakEventMode = BreakEventHandle;
 
     switch (mode) {
-    case BreakEventHandle:
+    case BreakEventHandle: {
         m_debuggerManagerAccess->notifyInferiorStopped();
-        updateThreadList();
+        m_currentThreadId = updateThreadList();
+        ThreadsHandler *threadsHandler = m_debuggerManagerAccess->threadsHandler();
+        const int threadIndex = threadIndexById(threadsHandler, m_currentThreadId);
+        if (threadIndex != -1)
+            threadsHandler->setCurrentThread(threadIndex);
         updateStackTrace();
+    }
         break;
     case BreakEventIgnoreOnce:
         m_engine->startWatchTimer();
@@ -1430,7 +1448,7 @@ void CdbDebugEnginePrivate::setDebuggeeHandles(HANDLE hDebuggeeProcess,  HANDLE
     m_hDebuggeeThread = hDebuggeeThread;
 }
 
-void CdbDebugEnginePrivate::updateThreadList()
+ULONG CdbDebugEnginePrivate::updateThreadList()
 {
     if (debugCDB)
         qDebug() << Q_FUNC_INFO << m_hDebuggeeProcess;
@@ -1439,25 +1457,25 @@ void CdbDebugEnginePrivate::updateThreadList()
     QList<ThreadData> threads;
     bool success = false;
     QString errorMessage;
+    ULONG currentThreadId = 0;
     do {
-        ULONG numberOfThreads;
-        HRESULT hr= m_cif.debugSystemObjects->GetNumberThreads(&numberOfThreads);
+        ULONG threadCount;
+        HRESULT hr= m_cif.debugSystemObjects->GetNumberThreads(&threadCount);
         if (FAILED(hr)) {
             errorMessage= msgComFailed("GetNumberThreads", hr);
             break;
         }
-        const ULONG maxThreadIds = 256;
-        ULONG threadIds[maxThreadIds];
-        ULONG biggestThreadId = qMin(maxThreadIds, numberOfThreads - 1);
-        hr = m_cif.debugSystemObjects->GetThreadIdsByIndex(0, biggestThreadId, threadIds, 0);
-        if (FAILED(hr)) {
-            errorMessage= msgComFailed("GetThreadIdsByIndex", hr);
-            break;
-        }
-        for (ULONG threadId = 0; threadId <= biggestThreadId; ++threadId) {
-            ThreadData thread;
-            thread.id = threadId;
-            threads.append(thread);
+        // Get ids and index of current
+        if (threadCount) {
+            m_cif.debugSystemObjects->GetCurrentThreadId(&currentThreadId);
+            QVector<ULONG> threadIds(threadCount);
+            hr = m_cif.debugSystemObjects->GetThreadIdsByIndex(0, threadCount, &(*threadIds.begin()), 0);
+            if (FAILED(hr)) {
+                errorMessage= msgComFailed("GetThreadIdsByIndex", hr);
+                break;
+            }
+            for (ULONG i = 0; i < threadCount; i++)
+                threads.push_back(ThreadData(threadIds.at(i)));
         }
 
         th->setThreads(threads);
@@ -1465,6 +1483,7 @@ void CdbDebugEnginePrivate::updateThreadList()
     } while (false);
     if (!success)
         m_engine->warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
+    return currentThreadId;
 }
 
 void CdbDebugEnginePrivate::updateStackTrace()
diff --git a/src/plugins/debugger/cdb/cdbdebugengine_p.h b/src/plugins/debugger/cdb/cdbdebugengine_p.h
index 23eb56482755ce9ae4cc308d8771464da25b94fe..53e6737343e70cd2d3fcdb7d434b984ef3612fc7 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine_p.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine_p.h
@@ -115,7 +115,7 @@ struct CdbDebugEnginePrivate
 
     bool isDebuggeeRunning() const { return m_watchTimer != -1; }
     void handleDebugEvent();
-    void updateThreadList();    
+    ULONG updateThreadList();
     void updateStackTrace();
     void updateModules();
 
diff --git a/src/plugins/debugger/cdb/cdbstackframecontext.cpp b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
index f68beb0db3cccc1b114f87a3311be4f9009ce912..8c14d45fff946c8b20bdbdf01e2b2809d24ee95c 100644
--- a/src/plugins/debugger/cdb/cdbstackframecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
@@ -40,7 +40,7 @@
 namespace Debugger {
 namespace Internal {
 
-enum { OwnerNewItem, OwnerSymbolGroup, OwnerDumper };
+enum { OwnerNewItem, OwnerSymbolGroup, OwnerSymbolGroupDumper , OwnerDumper };
 
 typedef QSharedPointer<CdbDumperHelper> SharedPointerCdbDumperHelper;
 typedef QList<WatchData> WatchDataList;
@@ -216,6 +216,12 @@ WatchHandleDumperInserter &WatchHandleDumperInserter::operator=(WatchData &wd)
         wd.source = OwnerDumper;
         return *this;
     }
+    // Expanded by internal dumper? : ok
+    if (wd.source == OwnerSymbolGroupDumper) {
+        m_wh->insertData(wd);
+        return *this;
+    }
+    // Try library dumpers.
     switch (m_dumper->dumpType(wd, true, OwnerDumper, &m_dumperResult, &errorMessage)) {
     case CdbDumperHelper::DumpOk:
         if (debugCDBWatchHandling)
@@ -258,13 +264,15 @@ bool CdbStackFrameContext::populateModelInitially(WatchHandler *wh, QString *err
         qDebug() << "populateModelInitially dumpers=" << m_useDumpers;
     // Recurse down items that are initially expanded in the view, stop processing for
     // dumper items.
+    const CdbSymbolGroupRecursionContext rctx(m_symbolContext, OwnerSymbolGroupDumper,
+                                              m_dumper->comInterfaces()->debugDataSpaces);
     const bool rc = m_useDumpers ?
-        CdbSymbolGroupContext::populateModelInitially(m_symbolContext,
+        CdbSymbolGroupContext::populateModelInitially(rctx,
                                                       WatchHandleDumperInserter(wh, m_dumper),
                                                       WatchHandlerExpandedPredicate(wh),
                                                       isDumperPredicate,
                                                       errorMessage) :
-        CdbSymbolGroupContext::populateModelInitially(m_symbolContext,
+        CdbSymbolGroupContext::populateModelInitially(rctx,
                                                       WatchHandlerModelInserter(wh),
                                                       WatchHandlerExpandedPredicate(wh),
                                                       falsePredicate,
@@ -279,9 +287,11 @@ bool CdbStackFrameContext::completeData(const WatchData &incompleteLocal,
     if (debugCDBWatchHandling)
         qDebug() << ">completeData src=" << incompleteLocal.source << incompleteLocal.toString();
 
+    const CdbSymbolGroupRecursionContext rctx(m_symbolContext, OwnerSymbolGroupDumper,
+                                              m_dumper->comInterfaces()->debugDataSpaces);
     // Expand symbol group items, recurse one level from desired item
     if (!m_useDumpers) {
-        return CdbSymbolGroupContext::completeData(m_symbolContext, incompleteLocal,
+        return CdbSymbolGroupContext::completeData(rctx, incompleteLocal,
                                                    WatchHandlerModelInserter(wh),
                                                    MatchINamePredicate(incompleteLocal.iname),
                                                    falsePredicate,
@@ -311,7 +321,7 @@ bool CdbStackFrameContext::completeData(const WatchData &incompleteLocal,
     }
 
     // Expand symbol group items, recurse one level from desired item
-    return CdbSymbolGroupContext::completeData(m_symbolContext, incompleteLocal,
+    return CdbSymbolGroupContext::completeData(rctx, incompleteLocal,
                                                WatchHandleDumperInserter(wh, m_dumper),
                                                MatchINamePredicate(incompleteLocal.iname),
                                                isDumperPredicate,
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
index 5d82835f53dad00e411b14623ca7fd350413df5d..ef854c8b3600af9da676c47e8654a5e11bb91afc 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
@@ -33,15 +33,22 @@
 #include "watchutils.h"
 
 #include <QtCore/QTextStream>
+#include <QtCore/QCoreApplication>
 #include <QtCore/QRegExp>
 
 enum { debug = 0 };
+enum { debugInternalDumpers = 0 };
 
 static inline QString msgSymbolNotFound(const QString &s)
 {
     return QString::fromLatin1("The symbol '%1' could not be found.").arg(s);
 }
 
+static inline QString msgOutOfScope()
+{
+    return QCoreApplication::translate("SymbolGroup", "Out of scope");
+}
+
 static inline bool isTopLevelSymbol(const DEBUG_SYMBOL_PARAMETERS &p)
 {
     return p.ParentSymbol == DEBUG_ANY_ID;
@@ -102,6 +109,16 @@ static inline QString getSymbolString(IDebugSymbolGroup2 *sg,
 namespace Debugger {
 namespace Internal {
 
+
+CdbSymbolGroupRecursionContext::CdbSymbolGroupRecursionContext(CdbSymbolGroupContext *ctx,
+                                                         int ido,
+                                                         CIDebugDataSpaces *ds) :
+    context(ctx),
+    internalDumperOwner(ido),
+    dataspaces(ds)
+{
+}
+
 static inline CdbSymbolGroupContext::SymbolState getSymbolState(const DEBUG_SYMBOL_PARAMETERS &p)
 {
     if (p.SubElements == 0u)
@@ -419,6 +436,13 @@ WatchData CdbSymbolGroupContext::symbolAt(unsigned long index) const
     return wd;
 }
 
+WatchData CdbSymbolGroupContext::dumpSymbolAt(CIDebugDataSpaces *ds, unsigned long index)
+{
+    WatchData rc = symbolAt(index);
+    dump(ds, &rc);
+    return rc;
+}
+
 bool CdbSymbolGroupContext::assignValue(const QString &iname, const QString &value,
                                         QString *newValue, QString *errorMessage)
 {
@@ -561,5 +585,189 @@ bool CdbSymbolGroupContext::debugValueToInteger(const DEBUG_VALUE &dv, qint64 *v
     return false;
 }
 
+/* The special type dumpers have an integer return code meaning:
+ *  0:  ok
+ *  1:  Dereferencing or retrieving memory failed, this is out of scope,
+ *      do not try to query further.
+ * > 1: A structural error was encountered, that is, the implementation
+ *      of the class changed (Qt or say, a different STL implementation).
+ *      Visibly warn about it.
+ * To add further types, have a look at the toString() output of the
+ * symbol group. */
+
+static QString msgStructuralError(const QString &type, int code)
+{
+    return QString::fromLatin1("Warning: Internal dumper for '%1' failed with %2.").arg(type).arg(code);
+}
+
+static inline bool isStdStringOrPointer(const QString &type)
+{
+#define STD_WSTRING "std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> >"
+#define STD_STRING "std::basic_string<char,std::char_traits<char>,std::allocator<char> >"
+    return type.endsWith(QLatin1String(STD_STRING))
+            || type.endsWith(QLatin1String(STD_STRING" *"))
+            || type.endsWith(QLatin1String(STD_WSTRING))
+            || type.endsWith(QLatin1String(STD_WSTRING" *"));
+#undef STD_WSTRING
+#undef STD_STRING
+}
+
+CdbSymbolGroupContext::DumperResult
+        CdbSymbolGroupContext::dump(CIDebugDataSpaces *ds, WatchData *wd)
+{
+    DumperResult rc = DumperNotHandled;
+    do {
+        // Is this a previously detected Null-Pointer?
+        if (wd->isHasChildrenKnown() && !wd->hasChildren)
+            break;
+        // QString
+        if (wd->type.endsWith(QLatin1String("QString")) || wd->type.endsWith(QLatin1String("QString *"))) {
+            const int drc = dumpQString(ds, wd);
+            switch (drc) {
+            case 0:
+                rc = DumperOk;
+                break;
+            case 1:
+                rc = DumperError;
+                break;
+            default:
+                qWarning("%s\n", qPrintable(msgStructuralError(wd->type, drc)));
+                rc = DumperNotHandled;
+                break;
+            }
+        }
+        // StdString
+        if (isStdStringOrPointer(wd->type)) {
+            const int drc = dumpStdString(wd);
+            switch (drc) {
+            case 0:
+                rc = DumperOk;
+                break;
+            case 1:
+                rc = DumperError;
+                break;
+            default:
+                qWarning("%s\n", qPrintable(msgStructuralError(wd->type, drc)));
+                rc = DumperNotHandled;
+                break;
+            }
+
+        }
+    } while (false);
+    if (debugInternalDumpers)
+        qDebug() << "CdbSymbolGroupContext::dump" << rc << wd->toString();
+    return rc;
+}
+
+// Get integer value of symbol group
+static inline bool getIntValue(CIDebugSymbolGroup *sg, int index, int *value)
+{
+    const QString valueS = getSymbolString(sg, &IDebugSymbolGroup2::GetSymbolValueTextWide, index);
+    bool ok;
+    *value = valueS.toInt(&ok);
+    return ok;
+}
+
+// Get pointer value of symbol group ("0xAAB")
+static inline bool getPointerValue(CIDebugSymbolGroup *sg, int index, quint64 *value)
+{
+    *value = 0;
+    QString valueS = getSymbolString(sg, &IDebugSymbolGroup2::GetSymbolValueTextWide, index);
+    if (!valueS.startsWith(QLatin1String("0x")))
+        return false;
+    valueS.remove(0, 2);
+    bool ok;
+    *value = valueS.toULongLong(&ok, 16);
+    return ok;
+}
+
+int CdbSymbolGroupContext::dumpQString(CIDebugDataSpaces *ds, WatchData *wd)
+{
+    const int maxLength = 40;
+    QString errorMessage;
+    unsigned long stringIndex;
+    if (!lookupPrefix(wd->iname, &stringIndex))
+        return 1;
+
+    // Expand string and it's "d" (step over 'static null')
+    if (!expandSymbol(wd->iname, stringIndex, &errorMessage))
+        return 2;
+    const unsigned long dIndex = stringIndex + 4;
+    if (!expandSymbol(wd->iname, dIndex, &errorMessage))
+        return 3;
+    const unsigned long sizeIndex = dIndex + 3;
+    const unsigned long arrayIndex = dIndex + 4;
+    // Get size and pointer
+    int size;
+    if (!getIntValue(m_symbolGroup, sizeIndex, &size))
+        return 4;
+    quint64 array;
+    if (!getPointerValue(m_symbolGroup, arrayIndex, &array))
+        return 5;
+    // Fetch
+    const bool truncated = size > maxLength;
+    if (truncated)
+        size = maxLength;
+    const QChar doubleQuote = QLatin1Char('"');
+    QString value(doubleQuote);
+    if (size) {
+        // Should this ever be a remote debugger, need to check byte order.
+        unsigned short *buf =  new unsigned short[size + 1];
+        unsigned long bytesRead;
+        const HRESULT hr = ds->ReadVirtual(array, buf, size * sizeof(unsigned short), &bytesRead);
+        if (FAILED(hr)) {
+            delete [] buf;
+            return 1;
+        }
+        buf[bytesRead / sizeof(unsigned short)] = 0;
+        value += QString::fromUtf16(buf);
+        delete [] buf;
+        if (truncated)
+            value += QLatin1String("...");
+    }
+    value += doubleQuote;
+    wd->setValue(value);
+    wd->setHasChildren(false);
+    return 0;
+}
+
+int CdbSymbolGroupContext::dumpStdString(WatchData *wd)
+{
+    const int maxLength = 40;
+    QString errorMessage;
+    unsigned long stringIndex;
+    if (!lookupPrefix(wd->iname, &stringIndex))
+        return 1;
+
+    // Expand string ->string_val->_bx.
+    if (!expandSymbol(wd->iname, stringIndex, &errorMessage))
+        return 1;
+    const unsigned long bxIndex = stringIndex + 3;
+    if (!expandSymbol(wd->iname, bxIndex, &errorMessage))
+        return 2;
+    // Check if size is something sane
+    const int sizeIndex = stringIndex + 6;
+    int size;
+    if (!getIntValue(m_symbolGroup, sizeIndex, &size))
+        return 3;
+    if (size < 0)
+        return 1;
+    // Just copy over the value of the buf[]-array, which should be the string
+    const QChar doubleQuote = QLatin1Char('"');
+    const int bufIndex = stringIndex + 4;
+    QString bufValue = getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolValueTextWide, bufIndex);
+    const int quotePos = bufValue.indexOf(doubleQuote);
+    if (quotePos == -1)
+        return 1;
+    bufValue.remove(0, quotePos);
+    if (bufValue.size() > maxLength) {
+        bufValue.truncate(maxLength);
+        bufValue += QLatin1String("...\"");
+    }
+    wd->setValue(bufValue);
+    wd->setHasChildren(false);
+    return 0;
+}
+
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
index 91ec5fd92400f599b2251d350fa539a2ab8b8dae..24fc355d375c4607f389c23834b31551372ce1fb 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
@@ -46,6 +46,7 @@ namespace Internal {
 
 class WatchData;
 class WatchHandler;
+struct CdbSymbolGroupRecursionContext;
 
 /* A thin wrapper around the IDebugSymbolGroup2 interface which represents
  * a flat list of symbols using an index (for example, belonging to a stack
@@ -73,7 +74,7 @@ class CdbSymbolGroupContext
 public:
     ~CdbSymbolGroupContext();
     static CdbSymbolGroupContext *create(const QString &prefix,
-                                         CIDebugSymbolGroup *symbolGroup,                                         
+                                         CIDebugSymbolGroup *symbolGroup,
                                          QString *errorMessage);
 
     QString prefix() const { return m_prefix; }
@@ -87,7 +88,7 @@ public:
     // to terminate processing after insertion of an item (if the calling
     // routine wants to insert another subtree).
     template <class OutputIterator, class RecursionPredicate, class IgnorePredicate>
-    static bool populateModelInitially(CdbSymbolGroupContext *sg,
+    static bool populateModelInitially(const CdbSymbolGroupRecursionContext &ctx,
                                        OutputIterator it,
                                        RecursionPredicate recursionPredicate,
                                        IgnorePredicate ignorePredicate,
@@ -99,7 +100,7 @@ public:
     // to terminate processing after insertion of an item (if the calling
     // routine wants to insert another subtree).
     template <class OutputIterator, class RecursionPredicate, class IgnorePredicate>
-    static bool completeData (CdbSymbolGroupContext *sg,
+    static bool completeData (const CdbSymbolGroupRecursionContext &ctx,
                               WatchData incompleteLocal,
                               OutputIterator it,
                               RecursionPredicate recursionPredicate,
@@ -108,9 +109,19 @@ public:
 
     // Retrieve child symbols of prefix as a sequence of WatchData.
     template <class OutputIterator>
-            bool getChildSymbols(const QString &prefix, OutputIterator it, QString *errorMessage);
+            bool getChildSymbols(const QString &prefix, OutputIterator it, QString *errorMessage)
+            { return getDumpChildSymbols(0, prefix, 0, it, errorMessage); }
+    // Retrieve child symbols of prefix as a sequence of WatchData.
+    // Is CIDebugDataSpaces is != 0, try internal dumper and set owner
+    template <class OutputIterator>
+            bool getDumpChildSymbols(CIDebugDataSpaces *ds, const QString &prefix,
+                                      int dumpedOwner,
+                                      OutputIterator it, QString *errorMessage);
 
     WatchData symbolAt(unsigned long index) const;
+    // Run the internal dumpers on the symbol
+    WatchData dumpSymbolAt(CIDebugDataSpaces *ds, unsigned long index);
+
     bool lookupPrefix(const QString &prefix, unsigned long *index) const;
 
     enum SymbolState { LeafSymbol, ExpandedSymbol, CollapsedSymbol };
@@ -127,6 +138,10 @@ public:
     // format an array of unsigned longs as "0x323, 0x2322, ..."
     static QString hexFormatArray(const unsigned short *array, int size);
 
+    // Dump
+    enum DumperResult { DumperOk, DumperError, DumperNotHandled };
+    DumperResult dump(CIDebugDataSpaces *ds, WatchData *wd);
+
 private:
     typedef QMap<QString, unsigned long>  NameIndexMap;
 
@@ -140,8 +155,11 @@ private:
                                  unsigned long *parentId,
                                  QString *errorMessage);
     bool expandSymbol(const QString &prefix, unsigned long index, QString *errorMessage);
-    void populateINameIndexMap(const QString &prefix, unsigned long parentId, unsigned long start, unsigned long count);    
-    QString symbolINameAt(unsigned long index) const;  
+    void populateINameIndexMap(const QString &prefix, unsigned long parentId, unsigned long start, unsigned long count);
+    QString symbolINameAt(unsigned long index) const;
+
+    int dumpQString(CIDebugDataSpaces *ds, WatchData *wd);
+    int dumpStdString(WatchData *wd);
 
     inline DEBUG_SYMBOL_PARAMETERS *symbolParameters() { return &(*m_symbolParameters.begin()); }
     inline const DEBUG_SYMBOL_PARAMETERS *symbolParameters() const { return &(*m_symbolParameters.constBegin()); }
@@ -155,6 +173,16 @@ private:
     int m_unnamedSymbolNumber;
 };
 
+
+// A convenience struct to save parameters for the model recursion.
+struct CdbSymbolGroupRecursionContext {
+    explicit CdbSymbolGroupRecursionContext(CdbSymbolGroupContext *ctx, int internalDumperOwner, CIDebugDataSpaces *ds);
+
+    CdbSymbolGroupContext *context;
+    int internalDumperOwner;
+    CIDebugDataSpaces *dataspaces;
+};
+
 // Helper to a sequence of  WatchData into a list.
 class WatchDataBackInserter
 {
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h b/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h
index ccaba97ee893f600c8afbe0e8d29717fa338a7fb..561b0ac57b361910892089b020dbc4d134734690 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h
@@ -48,18 +48,32 @@ enum { debugSgRecursion = 0 };
 }
 
 template <class OutputIterator>
-bool CdbSymbolGroupContext::getChildSymbols(const QString &prefix, OutputIterator it, QString *errorMessage)
+bool CdbSymbolGroupContext::getDumpChildSymbols(CIDebugDataSpaces *ds, const QString &prefix,
+                             int dumpedOwner,
+                             OutputIterator it, QString *errorMessage)
 {
     unsigned long start;
     unsigned long parentId;
     if (!getChildSymbolsPosition(prefix, &start, &parentId, errorMessage))
         return false;
-    // Skip over expanded children
-    const unsigned long end = m_symbolParameters.size();
-    for (unsigned long s = start; s < end; ++s) {
+    // Skip over expanded children. Internal dumping might expand
+    // children, so, re-evaluate size in end condition.
+    for (int s = start; s < m_symbolParameters.size(); ++s) {
         const DEBUG_SYMBOL_PARAMETERS &p = m_symbolParameters.at(s);
         if (p.ParentSymbol == parentId && isSymbolDisplayable(p)) {
-            *it = symbolAt(s);
+            WatchData wd = symbolAt(s);
+            // Run internal dumper, mark ownership
+            if (ds) {
+                switch (dump(ds, &wd)) {
+                case DumperOk:
+                case DumperError: // Not initialized yet, do not run other dumpers
+                    wd.source = dumpedOwner;
+                    break;
+                case DumperNotHandled:
+                    break;
+                }
+            }
+            *it = wd;
             ++it;
         }
     }
@@ -73,7 +87,7 @@ bool CdbSymbolGroupContext::getChildSymbols(const QString &prefix, OutputIterato
 // (expand icon), though (ignore for simplicity).
 template <class OutputIterator, class RecursionPredicate, class IgnorePredicate>
 bool insertSymbolRecursion(WatchData wd,
-                           CdbSymbolGroupContext *sg,
+                           const CdbSymbolGroupRecursionContext &ctx,
                            OutputIterator it,
                            RecursionPredicate recursionPredicate,
                            IgnorePredicate ignorePredicate,
@@ -110,13 +124,16 @@ bool insertSymbolRecursion(WatchData wd,
         return true;
     QList<WatchData> watchList;
     // This implicitly enforces expansion
-    if (!sg->getChildSymbols(wd.iname, WatchDataBackInserter(watchList), errorMessage))
+    if (!ctx.context->getDumpChildSymbols(ctx.dataspaces,
+                                          wd.iname,
+                                          ctx.internalDumperOwner,
+                                          WatchDataBackInserter(watchList), errorMessage))
         return false;
     const int childCount = watchList.size();
     for (int c = 0; c < childCount; c++) {
         const WatchData &cwd = watchList.at(c);
         if (wd.isValid()) { // We sometimes get empty names for deeply nested data
-            if (!insertSymbolRecursion(cwd, sg, it, recursionPredicate, ignorePredicate, errorMessage))
+            if (!insertSymbolRecursion(cwd, ctx, it, recursionPredicate, ignorePredicate, errorMessage))
                 return false;
         }  else {
             const QString msg = QString::fromLatin1("WARNING: Skipping invalid child symbol #%2 (type %3) of '%4'.").
@@ -128,7 +145,7 @@ bool insertSymbolRecursion(WatchData wd,
 }
 
 template <class OutputIterator, class RecursionPredicate, class IgnorePredicate>
-bool CdbSymbolGroupContext::populateModelInitially(CdbSymbolGroupContext *sg,
+bool CdbSymbolGroupContext::populateModelInitially(const CdbSymbolGroupRecursionContext &ctx,
                                                    OutputIterator it,
                                                    RecursionPredicate recursionPredicate,
                                                    IgnorePredicate ignorePredicate,
@@ -139,17 +156,20 @@ bool CdbSymbolGroupContext::populateModelInitially(CdbSymbolGroupContext *sg,
 
     // Insert root items
     QList<WatchData> watchList;
-    if (!sg->getChildSymbols(sg->prefix(), WatchDataBackInserter(watchList), errorMessage))
+    CdbSymbolGroupContext *sg = ctx.context;
+    if (!sg->getDumpChildSymbols(ctx.dataspaces, sg->prefix(),
+                                 ctx.internalDumperOwner,
+                                 WatchDataBackInserter(watchList), errorMessage))
         return false;
     // Insert data
     foreach(const WatchData &wd, watchList)
-        if (!insertSymbolRecursion(wd, sg, it, recursionPredicate, ignorePredicate, errorMessage))
+        if (!insertSymbolRecursion(wd, ctx, it, recursionPredicate, ignorePredicate, errorMessage))
             return false;
     return true;
 }
 
 template <class OutputIterator, class RecursionPredicate, class IgnorePredicate>
-bool CdbSymbolGroupContext::completeData(CdbSymbolGroupContext *sg,
+bool CdbSymbolGroupContext::completeData(const CdbSymbolGroupRecursionContext &ctx,
                                          WatchData incompleteLocal,
                                          OutputIterator it,
                                          RecursionPredicate recursionPredicate,
@@ -160,7 +180,7 @@ bool CdbSymbolGroupContext::completeData(CdbSymbolGroupContext *sg,
         qDebug().nospace() << "###>CdbSymbolGroupContext::completeData" << ' ' << incompleteLocal.iname << '\n';
     // If the symbols are already expanded in the context, they will be re-inserted,
     // which is not handled for simplicity.
-    if (!insertSymbolRecursion(incompleteLocal, sg, it, recursionPredicate, ignorePredicate, errorMessage))
+    if (!insertSymbolRecursion(incompleteLocal, ctx, it, recursionPredicate, ignorePredicate, errorMessage))
         return false;
     return true;
 }
diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h
index 538eef992e61b89387d08be1db9ffbeae4c64a3a..aca6527ce23fa520fdd9b5cac43a839d7ca054aa 100644
--- a/src/plugins/debugger/stackhandler.h
+++ b/src/plugins/debugger/stackhandler.h
@@ -103,6 +103,7 @@ private:
 
 struct ThreadData
 {
+    ThreadData(int threadId = 0) : id(threadId) {}
     int id;
 };
 
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index 490fd2a64a89a35c3bbd392eb140a54541570a44..49b4cc02c569b9056066e09d7db0c0a7463f4660 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -567,21 +567,24 @@ QList<WatchData> QtDumperResult::toWatchData(int source) const
                 wchild.valuedisabled = dchild.valuedisabled;
                 wchild.setValue(decodeData(dchild.value, dchild.valueEncoded));
             }
-            wchild.setType(dchild.type.isEmpty() ? childType : dchild.type);
             wchild.setAddress(dchild.address);
-            // Child overrides.
-            const int effectiveChildChildCount = dchild.childCount == -1 ?  childChildCount : dchild.childCount;
-            switch (effectiveChildChildCount) {
+            // The type setter sets hasChildren for known types.
+            wchild.setType(dchild.type.isEmpty() ? childType : dchild.type);
+            if (wchild.isHasChildrenNeeded()) {
+                // Child overrides.
+                const int effectiveChildChildCount = dchild.childCount == -1 ?  childChildCount : dchild.childCount;
+                switch (effectiveChildChildCount) {
                 case -1:
-                wchild.setChildrenNeeded();
-                wchild.setHasChildrenNeeded();
-                break;
+                    wchild.setChildrenNeeded();
+                    wchild.setHasChildrenNeeded();
+                    break;
                 case 0:
-                wchild.setHasChildren(false);
-                break;
+                    wchild.setHasChildren(false);
+                    break;
                 default:
-                wchild.setHasChildren(true);
-                break;
+                    wchild.setHasChildren(true);
+                    break;
+                }
             }
         }
     }