diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index 27163ef3fae631f7e25a85a263ca3233654d79c0..8bb0d7fae7d0fcb9c84cc0a1794ccf220cce0c3d 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -87,10 +87,11 @@ QDataStream& operator>>(QDataStream& s, WatchData &data)
     QString value;
     QString type;
     bool hasChildren;
-    s >> data.exp >> data.name >> value >> type >> hasChildren;
+    s >> data.exp >> data.name >> value >> type >> hasChildren >> data.objectId;
     data.setType(type, false);
     data.setValue(value);
     data.setHasChildren(hasChildren);
+    data.setAllUnneeded();
     return s;
 }
 
@@ -526,7 +527,7 @@ void QmlEngine::updateWatchData(const WatchData &data)
     //watchHandler()->rebuildModel();
     showStatusMessage(tr("Stopped."), 5000);
 
-    if (!data.name.isEmpty()) {
+    if (!data.name.isEmpty() && data.isValueNeeded()) {
         QByteArray reply;
         QDataStream rs(&reply, QIODevice::WriteOnly);
         rs << QByteArray("EXEC");
@@ -534,6 +535,10 @@ void QmlEngine::updateWatchData(const WatchData &data)
         sendMessage(reply);
     }
 
+    if (!data.name.isEmpty() && data.isChildrenNeeded() && watchHandler()->isExpandedIName(data.iname)) {
+        expandObject(data.iname, data.objectId);
+    }
+
     {
         QByteArray reply;
         QDataStream rs(&reply, QIODevice::WriteOnly);
@@ -543,6 +548,16 @@ void QmlEngine::updateWatchData(const WatchData &data)
     }
 }
 
+void QmlEngine::expandObject(const QByteArray& iname, quint64 objectId)
+{
+    QByteArray reply;
+    QDataStream rs(&reply, QIODevice::WriteOnly);
+    rs << QByteArray("EXPAND");
+    rs << iname << objectId;
+    sendMessage(reply);
+}
+
+
 DebuggerEngine *createQmlEngine(const DebuggerStartParameters &sp)
 {
     return new QmlEngine(sp);
@@ -599,11 +614,17 @@ void QmlEngine::messageReceived(const QByteArray &message)
         foreach (WatchData data, watches) {
             data.iname = watchHandler()->watcherName(data.exp);
             watchHandler()->insertData(data);
+
+            if (watchHandler()->expandedINames().contains(data.iname))
+                expandObject(data.iname, data.objectId);
         }
 
         foreach (WatchData data, locals) {
             data.iname = "local." + data.exp;
             watchHandler()->insertData(data);
+
+            if (watchHandler()->expandedINames().contains(data.iname))
+                expandObject(data.iname, data.objectId);
         }
 
         watchHandler()->endCycle();
@@ -614,6 +635,18 @@ void QmlEngine::messageReceived(const QByteArray &message)
         stream >> iname >> data;
         data.iname = iname;
         watchHandler()->insertData(data);
+
+    } else if (command == "EXPANDED") {
+        QList<WatchData> result;
+        QByteArray iname;
+        stream >> iname >> result;
+        foreach (WatchData data, result) {
+            data.iname = iname + '.' + data.exp;
+            watchHandler()->insertData(data);
+
+            if (watchHandler()->expandedINames().contains(data.iname)) 
+                expandObject(data.iname, data.objectId);
+        }
     } else {
         qDebug() << Q_FUNC_INFO << "Unknown command: " << command;
     }
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index dc4d9010af70dd6985ca019a099c781bc21f0788..49fe81caabfa5cf7886fb9f20576bd1ce8d7d8a1 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -128,6 +128,8 @@ signals:
     void sendMessage(const QByteArray &msg);
 
 private:
+    void expandObject(const QByteArray &iname, quint64 objectId);
+
 #if 0
     void createDockWidgets();
     bool connectToViewer(); // using host, port from widgets
diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp
index bf6b34e02daf0968c79802c9e3c2794bcaa862f4..dcd490e79c6dfd3546cdf84a6a07e192274154c3 100644
--- a/src/plugins/debugger/watchdata.cpp
+++ b/src/plugins/debugger/watchdata.cpp
@@ -25,6 +25,7 @@ WatchData::WatchData() :
     valueEditable(true),
     error(false),
     source(0),
+    objectId(0),
     state(InitialState),
     changed(false)
 {
diff --git a/src/plugins/debugger/watchdata.h b/src/plugins/debugger/watchdata.h
index cdc9067430f91a8125426d0d20f1c473186c6c60..0cd0dae433a8399fdd10e573deb4e356c6ad691f 100644
--- a/src/plugins/debugger/watchdata.h
+++ b/src/plugins/debugger/watchdata.h
@@ -130,6 +130,7 @@ public:
 
 public:
     int source;  // Originated from dumper or symbol evaluation? (CDB only)
+    quint64 objectId; // Object id used for the QMLEngine
     int state;
     bool changed;
 };
diff --git a/src/tools/qml/qmlobserver/jsdebuggeragent.cpp b/src/tools/qml/qmlobserver/jsdebuggeragent.cpp
index d79b18c4d4ebf27830a3c9e62065fe6fadd9227d..51ecea7dd6c5f61213eb936f13fc1e4e4e2f3fc4 100644
--- a/src/tools/qml/qmlobserver/jsdebuggeragent.cpp
+++ b/src/tools/qml/qmlobserver/jsdebuggeragent.cpp
@@ -52,13 +52,13 @@
 
 QT_BEGIN_NAMESPACE
 
-namespace {
 struct JSAgentWatchData {
     QByteArray exp;
     QString name;
     QString value;
     QString type;
     bool hasChildren;
+    quint64 objectId;
 
     static JSAgentWatchData fromScriptValue(const QString &expression, const QScriptValue &value)
     {
@@ -67,6 +67,7 @@ struct JSAgentWatchData {
         data.name = expression;
         data.hasChildren = false;
         data.value = value.toString();
+        data.objectId = value.objectId();
         if (value.isArray()) {
             data.type = QLatin1String("Array");
             data.value = QString::fromLatin1("[Array of length %1]").arg(value.property("length").toString());
@@ -113,9 +114,24 @@ struct JSAgentWatchData {
 
 QDataStream& operator<<(QDataStream& s, const JSAgentWatchData& data)
 {
-    return s << data.exp << data.name << data.value << data.type << data.hasChildren;
+    return s << data.exp << data.name << data.value << data.type << data.hasChildren << data.objectId;
 }
 
+static QList<JSAgentWatchData> expandObject(const QScriptValue &object)
+{
+    QList<JSAgentWatchData> result;
+    QScriptValueIterator it(object);
+    while (it.hasNext()) {
+        it.next();
+        result << JSAgentWatchData::fromScriptValue(it.name(), it.value());
+    }
+    return result;
+}
+
+void JSDebuggerAgent::recordKnownObjects(const QList<JSAgentWatchData>& list)
+{
+    foreach (const JSAgentWatchData &data, list)
+        knownObjectIds << data.objectId;
 }
 
 
@@ -289,6 +305,7 @@ void JSDebuggerAgent::messageReceived(const QByteArray& message)
         ds >> id >> expr;
 
         JSAgentWatchData data = JSAgentWatchData::fromScriptValue(expr, engine()->evaluate(expr));
+        knownObjectIds << data.objectId;
         // Clear any exceptions occurred during locals evaluation.
         engine()->clearExceptions();
 
@@ -297,6 +314,27 @@ void JSDebuggerAgent::messageReceived(const QByteArray& message)
         rs << QByteArray("RESULT") << id << data;
         sendMessage(reply);
         state = oldState;
+    } else if (command == "EXPAND") {
+        State oldState = state;
+        state = Stopped;
+        QByteArray requestId;
+        quint64 objectId;
+        ds >> requestId >> objectId;
+        QScriptValue v;
+        if (knownObjectIds.contains(objectId))
+            v = engine()->objectById(objectId);
+
+        QList<JSAgentWatchData> result = expandObject(v);
+        recordKnownObjects(result);
+
+        // Clear any exceptions occurred during locals evaluation.
+        engine()->clearExceptions();
+
+        QByteArray reply;
+        QDataStream rs(&reply, QIODevice::WriteOnly);
+        rs << QByteArray("EXPANDED") << requestId << result;
+        sendMessage(reply);
+        state = oldState;
 
     } else {
         qDebug() << Q_FUNC_INFO << "Unknown command" << command;
@@ -307,6 +345,7 @@ void JSDebuggerAgent::messageReceived(const QByteArray& message)
 
 void JSDebuggerAgent::stopped()
 {
+    knownObjectIds.clear();
     state = Stopped;
     QList<QPair<QString, QPair<QString, qint32> > > backtrace;
 
@@ -335,17 +374,14 @@ void JSDebuggerAgent::stopped()
         backtrace.append(qMakePair(functionName, qMakePair( QUrl(info.fileName()).toLocalFile(), info.lineNumber() ) ) );
     }
     QList<JSAgentWatchData> watches;
-    foreach (const QString &expr, watchExpressions) {
+    foreach (const QString &expr, watchExpressions)
         watches << JSAgentWatchData::fromScriptValue(expr,  engine()->evaluate(expr));
-    }
 
-    QList<JSAgentWatchData> locals;
     QScriptValue activationObject = engine()->currentContext()->activationObject();
-    QScriptValueIterator it(activationObject);
-    while (it.hasNext()) {
-        it.next();
-        locals << JSAgentWatchData::fromScriptValue(it.name(), it.value());
-    }
+    QList<JSAgentWatchData> locals = expandObject(activationObject);
+
+    recordKnownObjects(watches);
+    recordKnownObjects(locals);
 
     // Clear any exceptions occurred during locals evaluation.
     engine()->clearExceptions();
diff --git a/src/tools/qml/qmlobserver/jsdebuggeragent.h b/src/tools/qml/qmlobserver/jsdebuggeragent.h
index a374ce4d334d2d5fa3241785dce422ee68af950a..a842bf3c4a85b583a16606df2594ccdac09080cb 100644
--- a/src/tools/qml/qmlobserver/jsdebuggeragent.h
+++ b/src/tools/qml/qmlobserver/jsdebuggeragent.h
@@ -62,6 +62,8 @@
 
 QT_BEGIN_NAMESPACE
 
+class JSAgentWatchData;
+
 class JSDebuggerAgent : public QDeclarativeDebugService , public QScriptEngineAgent
 { Q_OBJECT
 public:
@@ -100,6 +102,7 @@ public slots:
 //    void pauses();
 
 private:
+
     enum State {
         NoState,
         SteppingIntoState,
@@ -114,10 +117,14 @@ private:
     void continueExec();
     void stopped();
 
+
+    void recordKnownObjects(const QList<JSAgentWatchData> &);
+
     QEventLoop loop;
     QHash <qint64, QString> filenames;
     QSet< QPair<QString, qint32> > breakpointList;
     QStringList watchExpressions;
+    QSet<qint64> knownObjectIds;
 
     Q_DISABLE_COPY(JSDebuggerAgent)
 };