diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py
index c2ebc24e6320ad82e6ec81f0330604825f68a200..f3cdc691406fff283f1ca8ac22851d3622d193be 100755
--- a/share/qtcreator/dumper/lbridge.py
+++ b/share/qtcreator/dumper/lbridge.py
@@ -20,14 +20,110 @@ cdbLoaded = False
 lldbLoaded = False
 gdbLoaded = False
 
+# Encodings. Keep that synchronized with DebuggerEncoding in watchutils.h
+Unencoded8Bit, \
+Base64Encoded8BitWithQuotes, \
+Base64Encoded16BitWithQuotes, \
+Base64Encoded32BitWithQuotes, \
+Base64Encoded16Bit, \
+Base64Encoded8Bit, \
+Hex2EncodedLatin1, \
+Hex4EncodedLittleEndian, \
+Hex8EncodedLittleEndian, \
+Hex2EncodedUtf8, \
+Hex8EncodedBigEndian, \
+Hex4EncodedBigEndian, \
+Hex4EncodedLittleEndianWithoutQuotes, \
+Hex2EncodedLocal8Bit, \
+JulianDate, \
+MillisecondsSinceMidnight, \
+JulianDateAndMillisecondsSinceMidnight, \
+Hex2EncodedInt1, \
+Hex2EncodedInt2, \
+Hex2EncodedInt4, \
+Hex2EncodedInt8, \
+Hex2EncodedUInt1, \
+Hex2EncodedUInt2, \
+Hex2EncodedUInt4, \
+Hex2EncodedUInt8, \
+Hex2EncodedFloat4, \
+Hex2EncodedFloat8 \
+    = range(27)
+
+# Display modes. Keep that synchronized with DebuggerDisplay in watchutils.h
+StopDisplay, \
+DisplayImageData, \
+DisplayUtf16String, \
+DisplayImageFile, \
+DisplayProcess, \
+DisplayLatin1String, \
+DisplayUtf8String \
+    = range(7)
+
 #######################################################################
 #
 # Helpers
 #
 #######################################################################
 
-currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
-#print "DIR: %s " % currentDir
+# This is a cache mapping from 'type name' to 'display alternatives'.
+qqFormats = {}
+
+# This is a cache of all known dumpers.
+qqDumpers = {}
+
+# This is a cache of all dumpers that support writing.
+qqEditable = {}
+
+# This keeps canonical forms of the typenames, without array indices etc.
+qqStripForFormat = {}
+
+def stripForFormat(typeName):
+    global qqStripForFormat
+    if typeName in qqStripForFormat:
+        return qqStripForFormat[typeName]
+    stripped = ""
+    inArray = 0
+    for c in stripClassTag(typeName):
+        if c == '<':
+            break
+        if c == ' ':
+            continue
+        if c == '[':
+            inArray += 1
+        elif c == ']':
+            inArray -= 1
+        if inArray and ord(c) >= 48 and ord(c) <= 57:
+            continue
+        stripped +=  c
+    qqStripForFormat[typeName] = stripped
+    return stripped
+
+
+def registerDumper(function):
+    global qqDumpers, qqFormats, qqEditable
+    try:
+        funcname = function.func_name
+        if funcname.startswith("qdump__"):
+            type = funcname[7:]
+            qqDumpers[type] = function
+            qqFormats[type] = qqFormats.get(type, "")
+        elif funcname.startswith("qform__"):
+            type = funcname[7:]
+            formats = ""
+            try:
+                formats = function()
+            except:
+                pass
+            qqFormats[type] = formats
+        elif funcname.startswith("qedit__"):
+            type = funcname[7:]
+            try:
+                qqEditable[type] = function
+            except:
+                pass
+    except:
+        pass
 
 def warn(message):
     print 'XXX={"%s"}@\n' % message.encode("latin1").replace('"', "'")
@@ -68,22 +164,6 @@ class Type:
     def strip_typedefs(self):
         return self
 
-class Value:
-    def __init__(self, var):
-        self.raw = var
-        self.is_optimized_out = False
-        self.address = var.addr
-        self.type = Type(var)
-        self.name = var.name
-
-    def __str__(self):
-        return str(self.raw.value)
-
-    def __getitem__(self, name):
-        return None if self.raw is None else  self.raw.GetChildMemberWithName(name)
-
-    def fields(self):
-        return [Value(self.raw.GetChildAtIndex(i)) for i in xrange(self.raw.num_children)]
 
 def currentFrame():
     currentThread = self.process.GetThreadAtIndex(0)
@@ -167,6 +247,33 @@ def loggingCallback(args):
     s = s.replace('"', "'")
     sys.stdout.write('log="%s"@\n' % s)
 
+def check(exp):
+    if not exp:
+        raise RuntimeError("Check failed")
+
+def checkSimpleRef(ref):
+    count = ref["_q_value"]
+    check(count > 0)
+    check(count < 1000000)
+
+def checkRef(ref):
+    return True
+    try:
+        count = ref["atomic"]["_q_value"] # Qt 5.
+        minimum = -1
+    except:
+        count = ref["_q_value"] # Qt 4.
+        minimum = 0
+    # Assume there aren't a million references to any object.
+    check(count >= minimum)
+    check(count < 1000000)
+
+
+def valueChildAccess(self, name):
+    return self.GetChildMemberWithName(name)
+
+lldb.SBValue.__getitem__ = valueChildAccess
+
 class Children:
     def __init__(self, d, numChild = 1, childType = None, childNumChild = None,
             maxNumChild = None, addrBase = None, addrStep = None):
@@ -272,10 +379,17 @@ class Debugger:
     def put(self, stuff):
         sys.stdout.write(stuff)
 
+    def currentItemFormat(self):
+        #format = self.formats.get(self.currentIName)
+        #if format is None:
+        #    format = self.typeformats.get(stripForFormat(str(self.currentType)))
+        #return format
+        return 0
+
     def putNumChild(self, numchild):
         #warn("NUM CHILD: '%s' '%s'" % (numchild, self.currentChildNumChild))
-        if numchild != self.currentChildNumChild:
-            self.put('numchild="%s",' % numchild)
+        #if numchild != self.currentChildNumChild:
+        self.put('numchild="%s",' % numchild)
 
     def putValue(self, value, encoding = None, priority = 0):
         # Higher priority values override lower ones.
@@ -283,6 +397,7 @@ class Debugger:
             self.currentValue = value
             self.currentValuePriority = priority
             self.currentValueEncoding = encoding
+        #self.put('value="%s",' % value)
 
     def setupInferior(self, args):
         fileName = args['executable']
@@ -293,6 +408,7 @@ class Debugger:
             self.report('state="inferiorsetupok",msg="%s",exe="%s"' % (error, fileName))
         else:
             self.report('state="inferiorsetupfailed",msg="%s",exe="%s"' % (error, fileName))
+        self.importDumpers()
 
     def runEngine(self, _):
         error = lldb.SBError()
@@ -364,7 +480,7 @@ class Debugger:
         result += '],current-thread-id="%s"},' % self.currentThread().id
         self.report(result)
 
-    def reportStack(self):
+    def reportStack(self, _ = None):
         if self.process is None:
             self.report('msg="No process"')
         else:
@@ -386,32 +502,89 @@ class Debugger:
             result += '],hasmore="%s"},' % hasmore
             self.report(result)
 
+    def putType(self, typeName):
+            self.put('type="%s",' % typeName)
+
+    def putStringValue(self, value, priority = 0):
+        if not value is None:
+            str = self.encodeString(value)
+            self.putValue(str, Hex4EncodedLittleEndian, priority)
+
+    def readRawMemory(self, base, size):
+        error = lldb.SBError()
+        contents = self.process.ReadMemory(base, size, error)
+        return binascii.hexlify(contents)
+
+    def computeLimit(self, size, limit):
+        if limit is None:
+            return size
+        if limit == 0:
+            #return min(size, qqStringCutOff)
+            return min(size, 100)
+        return min(size, limit)
+
+    def qStringData(self, value):
+        private = value['d']
+        checkRef(private['ref'])
+        try:
+            # Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
+            offset = private['offset']
+            data = int(private.GetValue(), 0) + int(offset.GetValue())
+            return data, int(private['size'].GetValue()), int(private['alloc'].GetValue())
+        except:
+            # Qt 4.
+            return private['data'], int(private['size']), int(private['alloc'])
+
+    def encodeString(self, value, limit = 0):
+        data, size, alloc = self.qStringData(value)
+        if alloc != 0:
+            check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
+        limit = self.computeLimit(size, limit)
+        s = self.readRawMemory(data, 2 * limit)
+        if limit < size:
+            s += "2e002e002e00"
+        return s
+
+    def putValue(self, value, encoding = None, priority = 0):
+        # Higher priority values override lower ones.
+        #if priority >= self.currentValuePriority:
+        #    self.currentValue = value
+        #    self.currentValuePriority = priority
+        #    self.currentValueEncoding = encoding
+        if not encoding is None:
+            self.put('valueencoded="%d",' % encoding)
+        self.put('value="%s",' % value)
+
     def putItem(self, value, tryDynamic=True):
-        #val = value.GetDynamicValue(lldb.eDynamicCanRunTarget)
-        val = value
-        v = val.GetValue()
-        #numchild = 1 if val.MightHaveChildren() else 0
-        numchild = val.GetNumChildren()
-        self.put('iname="%s",' % self.currentIName)
-        self.put('type="%s",' % val.GetTypeName())
-        #self.put('vtype="%s",' % val.GetValueType())
-        self.put('value="%s",' % ("" if v is None else v))
-        self.put('numchild="%s",' % numchild)
-        self.put('addr="0x%x",' % val.GetLoadAddress())
-        if self.currentIName in self.expandedINames:
-            with Children(self):
-                self.putFields(value)
+        global qqDumpers
+        #value = value.GetDynamicValue(lldb.eDynamicCanRunTarget)
+        typeName = value.GetTypeName()
+        if typeName in qqDumpers:
+            self.putType(typeName)
+            qqDumpers[typeName](self, value)
+        else:
+            v = value.GetValue()
+            #numchild = 1 if value.MightHaveChildren() else 0
+            numchild = value.GetNumChildren()
+            self.put('iname="%s",' % self.currentIName)
+            self.put('type="%s",' % typeName)
+            self.put('value="%s",' % ("" if v is None else v))
+            self.put('numchild="%s",' % numchild)
+            self.put('addr="0x%x",' % value.GetLoadAddress())
+            if self.currentIName in self.expandedINames:
+                with Children(self):
+                    self.putFields(value)
 
     def putFields(self, value):
         n = value.GetNumChildren()
         if n > 10000:
             n = 10000
         for i in xrange(n):
-            field = value.GetChildAtIndex(i)
-            with SubItem(self, field.GetName()):
-                self.putItem(field)
+            child = value.GetChildAtIndex(i)
+            with SubItem(self, child.GetName()):
+                self.putItem(child)
 
-    def reportVariables(self):
+    def reportVariables(self, _ = None):
         frame = self.currentThread().GetSelectedFrame()
         self.currentIName = "local"
         self.put('data=[')
@@ -421,7 +594,7 @@ class Debugger:
         self.put(']')
         self.report('')
 
-    def reportData(self):
+    def reportData(self, _ = None):
         self.reportRegisters()
         if self.process is None:
             self.report('process="none"')
@@ -451,7 +624,7 @@ class Debugger:
         sys.stdout.write(stuff)
         sys.stdout.write("@\n")
 
-    def interruptInferior(self):
+    def interruptInferior(self, _ = None):
         if self.process is None:
             self.report('msg="No process"')
         else:
@@ -459,7 +632,7 @@ class Debugger:
             error = self.process.Stop()
             self.reportError(error)
 
-    def detachInferior(self):
+    def detachInferior(self, _ = None):
         if self.process is None:
             self.report('msg="No process"')
         else:
@@ -467,7 +640,7 @@ class Debugger:
             self.reportError(error)
             self.reportData()
 
-    def continueInferior(self):
+    def continueInferior(self, _ = None):
         if self.process is None:
             self.report('msg="No process"')
         else:
@@ -585,7 +758,7 @@ class Debugger:
         result += "]"
         self.report(result)
 
-    def do_listModules(self, args):
+    def listModules(self, args):
         result = 'modules=['
         for module in self.target.modules:
             result += '{file="%s"' % module.file.fullpath
@@ -667,8 +840,9 @@ class Debugger:
     def requestModuleSymbols(self, frame):
         self.handleCommand("target module list " + frame)
 
-    def executeDebuggerCommand(self, command):
+    def executeDebuggerCommand(self, args):
         result = lldb.SBCommandReturnObject()
+        command = args['command']
         self.debugger.GetCommandInterpreter().HandleCommand(command, result)
         success = result.Succeeded()
         if success:
@@ -715,21 +889,19 @@ class Debugger:
         result += ',contents="%s"}' % binascii.hexlify(contents)
         self.report(result)
 
-#execfile(os.path.join(currentDir, "dumper.py"))
-#execfile(os.path.join(currentDir, "qttypes.py"))
-
-#def importPlainDumpers(args):
-#    pass
+    def importDumpers(self, _ = None):
+        result = lldb.SBCommandReturnObject()
+        interpreter = self.debugger.GetCommandInterpreter()
+        global qqDumpers, qqFormats, qqEditable
+        items = globals()
+        for key in items:
+            registerDumper(items[key])
 
-#def bbsetup(args = ''):
-#    global qqDumpers, qqFormats, qqEditable
-#    typeCache = {}
-#
-#    items = globals()
-#    for key in items:
-#        registerDumper(items[key])
 
-#bbsetup()
+currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+#warn("currentdir: %s" % currentDir)
+#execfile(os.path.join(currentDir, "dumper.py"))
+execfile(os.path.join(currentDir, "qttypes.py"))
 
 import sys
 import select
@@ -739,6 +911,7 @@ lldbLoaded = True
 if __name__ == '__main__':
     db = Debugger()
     db.report('state="enginesetupok"')
+    #importPlainDumpers()
     while True:
         rlist, _, _ = select.select([sys.stdin], [], [], 0.1)
         if rlist:
diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp
index 25887ec863eca33a5dc762b4c7a569c08625a560..457320524cd46335967b1832a44f36332118de61 100644
--- a/src/plugins/debugger/lldb/lldbengine.cpp
+++ b/src/plugins/debugger/lldb/lldbengine.cpp
@@ -82,34 +82,26 @@ LldbEngine::LldbEngine(const DebuggerStartParameters &startParameters)
     : DebuggerEngine(startParameters)
 {
     m_lastAgentId = 0;
+    m_lastToken = 0;
     setObjectName(QLatin1String("LldbEngine"));
 }
 
 LldbEngine::~LldbEngine()
 {}
 
-void LldbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages languages)
+void LldbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages)
 {
-    if (!(languages & CppLanguage))
-        return;
-    QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
-    if (state() == DebuggerNotReady) {
-        showMessage(_("LLDB PROCESS NOT RUNNING, PLAIN CMD IGNORED: ") + command);
-        return;
-    }
-    //runCommand(command.toUtf8());
-    m_lldbProc.write(command.toUtf8() + '\n');
+    runCommand(Command("executeDebuggerCommand").arg("command", command));
 }
 
-static int token = 1;
-
 void LldbEngine::runCommand(const Command &command)
 {
     QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll());
-    ++token;
+    ++m_lastToken;
+    QByteArray token = QByteArray::number(m_lastToken);
     QByteArray cmd = "db {'cmd':'" + command.function + "',"
-        + command.args + "'token':" + QByteArray::number(token) + "}\n";
-    showMessage(QString::number(token) + _(cmd), LogInput);
+        + command.args + "'token':" + token + "}\n";
+    showMessage(_(token + cmd), LogInput);
     m_lldbProc.write(cmd);
 }
 
diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h
index 6679c56b775ae40e7d1b7f68ba116050de994533..4b37429130747df537d6ff70ef2d7249d11a1bbe 100644
--- a/src/plugins/debugger/lldb/lldbengine.h
+++ b/src/plugins/debugger/lldb/lldbengine.h
@@ -185,6 +185,7 @@ private:
 
     // FIXME: Make generic.
     int m_lastAgentId;
+    int m_lastToken;
     QMap<QPointer<DisassemblerAgent>, int> m_disassemblerAgents;
     QMap<QPointer<MemoryAgent>, int> m_memoryAgents;
     QHash<int, QPointer<QObject> > m_memoryAgentTokens;