diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index 7d054e68dd430d24dd42de3d94ad47ad38d3c04b..b8db4f753bae551d72657cdeb92c07dadb29b70c 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -145,6 +145,7 @@ CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEn
     m_debuggerManager(parent),
     m_debuggerManagerAccess(parent->engineInterface()),
     m_currentStackTrace(0),
+    m_firstActivatedFrame(true),
     m_mode(AttachCore)
 {   
 }
@@ -428,22 +429,15 @@ void CdbDebugEngine::exitDebugger()
     killWatchTimer();
 }
 
-class ModelBuildIterator {
-public:
-    explicit ModelBuildIterator(WatchHandler *wh) : m_wh(wh) {}
-
-    ModelBuildIterator & operator*() { return *this; }
-    ModelBuildIterator &operator=(const WatchData &wd);
-    ModelBuildIterator &operator++() { return *this; }
-
-private:
-    WatchHandler *m_wh;
-};
-
-ModelBuildIterator &ModelBuildIterator::operator=(const WatchData &wd)
+CdbSymbolGroupContext *CdbDebugEnginePrivate::getStackFrameSymbolGroupContext(int frameIndex, QString *errorMessage) const
 {
-    m_wh->insertData(wd);
-    return *this;
+    if (!m_currentStackTrace) {
+        *errorMessage = QLatin1String(msgNoStackTraceC);
+        return 0;
+    }
+    if (CdbSymbolGroupContext *sg = m_currentStackTrace->symbolGroupContextAt(frameIndex, errorMessage))
+        return sg;
+    return 0;
 }
 
 bool CdbDebugEnginePrivate::updateLocals(int frameIndex,
@@ -452,36 +446,29 @@ bool CdbDebugEnginePrivate::updateLocals(int frameIndex,
 {
     if (debugCDB)
         qDebug() << Q_FUNC_INFO << frameIndex;
-    bool success = false;
     wh->cleanup();
-    do {
-        if (!m_currentStackTrace) {
-            *errorMessage = QLatin1String(msgNoStackTraceC);
-            break;
-        }
 
-        CdbSymbolGroupContext *sgc = m_currentStackTrace->symbolGroupContextAt(frameIndex, errorMessage);
-        if (!sgc) {
-            break;
-        }
-        ModelBuildIterator it(wh);
-        sgc->getSymbols(sgc->prefix(), it);
-        success = true;
-    } while (false);
-    wh->rebuildModel();
+    bool success = false;
+    if (CdbSymbolGroupContext *sgc = getStackFrameSymbolGroupContext(frameIndex, errorMessage))
+        success = CdbSymbolGroupContext::populateModelInitially(sgc, wh, errorMessage);
 
+    wh->rebuildModel();
     return success;
 }
 
 void CdbDebugEngine::updateWatchModel()
 {
-    WatchHandler *watchHandler = m_d->m_debuggerManagerAccess->watchHandler();
-    const QList<WatchData> incomplete = watchHandler->takeCurrentIncompletes();
-
+    const int frameIndex = m_d->m_debuggerManagerAccess->stackHandler()->currentIndex();
     if (debugCDB)
-        qDebug() << Q_FUNC_INFO << incomplete.size();
-    foreach (const WatchData& wd, incomplete)
-        qDebug() << Q_FUNC_INFO << wd.toString();
+        qDebug() << Q_FUNC_INFO << "fi=" << frameIndex;
+
+    bool success = false;
+    QString errorMessage;    
+    if (CdbSymbolGroupContext *sg = m_d->m_currentStackTrace->symbolGroupContextAt(frameIndex, &errorMessage))
+        success = CdbSymbolGroupContext::completeModel(sg, m_d->m_debuggerManagerAccess->watchHandler(), &errorMessage);
+
+    if (!success)
+        qWarning("%s : %s", Q_FUNC_INFO, qPrintable(errorMessage));
 }
 
 void CdbDebugEngine::stepExec()
@@ -655,17 +642,18 @@ void CdbDebugEngine::activateFrame(int frameIndex)
     bool success = false;
     do {
         StackHandler *stackHandler = m_d->m_debuggerManagerAccess->stackHandler();
+        WatchHandler *watchHandler = m_d->m_debuggerManagerAccess->watchHandler();
         const int oldIndex = stackHandler->currentIndex();
         if (frameIndex >= stackHandler->stackSize()) {
             errorMessage = msgStackIndexOutOfRange(frameIndex, stackHandler->stackSize());
             break;
         }
 
-        if (oldIndex != frameIndex) {
+        if (oldIndex != frameIndex)
             stackHandler->setCurrentIndex(frameIndex);
-            if (!m_d->updateLocals(frameIndex, m_d->m_debuggerManagerAccess->watchHandler(), &errorMessage))
+        if (oldIndex != frameIndex || m_d->m_firstActivatedFrame)
+            if (!m_d->updateLocals(frameIndex, watchHandler, &errorMessage))
                 break;
-        }
 
         const StackFrame &frame = stackHandler->currentFrame();
         if (!frame.isUsable()) {
@@ -678,6 +666,7 @@ void CdbDebugEngine::activateFrame(int frameIndex)
     } while (false);
     if (!success)
         qWarning("%s", qPrintable(errorMessage));
+    m_d->m_firstActivatedFrame = false;
 }
 
 void CdbDebugEngine::selectThread(int index)
@@ -917,6 +906,7 @@ void CdbDebugEnginePrivate::updateStackTrace()
         m_debuggerManager->gotoLocation(stackFrames.at(current).file,
                                         stackFrames.at(current).line, true);
     }
+    m_firstActivatedFrame = true;
 }
 
 void CdbDebugEnginePrivate::handleDebugOutput(const char *szOutputString)
diff --git a/src/plugins/debugger/cdb/cdbdebugengine_p.h b/src/plugins/debugger/cdb/cdbdebugengine_p.h
index e1991f707deedc75d73b052014eb6653372aaf13..cd28883a713f63c29cf08ecf38522e64b8deb7ba 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine_p.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine_p.h
@@ -79,6 +79,7 @@ struct CdbDebugEnginePrivate
     void handleDebugOutput(const char* szOutputString);
     void handleBreakpointEvent(PDEBUG_BREAKPOINT pBP);
     void cleanStackTrace();
+    CdbSymbolGroupContext *getStackFrameSymbolGroupContext(int frameIndex, QString *errorMessage) const;
 
     HANDLE                  m_hDebuggeeProcess;
     HANDLE                  m_hDebuggeeThread;
@@ -98,6 +99,7 @@ struct CdbDebugEnginePrivate
     DebuggerManager *m_debuggerManager;
     IDebuggerManagerAccessForEngines *m_debuggerManagerAccess;
     CdbStackTraceContext *m_currentStackTrace;
+    bool m_firstActivatedFrame;
 
     DebuggerStartMode m_mode;
     Core::Utils::ConsoleProcess m_consoleStubProc;
diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
index d569c6a9baefb6a6b93500c6d06a85b31611d293..f80766941db22f7f3812b6563d28c2a8241127a9 100644
--- a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp
@@ -127,7 +127,9 @@ CdbSymbolGroupContext *CdbStackTraceContext::symbolGroupContextAt(int index, QSt
     IDebugSymbolGroup2 *sg  = createSymbolGroup(index, errorMessage);
     if (!sg)
         return 0;
-    CdbSymbolGroupContext *sc = new CdbSymbolGroupContext(QLatin1String("local"), sg);
+    CdbSymbolGroupContext *sc = CdbSymbolGroupContext::create(QLatin1String("local"), sg, errorMessage);
+    if (!sc)
+        return 0;                                \
     m_symbolContexts[index] = sc;
     return sc;
 }
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
index aa52ef55e1a304a4d95b832cbefcaf8b24de7702..2bedaa875fa4b87b43f28301e9f7544ad5e0079f 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
@@ -30,6 +30,37 @@
 #include "cdbsymbolgroupcontext.h"
 #include "cdbdebugengine_p.h"
 #include "watchhandler.h"
+#include "watchutils.h"
+#include <QtCore/QTextStream>
+
+static inline void debugSymbolFlags(unsigned long f, QTextStream &str)
+{
+    if (f & DEBUG_SYMBOL_EXPANDED)
+        str << "DEBUG_SYMBOL_EXPANDED";
+    if (f & DEBUG_SYMBOL_READ_ONLY)
+        str << "|DEBUG_SYMBOL_READ_ONLY";
+    if (f & DEBUG_SYMBOL_IS_ARRAY)
+        str << "|DEBUG_SYMBOL_IS_ARRAY";
+    if (f & DEBUG_SYMBOL_IS_FLOAT)
+        str << "|DEBUG_SYMBOL_IS_FLOAT";
+    if (f & DEBUG_SYMBOL_IS_ARGUMENT)
+        str << "|DEBUG_SYMBOL_IS_ARGUMENT";
+    if (f & DEBUG_SYMBOL_IS_LOCAL)
+        str << "|DEBUG_SYMBOL_IS_LOCAL";
+}
+
+ QTextStream &operator<<(QTextStream &str, const DEBUG_SYMBOL_PARAMETERS& p)
+{
+    str << " Type=" << p.TypeId << " parent=";
+    if (p.ParentSymbol == DEBUG_ANY_ID) {
+        str << "<ROOT>";
+    } else {
+       str << p.ParentSymbol;
+    }
+    str << " Subs=" << p.SubElements << " flags=" << p.Flags << '/';
+    debugSymbolFlags(p.Flags, str);
+    return str;
+}
 
 // A helper function to extract a string value from a member function of
 // IDebugSymbolGroup2 taking the symbol index and a character buffer.
@@ -68,84 +99,182 @@ CdbSymbolGroupContext::~CdbSymbolGroupContext()
     m_symbolGroup->Release();
 }
 
-CdbSymbolGroupContext::Range
-    CdbSymbolGroupContext::getSymbolRange(const QString &prefix)
+CdbSymbolGroupContext *CdbSymbolGroupContext::create(const QString &prefix,
+                                                     IDebugSymbolGroup2 *symbolGroup,
+                                                     QString *errorMessage)
+{
+    CdbSymbolGroupContext *rc= new CdbSymbolGroupContext(prefix, symbolGroup);
+    if (!rc->init(errorMessage)) {
+        delete rc;
+        return 0;
+    }
+    return rc;
+}
+
+bool CdbSymbolGroupContext::init(QString *errorMessage)
+{
+    // retrieve the root symbols
+    ULONG count;
+    HRESULT hr = m_symbolGroup->GetNumberSymbols(&count);
+    if (FAILED(hr)) {
+        *errorMessage = msgComFailed("GetNumberSymbols", hr);
+        return false;
+    }
+
+    m_symbolParameters.reserve(3u * count);
+    m_symbolParameters.resize(count);
+
+    hr = m_symbolGroup->GetSymbolParameters(0, count, symbolParameters());
+    if (FAILED(hr)) {
+        *errorMessage = msgComFailed("GetSymbolParameters", hr);
+        return false;
+    }
+    populateINameIndexMap(m_prefix, 0, count);
+    return true;
+}
+
+void CdbSymbolGroupContext::populateINameIndexMap(const QString &prefix, unsigned long start, unsigned long count)
+{
+    const QString symbolPrefix = prefix + m_nameDelimiter;
+    const unsigned long end = start + count;
+    for (unsigned long i = start; i < end; i++)
+        if (isSymbolDisplayable(m_symbolParameters.at(i))) {
+        const QString name = symbolPrefix + getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolNameWide, i);
+        m_inameIndexMap.insert(name, i);        
+    }
+}
+
+QString CdbSymbolGroupContext::toString() const
+{
+    QString rc;
+    QTextStream str(&rc);
+    const int count = m_symbolParameters.size();
+    for (int i = 0; i < count; i++) {
+        str << i << ' ';
+        const DEBUG_SYMBOL_PARAMETERS &p = m_symbolParameters.at(i);
+        if (p.ParentSymbol != DEBUG_ANY_ID)
+            str << "    ";
+        str << getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolNameWide, i);
+        if (p.Flags & DEBUG_SYMBOL_IS_LOCAL)
+            str << " '" << getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolTypeNameWide, i);
+        str << p << '\n';
+    }
+    return rc;
+}
+
+bool CdbSymbolGroupContext::isSymbolDisplayable(const DEBUG_SYMBOL_PARAMETERS &p)
+{
+    return p.Flags & (DEBUG_SYMBOL_IS_LOCAL|DEBUG_SYMBOL_IS_ARGUMENT);
+}
+
+static inline bool isSymbolExpanded(const DEBUG_SYMBOL_PARAMETERS &p) { return p.Flags & DEBUG_SYMBOL_EXPANDED; }
+
+bool CdbSymbolGroupContext::isExpanded(unsigned long index) const
+{
+    return isSymbolExpanded(m_symbolParameters.at(index));
+}
+
+/* Retrieve children and get the position. */
+bool CdbSymbolGroupContext::getChildSymbolsPosition(const QString &prefix,
+                                                    unsigned long *start,
+                                                    unsigned long *parentId,
+                                                    QString *errorMessage)
 {
     if (debugCDB)
-        qDebug() << Q_FUNC_INFO << prefix;
-    const ChildRangeMap::const_iterator it = m_childRanges.constFind(prefix);
-    if (it != m_childRanges.constEnd())
-        return it.value();
-    const Range r = prefix == m_prefix ? allocateRootSymbols() : allocateChildSymbols(prefix);
-    m_childRanges.insert(prefix, r);
-    return r;
-}
-
-CdbSymbolGroupContext::Range
-    CdbSymbolGroupContext::allocateChildSymbols(const QString &prefix)
-{
-    unsigned long startPos = 0;
-    unsigned long count = 0;
-
-    bool success = false;
-    QString errorMessage;
-    do {
-        const int parentIndex = m_symbolINames.indexOf(prefix);
-        if (parentIndex == -1) {
-            errorMessage = QString::fromLatin1("Prefix not found '%1'").arg(prefix);
-            break;
-        }
+        qDebug() << Q_FUNC_INFO << '\n'<< prefix;
 
-        success = true;
-    } while (false);
-    if (!success) {
-        qWarning("%s\n", qPrintable(errorMessage));
+    *start = *parentId = 0;
+    // Root item?
+    if (prefix == m_prefix) {
+        *start = 0;
+        *parentId = DEBUG_ANY_ID;
+        if (debugCDB)
+            qDebug() << '<' << prefix << "at" << *start << '\n' << toString();
+        return true;
+    }
+    // Get parent index, make sure it is expanded
+    NameIndexMap::const_iterator nit = m_inameIndexMap.constFind(prefix);
+    if (nit == m_inameIndexMap.constEnd()) {
+        *errorMessage = QString::fromLatin1("'%1' not found.").arg(prefix);
+        return false;
     }
-    return Range(startPos, count);
+    *parentId = nit.value();
+    *start = nit.value() + 1;
+    if (!expandSymbol(prefix, *parentId, errorMessage))
+        return false;
+    if (debugCDB)
+        qDebug() << '<' << prefix << "at" << *start << '\n' << toString();
+    return true;
 }
 
-CdbSymbolGroupContext::Range
-    CdbSymbolGroupContext::allocateRootSymbols()
+// Expand a symbol using the symbol group interface.
+bool CdbSymbolGroupContext::expandSymbol(const QString &prefix, unsigned long index, QString *errorMessage)
 {
-    unsigned long startPos = 0;
-    unsigned long count = 0;
-    bool success = false;
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO << '\n' << prefix << index;
 
-    QString errorMessage;
-    do {
-        HRESULT hr = m_symbolGroup->GetNumberSymbols(&count);
-        if (FAILED(hr)) {
-            errorMessage = msgComFailed("GetNumberSymbols", hr);
-            break;
-        }
+    if (isExpanded(index))
+        return true;
 
-        m_symbolParameters.reserve(3u * count);
-        m_symbolParameters.resize(count);
+    HRESULT hr = m_symbolGroup->ExpandSymbol(index, TRUE);
+    if (FAILED(hr)) {
+        *errorMessage = QString::fromLatin1("Unable to expand '%1' %2: %3").
+                        arg(prefix).arg(index).arg(msgComFailed("ExpandSymbol", hr));
+        return false;
+    }
+    // Hopefully, this will never fail, else data structure will be foobar.
+    const ULONG oldSize = m_symbolParameters.size();
+    ULONG newSize;
+    hr = m_symbolGroup->GetNumberSymbols(&newSize);
+    if (FAILED(hr)) {
+        *errorMessage = msgComFailed("GetNumberSymbols", hr);
+        return false;
+    }
 
-        hr = m_symbolGroup->GetSymbolParameters(0, count, symbolParameters());
-        if (FAILED(hr)) {
-            errorMessage = msgComFailed("GetSymbolParameters", hr);
-            break;
-        }
-        const QString symbolPrefix = m_prefix + m_nameDelimiter;
-        for (unsigned long i = 0; i < count; i++)
-            m_symbolINames.push_back(symbolPrefix + getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolNameWide, i));
+    // Retrieve the new parameter structs which will be inserted
+    // after the parents, offsetting consecutive indexes.
+    m_symbolParameters.resize(newSize);
 
-        success = true;
-    } while (false);
-    if (!success) {
-        clear();
-        count = 0;
-        qWarning("%s\n", qPrintable(errorMessage));
+    hr = m_symbolGroup->GetSymbolParameters(0, newSize, symbolParameters());
+    if (FAILED(hr)) {
+        *errorMessage = msgComFailed("GetSymbolParameters", hr);
+        return false;
     }
-    return Range(startPos, count);
+    // The new symbols are inserted after the parent symbol.
+    // We need to correct the following values in the name->index map
+    const unsigned long newSymbolCount = newSize - oldSize;
+    const NameIndexMap::iterator nend = m_inameIndexMap.end();
+    for (NameIndexMap::iterator it = m_inameIndexMap.begin(); it != nend; ++it)
+        if (it.value() > index)
+            it.value() += newSymbolCount;
+    // insert the new symbols
+    populateINameIndexMap(prefix, index + 1, newSymbolCount);
+    return true;
 }
 
 void CdbSymbolGroupContext::clear()
 {
     m_symbolParameters.clear();
-    m_childRanges.clear();
-    m_symbolINames.clear();
+    m_inameIndexMap.clear();
+}
+
+int CdbSymbolGroupContext::getDisplayableChildCount(unsigned long index) const
+{
+    if (!isExpanded(index))
+        return 0;
+    int rc = 0;
+    // Skip over expanded children, count displayable ones
+    const unsigned long childCount = m_symbolParameters.at(index).SubElements;
+    unsigned long seenChildren = 0;
+    for (unsigned long c = index + 1; seenChildren < childCount; c++) {
+        const DEBUG_SYMBOL_PARAMETERS &params = m_symbolParameters.at(c);
+        if (params.ParentSymbol == index) {
+            seenChildren++;
+            if (isSymbolDisplayable(params))
+                rc++;
+        }
+    }
+    return rc;
 }
 
 WatchData CdbSymbolGroupContext::symbolAt(unsigned long index) const
@@ -154,23 +283,131 @@ WatchData CdbSymbolGroupContext::symbolAt(unsigned long index) const
         qDebug() << Q_FUNC_INFO << index;
 
     WatchData wd;
-    wd.iname = m_symbolINames.at(index);
+    wd.iname = m_inameIndexMap.key(index);
     const int lastDelimiterPos = wd.iname.lastIndexOf(m_nameDelimiter);
     wd.name = lastDelimiterPos == -1 ? wd.iname : wd.iname.mid(lastDelimiterPos + 1);
-    wd.type = getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolTypeNameWide, index);
-    wd.value = getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolValueTextWide, index);
+    wd.setType(getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolTypeNameWide, index));
+    wd.setValue(getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolValueTextWide, index).toUtf8());
+    wd.setChildrenNeeded(); // compensate side effects of above setters
+    wd.setChildCountNeeded();
+    // Figure out children. The SubElement is only a guess unless the symbol,
+    // is expanded, so, we leave this as a guess for later updates.
     const DEBUG_SYMBOL_PARAMETERS &params = m_symbolParameters.at(index);
     if (params.SubElements) {
-        wd.setTypeUnneeded();
-        wd.setValueUnneeded();
-        wd.setChildCount(1);
+        if (isSymbolExpanded(params))
+            wd.setChildCount(getDisplayableChildCount(index));
+        wd.setChildrenUnneeded();
     } else {
-        wd.setAllUnneeded();
+        wd.setChildCount(0);
     }
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO << '\n' << wd.toString();
+    return wd;
+}
+
+class WatchDataBackInserter {
+public:
+    explicit WatchDataBackInserter(QList<WatchData> &wh) : m_wh(wh) {}
+
+    WatchDataBackInserter & operator*() { return *this; }
+    WatchDataBackInserter &operator=(const WatchData &wd) {
+        m_wh.push_back(wd);
+        return *this;
+    }
+    WatchDataBackInserter &operator++() { return *this; }
+
+private:
+    QList<WatchData> &m_wh;
+};
+
+static bool insertChildrenRecursion(const QString &iname,
+                                    CdbSymbolGroupContext *sg,
+                                    WatchHandler *watchHandler,
+                                    int level,
+                                    QString *errorMessage,
+                                    int *childCount = 0);
+
+// Insert a symbol and its children recursively if
+// they are known.
+static bool insertSymbolRecursion(const WatchData wd,
+                                  CdbSymbolGroupContext *sg,
+                                  WatchHandler *watchHandler,
+                                  int level,
+                                  QString *errorMessage
+                                  )
+{
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO << '\n' << wd.iname << level;
+
+    watchHandler->insertData(wd);
+    if (wd.childCount && wd.isChildCountKnown())
+        return insertChildrenRecursion(wd.iname, sg, watchHandler, level + 1, errorMessage);
+    return true;
+}
+
+// Insert the children of prefix.
+static bool insertChildrenRecursion(const QString &iname,
+                                    CdbSymbolGroupContext *sg,
+                                    WatchHandler *watchHandler,
+                                    int level,
+                                    QString *errorMessage,
+                                    int *childCount)
+{
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO << '\n' << iname << level;
+
+    QList<WatchData> watchList;
+    if (!sg->getChildSymbols(iname, WatchDataBackInserter(watchList), errorMessage))
+        return false;
+    if (childCount)
+        *childCount = watchList.size();
+    foreach(const WatchData &wd, watchList)
+        if (!insertSymbolRecursion(wd, sg, watchHandler, level + 1, errorMessage))
+            return false;
+    return true;
+}
+
+bool CdbSymbolGroupContext::populateModelInitially(CdbSymbolGroupContext *sg,
+                                                   WatchHandler *watchHandler,
+                                                   QString *errorMessage)
+{
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO;
+
+    // Insert root items and known children.
+    QList<WatchData> watchList;
+    if (!sg->getChildSymbols(sg->prefix(), WatchDataBackInserter(watchList), errorMessage))
+        return false;
+
+    foreach(const WatchData &wd, watchList)
+        if (!insertSymbolRecursion(wd, sg, watchHandler, 0, errorMessage))
+            return false;
+    return true;
+}
+
+bool CdbSymbolGroupContext::completeModel(CdbSymbolGroupContext *sg,
+                                          WatchHandler *watchHandler,
+                                          QString *errorMessage)
+{
+    const QList<WatchData> incomplete = watchHandler->takeCurrentIncompletes();
     if (debugCDB) {
-        qDebug() << Q_FUNC_INFO << wd.toString();
+        QDebug nsp = qDebug().nospace();
+        nsp << Q_FUNC_INFO << '\n' <<  incomplete.size();
+        foreach(const WatchData& wd, incomplete)
+            nsp << ' ' << wd.iname;
+        nsp << '\n';
     }
-    return wd;
+    // At this point, it should be nodes with unknown children.
+    int childCount;
+    foreach(WatchData wd, incomplete) {
+        if (insertChildrenRecursion(wd.iname, sg, watchHandler, 0, errorMessage, &childCount)) {
+            wd.setChildCount(childCount);
+            watchHandler->insertData(wd);
+        } else {
+            return false;
+        }
+    }
+    return true;
 }
 
 }
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
index e5c4ea7c9c731fba630ba1dca161ecdfa0caf2ae..8a3cf4dc80e3d8ae10000eff5ebdcd4b13e1eb63 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
@@ -44,65 +44,85 @@ namespace Debugger {
     namespace Internal {
 
 class WatchData;
+class WatchHandler;
 
 /* A thin wrapper around the IDebugSymbolGroup2 interface which represents
- * a flat list of symbols using an index (for example, belonging to a stack frame).
- * It uses the hierarchical naming convention of WatchHandler as:
+ * a flat list of symbols using an index (for example, belonging to a stack
+ * frame). It uses the hierarchical naming convention of WatchHandler as in:
  * "local" (invisible root)
  * "local.string" (local class variable)
- * "local.string.data" (class member).
- * IDebugSymbolGroup2 can "expand" expandable symbols, appending to the flat list.
- */
+ * "local.string.data" (class member)
+ * and maintains a mapping iname -> index.
+ * IDebugSymbolGroup2 can "expand" expandable symbols, inserting them into the
+ * flat list after their parent. */
 
 class CdbSymbolGroupContext
 {
     Q_DISABLE_COPY(CdbSymbolGroupContext);
-
-    // Start position and length of range in m_symbolParameters
-    typedef QPair<unsigned long, unsigned long> Range;
+     explicit CdbSymbolGroupContext(const QString &prefix,
+                                    IDebugSymbolGroup2 *symbolGroup);
 
 public:
-    explicit CdbSymbolGroupContext(const QString &prefix,
-                                   IDebugSymbolGroup2 *symbolGroup);
     ~CdbSymbolGroupContext();
+    static CdbSymbolGroupContext *create(const QString &prefix,
+                                         IDebugSymbolGroup2 *symbolGroup,
+                                         QString *errorMessage);
 
     QString prefix() const { return m_prefix; }
 
+    static bool populateModelInitially(CdbSymbolGroupContext *sg, WatchHandler *wh, QString *errorMessage);
+    static bool completeModel(CdbSymbolGroupContext *sg, WatchHandler *wh, QString *errorMessage);
+
     // Retrieve child symbols of prefix as a sequence of WatchData.
     template <class OutputIterator>
-            void getSymbols(const QString &prefix, OutputIterator it);
+            bool getChildSymbols(const QString &prefix, OutputIterator it, QString *errorMessage);
 
 private:
+    typedef QMap<QString, unsigned long>  NameIndexMap;
+
+    static inline bool isSymbolDisplayable(const DEBUG_SYMBOL_PARAMETERS &p);
+
+    bool init(QString *errorMessage);
     void clear();
-    Range getSymbolRange(const QString &prefix);
-    Range allocateChildSymbols(const QString &prefix);
-    Range allocateRootSymbols();
+    QString toString() const;
+    bool getChildSymbolsPosition(const QString &prefix,
+                                 unsigned long *startPos,
+                                 unsigned long *parentId,
+                                 QString *errorMessage);
+    bool expandSymbol(const QString &prefix, unsigned long index, QString *errorMessage);
+    void populateINameIndexMap(const QString &prefix, unsigned long start, unsigned long count);
     WatchData symbolAt(unsigned long index) const;
+    bool isExpanded(unsigned long index) const;
+    int getDisplayableChildCount(unsigned long index) const;
 
     inline DEBUG_SYMBOL_PARAMETERS *symbolParameters() { return &(*m_symbolParameters.begin()); }
     inline const DEBUG_SYMBOL_PARAMETERS *symbolParameters() const { return &(*m_symbolParameters.constBegin()); }
 
     const QString m_prefix;
     const QChar m_nameDelimiter;
-    IDebugSymbolGroup2 *m_symbolGroup;
 
-    QStringList m_symbolINames;
+    IDebugSymbolGroup2 *m_symbolGroup;
+    NameIndexMap m_inameIndexMap;
     QVector<DEBUG_SYMBOL_PARAMETERS> m_symbolParameters;
-
-    typedef QMap<QString, Range> ChildRangeMap;
-
-    ChildRangeMap m_childRanges;
 };
 
 template <class OutputIterator>
-void CdbSymbolGroupContext::getSymbols(const QString &prefix, OutputIterator it)
+bool CdbSymbolGroupContext::getChildSymbols(const QString &prefix, OutputIterator it, QString *errorMessage)
 {
-    const Range  r = getSymbolRange(prefix);
-    const unsigned long end = r.first + r.second;
-    for (unsigned long i = r.first; i < end; i++) {
-        *it = symbolAt(i);
-        ++it;
+    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) {
+        const DEBUG_SYMBOL_PARAMETERS &p = m_symbolParameters.at(s);
+        if (p.ParentSymbol == parentId && isSymbolDisplayable(p)) {
+            *it = symbolAt(s);
+            ++it;
+        }
     }
+    return true;
 }
 
 }