diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py
index 7e614ff75f64648378850ca4f3b4559f5fa3ec96..e2bda10df3160c232e62ca119769ecee0491c390 100644
--- a/share/qtcreator/gdbmacros/dumper.py
+++ b/share/qtcreator/gdbmacros/dumper.py
@@ -1047,6 +1047,7 @@ class Dumper:
         self.useFancy = "fancy" in options
         self.passExceptions = "pe" in options
         self.autoDerefPointers = "autoderef" in options
+        self.partialUpdate = "partial" in options
         #self.ns = qqNs
         self.ns = qtNamespace()
 
@@ -1059,9 +1060,29 @@ class Dumper:
         #
         # Locals
         #
-        locals = listOfLocals(varList)
-        if "nolocals" in options:
-            locals = []
+        fullUpdateNeeded = True
+        if self.partialUpdate and len(varList) == 1:
+            #warn("PARTIAL: %s" % varList)
+            parts = varList[0].split('.')
+            #warn("PARTIAL PARTS: %s" % parts)
+            name = parts[1]
+            #warn("PARTIAL VAR: %s" % name)
+            #fullUpdateNeeded = False
+            try:
+                frame = gdb.selected_frame()
+                item = Item(0, "local", name, name)
+                item.value = frame.read_var(name)
+                locals = [item]
+                #warn("PARTIAL LOCALS: %s" % locals)
+                fullUpdateNeeded = False
+            except:
+                pass
+            varList = []
+
+        if fullUpdateNeeded:
+            locals = listOfLocals(varList)
+            if "nolocals" in options:
+                locals = []
 
         # Take care of the return value of the last function call.
         if len(resultVarName) > 0:
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index 89a655e8cf9d29d4f9ffafdce7861b010ab388b9..c755224809f4674123256ba7f1eb7b7879ad52b0 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -691,7 +691,7 @@ void CdbEngine::evaluateWatcher(WatchData *wd)
     wd->setHasChildren(false);
 }
 
-void CdbEngine::updateWatchData(const WatchData &incomplete)
+void CdbEngine::updateWatchData(const WatchData &incomplete, const WatchUpdateFlags &flags)
 {
     // Watch item was edited while running
     if (m_d->isDebuggeeRunning())
diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h
index ebb86f956ee0866453855d5e3e04f0105af3824e..8dba973dd34bddf1165d612ac7239bb359c04712 100644
--- a/src/plugins/debugger/cdb/cdbengine.h
+++ b/src/plugins/debugger/cdb/cdbengine.h
@@ -62,7 +62,7 @@ public:
     virtual void shutdownInferior();
     virtual void shutdownEngine();
     virtual void detachDebugger();
-    virtual void updateWatchData(const WatchData &data);
+    virtual void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
     virtual unsigned debuggerCapabilities() const;
 
     virtual void executeStep();
diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h
index b400435e8a970bb42fa03b345e50ff290c46e824..7340efcfae9b849c415757338170cd37d311239a 100644
--- a/src/plugins/debugger/debuggerengine.h
+++ b/src/plugins/debugger/debuggerengine.h
@@ -130,6 +130,12 @@ class WatchHandler;
 
 class DebuggerEnginePrivate;
 
+struct WatchUpdateFlags
+{
+    WatchUpdateFlags() : tryIncremental(false) {}
+    bool tryIncremental;
+};
+
 // FIXME: DEBUGGER_EXPORT?
 class DEBUGGER_EXPORT DebuggerEngine : public QObject
 {
@@ -140,10 +146,11 @@ public:
     virtual ~DebuggerEngine();
 
     virtual void setToolTipExpression(const QPoint & /* mousePos */,
-            TextEditor::ITextEditor * /* editor */, int /* cursorPos */) { }
+            TextEditor::ITextEditor * /* editor */, int /* cursorPos */) {}
     void initializeFromTemplate(DebuggerEngine *other);
 
-    virtual void updateWatchData(const WatchData & /* data */) { }
+    virtual void updateWatchData(const WatchData & /* data */,
+        const WatchUpdateFlags & /* flags */ = WatchUpdateFlags()) {}
     void startDebugger(DebuggerRunControl *runControl);
     virtual bool isSessionEngine() const { return false; }
 
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index c0ecd0086ead0d9a702dcf9397988fcbfcd00228..aa9095b2ff091c30d324294ffdf53a02b3219ac1 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -3328,7 +3328,7 @@ bool GdbEngine::hasDebuggingHelperForType(const QByteArray &type) const
 }
 
 
-void GdbEngine::updateWatchData(const WatchData &data)
+void GdbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &flags)
 {
     if (isSynchronous()) {
         // This should only be called for fresh expanded items, not for
@@ -3358,7 +3358,22 @@ void GdbEngine::updateWatchData(const WatchData &data)
         }
         m_processedNames.insert(processedName);
 
-        updateLocals();
+        // FIXME: Is this sufficient when "external" changes are
+        // triggered e.g. by manually entered command in the gdb console?
+        //qDebug() << "TRY PARTIAL: " << flags.tryIncremental
+        //        << hasPython()
+        //        << (m_pendingWatchRequests == 0)
+        //        << (m_pendingBreakpointRequests == 0);
+
+        bool tryPartial = flags.tryIncremental
+                && hasPython()
+                && m_pendingWatchRequests == 0
+                && m_pendingBreakpointRequests == 0;
+
+        if (tryPartial)
+            updateLocalsPython(true, data.iname);
+        else
+            updateLocals();
 #endif
     } else {
         // Bump requests to avoid model rebuilding during the nested
@@ -3491,7 +3506,7 @@ void GdbEngine::updateLocals(const QVariant &cookie)
     m_pendingWatchRequests = 0;
     m_pendingBreakpointRequests = 0;
     if (hasPython())
-        updateLocalsPython(QByteArray());
+        updateLocalsPython(false, QByteArray());
     else
         updateLocalsClassic(cookie);
 }
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 514f3a9f4824881e65e26abc75ff76aa22d80c9c..d966f1007bafbda6431eb571708367e7d38c27d1 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -460,7 +460,7 @@ private: ////////// View & Data Stuff //////////
     // FIXME: BaseClass. called to improve situation for a watch item
     void updateSubItemClassic(const WatchData &data);
 
-    void virtual updateWatchData(const WatchData &data);
+    void virtual updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
     Q_SLOT void updateWatchDataHelper(const WatchData &data);
     void rebuildWatchModel();
     bool showToolTip();
@@ -492,7 +492,7 @@ private: ////////// View & Data Stuff //////////
 
     void updateLocals(const QVariant &cookie = QVariant());
         void updateLocalsClassic(const QVariant &cookie);
-        void updateLocalsPython(const QByteArray &varList);
+        void updateLocalsPython(bool tryPartial, const QByteArray &varList);
             void handleStackFramePython(const GdbResponse &response);
 
     void handleStackListLocalsClassic(const GdbResponse &response);
diff --git a/src/plugins/debugger/gdb/pythongdbengine.cpp b/src/plugins/debugger/gdb/pythongdbengine.cpp
index a9da01c2aebb465e8f351e8fcf64008067f45479..63532e148e798f33d381ce55f15810d4a2c29c0f 100644
--- a/src/plugins/debugger/gdb/pythongdbengine.cpp
+++ b/src/plugins/debugger/gdb/pythongdbengine.cpp
@@ -46,12 +46,11 @@
 namespace Debugger {
 namespace Internal {
 
-void GdbEngine::updateLocalsPython(const QByteArray &varList)
+void GdbEngine::updateLocalsPython(bool tryPartial, const QByteArray &varList)
 {
     PRECONDITION;
     m_processedNames.clear();
-
-    watchHandler()->beginCycle();
+    watchHandler()->beginCycle(!tryPartial);
     //m_toolTipExpression.clear();
     WatchHandler *handler = watchHandler();
 
@@ -84,6 +83,8 @@ void GdbEngine::updateLocalsPython(const QByteArray &varList)
         options += "pe,";
     if (options.isEmpty())
         options += "defaults,";
+    if (tryPartial)
+        options += "partial,";
     options.chop(1);
 
     QByteArray resultVar;
@@ -92,7 +93,7 @@ void GdbEngine::updateLocalsPython(const QByteArray &varList)
 
     postCommand("bb options:" + options + " vars:" + varList + ' '
             + resultVar + expanded + " watchers:" + watchers.toHex(),
-        WatchUpdate, CB(handleStackFramePython));
+        WatchUpdate, CB(handleStackFramePython), QVariant(tryPartial));
 }
 
 void GdbEngine::handleStackListLocalsPython(const GdbResponse &response)
@@ -105,7 +106,7 @@ void GdbEngine::handleStackListLocalsPython(const GdbResponse &response)
             varList.append(',');
             varList.append(child.data());
         }
-        updateLocalsPython(varList);
+        updateLocalsPython(false, varList);
     }
 }
 
@@ -113,6 +114,8 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
 {
     PRECONDITION;
     if (response.resultClass == GdbResultDone) {
+        bool partial = response.cookie.toBool();
+        //qDebug() << "READING " << (partial ? "PARTIAL" : "FULL");
         QByteArray out = response.data.findChild("consolestreamoutput").data();
         while (out.endsWith(' ') || out.endsWith('\n'))
             out.chop(1);
diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp
index 24b3502842a76835e2babca7e906fca2fa3fb972..5cf93fabbbfc443f827f71b4a8dca4de1b476605 100644
--- a/src/plugins/debugger/pdb/pdbengine.cpp
+++ b/src/plugins/debugger/pdb/pdbengine.cpp
@@ -556,7 +556,7 @@ void PdbEngine::assignValueInDebugger(const QString &expression,
 }
 
 
-void PdbEngine::updateWatchData(const WatchData &data)
+void PdbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &flags)
 {
     Q_UNUSED(data);
     updateAll();
diff --git a/src/plugins/debugger/pdb/pdbengine.h b/src/plugins/debugger/pdb/pdbengine.h
index bd5afb88cb5061c44ac253ed75f93aa095ffe192..879cde497ba8c506847071a357572fcb634d683c 100644
--- a/src/plugins/debugger/pdb/pdbengine.h
+++ b/src/plugins/debugger/pdb/pdbengine.h
@@ -103,7 +103,7 @@ private:
 
     bool supportsThreads() const { return true; }
     bool isSynchronous() const { return true; }
-    void updateWatchData(const WatchData &data);
+    void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
 
 signals:
     void outputReady(const QByteArray &data);
diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp
index 17486f657109949247407ad61b5c6088ae7a689c..54c68e3cf76d192314e3c28628a1b970820032b3 100644
--- a/src/plugins/debugger/qml/qmlcppengine.cpp
+++ b/src/plugins/debugger/qml/qmlcppengine.cpp
@@ -98,9 +98,9 @@ void QmlCppEngine::setToolTipExpression(const QPoint & mousePos,
     m_activeEngine->setToolTipExpression(mousePos, editor, cursorPos);
 }
 
-void QmlCppEngine::updateWatchData(const WatchData &data)
+void QmlCppEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &flags)
 {
-    m_activeEngine->updateWatchData(data);
+    m_activeEngine->updateWatchData(data, flags);
 }
 
 void QmlCppEngine::watchPoint(const QPoint &point)
diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h
index d33e010528f70966b0e155edc7d38e6a827508b5..3723347d73edf9abe2ff9d8905ac67388e3bdc94 100644
--- a/src/plugins/debugger/qml/qmlcppengine.h
+++ b/src/plugins/debugger/qml/qmlcppengine.h
@@ -24,7 +24,7 @@ public:
 
     virtual void setToolTipExpression(const QPoint & /* mousePos */,
             TextEditor::ITextEditor * /* editor */, int /* cursorPos */);
-    virtual void updateWatchData(const WatchData & /* data */);
+    virtual void updateWatchData(const WatchData & /* data */, const WatchUpdateFlags &flags);
 
     virtual void watchPoint(const QPoint &);
     virtual void fetchMemory(MemoryViewAgent *, QObject *,
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index bde16e30dc540fb6edce3bced1c13f1fef503ad8..d54a934c0355ef1c14621d2f8280c392b1e28a9e 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -476,7 +476,7 @@ void QmlEngine::assignValueInDebugger(const QString &expression,
     }
 }
 
-void QmlEngine::updateWatchData(const WatchData &data)
+void QmlEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &)
 {
 //    qDebug() << "UPDATE WATCH DATA" << data.toString();
     //watchHandler()->rebuildModel();
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index 31f08d027986262721adc5986345b586d2b28efd..76da03384c8cdb553ce60af8cb0508ea96f9f827 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -117,7 +117,7 @@ private:
     void reloadFullStack() {}
 
     bool supportsThreads() const { return false; }
-    void updateWatchData(const WatchData &data);
+    void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
     void executeDebuggerCommand(const QString& command);
 
     unsigned int debuggerCapabilities() const;
diff --git a/src/plugins/debugger/script/scriptengine.cpp b/src/plugins/debugger/script/scriptengine.cpp
index 08e846b446bbe1ef95f8821d361ccc7da175657d..e17ca50580beff56d3f6920150dddf0c7ddfe0fc 100644
--- a/src/plugins/debugger/script/scriptengine.cpp
+++ b/src/plugins/debugger/script/scriptengine.cpp
@@ -721,7 +721,7 @@ void ScriptEngine::updateLocals()
     notifyInferiorRunOk();
 }
 
-void ScriptEngine::updateWatchData(const WatchData &data)
+void ScriptEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &flags)
 {
     updateSubItem(data);
 }
diff --git a/src/plugins/debugger/script/scriptengine.h b/src/plugins/debugger/script/scriptengine.h
index b27ba493e647071df4d2393d5684ab5f4699e265..fe6572e025c64dccb8feed564ed96004b616365a 100644
--- a/src/plugins/debugger/script/scriptengine.h
+++ b/src/plugins/debugger/script/scriptengine.h
@@ -101,7 +101,7 @@ private:
 
     bool supportsThreads() const { return true; }
     bool checkForBreakCondition(bool byFunction);
-    void updateWatchData(const WatchData &data);
+    void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
     void updateLocals();
     void updateSubItem(const WatchData &data);
 
diff --git a/src/plugins/debugger/tcf/tcfengine.cpp b/src/plugins/debugger/tcf/tcfengine.cpp
index 88a2d33bbb1552b8981c058b1ff330f7318dbc7b..3e76236ecbb8b2954dfd45fab44144c35fdd263a 100644
--- a/src/plugins/debugger/tcf/tcfengine.cpp
+++ b/src/plugins/debugger/tcf/tcfengine.cpp
@@ -554,7 +554,7 @@ void TcfEngine::updateLocals()
 {
 }
 
-void TcfEngine::updateWatchData(const WatchData &)
+void TcfEngine::updateWatchData(const WatchData &, const WatchUpdateFlags &)
 {
     //qq->watchHandler()->rebuildModel();
     showStatusMessage(tr("Stopped."), 5000);
diff --git a/src/plugins/debugger/tcf/tcfengine.h b/src/plugins/debugger/tcf/tcfengine.h
index 583a28734b08f5010562e387dc771900c805ba74..2ab8db8a014545aa16b99525a421157fbadfdb5a 100644
--- a/src/plugins/debugger/tcf/tcfengine.h
+++ b/src/plugins/debugger/tcf/tcfengine.h
@@ -106,7 +106,7 @@ private:
 
     bool supportsThreads() const { return true; }
     void maybeBreakNow(bool byFunction);
-    void updateWatchData(const WatchData &data);
+    void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
     void updateLocals();
     void updateSubItem(const WatchData &data);
 
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index 13bdfb288a987a35adb5af91f99d4fa1c8722475..dbfa14b899e967a8186bad4fc8d99d5abcdcdf43 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -487,7 +487,9 @@ void WatchModel::fetchMore(const QModelIndex &index)
     if (item->children.isEmpty()) {
         WatchData data = *item;
         data.setChildrenNeeded();
-        engine()->updateWatchData(data);
+        WatchUpdateFlags flags;
+        flags.tryIncremental = true;
+        engine()->updateWatchData(data, flags);
     }
 }
 
@@ -1146,16 +1148,17 @@ WatchHandler::WatchHandler(DebuggerEngine *engine)
         SIGNAL(triggered()), this, SLOT(emitAllChanged()));
 }
 
-void WatchHandler::beginCycle()
+void WatchHandler::beginCycle(bool fullCycle)
 {
-    ++generationCounter;
+    if (fullCycle)
+        ++generationCounter;
     m_return->beginCycle();
     m_locals->beginCycle();
     m_watchers->beginCycle();
     m_tooltips->beginCycle();
 }
 
-void WatchHandler::endCycle()
+void WatchHandler::endCycle(bool /*fullCycle*/)
 {
     m_return->endCycle();
     m_locals->endCycle();
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index 6ee27029c1aa628e7a811496f3b36867f43607ae..85e8f671bdad90b0074ad3253055f4941f0226aa 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -143,9 +143,9 @@ public:
     void removeWatchExpression(const QString &exp);
     Q_SLOT void emitAllChanged();
 
-    void beginCycle(); // Called at begin of updateLocals() cycle
+    void beginCycle(bool fullCycle = true); // Called at begin of updateLocals() cycle
     void updateWatchers(); // Called after locals are fetched
-    void endCycle(); // Called after all results have been received
+    void endCycle(bool fullCycle = true); // Called after all results have been received
     void showEditValue(const WatchData &data);
 
     void insertData(const WatchData &data);
diff --git a/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp b/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp
index 61edeb1069f73dae070a6d2934fa1d14456880c2..be858a91eaf5f4492637b9840de7fb743cf94242 100644
--- a/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp
+++ b/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp
@@ -793,6 +793,7 @@ public:
 void testQObject(int &argc, char *argv[])
 {
     QApplication app(argc, argv);
+    QString longString = QString(10000, QLatin1Char('A'));
 #if 1
     Names::Bar::TestObject test;
     test.setMyProp1("HELLO");