diff --git a/share/qtcreator/dumper/dumper.py b/share/qtcreator/dumper/dumper.py
deleted file mode 100644
index 278a5cf1be13664b7d4249bccdbe2c5a0599b70e..0000000000000000000000000000000000000000
--- a/share/qtcreator/dumper/dumper.py
+++ /dev/null
@@ -1,1944 +0,0 @@
-import sys
-import base64
-import __builtin__
-import os
-import os.path
-import subprocess
-import tempfile
-
-# Fails on Windows.
-try:
-    import curses.ascii
-    def printableChar(ucs):
-        if curses.ascii.isprint(ucs):
-            return ucs
-        return '?'
-except:
-    def printableChar(ucs):
-        if ucs >= 32 and ucs <= 126:
-            return ucs
-        return '?'
-
-
-def childAt(value, index):
-    field = value.type.fields()[index]
-    if len(field.name):
-        return value[field.name]
-    # FIXME: Cheat. There seems to be no official way to access
-    # the real item, so we pass back the value. That at least
-    # enables later ...["name"] style accesses as gdb handles
-    # them transparently.
-    return value
-
-def addressOf(value):
-    return gdb.Value(value.address).cast(value.type.pointer())
-
-
-#gdb.Value.child = impl_Value_child
-
-# Fails on SimulatorQt.
-tempFileCounter = 0
-try:
-    # Test if 2.6 is used (Windows), trigger exception and default
-    # to 2nd version.
-    file = tempfile.NamedTemporaryFile(prefix="py_",delete=True)
-    file.close()
-    def createTempFile():
-        file = tempfile.NamedTemporaryFile(prefix="py_",delete=True)
-        file.close()
-        return file.name
-
-except:
-    def createTempFile():
-        global tempFileCounter
-        tempFileCounter += 1
-        fileName = "%s/py_tmp_%d_%d" \
-            % (tempfile.gettempdir(), os.getpid(), tempFileCounter)
-        return fileName
-
-def removeTempFile(name):
-    try:
-        os.remove(name)
-    except:
-        pass
-
-def showException(msg, exType, exValue, exTraceback):
-    warn("**** CAUGHT EXCEPTION: %s ****" % msg)
-    try:
-        import traceback
-        for line in traceback.format_exception(exType, exValue, exTraceback):
-            warn("%s" % line)
-    except:
-        pass
-
-verbosity = 0
-verbosity = 1
-
-# Some "Enums"
-
-# 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)
-
-
-qqStringCutOff = 10000
-
-#
-# Gnuplot based display for array-like structures.
-#
-gnuplotPipe = {}
-gnuplotPid = {}
-
-def hasPlot():
-    fileName = "/usr/bin/gnuplot"
-    return os.path.isfile(fileName) and os.access(fileName, os.X_OK)
-
-
-#
-# Threads
-#
-def hasInferiorThreadList():
-    #return False
-    try:
-        a = gdb.inferiors()[0].threads()
-        return True
-    except:
-        return False
-
-#
-# VTable
-#
-def hasVTable(type):
-    fields = type.fields()
-    if len(fields) == 0:
-        return False
-    if fields[0].is_base_class:
-        return hasVTable(fields[0].type)
-    return str(fields[0].type) ==  "int (**)(void)"
-
-def dynamicTypeName(value):
-    if hasVTable(value.type):
-        #vtbl = str(parseAndEvaluate("{int(*)(int)}%s" % long(value.address)))
-        try:
-            # Fails on 7.1 due to the missing to_string.
-            vtbl = gdb.execute("info symbol {int*}%s" % long(value.address),
-                to_string = True)
-            pos1 = vtbl.find("vtable ")
-            if pos1 != -1:
-                pos1 += 11
-                pos2 = vtbl.find(" +", pos1)
-                if pos2 != -1:
-                    return vtbl[pos1 : pos2]
-        except:
-            pass
-    return str(value.type)
-
-def downcast(value):
-    try:
-        return value.cast(value.dynamic_type)
-    except:
-        pass
-    #try:
-    #    return value.cast(lookupType(dynamicTypeName(value)))
-    #except:
-    #    pass
-    return value
-
-def expensiveDowncast(value):
-    try:
-        return value.cast(value.dynamic_type)
-    except:
-        pass
-    try:
-        return value.cast(lookupType(dynamicTypeName(value)))
-    except:
-        pass
-    return value
-
-typeCache = {}
-
-def lookupType(typestring):
-    global typeCache
-    global typesToReport
-    type = typeCache.get(typestring)
-    #warn("LOOKUP 1: %s -> %s" % (typestring, type))
-    if not type is None:
-        return type
-
-    if typestring == "void":
-        type = gdb.lookup_type(typestring)
-        typeCache[typestring] = type
-        typesToReport[typestring] = type
-        return type
-
-    try:
-        type = gdb.parse_and_eval("{%s}&main" % typestring).type
-        if not type is None:
-            typeCache[typestring] = type
-            typesToReport[typestring] = type
-            return type
-    except:
-        pass
-
-    # See http://sourceware.org/bugzilla/show_bug.cgi?id=13269
-    # gcc produces "{anonymous}", gdb "(anonymous namespace)"
-    # "<unnamed>" has been seen too. The only thing gdb
-    # understands when reading things back is "(anonymous namespace)"
-    if typestring.find("{anonymous}") != -1:
-        ts = typestring
-        ts = ts.replace("{anonymous}", "(anonymous namespace)")
-        type = lookupType(ts)
-        if not type is None:
-            typeCache[typestring] = type
-            typesToReport[typestring] = type
-            return type
-
-    #warn(" RESULT FOR 7.2: '%s': %s" % (typestring, type))
-
-    # This part should only trigger for
-    # gdb 7.1 for types with namespace separators.
-    # And anonymous namespaces.
-
-    ts = typestring
-    while True:
-        #warn("TS: '%s'" % ts)
-        if ts.startswith("class "):
-            ts = ts[6:]
-        elif ts.startswith("struct "):
-            ts = ts[7:]
-        elif ts.startswith("const "):
-            ts = ts[6:]
-        elif ts.startswith("volatile "):
-            ts = ts[9:]
-        elif ts.startswith("enum "):
-            ts = ts[5:]
-        elif ts.endswith(" const"):
-            ts = ts[:-6]
-        elif ts.endswith(" volatile"):
-            ts = ts[:-9]
-        elif ts.endswith("*const"):
-            ts = ts[:-5]
-        elif ts.endswith("*volatile"):
-            ts = ts[:-8]
-        else:
-            break
-
-    if ts.endswith('*'):
-        type = lookupType(ts[0:-1])
-        if not type is None:
-            type = type.pointer()
-            typeCache[typestring] = type
-            typesToReport[typestring] = type
-            return type
-
-    try:
-        #warn("LOOKING UP '%s'" % ts)
-        type = gdb.lookup_type(ts)
-    except RuntimeError, error:
-        #warn("LOOKING UP '%s': %s" % (ts, error))
-        # See http://sourceware.org/bugzilla/show_bug.cgi?id=11912
-        exp = "(class '%s'*)0" % ts
-        try:
-            type = parseAndEvaluate(exp).type.target()
-        except:
-            # Can throw "RuntimeError: No type named class Foo."
-            pass
-    except:
-        #warn("LOOKING UP '%s' FAILED" % ts)
-        pass
-
-    if not type is None:
-        typeCache[typestring] = type
-        typesToReport[typestring] = type
-        return type
-
-    # This could still be None as gdb.lookup_type("char[3]") generates
-    # "RuntimeError: No type named char[3]"
-    typeCache[typestring] = type
-    typesToReport[typestring] = type
-    return type
-
-def cleanAddress(addr):
-    if addr is None:
-        return "<no address>"
-    # We cannot use str(addr) as it yields rubbish for char pointers
-    # that might trigger Unicode encoding errors.
-    #return addr.cast(lookupType("void").pointer())
-    # We do not use "hex(...)" as it (sometimes?) adds a "L" suffix.
-    return "0x%x" % long(addr)
-
-def extractTemplateArgument(type, position):
-    level = 0
-    skipSpace = False
-    inner = ""
-    type = str(type)
-    for c in type[type.find('<') + 1 : -1]:
-        if c == '<':
-            inner += c
-            level += 1
-        elif c == '>':
-            level -= 1
-            inner += c
-        elif c == ',':
-            if level == 0:
-                if position == 0:
-                    return inner
-                position -= 1
-                inner = ""
-            else:
-                inner += c
-                skipSpace = True
-        else:
-            if skipSpace and c == ' ':
-                pass
-            else:
-                inner += c
-                skipSpace = False
-    return inner
-
-def templateArgument(type, position):
-    try:
-        # This fails on stock 7.2 with
-        # "RuntimeError: No type named myns::QObject.\n"
-        return type.template_argument(position)
-    except:
-        # That's something like "myns::QList<...>"
-        return lookupType(extractTemplateArgument(type.strip_typedefs(), position))
-
-
-# Workaround for gdb < 7.1
-def numericTemplateArgument(type, position):
-    try:
-        return int(type.template_argument(position))
-    except RuntimeError, error:
-        # ": No type named 30."
-        msg = str(error)
-        msg = msg[14:-1]
-        # gdb at least until 7.4 produces for std::array<int, 4u>
-        # for template_argument(1): RuntimeError: No type named 4u.
-        if msg[-1] == 'u':
-           msg = msg[0:-1]
-        return int(msg)
-
-
-class OutputSafer:
-    def __init__(self, d):
-        self.d = d
-
-    def __enter__(self):
-        self.savedOutput = self.d.output
-        self.d.output = []
-
-    def __exit__(self, exType, exValue, exTraceBack):
-        if self.d.passExceptions and not exType is None:
-            showException("OUTPUTSAFER", exType, exValue, exTraceBack)
-            self.d.output = self.savedOutput
-        else:
-            self.savedOutput.extend(self.d.output)
-            self.d.output = self.savedOutput
-        return False
-
-
-class NoAddress:
-    def __init__(self, d):
-        self.d = d
-
-    def __enter__(self):
-        self.savedPrintsAddress = self.d.currentPrintsAddress
-        self.d.currentPrintsAddress = False
-
-    def __exit__(self, exType, exValue, exTraceBack):
-        self.d.currentPrintsAddress = self.savedPrintsAddress
-
-
-
-class SubItem:
-    def __init__(self, d, component):
-        self.d = d
-        self.iname = "%s.%s" % (d.currentIName, component)
-        self.name = component
-
-    def __enter__(self):
-        self.d.put('{')
-        #if not self.name is None:
-        if isinstance(self.name, str):
-            self.d.put('name="%s",' % self.name)
-        self.savedIName = self.d.currentIName
-        self.savedValue = self.d.currentValue
-        self.savedValuePriority = self.d.currentValuePriority
-        self.savedValueEncoding = self.d.currentValueEncoding
-        self.savedType = self.d.currentType
-        self.savedTypePriority = self.d.currentTypePriority
-        self.savedCurrentAddress = self.d.currentAddress
-        self.d.currentIName = self.iname
-        self.d.currentValuePriority = -100
-        self.d.currentValueEncoding = None
-        self.d.currentType = ""
-        self.d.currentTypePriority = -100
-        self.d.currentAddress = None
-
-    def __exit__(self, exType, exValue, exTraceBack):
-        #warn(" CURRENT VALUE: %s %s %s" % (self.d.currentValue,
-        #    self.d.currentValueEncoding, self.d.currentValuePriority))
-        if not exType is None:
-            if self.d.passExceptions:
-                showException("SUBITEM", exType, exValue, exTraceBack)
-            self.d.putNumChild(0)
-            self.d.putValue("<not accessible>")
-        try:
-            #warn("TYPE VALUE: %s" % self.d.currentValue)
-            typeName = stripClassTag(self.d.currentType)
-            #warn("TYPE: '%s'  DEFAULT: '%s' % (typeName, self.d.currentChildType))
-
-            if len(typeName) > 0 and typeName != self.d.currentChildType:
-                self.d.put('type="%s",' % typeName) # str(type.unqualified()) ?
-            if  self.d.currentValue is None:
-                self.d.put('value="<not accessible>",numchild="0",')
-            else:
-                if not self.d.currentValueEncoding is None:
-                    self.d.put('valueencoded="%d",' % self.d.currentValueEncoding)
-                self.d.put('value="%s",' % self.d.currentValue)
-        except:
-            pass
-        if not self.d.currentAddress is None:
-            self.d.put(self.d.currentAddress)
-        self.d.put('},')
-        self.d.currentIName = self.savedIName
-        self.d.currentValue = self.savedValue
-        self.d.currentValuePriority = self.savedValuePriority
-        self.d.currentValueEncoding = self.savedValueEncoding
-        self.d.currentType = self.savedType
-        self.d.currentTypePriority = self.savedTypePriority
-        self.d.currentAddress = self.savedCurrentAddress
-        return True
-
-class TopLevelItem(SubItem):
-    def __init__(self, d, iname):
-        self.d = d
-        self.iname = iname
-        self.name = None
-
-class UnnamedSubItem(SubItem):
-    def __init__(self, d, component):
-        self.d = d
-        self.iname = "%s.%s" % (self.d.currentIName, component)
-        self.name = None
-
-class Children:
-    def __init__(self, d, numChild = 1, childType = None, childNumChild = None,
-            maxNumChild = None, addrBase = None, addrStep = None):
-        self.d = d
-        self.numChild = numChild
-        self.childNumChild = childNumChild
-        self.maxNumChild = maxNumChild
-        self.addrBase = addrBase
-        self.addrStep = addrStep
-        self.printsAddress = True
-        if childType is None:
-            self.childType = None
-        else:
-            self.childType = stripClassTag(str(childType))
-            self.d.put('childtype="%s",' % self.childType)
-            if childNumChild is None:
-                if isSimpleType(childType):
-                    self.d.put('childnumchild="0",')
-                    self.childNumChild = 0
-                elif childType.code == PointerCode:
-                    self.d.put('childnumchild="1",')
-                    self.childNumChild = 1
-            else:
-                self.d.put('childnumchild="%s",' % childNumChild)
-                self.childNumChild = childNumChild
-        try:
-            if not addrBase is None and not addrStep is None:
-                self.d.put('addrbase="0x%x",' % long(addrBase))
-                self.d.put('addrstep="0x%x",' % long(addrStep))
-                self.printsAddress = False
-        except:
-            warn("ADDRBASE: %s" % addrBase)
-        #warn("CHILDREN: %s %s %s" % (numChild, childType, childNumChild))
-
-    def __enter__(self):
-        self.savedChildType = self.d.currentChildType
-        self.savedChildNumChild = self.d.currentChildNumChild
-        self.savedNumChild = self.d.currentNumChild
-        self.savedMaxNumChild = self.d.currentMaxNumChild
-        self.savedPrintsAddress = self.d.currentPrintsAddress
-        self.d.currentChildType = self.childType
-        self.d.currentChildNumChild = self.childNumChild
-        self.d.currentNumChild = self.numChild
-        self.d.currentMaxNumChild = self.maxNumChild
-        self.d.currentPrintsAddress = self.printsAddress
-        self.d.put("children=[")
-
-    def __exit__(self, exType, exValue, exTraceBack):
-        if not exType is None:
-            if self.d.passExceptions:
-                showException("CHILDREN", exType, exValue, exTraceBack)
-            self.d.putNumChild(0)
-            self.d.putValue("<not accessible>")
-        if not self.d.currentMaxNumChild is None:
-            if self.d.currentMaxNumChild < self.d.currentNumChild:
-                self.d.put('{name="<incomplete>",value="",type="",numchild="0"},')
-        self.d.currentChildType = self.savedChildType
-        self.d.currentChildNumChild = self.savedChildNumChild
-        self.d.currentNumChild = self.savedNumChild
-        self.d.currentMaxNumChild = self.savedMaxNumChild
-        self.d.currentPrintsAddress = self.savedPrintsAddress
-        self.d.put('],')
-        return True
-
-
-def value(expr):
-    value = parseAndEvaluate(expr)
-    try:
-        return int(value)
-    except:
-        return str(value)
-
-def isSimpleType(typeobj):
-    code = typeobj.code
-    return code == BoolCode \
-        or code == CharCode \
-        or code == IntCode \
-        or code == FloatCode \
-        or code == EnumCode \
-        or code == SimpleValueCode
-
-def simpleEncoding(typeobj):
-    code = typeobj.code
-    if code == BoolCode or code == CharCode:
-        return Hex2EncodedInt1
-    if code == IntCode:
-        if str(typeobj).find("unsigned") >= 0:
-            if typeobj.sizeof == 1:
-                return Hex2EncodedUInt1
-            if typeobj.sizeof == 2:
-                return Hex2EncodedUInt2
-            if typeobj.sizeof == 4:
-                return Hex2EncodedUInt4
-            if typeobj.sizeof == 8:
-                return Hex2EncodedUInt8
-        else:
-            if typeobj.sizeof == 1:
-                return Hex2EncodedInt1
-            if typeobj.sizeof == 2:
-                return Hex2EncodedInt2
-            if typeobj.sizeof == 4:
-                return Hex2EncodedInt4
-            if typeobj.sizeof == 8:
-                return Hex2EncodedInt8
-    if code == FloatCode:
-        if typeobj.sizeof == 4:
-            return Hex2EncodedFloat4
-        if typeobj.sizeof == 8:
-            return Hex2EncodedFloat8
-    return None
-
-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):
-    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 couldBePointer(p, align):
-#    type = lookupType("unsigned int")
-#    ptr = gdb.Value(p).cast(type)
-#    d = int(str(ptr))
-#    warn("CHECKING : %s %d " % (p, ((d & 3) == 0 and (d > 1000 or d == 0))))
-#    return (d & (align - 1)) and (d > 1000 or d == 0)
-
-
-def checkAccess(p, align = 1):
-    return p.dereference()
-
-def checkContents(p, expected, align = 1):
-    if int(p.dereference()) != expected:
-        raise RuntimeError("Contents check failed")
-
-def checkPointer(p, align = 1):
-    if not isNull(p):
-        p.dereference()
-
-def isAccessible(p):
-    try:
-        long(p)
-        return True
-    except:
-        return False
-
-def isNull(p):
-    # The following can cause evaluation to abort with "UnicodeEncodeError"
-    # for invalid char *, as their "contents" is being examined
-    #s = str(p)
-    #return s == "0x0" or s.startswith("0x0 ")
-    #try:
-    #    # Can fail with: "RuntimeError: Cannot access memory at address 0x5"
-    #    return p.cast(lookupType("void").pointer()) == 0
-    #except:
-    #    return False
-    try:
-        # Can fail with: "RuntimeError: Cannot access memory at address 0x5"
-        return long(p) == 0
-    except:
-        return False
-
-Value = gdb.Value
-
-def stripClassTag(typeName):
-    if typeName.startswith("class "):
-        return typeName[6:]
-    if typeName.startswith("struct "):
-        return typeName[7:]
-    if typeName.startswith("const "):
-        return typeName[6:]
-    if typeName.startswith("volatile "):
-        return typeName[9:]
-    return typeName
-
-def checkPointerRange(p, n):
-    for i in xrange(n):
-        checkPointer(p)
-        ++p
-
-def call2(value, func, args):
-    # args is a tuple.
-    arg = ""
-    for i in range(len(args)):
-        if i:
-            arg += ','
-        a = args[i]
-        if (':' in a) and not ("'" in a):
-            arg = "'%s'" % a
-        else:
-            arg += a
-
-    #warn("CALL: %s -> %s(%s)" % (value, func, arg))
-    type = stripClassTag(str(value.type))
-    if type.find(":") >= 0:
-        type = "'" + type + "'"
-    # 'class' is needed, see http://sourceware.org/bugzilla/show_bug.cgi?id=11912
-    exp = "((class %s*)%s)->%s(%s)" % (type, value.address, func, arg)
-    #warn("CALL: %s" % exp)
-    result = None
-    try:
-        result = parseAndEvaluate(exp)
-    except:
-        pass
-    #warn("  -> %s" % result)
-    return result
-
-def call(value, func, *args):
-    return call2(value, func, args)
-
-def makeValue(type, init):
-    type = "::" + stripClassTag(str(type));
-    # Avoid malloc symbol clash with QVector.
-    gdb.execute("set $d = (%s*)calloc(sizeof(%s), 1)" % (type, type))
-    gdb.execute("set *$d = {%s}" % init)
-    value = parseAndEvaluate("$d").dereference()
-    #warn("  TYPE: %s" % value.type)
-    #warn("  ADDR: %s" % value.address)
-    #warn("  VALUE: %s" % value)
-    return value
-
-def makeStdString(init):
-    # Works only for small allocators, but they are usually empty.
-    gdb.execute("set $d=(std::string*)calloc(sizeof(std::string), 2)");
-    gdb.execute("call($d->basic_string(\"" + init +
-        "\",*(std::allocator<char>*)(1+$d)))")
-    value = parseAndEvaluate("$d").dereference()
-    #warn("  TYPE: %s" % value.type)
-    #warn("  ADDR: %s" % value.address)
-    #warn("  VALUE: %s" % value)
-    return value
-
-
-def makeExpression(value):
-    type = "::" + stripClassTag(str(value.type))
-    #warn("  TYPE: %s" % type)
-    #exp = "(*(%s*)(&%s))" % (type, value.address)
-    exp = "(*(%s*)(%s))" % (type, value.address)
-    #warn("  EXP: %s" % exp)
-    return exp
-
-qqNs = None
-
-def qtNamespace():
-    # FIXME: This only works when call from inside a Qt function frame.
-    global qqNs
-    if not qqNs is None:
-        return qqNs
-    try:
-        str = catchCliOutput("ptype QString::Null")[0]
-        # The result looks like:
-        # "type = const struct myns::QString::Null {"
-        # "    <no data fields>"
-        # "}"
-        pos1 = str.find("struct") + 7
-        pos2 = str.find("QString::Null")
-        if pos1 > -1 and pos2 > -1:
-            qqNs = str[pos1:pos2]
-            return qqNs
-        return ""
-    except:
-        return ""
-
-def findFirstZero(p, maximum):
-    for i in xrange(maximum):
-        if p.dereference() == 0:
-            return i
-        p = p + 1
-    return maximum + 1
-
-def encodeCArray(p, innerType, suffix):
-    t = lookupType(innerType)
-    p = p.cast(t.pointer())
-    limit = findFirstZero(p, qqStringCutOff)
-    s = readRawMemory(p, limit * t.sizeof)
-    if limit > qqStringCutOff:
-        s += suffix
-    return s
-
-def encodeCharArray(p):
-    return encodeCArray(p, "unsigned char", "2e2e2e")
-
-def encodeChar2Array(p):
-    return encodeCArray(p, "unsigned short", "2e002e002e00")
-
-def encodeChar4Array(p):
-    return encodeCArray(p, "unsigned int", "2e0000002e0000002e000000")
-
-def qByteArrayData(value):
-    private = value['d']
-    checkRef(private['ref'])
-    try:
-        # Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
-        offset = private['offset']
-        charPointerType = lookupType('char *')
-        data = private.cast(charPointerType) + private['offset']
-        return data, int(private['size']), int(private['alloc'])
-    except:
-        # Qt 4:
-        return private['data'], int(private['size']), int(private['alloc'])
-
-def computeLimit(size, limit):
-    if limit is None:
-        return size
-    if limit == 0:
-        return min(size, qqStringCutOff)
-    return min(size, limit)
-
-def encodeByteArray(value, limit = None):
-    data, size, alloc = qByteArrayData(value)
-    if alloc != 0:
-        check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
-    limit = computeLimit(size, limit)
-    s = readRawMemory(data, limit)
-    if limit < size:
-        s += "2e2e2e"
-    return s
-
-def qStringData(value):
-    private = value['d']
-    checkRef(private['ref'])
-    try:
-        # Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
-        offset = private['offset']
-        ushortPointerType = lookupType('ushort *')
-        data = private.cast(ushortPointerType) + offset / 2
-        return data, int(private['size']), int(private['alloc'])
-    except:
-        # Qt 4.
-        return private['data'], int(private['size']), int(private['alloc'])
-
-def encodeString(value, limit = 0):
-    data, size, alloc = qStringData(value)
-    if alloc != 0:
-        check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
-    limit = computeLimit(size, limit)
-    s = readRawMemory(data, 2 * limit)
-    if limit < size:
-        s += "2e002e002e00"
-    return s
-
-def encodeByteArray(value, limit = None):
-    data, size, alloc = qByteArrayData(value)
-    if alloc != 0:
-        check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
-    limit = computeLimit(size, limit)
-    s = readRawMemory(data, limit)
-    if limit < size:
-        s += "2e2e2e"
-    return s
-
-def stripTypedefs(type):
-    type = type.unqualified()
-    while type.code == TypedefCode:
-        type = type.strip_typedefs().unqualified()
-    return type
-
-
-#######################################################################
-#
-# LocalItem
-#
-#######################################################################
-
-# Contains iname, name, and value.
-class LocalItem:
-    pass
-
-#######################################################################
-#
-# SetupCommand
-#
-#######################################################################
-
-# 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
-
-
-
-#######################################################################
-#
-# Edit Command
-#
-#######################################################################
-
-def bbedit(args):
-    global qqEditable
-    (type, expr, value) = args.split(",")
-    type = base64.b16decode(type, True)
-    ns = qtNamespace()
-    if type.startswith(ns):
-        type = type[len(ns):]
-    type = type.replace("::", "__")
-    pos = type.find('<')
-    if pos != -1:
-        type = type[0:pos]
-    expr = base64.b16decode(expr, True)
-    value = base64.b16decode(value, True)
-    #warn("EDIT: %s %s %s %s: " % (pos, type, expr, value))
-    if qqEditable.has_key(type):
-        qqEditable[type](expr, value)
-    else:
-        gdb.execute("set (%s)=%s" % (expr, value))
-
-registerCommand("bbedit", bbedit)
-
-
-#######################################################################
-#
-# Frame Command
-#
-#######################################################################
-
-typesToReport = {}
-
-def bb(args):
-    global typesToReport
-    output = Dumper(args).output
-    output.append('],typeinfo=[')
-    for name, type in typesToReport.iteritems():
-        # Happens e.g. for '(anonymous namespace)::InsertDefOperation'
-        if not type is None:
-            output.append('{name="%s",size="%s"}'
-                % (base64.b64encode(name), type.sizeof))
-    output.append(']')
-    typesToReport = {}
-    return "".join(output)
-
-
-def p1(args):
-    import cProfile
-    cProfile.run('bb("%s")' % args, "/tmp/bbprof")
-    import pstats
-    pstats.Stats('/tmp/bbprof').sort_stats('time').print_stats()
-    return ""
-
-
-def p2(args):
-    import timeit
-    return timeit.repeat('bb("%s")' % args,
-        'from __main__ import bb', number=10)
-
-registerCommand("bb", bb)
-registerCommand("p1", p1)
-registerCommand("p2", p2)
-
-
-#######################################################################
-#
-# The Dumper Class
-#
-#######################################################################
-
-
-class Dumper:
-    def defaultInit(self):
-        self.output = []
-        self.currentIName = ""
-        self.currentPrintsAddress = True
-        self.currentChildType = ""
-        self.currentChildNumChild = -1
-        self.currentMaxNumChild = -1
-        self.currentNumChild = -1
-        self.currentValue = None
-        self.currentValuePriority = -100
-        self.currentValueEncoding = None
-        self.currentType = None
-        self.currentTypePriority = -100
-        self.currentAddress = None
-        self.typeformats = {}
-        self.formats = {}
-        self.useDynamicType = True
-        self.expandedINames = {}
-
-    def __init__(self, args):
-        self.defaultInit()
-
-        watchers = ""
-        resultVarName = ""
-        options = []
-        varList = []
-
-        self.output.append('data=[')
-        for arg in args.split(' '):
-            pos = arg.find(":") + 1
-            if arg.startswith("options:"):
-                options = arg[pos:].split(",")
-            elif arg.startswith("vars:"):
-                if len(arg[pos:]) > 0:
-                    varList = arg[pos:].split(",")
-            elif arg.startswith("resultvarname:"):
-                resultVarName = arg[pos:]
-            elif arg.startswith("expanded:"):
-                self.expandedINames = set(arg[pos:].split(","))
-            elif arg.startswith("typeformats:"):
-                for f in arg[pos:].split(","):
-                    pos = f.find("=")
-                    if pos != -1:
-                        type = base64.b16decode(f[0:pos], True)
-                        self.typeformats[type] = int(f[pos+1:])
-            elif arg.startswith("formats:"):
-                for f in arg[pos:].split(","):
-                    pos = f.find("=")
-                    if pos != -1:
-                        self.formats[f[0:pos]] = int(f[pos+1:])
-            elif arg.startswith("watchers:"):
-                watchers = base64.b16decode(arg[pos:], True)
-
-        self.useDynamicType = "dyntype" in options
-        self.useFancy = "fancy" in options
-        self.passExceptions = "pe" in options
-        #self.passExceptions = True
-        self.autoDerefPointers = "autoderef" in options
-        self.partialUpdate = "partial" in options
-        self.tooltipOnly = "tooltiponly" in options
-        self.noLocals = "nolocals" in options
-        self.ns = qtNamespace()
-
-        #warn("NAMESPACE: '%s'" % self.ns)
-        #warn("VARIABLES: %s" % varList)
-        #warn("EXPANDED INAMES: %s" % self.expandedINames)
-        #warn("WATCHERS: %s" % watchers)
-        #warn("PARTIAL: %s" % self.partialUpdate)
-        #warn("NO LOCALS: %s" % self.noLocals)
-        module = sys.modules[__name__]
-
-        #
-        # Locals
-        #
-        locals = []
-        fullUpdateNeeded = True
-        if self.partialUpdate and len(varList) == 1 and not self.tooltipOnly:
-            #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 = LocalItem()
-                item.iname = "local." + name
-                item.name = name
-                item.value = frame.read_var(name)
-                locals = [item]
-                #warn("PARTIAL LOCALS: %s" % locals)
-                fullUpdateNeeded = False
-            except:
-                pass
-            varList = []
-
-        if fullUpdateNeeded and not self.tooltipOnly and not self.noLocals:
-            locals = listOfLocals(varList)
-
-        if "autotest" in options:
-            for item in listOfLocals([]):
-                self.expandedINames.add(item.iname)
-                self.expandedINames.discard("")
-                #warn("EXPANDED: %s" % self.expandedINames)
-
-        # Take care of the return value of the last function call.
-        if len(resultVarName) > 0:
-            try:
-                item = LocalItem()
-                item.name = resultVarName
-                item.iname = "return." + resultVarName
-                item.value = parseAndEvaluate(resultVarName)
-                locals.append(item)
-            except:
-                # Don't bother. It's only supplementary information anyway.
-                pass
-
-        for item in locals:
-            value = downcast(item.value) if self.useDynamicType else item.value
-            with OutputSafer(self):
-                self.anonNumber = -1
-
-                type = value.type.unqualified()
-                typeName = str(type)
-
-                # Special handling for char** argv.
-                if type.code == PointerCode \
-                        and item.iname == "local.argv" \
-                        and typeName == "char **":
-                    n = 0
-                    p = value
-                    # p is 0 for "optimized out" cases. Or contains rubbish.
-                    try:
-                        if not isNull(p):
-                            while not isNull(p.dereference()) and n <= 100:
-                                p += 1
-                                n += 1
-                    except:
-                        pass
-
-                    with TopLevelItem(self, item.iname):
-                        self.put('iname="local.argv",name="argv",')
-                        self.putItemCount(n, 100)
-                        self.putType(typeName)
-                        self.putNumChild(n)
-                        if self.currentIName in self.expandedINames:
-                            p = value
-                            with Children(self, n):
-                                for i in xrange(n):
-                                    self.putSubItem(i, p.dereference())
-                                    p += 1
-                    continue
-
-                else:
-                    # A "normal" local variable or parameter.
-                    with TopLevelItem(self, item.iname):
-                        self.put('iname="%s",' % item.iname)
-                        self.put('name="%s",' % item.name)
-                        self.putItem(value)
-
-        #
-        # Watchers
-        #
-        with OutputSafer(self):
-            if len(watchers) > 0:
-                self.put(",")
-                for watcher in watchers.split("##"):
-                    (exp, iname) = watcher.split("#")
-                    self.handleWatch(exp, iname)
-
-        #print('data=[' + locals + sep + watchers + ']\n')
-
-
-    def handleWatch(self, exp, iname):
-        exp = str(exp)
-        escapedExp = base64.b64encode(exp);
-        #warn("HANDLING WATCH %s, INAME: '%s'" % (exp, iname))
-        if exp.startswith("[") and exp.endswith("]"):
-            #warn("EVAL: EXP: %s" % exp)
-            with TopLevelItem(self, iname):
-                self.put('iname="%s",' % iname)
-                self.put('wname="%s",' % escapedExp)
-                try:
-                    list = eval(exp)
-                    self.putValue("")
-                    self.putNoType()
-                    self.putNumChild(len(list))
-                    # This is a list of expressions to evaluate
-                    with Children(self, len(list)):
-                        itemNumber = 0
-                        for item in list:
-                            self.handleWatch(item, "%s.%d" % (iname, itemNumber))
-                            itemNumber += 1
-                except RuntimeError, error:
-                    warn("EVAL: ERROR CAUGHT %s" % error)
-                    self.putValue("<syntax error>")
-                    self.putNoType()
-                    self.putNumChild(0)
-                    self.put("children=[],")
-            return
-
-        with TopLevelItem(self, iname):
-            self.put('iname="%s",' % iname)
-            self.put('wname="%s",' % escapedExp)
-            if len(exp) == 0: # The <Edit> case
-                self.putValue(" ")
-                self.putNoType()
-                self.putNumChild(0)
-            else:
-                try:
-                    value = parseAndEvaluate(exp)
-                    self.putItem(value)
-                except RuntimeError:
-                    self.currentType = " "
-                    self.currentValue = "<no such value>"
-                    self.currentChildNumChild = -1
-                    self.currentNumChild = 0
-                    self.putNumChild(0)
-
-
-    def put(self, value):
-        self.output.append(value)
-
-    def putField(self, name, value):
-        self.put('%s="%s",' % (name, value))
-
-    def childRange(self):
-        if self.currentMaxNumChild is None:
-            return xrange(0, self.currentNumChild)
-        return xrange(min(self.currentMaxNumChild, self.currentNumChild))
-
-    # Convenience function.
-    def putItemCount(self, count, maximum = 1000000000):
-        # This needs to override the default value, so don't use 'put' directly.
-        if count > maximum:
-            self.putValue('<>%s items>' % maximum)
-        else:
-            self.putValue('<%s items>' % count)
-
-    def putType(self, type, priority = 0):
-        # Higher priority values override lower ones.
-        if priority >= self.currentTypePriority:
-            self.currentType = str(type)
-            self.currentTypePriority = priority
-
-    def putNoType(self):
-        # FIXME: replace with something that does not need special handling
-        # in SubItem.__exit__().
-        self.putBetterType(" ")
-
-    def putInaccessible(self):
-        #self.putBetterType(" ")
-        self.putNumChild(0)
-        self.currentValue = None
-
-    def putBetterType(self, type, priority = 0):
-        self.currentType = str(type)
-        self.currentTypePriority = self.currentTypePriority + 1
-
-    def putAddress(self, addr):
-        if self.currentPrintsAddress:
-            try:
-                # addr can be "None", long(None) fails.
-                #self.put('addr="0x%x",' % long(addr))
-                self.currentAddress = 'addr="0x%x",' % long(addr)
-            except:
-                pass
-
-    def putNumChild(self, numchild):
-        #warn("NUM CHILD: '%s' '%s'" % (numchild, self.currentChildNumChild))
-        if numchild != self.currentChildNumChild:
-            self.put('numchild="%s",' % numchild)
-
-    def putEmptyValue(self, priority = -10):
-        if priority >= self.currentValuePriority:
-            self.currentValue = ""
-            self.currentValuePriority = priority
-            self.currentValueEncoding = None
-
-    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
-
-    def putPointerValue(self, value):
-        # Use a lower priority
-        if value is None:
-            self.putEmptyValue(-1)
-        else:
-            self.putValue("0x%x" % value.cast(
-                lookupType("unsigned long")), None, -1)
-
-    def putStringValue(self, value, priority = 0):
-        if not value is None:
-            str = encodeString(value)
-            self.putValue(str, Hex4EncodedLittleEndian, priority)
-
-    def putDisplay(self, format, value = None, cmd = None):
-        self.put('editformat="%s",' % format)
-        if cmd is None:
-            if not value is None:
-                self.put('editvalue="%s",' % value)
-        else:
-            self.put('editvalue="%s|%s",' % (cmd, value))
-
-    def putByteArrayValue(self, value):
-        str = encodeByteArray(value)
-        self.putValue(str, Hex2EncodedLatin1)
-
-    def putName(self, name):
-        self.put('name="%s",' % name)
-
-    def putMapName(self, value):
-        ns = qtNamespace()
-        if str(value.type) == ns + "QString":
-            self.put('key="%s",' % encodeString(value))
-            self.put('keyencoded="%s",' % Hex4EncodedLittleEndian)
-        elif str(value.type) == ns + "QByteArray":
-            self.put('key="%s",' % encodeByteArray(value))
-            self.put('keyencoded="%s",' % Hex2EncodedLatin1)
-        else:
-            self.put('name="%s",' % value)
-
-    def isExpanded(self):
-        #warn("IS EXPANDED: %s in %s: %s" % (self.currentIName,
-        #    self.expandedINames, self.currentIName in self.expandedINames))
-        return self.currentIName in self.expandedINames
-
-    def isExpandedSubItem(self, component):
-        iname = "%s.%s" % (self.currentIName, component)
-        #warn("IS EXPANDED: %s in %s" % (iname, self.expandedINames))
-        return iname in self.expandedINames
-
-    def stripNamespaceFromType(self, typeName):
-        type = stripClassTag(typeName)
-        if len(self.ns) > 0 and type.startswith(self.ns):
-            type = type[len(self.ns):]
-        pos = type.find("<")
-        # FIXME: make it recognize  foo<A>::bar<B>::iterator?
-        while pos != -1:
-            pos1 = type.rfind(">", pos)
-            type = type[0:pos] + type[pos1+1:]
-            pos = type.find("<")
-        return type
-
-    def isMovableType(self, type):
-        if type.code == PointerCode:
-            return True
-        if isSimpleType(type):
-            return True
-        return self.stripNamespaceFromType(str(type)) in movableTypes
-
-    def putIntItem(self, name, value):
-        with SubItem(self, name):
-            self.putValue(value)
-            self.putType("int")
-            self.putNumChild(0)
-
-    def putBoolItem(self, name, value):
-        with SubItem(self, name):
-            self.putValue(value)
-            self.putType("bool")
-            self.putNumChild(0)
-
-    def currentItemFormat(self):
-        format = self.formats.get(self.currentIName)
-        if format is None:
-            format = self.typeformats.get(stripForFormat(str(self.currentType)))
-        return format
-
-    def putSubItem(self, component, value, tryDynamic=True):
-        with SubItem(self, component):
-            self.putItem(value, tryDynamic)
-
-    def putNamedSubItem(self, component, value, name):
-        with SubItem(self, component):
-            self.putName(name)
-            self.putItem(value)
-
-    def tryPutArrayContents(self, typeobj, base, n):
-        if not isSimpleType(typeobj):
-            return False
-        size = n * typeobj.sizeof;
-        self.put('childtype="%s",' % typeobj)
-        self.put('addrbase="0x%x",' % long(base))
-        self.put('addrstep="0x%x",' % long(typeobj.sizeof))
-        self.put('arrayencoding="%s",' % simpleEncoding(typeobj))
-        self.put('arraydata="')
-        self.put(readRawMemory(base, size))
-        self.put('",')
-        return True
-
-    def putPlotData(self, type, base, n, plotFormat):
-        if self.isExpanded():
-            self.putArrayData(type, base, n)
-        if not hasPlot():
-            return
-        if not isSimpleType(type):
-            #self.putValue(self.currentValue + " (not plottable)")
-            self.putValue(self.currentValue)
-            self.putField("plottable", "0")
-            return
-        global gnuplotPipe
-        global gnuplotPid
-        format = self.currentItemFormat()
-        iname = self.currentIName
-        #if False:
-        if format != plotFormat:
-            if iname in gnuplotPipe:
-                os.kill(gnuplotPid[iname], 9)
-                del gnuplotPid[iname]
-                gnuplotPipe[iname].terminate()
-                del gnuplotPipe[iname]
-            return
-        base = base.cast(type.pointer())
-        if not iname in gnuplotPipe:
-            gnuplotPipe[iname] = subprocess.Popen(["gnuplot"],
-                    stdin=subprocess.PIPE)
-            gnuplotPid[iname] = gnuplotPipe[iname].pid
-        f = gnuplotPipe[iname].stdin;
-        f.write("set term wxt noraise\n")
-        f.write("set title 'Data fields'\n")
-        f.write("set xlabel 'Index'\n")
-        f.write("set ylabel 'Value'\n")
-        f.write("set grid\n")
-        f.write("set style data lines;\n")
-        f.write("plot  '-' title '%s'\n" % iname)
-        for i in range(1, n):
-            f.write(" %s\n" % base.dereference())
-            base += 1
-        f.write("e\n")
-
-
-    def putArrayData(self, type, base, n,
-            childNumChild = None, maxNumChild = 10000):
-        base = base.cast(type.pointer())
-        if not self.tryPutArrayContents(type, base, n):
-            with Children(self, n, type, childNumChild, maxNumChild,
-                    base, type.sizeof):
-                for i in self.childRange():
-                    self.putSubItem(i, (base + i).dereference())
-
-
-    def putCallItem(self, name, value, func, *args):
-        result = call2(value, func, args)
-        with SubItem(self, name):
-            self.putItem(result)
-
-    def putItem(self, value, tryDynamic=True):
-        if value is None:
-            # Happens for non-available watchers in gdb versions that
-            # need to use gdb.execute instead of gdb.parse_and_eval
-            self.putValue("<not available>")
-            self.putType("<unknown>")
-            self.putNumChild(0)
-            return
-
-        global qqDumpers, qqFormats
-
-        type = value.type.unqualified()
-        typeName = str(type)
-        tryDynamic &= self.useDynamicType
-        lookupType(typeName) # Fill type cache
-        if tryDynamic:
-            self.putAddress(value.address)
-
-        # FIXME: Gui shows references stripped?
-        #warn(" ")
-        #warn("REAL INAME: %s " % self.currentIName)
-        #warn("REAL TYPE: %s " % value.type)
-        #warn("REAL CODE: %s " % value.type.code)
-        #warn("REAL VALUE: %s " % value)
-
-        if type.code == ReferenceCode:
-            try:
-                # Try to recognize null references explicitly.
-                if long(value.address) == 0:
-                    self.putValue("<null reference>")
-                    self.putType(typeName)
-                    self.putNumChild(0)
-                    return
-            except:
-                pass
-
-            if tryDynamic:
-                try:
-                    # Dynamic references are not supported by gdb, see
-                    # http://sourceware.org/bugzilla/show_bug.cgi?id=14077.
-                    # Find the dynamic type manually using referenced_type.
-                    value = value.referenced_value()
-                    value = value.cast(value.dynamic_type)
-                    self.putItem(value)
-                    self.putBetterType("%s &" % value.type)
-                    return
-                except:
-                    pass
-
-            try:
-                # FIXME: This throws "RuntimeError: Attempt to dereference a
-                # generic pointer." with MinGW's gcc 4.5 when it "identifies"
-                # a "QWidget &" as "void &" and with optimized out code.
-                self.putItem(value.cast(type.target().unqualified()))
-                self.putBetterType(typeName)
-                return
-            except RuntimeError:
-                self.putValue("<optimized out reference>")
-                self.putType(typeName)
-                self.putNumChild(0)
-                return
-
-        if type.code == IntCode or type.code == CharCode or type.code == SimpleValueCode:
-            self.putType(typeName)
-            if value.is_optimized_out:
-                self.putValue("<optimized out>")
-            else:
-                self.putValue(value)
-            self.putNumChild(0)
-            return
-
-        if type.code == FloatCode or type.code == BoolCode:
-            self.putType(typeName)
-            if value.is_optimized_out:
-                self.putValue("<optimized out>")
-            else:
-                self.putValue(value)
-            self.putNumChild(0)
-            return
-
-        if type.code == EnumCode:
-            self.putType(typeName)
-            if value.is_optimized_out:
-                self.putValue("<optimized out>")
-            else:
-                self.putValue("%s (%d)" % (value, value))
-            self.putNumChild(0)
-            return
-
-        if type.code == ComplexCode:
-            self.putType(typeName)
-            if value.is_optimized_out:
-                self.putValue("<optimized out>")
-            else:
-                self.putValue("%s" % value)
-            self.putNumChild(0)
-            return
-
-        if type.code == TypedefCode:
-            if typeName in qqDumpers:
-                self.putType(typeName)
-                qqDumpers[typeName](self, value)
-                return
-
-            type = stripTypedefs(type)
-            # The cast can destroy the address?
-            #self.putAddress(value.address)
-            # Workaround for http://sourceware.org/bugzilla/show_bug.cgi?id=13380
-            if type.code == ArrayCode:
-                value = parseAndEvaluate("{%s}%s" % (type, value.address))
-            else:
-                try:
-                    value = value.cast(type)
-                except:
-                    self.putValue("<optimized out typedef>")
-                    self.putType(typeName)
-                    self.putNumChild(0)
-                    return
-
-            self.putItem(value)
-            self.putBetterType(typeName)
-            return
-
-        if type.code == ArrayCode:
-            qdump____c_style_array__(self, value)
-            return
-
-        if type.code == PointerCode:
-            #warn("POINTER: %s" % value)
-
-            # This could still be stored in a register and
-            # potentially dereferencable.
-            if value.is_optimized_out:
-                self.putValue("<optimized out>")
-
-            try:
-                value.dereference()
-            except:
-                # Failure to dereference a pointer should at least
-                # show the value of a pointer.
-                self.putValue(cleanAddress(value))
-                self.putType(typeName)
-                self.putNumChild(0)
-                return
-
-            if isNull(value):
-                #warn("NULL POINTER")
-                self.putType(typeName)
-                self.putValue("0x0")
-                self.putNumChild(0)
-                return
-
-            innerType = type.target()
-            innerTypeName = str(innerType.unqualified())
-            format = self.formats.get(self.currentIName)
-            if format is None:
-                format = self.typeformats.get(stripForFormat(str(type)))
-
-            if innerType.code == VoidCode:
-                #warn("VOID POINTER: %s" % format)
-                self.putType(typeName)
-                self.putValue(str(value))
-                self.putNumChild(0)
-                return
-
-            if format == None and innerTypeName == "char":
-                # Use Latin1 as default for char *.
-                self.putType(typeName)
-                self.putValue(encodeCharArray(value), Hex2EncodedLatin1)
-                self.putNumChild(0)
-                return
-
-            if format == 0:
-                # Explicitly requested bald pointer.
-                self.putType(typeName)
-                self.putPointerValue(value)
-                self.putNumChild(1)
-                if self.currentIName in self.expandedINames:
-                    with Children(self):
-                        with SubItem(self, '*'):
-                            self.putItem(value.dereference())
-                return
-
-            if format == 1:
-                # Explicitly requested Latin1 formatting.
-                self.putType(typeName)
-                self.putValue(encodeCharArray(value), Hex2EncodedLatin1)
-                self.putNumChild(0)
-                return
-
-            if format == 2:
-                # Explicitly requested UTF-8 formatting.
-                self.putType(typeName)
-                self.putValue(encodeCharArray(value), Hex2EncodedUtf8)
-                self.putNumChild(0)
-                return
-
-            if format == 3:
-                # Explicitly requested local 8 bit formatting.
-                self.putType(typeName)
-                self.putValue(encodeCharArray(value), Hex2EncodedLocal8Bit)
-                self.putNumChild(0)
-                return
-
-            if format == 4:
-                # Explicitly requested UTF-16 formatting.
-                self.putType(typeName)
-                self.putValue(encodeChar2Array(value), Hex4EncodedLittleEndian)
-                self.putNumChild(0)
-                return
-
-            if format == 5:
-                # Explicitly requested UCS-4 formatting.
-                self.putType(typeName)
-                self.putValue(encodeChar4Array(value), Hex8EncodedLittleEndian)
-                self.putNumChild(0)
-                return
-
-            if innerType.code == MethodCode or innerType.code == FunctionCode:
-                # A function pointer with format None.
-                self.putValue(str(value))
-                self.putType(typeName)
-                self.putNumChild(0)
-                return
-
-            #warn("AUTODEREF: %s" % self.autoDerefPointers)
-            #warn("INAME: %s" % self.currentIName)
-            if self.autoDerefPointers or self.currentIName.endswith('.this'):
-                ## Generic pointer type with format None
-                #warn("GENERIC AUTODEREF POINTER: %s AT %s TO %s"
-                #    % (type, value.address, innerTypeName))
-                # Never dereference char types.
-                if innerTypeName != "char" \
-                        and innerTypeName != "signed char" \
-                        and innerTypeName != "unsigned char"  \
-                        and innerTypeName != "wchar_t":
-                    self.putType(innerType)
-                    savedCurrentChildType = self.currentChildType
-                    self.currentChildType = stripClassTag(innerTypeName)
-                    self.putItem(value.dereference())
-                    self.currentChildType = savedCurrentChildType
-                    #self.putPointerValue(value)
-                    self.put('origaddr="%s",' % value.address)
-                    return
-
-            # Fall back to plain pointer printing.
-            #warn("GENERIC PLAIN POINTER: %s" % value.type)
-            #warn("ADDR PLAIN POINTER: %s" % value.address)
-            self.putType(typeName)
-            self.putField("aaa", "1")
-            #self.put('addr="0x%x",' % long(value.address))
-            #self.putAddress(value.address)
-            self.putField("bbb", "1")
-            #self.putPointerValue(value)
-            self.putValue("0x%x" % value.cast(lookupType("unsigned long")))
-            self.putField("ccc", "1")
-            self.putNumChild(1)
-            if self.currentIName in self.expandedINames:
-                with Children(self):
-                    with SubItem(self, "*"):
-                        self.putItem(value.dereference())
-            return
-
-        if type.code == MethodPointerCode \
-                or type.code == MethodCode \
-                or type.code == FunctionCode \
-                or type.code == MemberPointerCode:
-            self.putType(typeName)
-            self.putValue(value)
-            self.putNumChild(0)
-            return
-
-        if typeName.startswith("<anon"):
-            # Anonymous union. We need a dummy name to distinguish
-            # multiple anonymous unions in the struct.
-            self.putType(type)
-            self.putValue("{...}")
-            self.anonNumber += 1
-            with Children(self, 1):
-                self.listAnonymous(value, "#%d" % self.anonNumber, type)
-            return
-
-        if type.code != StructCode and type.code != UnionCode:
-            warn("WRONG ASSUMPTION HERE: %s " % type.code)
-            check(False)
-
-
-        if tryDynamic:
-            self.putItem(expensiveDowncast(value), False)
-            return
-
-        format = self.formats.get(self.currentIName)
-        if format is None:
-            format = self.typeformats.get(stripForFormat(typeName))
-
-        if self.useFancy and (format is None or format >= 1):
-            self.putType(typeName)
-
-            nsStrippedType = self.stripNamespaceFromType(typeName)\
-                .replace("::", "__")
-
-            # The following block is only needed for D.
-            if nsStrippedType.startswith("_A"):
-                # DMD v2.058 encodes string[] as _Array_uns long long.
-                # With spaces.
-                if nsStrippedType.startswith("_Array_"):
-                    qdump_Array(self, value)
-                    return
-                if nsStrippedType.startswith("_AArray_"):
-                    qdump_AArray(self, value)
-                    return
-
-            #warn(" STRIPPED: %s" % nsStrippedType)
-            #warn(" DUMPERS: %s" % qqDumpers)
-            #warn(" DUMPERS: %s" % (nsStrippedType in qqDumpers))
-            dumper = qqDumpers.get(nsStrippedType, None)
-            if not dumper is None:
-                if tryDynamic:
-                    dumper(self, expensiveDowncast(value))
-                else:
-                    dumper(self, value)
-                return
-
-        # D arrays, gdc compiled.
-        if typeName.endswith("[]"):
-            n = value["length"]
-            base = value["ptr"]
-            self.putType(typeName)
-            self.putItemCount(n)
-            if self.isExpanded():
-                self.putArrayData(base.type.target(), base, n)
-            return
-
-        #warn("GENERIC STRUCT: %s" % type)
-        #warn("INAME: %s " % self.currentIName)
-        #warn("INAMES: %s " % self.expandedINames)
-        #warn("EXPANDED: %s " % (self.currentIName in self.expandedINames))
-        self.tryPutObjectNameValue(value)  # Is this too expensive?
-        self.putType(typeName)
-        self.putEmptyValue()
-        self.putNumChild(fieldCount(type))
-
-        if self.currentIName in self.expandedINames:
-            innerType = None
-            with Children(self, 1, childType=innerType):
-                self.putFields(value)
-
-    def putPlainChildren(self, value):
-        self.putEmptyValue(-99)
-        self.putNumChild(1)
-        if self.currentIName in self.expandedINames:
-            with Children(self):
-               self.putFields(value)
-
-    def tryPutObjectNameValue(self, value):
-        try:
-            # Is this derived from QObject?
-            dd = value["d_ptr"]["d"]
-            privateTypeName = self.ns + "QObjectPrivate"
-            privateType = lookupType(privateTypeName)
-            staticMetaObject = value["staticMetaObject"]
-            d_ptr = dd.cast(privateType.pointer()).dereference()
-            objectName = None
-            try:
-                objectName = d_ptr["objectName"]
-            except: # Qt 5
-                p = d_ptr["extraData"]
-                if not isNull(p):
-                    objectName = p.dereference()["objectName"]
-            if not objectName is None:
-                data, size, alloc = qStringData(objectName)
-                if size > 0:
-                    str = readRawMemory(data, 2 * size)
-                    self.putValue(str, Hex4EncodedLittleEndian, 1)
-        except:
-            pass
-
-    def putFields(self, value, dumpBase = True):
-        fields = extractFields(value)
-
-        # FIXME: Merge into this function.
-        if gdbLoaded:
-            self.putFieldsGdb(fields, value, dumpBase)
-            return
-
-        for field in fields:
-            with SubItem(self, field.name):
-                self.putItem(field)
-
-    def putFieldsGdb(self, fields, value, dumpBase):
-            #warn("TYPE: %s" % type)
-            #warn("FIELDS: %s" % fields)
-            baseNumber = 0
-            for field in fields:
-                #warn("FIELD: %s" % field)
-                #warn("  BITSIZE: %s" % field.bitsize)
-                #warn("  ARTIFICIAL: %s" % field.artificial)
-
-                if field.name is None:
-                    type = stripTypedefs(value.type)
-                    innerType = type.target()
-                    p = value.cast(innerType.pointer())
-                    for i in xrange(type.sizeof / innerType.sizeof):
-                        with SubItem(self, i):
-                            self.putItem(p.dereference())
-                        p = p + 1
-                    continue
-
-                # Ignore vtable pointers for virtual inheritance.
-                if field.name.startswith("_vptr."):
-                    with SubItem(self, "[vptr]"):
-                        # int (**)(void)
-                        n = 100
-                        self.putType(" ")
-                        self.putValue(value[field.name])
-                        self.putNumChild(n)
-                        if self.isExpanded():
-                            with Children(self):
-                                p = value[field.name]
-                                for i in xrange(n):
-                                    if long(p.dereference()) != 0:
-                                        with SubItem(self, i):
-                                            self.putItem(p.dereference())
-                                            self.putType(" ")
-                                            p = p + 1
-                    continue
-
-                #warn("FIELD NAME: %s" % field.name)
-                #warn("FIELD TYPE: %s" % field.type)
-                if field.is_base_class:
-                    # Field is base type. We cannot use field.name as part
-                    # of the iname as it might contain spaces and other
-                    # strange characters.
-                    if dumpBase:
-                        baseNumber += 1
-                        with UnnamedSubItem(self, "@%d" % baseNumber):
-                            self.put('iname="%s",' % self.currentIName)
-                            self.put('name="[%s]",' % field.name)
-                            self.putItem(value.cast(field.type), False)
-                elif len(field.name) == 0:
-                    # Anonymous union. We need a dummy name to distinguish
-                    # multiple anonymous unions in the struct.
-                    self.anonNumber += 1
-                    self.listAnonymous(value, "#%d" % self.anonNumber,
-                        field.type)
-                else:
-                    # Named field.
-                    with SubItem(self, field.name):
-                        #bitsize = getattr(field, "bitsize", None)
-                        #if not bitsize is None:
-                        #    self.put("bitsize=\"%s\"" % bitsize)
-                        self.putItem(downcast(value[field.name]))
-
-
-    def listAnonymous(self, value, name, type):
-        for field in type.fields():
-            #warn("FIELD NAME: %s" % field.name)
-            if len(field.name) > 0:
-                with SubItem(self, field.name):
-                    self.putItem(value[field.name])
-            else:
-                # Further nested.
-                self.anonNumber += 1
-                name = "#%d" % self.anonNumber
-                #iname = "%s.%s" % (selitem.iname, name)
-                #child = SameItem(item.value, iname)
-                with SubItem(self, name):
-                    self.put('name="%s",' % name)
-                    self.putEmptyValue()
-                    fieldTypeName = str(field.type)
-                    if fieldTypeName.endswith("<anonymous union>"):
-                        self.putType("<anonymous union>")
-                    elif fieldTypeName.endswith("<anonymous struct>"):
-                        self.putType("<anonymous struct>")
-                    else:
-                        self.putType(fieldTypeName)
-                    with Children(self, 1):
-                        self.listAnonymous(value, name, field.type)
-
-#######################################################################
-#
-# ThreadNames Command
-#
-#######################################################################
-
-def threadnames(arg):
-    ns = qtNamespace()
-    out = '['
-    oldthread = gdb.selected_thread()
-    try:
-        inferior = selectedInferior()
-        for thread in inferior.threads():
-            maximalStackDepth = int(arg)
-            thread.switch()
-            e = gdb.selected_frame ()
-            while True:
-                maximalStackDepth -= 1
-                if maximalStackDepth < 0:
-                    break
-                e = e.older()
-                if e == None or e.name() == None:
-                    break
-                if e.name() == ns + "QThreadPrivate::start":
-                    try:
-                        thrptr = e.read_var("thr").dereference()
-                        obtype = lookupType(ns + "QObjectPrivate").pointer()
-                        d_ptr = thrptr["d_ptr"]["d"].cast(obtype).dereference()
-                        objectName = d_ptr["objectName"]
-                        out += '{valueencoded="';
-                        out += str(Hex4EncodedLittleEndianWithoutQuotes)+'",id="'
-                        out += str(thread.num) + '",value="'
-                        out += encodeString(objectName)
-                        out += '"},'
-                    except:
-                        pass
-    except:
-        pass
-    oldthread.switch()
-    return out + ']'
-
-registerCommand("threadnames", threadnames)
-
-
-#######################################################################
-#
-# Mixed C++/Qml debugging
-#
-#######################################################################
-
-def qmlb(args):
-    # executeCommand(command, to_string=True).split("\n")
-    warm("RUNNING: break -f QScript::FunctionWrapper::proxyCall")
-    output = catchCliOutput("rbreak -f QScript::FunctionWrapper::proxyCall")
-    warn("OUTPUT: %s " % output)
-    bp = output[0]
-    warn("BP: %s " % bp)
-    # BP: ['Breakpoint 3 at 0xf166e7: file .../qscriptfunction.cpp, line 75.\\n'] \n"
-    pos = bp.find(' ') + 1
-    warn("POS: %s " % pos)
-    nr = bp[bp.find(' ') + 1 : bp.find(' at ')]
-    warn("NR: %s " % nr)
-    return bp
-
-registerCommand("qmlb", qmlb)
diff --git a/share/qtcreator/dumper/gbridge.py b/share/qtcreator/dumper/gbridge.py
index ba216f2209c35b2ac6e9f5aa7b66909d78378cc6..10619082cb901003aa0b1c0b8f2c44e9abf898e5 100644
--- a/share/qtcreator/dumper/gbridge.py
+++ b/share/qtcreator/dumper/gbridge.py
@@ -1,11 +1,17 @@
 
+import base64
 import binascii
+import __builtin__
 import gdb
 import inspect
 import os
+import os.path
+import subprocess
 import sys
+import tempfile
 import traceback
 
+
 cdbLoaded = False
 lldbLoaded = False
 gdbLoaded = False
@@ -430,9 +436,1947 @@ def importPlainDumpers(args):
 registerCommand("importPlainDumpers", importPlainDumpers)
 
 
+
+
+# Fails on Windows.
+try:
+    import curses.ascii
+    def printableChar(ucs):
+        if curses.ascii.isprint(ucs):
+            return ucs
+        return '?'
+except:
+    def printableChar(ucs):
+        if ucs >= 32 and ucs <= 126:
+            return ucs
+        return '?'
+
+
+def childAt(value, index):
+    field = value.type.fields()[index]
+    if len(field.name):
+        return value[field.name]
+    # FIXME: Cheat. There seems to be no official way to access
+    # the real item, so we pass back the value. That at least
+    # enables later ...["name"] style accesses as gdb handles
+    # them transparently.
+    return value
+
+def addressOf(value):
+    return gdb.Value(value.address).cast(value.type.pointer())
+
+
+#gdb.Value.child = impl_Value_child
+
+# Fails on SimulatorQt.
+tempFileCounter = 0
+try:
+    # Test if 2.6 is used (Windows), trigger exception and default
+    # to 2nd version.
+    file = tempfile.NamedTemporaryFile(prefix="py_",delete=True)
+    file.close()
+    def createTempFile():
+        file = tempfile.NamedTemporaryFile(prefix="py_",delete=True)
+        file.close()
+        return file.name
+
+except:
+    def createTempFile():
+        global tempFileCounter
+        tempFileCounter += 1
+        fileName = "%s/py_tmp_%d_%d" \
+            % (tempfile.gettempdir(), os.getpid(), tempFileCounter)
+        return fileName
+
+def removeTempFile(name):
+    try:
+        os.remove(name)
+    except:
+        pass
+
+def showException(msg, exType, exValue, exTraceback):
+    warn("**** CAUGHT EXCEPTION: %s ****" % msg)
+    try:
+        import traceback
+        for line in traceback.format_exception(exType, exValue, exTraceback):
+            warn("%s" % line)
+    except:
+        pass
+
+verbosity = 0
+verbosity = 1
+
+# Some "Enums"
+
+# 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)
+
+
+qqStringCutOff = 10000
+
+#
+# Gnuplot based display for array-like structures.
+#
+gnuplotPipe = {}
+gnuplotPid = {}
+
+def hasPlot():
+    fileName = "/usr/bin/gnuplot"
+    return os.path.isfile(fileName) and os.access(fileName, os.X_OK)
+
+
+#
+# Threads
+#
+def hasInferiorThreadList():
+    #return False
+    try:
+        a = gdb.inferiors()[0].threads()
+        return True
+    except:
+        return False
+
+#
+# VTable
+#
+def hasVTable(type):
+    fields = type.fields()
+    if len(fields) == 0:
+        return False
+    if fields[0].is_base_class:
+        return hasVTable(fields[0].type)
+    return str(fields[0].type) ==  "int (**)(void)"
+
+def dynamicTypeName(value):
+    if hasVTable(value.type):
+        #vtbl = str(parseAndEvaluate("{int(*)(int)}%s" % long(value.address)))
+        try:
+            # Fails on 7.1 due to the missing to_string.
+            vtbl = gdb.execute("info symbol {int*}%s" % long(value.address),
+                to_string = True)
+            pos1 = vtbl.find("vtable ")
+            if pos1 != -1:
+                pos1 += 11
+                pos2 = vtbl.find(" +", pos1)
+                if pos2 != -1:
+                    return vtbl[pos1 : pos2]
+        except:
+            pass
+    return str(value.type)
+
+def downcast(value):
+    try:
+        return value.cast(value.dynamic_type)
+    except:
+        pass
+    #try:
+    #    return value.cast(lookupType(dynamicTypeName(value)))
+    #except:
+    #    pass
+    return value
+
+def expensiveDowncast(value):
+    try:
+        return value.cast(value.dynamic_type)
+    except:
+        pass
+    try:
+        return value.cast(lookupType(dynamicTypeName(value)))
+    except:
+        pass
+    return value
+
+typeCache = {}
+
+def lookupType(typestring):
+    global typeCache
+    global typesToReport
+    type = typeCache.get(typestring)
+    #warn("LOOKUP 1: %s -> %s" % (typestring, type))
+    if not type is None:
+        return type
+
+    if typestring == "void":
+        type = gdb.lookup_type(typestring)
+        typeCache[typestring] = type
+        typesToReport[typestring] = type
+        return type
+
+    try:
+        type = gdb.parse_and_eval("{%s}&main" % typestring).type
+        if not type is None:
+            typeCache[typestring] = type
+            typesToReport[typestring] = type
+            return type
+    except:
+        pass
+
+    # See http://sourceware.org/bugzilla/show_bug.cgi?id=13269
+    # gcc produces "{anonymous}", gdb "(anonymous namespace)"
+    # "<unnamed>" has been seen too. The only thing gdb
+    # understands when reading things back is "(anonymous namespace)"
+    if typestring.find("{anonymous}") != -1:
+        ts = typestring
+        ts = ts.replace("{anonymous}", "(anonymous namespace)")
+        type = lookupType(ts)
+        if not type is None:
+            typeCache[typestring] = type
+            typesToReport[typestring] = type
+            return type
+
+    #warn(" RESULT FOR 7.2: '%s': %s" % (typestring, type))
+
+    # This part should only trigger for
+    # gdb 7.1 for types with namespace separators.
+    # And anonymous namespaces.
+
+    ts = typestring
+    while True:
+        #warn("TS: '%s'" % ts)
+        if ts.startswith("class "):
+            ts = ts[6:]
+        elif ts.startswith("struct "):
+            ts = ts[7:]
+        elif ts.startswith("const "):
+            ts = ts[6:]
+        elif ts.startswith("volatile "):
+            ts = ts[9:]
+        elif ts.startswith("enum "):
+            ts = ts[5:]
+        elif ts.endswith(" const"):
+            ts = ts[:-6]
+        elif ts.endswith(" volatile"):
+            ts = ts[:-9]
+        elif ts.endswith("*const"):
+            ts = ts[:-5]
+        elif ts.endswith("*volatile"):
+            ts = ts[:-8]
+        else:
+            break
+
+    if ts.endswith('*'):
+        type = lookupType(ts[0:-1])
+        if not type is None:
+            type = type.pointer()
+            typeCache[typestring] = type
+            typesToReport[typestring] = type
+            return type
+
+    try:
+        #warn("LOOKING UP '%s'" % ts)
+        type = gdb.lookup_type(ts)
+    except RuntimeError, error:
+        #warn("LOOKING UP '%s': %s" % (ts, error))
+        # See http://sourceware.org/bugzilla/show_bug.cgi?id=11912
+        exp = "(class '%s'*)0" % ts
+        try:
+            type = parseAndEvaluate(exp).type.target()
+        except:
+            # Can throw "RuntimeError: No type named class Foo."
+            pass
+    except:
+        #warn("LOOKING UP '%s' FAILED" % ts)
+        pass
+
+    if not type is None:
+        typeCache[typestring] = type
+        typesToReport[typestring] = type
+        return type
+
+    # This could still be None as gdb.lookup_type("char[3]") generates
+    # "RuntimeError: No type named char[3]"
+    typeCache[typestring] = type
+    typesToReport[typestring] = type
+    return type
+
+def cleanAddress(addr):
+    if addr is None:
+        return "<no address>"
+    # We cannot use str(addr) as it yields rubbish for char pointers
+    # that might trigger Unicode encoding errors.
+    #return addr.cast(lookupType("void").pointer())
+    # We do not use "hex(...)" as it (sometimes?) adds a "L" suffix.
+    return "0x%x" % long(addr)
+
+def extractTemplateArgument(type, position):
+    level = 0
+    skipSpace = False
+    inner = ""
+    type = str(type)
+    for c in type[type.find('<') + 1 : -1]:
+        if c == '<':
+            inner += c
+            level += 1
+        elif c == '>':
+            level -= 1
+            inner += c
+        elif c == ',':
+            if level == 0:
+                if position == 0:
+                    return inner
+                position -= 1
+                inner = ""
+            else:
+                inner += c
+                skipSpace = True
+        else:
+            if skipSpace and c == ' ':
+                pass
+            else:
+                inner += c
+                skipSpace = False
+    return inner
+
+def templateArgument(type, position):
+    try:
+        # This fails on stock 7.2 with
+        # "RuntimeError: No type named myns::QObject.\n"
+        return type.template_argument(position)
+    except:
+        # That's something like "myns::QList<...>"
+        return lookupType(extractTemplateArgument(type.strip_typedefs(), position))
+
+
+# Workaround for gdb < 7.1
+def numericTemplateArgument(type, position):
+    try:
+        return int(type.template_argument(position))
+    except RuntimeError, error:
+        # ": No type named 30."
+        msg = str(error)
+        msg = msg[14:-1]
+        # gdb at least until 7.4 produces for std::array<int, 4u>
+        # for template_argument(1): RuntimeError: No type named 4u.
+        if msg[-1] == 'u':
+           msg = msg[0:-1]
+        return int(msg)
+
+
+class OutputSafer:
+    def __init__(self, d):
+        self.d = d
+
+    def __enter__(self):
+        self.savedOutput = self.d.output
+        self.d.output = []
+
+    def __exit__(self, exType, exValue, exTraceBack):
+        if self.d.passExceptions and not exType is None:
+            showException("OUTPUTSAFER", exType, exValue, exTraceBack)
+            self.d.output = self.savedOutput
+        else:
+            self.savedOutput.extend(self.d.output)
+            self.d.output = self.savedOutput
+        return False
+
+
+class NoAddress:
+    def __init__(self, d):
+        self.d = d
+
+    def __enter__(self):
+        self.savedPrintsAddress = self.d.currentPrintsAddress
+        self.d.currentPrintsAddress = False
+
+    def __exit__(self, exType, exValue, exTraceBack):
+        self.d.currentPrintsAddress = self.savedPrintsAddress
+
+
+
+class SubItem:
+    def __init__(self, d, component):
+        self.d = d
+        self.iname = "%s.%s" % (d.currentIName, component)
+        self.name = component
+
+    def __enter__(self):
+        self.d.put('{')
+        #if not self.name is None:
+        if isinstance(self.name, str):
+            self.d.put('name="%s",' % self.name)
+        self.savedIName = self.d.currentIName
+        self.savedValue = self.d.currentValue
+        self.savedValuePriority = self.d.currentValuePriority
+        self.savedValueEncoding = self.d.currentValueEncoding
+        self.savedType = self.d.currentType
+        self.savedTypePriority = self.d.currentTypePriority
+        self.savedCurrentAddress = self.d.currentAddress
+        self.d.currentIName = self.iname
+        self.d.currentValuePriority = -100
+        self.d.currentValueEncoding = None
+        self.d.currentType = ""
+        self.d.currentTypePriority = -100
+        self.d.currentAddress = None
+
+    def __exit__(self, exType, exValue, exTraceBack):
+        #warn(" CURRENT VALUE: %s %s %s" % (self.d.currentValue,
+        #    self.d.currentValueEncoding, self.d.currentValuePriority))
+        if not exType is None:
+            if self.d.passExceptions:
+                showException("SUBITEM", exType, exValue, exTraceBack)
+            self.d.putNumChild(0)
+            self.d.putValue("<not accessible>")
+        try:
+            #warn("TYPE VALUE: %s" % self.d.currentValue)
+            typeName = stripClassTag(self.d.currentType)
+            #warn("TYPE: '%s'  DEFAULT: '%s' % (typeName, self.d.currentChildType))
+
+            if len(typeName) > 0 and typeName != self.d.currentChildType:
+                self.d.put('type="%s",' % typeName) # str(type.unqualified()) ?
+            if  self.d.currentValue is None:
+                self.d.put('value="<not accessible>",numchild="0",')
+            else:
+                if not self.d.currentValueEncoding is None:
+                    self.d.put('valueencoded="%d",' % self.d.currentValueEncoding)
+                self.d.put('value="%s",' % self.d.currentValue)
+        except:
+            pass
+        if not self.d.currentAddress is None:
+            self.d.put(self.d.currentAddress)
+        self.d.put('},')
+        self.d.currentIName = self.savedIName
+        self.d.currentValue = self.savedValue
+        self.d.currentValuePriority = self.savedValuePriority
+        self.d.currentValueEncoding = self.savedValueEncoding
+        self.d.currentType = self.savedType
+        self.d.currentTypePriority = self.savedTypePriority
+        self.d.currentAddress = self.savedCurrentAddress
+        return True
+
+class TopLevelItem(SubItem):
+    def __init__(self, d, iname):
+        self.d = d
+        self.iname = iname
+        self.name = None
+
+class UnnamedSubItem(SubItem):
+    def __init__(self, d, component):
+        self.d = d
+        self.iname = "%s.%s" % (self.d.currentIName, component)
+        self.name = None
+
+class Children:
+    def __init__(self, d, numChild = 1, childType = None, childNumChild = None,
+            maxNumChild = None, addrBase = None, addrStep = None):
+        self.d = d
+        self.numChild = numChild
+        self.childNumChild = childNumChild
+        self.maxNumChild = maxNumChild
+        self.addrBase = addrBase
+        self.addrStep = addrStep
+        self.printsAddress = True
+        if childType is None:
+            self.childType = None
+        else:
+            self.childType = stripClassTag(str(childType))
+            self.d.put('childtype="%s",' % self.childType)
+            if childNumChild is None:
+                if isSimpleType(childType):
+                    self.d.put('childnumchild="0",')
+                    self.childNumChild = 0
+                elif childType.code == PointerCode:
+                    self.d.put('childnumchild="1",')
+                    self.childNumChild = 1
+            else:
+                self.d.put('childnumchild="%s",' % childNumChild)
+                self.childNumChild = childNumChild
+        try:
+            if not addrBase is None and not addrStep is None:
+                self.d.put('addrbase="0x%x",' % long(addrBase))
+                self.d.put('addrstep="0x%x",' % long(addrStep))
+                self.printsAddress = False
+        except:
+            warn("ADDRBASE: %s" % addrBase)
+        #warn("CHILDREN: %s %s %s" % (numChild, childType, childNumChild))
+
+    def __enter__(self):
+        self.savedChildType = self.d.currentChildType
+        self.savedChildNumChild = self.d.currentChildNumChild
+        self.savedNumChild = self.d.currentNumChild
+        self.savedMaxNumChild = self.d.currentMaxNumChild
+        self.savedPrintsAddress = self.d.currentPrintsAddress
+        self.d.currentChildType = self.childType
+        self.d.currentChildNumChild = self.childNumChild
+        self.d.currentNumChild = self.numChild
+        self.d.currentMaxNumChild = self.maxNumChild
+        self.d.currentPrintsAddress = self.printsAddress
+        self.d.put("children=[")
+
+    def __exit__(self, exType, exValue, exTraceBack):
+        if not exType is None:
+            if self.d.passExceptions:
+                showException("CHILDREN", exType, exValue, exTraceBack)
+            self.d.putNumChild(0)
+            self.d.putValue("<not accessible>")
+        if not self.d.currentMaxNumChild is None:
+            if self.d.currentMaxNumChild < self.d.currentNumChild:
+                self.d.put('{name="<incomplete>",value="",type="",numchild="0"},')
+        self.d.currentChildType = self.savedChildType
+        self.d.currentChildNumChild = self.savedChildNumChild
+        self.d.currentNumChild = self.savedNumChild
+        self.d.currentMaxNumChild = self.savedMaxNumChild
+        self.d.currentPrintsAddress = self.savedPrintsAddress
+        self.d.put('],')
+        return True
+
+
+def value(expr):
+    value = parseAndEvaluate(expr)
+    try:
+        return int(value)
+    except:
+        return str(value)
+
+def isSimpleType(typeobj):
+    code = typeobj.code
+    return code == BoolCode \
+        or code == CharCode \
+        or code == IntCode \
+        or code == FloatCode \
+        or code == EnumCode \
+        or code == SimpleValueCode
+
+def simpleEncoding(typeobj):
+    code = typeobj.code
+    if code == BoolCode or code == CharCode:
+        return Hex2EncodedInt1
+    if code == IntCode:
+        if str(typeobj).find("unsigned") >= 0:
+            if typeobj.sizeof == 1:
+                return Hex2EncodedUInt1
+            if typeobj.sizeof == 2:
+                return Hex2EncodedUInt2
+            if typeobj.sizeof == 4:
+                return Hex2EncodedUInt4
+            if typeobj.sizeof == 8:
+                return Hex2EncodedUInt8
+        else:
+            if typeobj.sizeof == 1:
+                return Hex2EncodedInt1
+            if typeobj.sizeof == 2:
+                return Hex2EncodedInt2
+            if typeobj.sizeof == 4:
+                return Hex2EncodedInt4
+            if typeobj.sizeof == 8:
+                return Hex2EncodedInt8
+    if code == FloatCode:
+        if typeobj.sizeof == 4:
+            return Hex2EncodedFloat4
+        if typeobj.sizeof == 8:
+            return Hex2EncodedFloat8
+    return None
+
+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):
+    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 couldBePointer(p, align):
+#    type = lookupType("unsigned int")
+#    ptr = gdb.Value(p).cast(type)
+#    d = int(str(ptr))
+#    warn("CHECKING : %s %d " % (p, ((d & 3) == 0 and (d > 1000 or d == 0))))
+#    return (d & (align - 1)) and (d > 1000 or d == 0)
+
+
+def checkAccess(p, align = 1):
+    return p.dereference()
+
+def checkContents(p, expected, align = 1):
+    if int(p.dereference()) != expected:
+        raise RuntimeError("Contents check failed")
+
+def checkPointer(p, align = 1):
+    if not isNull(p):
+        p.dereference()
+
+def isAccessible(p):
+    try:
+        long(p)
+        return True
+    except:
+        return False
+
+def isNull(p):
+    # The following can cause evaluation to abort with "UnicodeEncodeError"
+    # for invalid char *, as their "contents" is being examined
+    #s = str(p)
+    #return s == "0x0" or s.startswith("0x0 ")
+    #try:
+    #    # Can fail with: "RuntimeError: Cannot access memory at address 0x5"
+    #    return p.cast(lookupType("void").pointer()) == 0
+    #except:
+    #    return False
+    try:
+        # Can fail with: "RuntimeError: Cannot access memory at address 0x5"
+        return long(p) == 0
+    except:
+        return False
+
+Value = gdb.Value
+
+def stripClassTag(typeName):
+    if typeName.startswith("class "):
+        return typeName[6:]
+    if typeName.startswith("struct "):
+        return typeName[7:]
+    if typeName.startswith("const "):
+        return typeName[6:]
+    if typeName.startswith("volatile "):
+        return typeName[9:]
+    return typeName
+
+def checkPointerRange(p, n):
+    for i in xrange(n):
+        checkPointer(p)
+        ++p
+
+def call2(value, func, args):
+    # args is a tuple.
+    arg = ""
+    for i in range(len(args)):
+        if i:
+            arg += ','
+        a = args[i]
+        if (':' in a) and not ("'" in a):
+            arg = "'%s'" % a
+        else:
+            arg += a
+
+    #warn("CALL: %s -> %s(%s)" % (value, func, arg))
+    type = stripClassTag(str(value.type))
+    if type.find(":") >= 0:
+        type = "'" + type + "'"
+    # 'class' is needed, see http://sourceware.org/bugzilla/show_bug.cgi?id=11912
+    exp = "((class %s*)%s)->%s(%s)" % (type, value.address, func, arg)
+    #warn("CALL: %s" % exp)
+    result = None
+    try:
+        result = parseAndEvaluate(exp)
+    except:
+        pass
+    #warn("  -> %s" % result)
+    return result
+
+def call(value, func, *args):
+    return call2(value, func, args)
+
+def makeValue(type, init):
+    type = "::" + stripClassTag(str(type));
+    # Avoid malloc symbol clash with QVector.
+    gdb.execute("set $d = (%s*)calloc(sizeof(%s), 1)" % (type, type))
+    gdb.execute("set *$d = {%s}" % init)
+    value = parseAndEvaluate("$d").dereference()
+    #warn("  TYPE: %s" % value.type)
+    #warn("  ADDR: %s" % value.address)
+    #warn("  VALUE: %s" % value)
+    return value
+
+def makeStdString(init):
+    # Works only for small allocators, but they are usually empty.
+    gdb.execute("set $d=(std::string*)calloc(sizeof(std::string), 2)");
+    gdb.execute("call($d->basic_string(\"" + init +
+        "\",*(std::allocator<char>*)(1+$d)))")
+    value = parseAndEvaluate("$d").dereference()
+    #warn("  TYPE: %s" % value.type)
+    #warn("  ADDR: %s" % value.address)
+    #warn("  VALUE: %s" % value)
+    return value
+
+
+def makeExpression(value):
+    type = "::" + stripClassTag(str(value.type))
+    #warn("  TYPE: %s" % type)
+    #exp = "(*(%s*)(&%s))" % (type, value.address)
+    exp = "(*(%s*)(%s))" % (type, value.address)
+    #warn("  EXP: %s" % exp)
+    return exp
+
+qqNs = None
+
+def qtNamespace():
+    # FIXME: This only works when call from inside a Qt function frame.
+    global qqNs
+    if not qqNs is None:
+        return qqNs
+    try:
+        str = catchCliOutput("ptype QString::Null")[0]
+        # The result looks like:
+        # "type = const struct myns::QString::Null {"
+        # "    <no data fields>"
+        # "}"
+        pos1 = str.find("struct") + 7
+        pos2 = str.find("QString::Null")
+        if pos1 > -1 and pos2 > -1:
+            qqNs = str[pos1:pos2]
+            return qqNs
+        return ""
+    except:
+        return ""
+
+def findFirstZero(p, maximum):
+    for i in xrange(maximum):
+        if p.dereference() == 0:
+            return i
+        p = p + 1
+    return maximum + 1
+
+def encodeCArray(p, innerType, suffix):
+    t = lookupType(innerType)
+    p = p.cast(t.pointer())
+    limit = findFirstZero(p, qqStringCutOff)
+    s = readRawMemory(p, limit * t.sizeof)
+    if limit > qqStringCutOff:
+        s += suffix
+    return s
+
+def encodeCharArray(p):
+    return encodeCArray(p, "unsigned char", "2e2e2e")
+
+def encodeChar2Array(p):
+    return encodeCArray(p, "unsigned short", "2e002e002e00")
+
+def encodeChar4Array(p):
+    return encodeCArray(p, "unsigned int", "2e0000002e0000002e000000")
+
+def qByteArrayData(value):
+    private = value['d']
+    checkRef(private['ref'])
+    try:
+        # Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
+        offset = private['offset']
+        charPointerType = lookupType('char *')
+        data = private.cast(charPointerType) + private['offset']
+        return data, int(private['size']), int(private['alloc'])
+    except:
+        # Qt 4:
+        return private['data'], int(private['size']), int(private['alloc'])
+
+def computeLimit(size, limit):
+    if limit is None:
+        return size
+    if limit == 0:
+        return min(size, qqStringCutOff)
+    return min(size, limit)
+
+def encodeByteArray(value, limit = None):
+    data, size, alloc = qByteArrayData(value)
+    if alloc != 0:
+        check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
+    limit = computeLimit(size, limit)
+    s = readRawMemory(data, limit)
+    if limit < size:
+        s += "2e2e2e"
+    return s
+
+def qStringData(value):
+    private = value['d']
+    checkRef(private['ref'])
+    try:
+        # Qt 5. Will fail on Qt 4 due to the missing 'offset' member.
+        offset = private['offset']
+        ushortPointerType = lookupType('ushort *')
+        data = private.cast(ushortPointerType) + offset / 2
+        return data, int(private['size']), int(private['alloc'])
+    except:
+        # Qt 4.
+        return private['data'], int(private['size']), int(private['alloc'])
+
+def encodeString(value, limit = 0):
+    data, size, alloc = qStringData(value)
+    if alloc != 0:
+        check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
+    limit = computeLimit(size, limit)
+    s = readRawMemory(data, 2 * limit)
+    if limit < size:
+        s += "2e002e002e00"
+    return s
+
+def encodeByteArray(value, limit = None):
+    data, size, alloc = qByteArrayData(value)
+    if alloc != 0:
+        check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
+    limit = computeLimit(size, limit)
+    s = readRawMemory(data, limit)
+    if limit < size:
+        s += "2e2e2e"
+    return s
+
+def stripTypedefs(type):
+    type = type.unqualified()
+    while type.code == TypedefCode:
+        type = type.strip_typedefs().unqualified()
+    return type
+
+
+#######################################################################
+#
+# LocalItem
+#
+#######################################################################
+
+# Contains iname, name, and value.
+class LocalItem:
+    pass
+
+#######################################################################
+#
+# SetupCommand
+#
+#######################################################################
+
+# 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
+
+
+
+#######################################################################
+#
+# Edit Command
+#
+#######################################################################
+
+def bbedit(args):
+    global qqEditable
+    (type, expr, value) = args.split(",")
+    type = base64.b16decode(type, True)
+    ns = qtNamespace()
+    if type.startswith(ns):
+        type = type[len(ns):]
+    type = type.replace("::", "__")
+    pos = type.find('<')
+    if pos != -1:
+        type = type[0:pos]
+    expr = base64.b16decode(expr, True)
+    value = base64.b16decode(value, True)
+    #warn("EDIT: %s %s %s %s: " % (pos, type, expr, value))
+    if qqEditable.has_key(type):
+        qqEditable[type](expr, value)
+    else:
+        gdb.execute("set (%s)=%s" % (expr, value))
+
+registerCommand("bbedit", bbedit)
+
+
+#######################################################################
+#
+# Frame Command
+#
+#######################################################################
+
+typesToReport = {}
+
+def bb(args):
+    global typesToReport
+    output = Dumper(args).output
+    output.append('],typeinfo=[')
+    for name, type in typesToReport.iteritems():
+        # Happens e.g. for '(anonymous namespace)::InsertDefOperation'
+        if not type is None:
+            output.append('{name="%s",size="%s"}'
+                % (base64.b64encode(name), type.sizeof))
+    output.append(']')
+    typesToReport = {}
+    return "".join(output)
+
+
+def p1(args):
+    import cProfile
+    cProfile.run('bb("%s")' % args, "/tmp/bbprof")
+    import pstats
+    pstats.Stats('/tmp/bbprof').sort_stats('time').print_stats()
+    return ""
+
+
+def p2(args):
+    import timeit
+    return timeit.repeat('bb("%s")' % args,
+        'from __main__ import bb', number=10)
+
+registerCommand("bb", bb)
+registerCommand("p1", p1)
+registerCommand("p2", p2)
+
+
+#######################################################################
+#
+# The Dumper Class
+#
+#######################################################################
+
+
+class Dumper:
+    def defaultInit(self):
+        self.output = []
+        self.currentIName = ""
+        self.currentPrintsAddress = True
+        self.currentChildType = ""
+        self.currentChildNumChild = -1
+        self.currentMaxNumChild = -1
+        self.currentNumChild = -1
+        self.currentValue = None
+        self.currentValuePriority = -100
+        self.currentValueEncoding = None
+        self.currentType = None
+        self.currentTypePriority = -100
+        self.currentAddress = None
+        self.typeformats = {}
+        self.formats = {}
+        self.useDynamicType = True
+        self.expandedINames = {}
+
+    def __init__(self, args):
+        self.defaultInit()
+
+        watchers = ""
+        resultVarName = ""
+        options = []
+        varList = []
+
+        self.output.append('data=[')
+        for arg in args.split(' '):
+            pos = arg.find(":") + 1
+            if arg.startswith("options:"):
+                options = arg[pos:].split(",")
+            elif arg.startswith("vars:"):
+                if len(arg[pos:]) > 0:
+                    varList = arg[pos:].split(",")
+            elif arg.startswith("resultvarname:"):
+                resultVarName = arg[pos:]
+            elif arg.startswith("expanded:"):
+                self.expandedINames = set(arg[pos:].split(","))
+            elif arg.startswith("typeformats:"):
+                for f in arg[pos:].split(","):
+                    pos = f.find("=")
+                    if pos != -1:
+                        type = base64.b16decode(f[0:pos], True)
+                        self.typeformats[type] = int(f[pos+1:])
+            elif arg.startswith("formats:"):
+                for f in arg[pos:].split(","):
+                    pos = f.find("=")
+                    if pos != -1:
+                        self.formats[f[0:pos]] = int(f[pos+1:])
+            elif arg.startswith("watchers:"):
+                watchers = base64.b16decode(arg[pos:], True)
+
+        self.useDynamicType = "dyntype" in options
+        self.useFancy = "fancy" in options
+        self.passExceptions = "pe" in options
+        #self.passExceptions = True
+        self.autoDerefPointers = "autoderef" in options
+        self.partialUpdate = "partial" in options
+        self.tooltipOnly = "tooltiponly" in options
+        self.noLocals = "nolocals" in options
+        self.ns = qtNamespace()
+
+        #warn("NAMESPACE: '%s'" % self.ns)
+        #warn("VARIABLES: %s" % varList)
+        #warn("EXPANDED INAMES: %s" % self.expandedINames)
+        #warn("WATCHERS: %s" % watchers)
+        #warn("PARTIAL: %s" % self.partialUpdate)
+        #warn("NO LOCALS: %s" % self.noLocals)
+        module = sys.modules[__name__]
+
+        #
+        # Locals
+        #
+        locals = []
+        fullUpdateNeeded = True
+        if self.partialUpdate and len(varList) == 1 and not self.tooltipOnly:
+            #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 = LocalItem()
+                item.iname = "local." + name
+                item.name = name
+                item.value = frame.read_var(name)
+                locals = [item]
+                #warn("PARTIAL LOCALS: %s" % locals)
+                fullUpdateNeeded = False
+            except:
+                pass
+            varList = []
+
+        if fullUpdateNeeded and not self.tooltipOnly and not self.noLocals:
+            locals = listOfLocals(varList)
+
+        if "autotest" in options:
+            for item in listOfLocals([]):
+                self.expandedINames.add(item.iname)
+                self.expandedINames.discard("")
+                #warn("EXPANDED: %s" % self.expandedINames)
+
+        # Take care of the return value of the last function call.
+        if len(resultVarName) > 0:
+            try:
+                item = LocalItem()
+                item.name = resultVarName
+                item.iname = "return." + resultVarName
+                item.value = parseAndEvaluate(resultVarName)
+                locals.append(item)
+            except:
+                # Don't bother. It's only supplementary information anyway.
+                pass
+
+        for item in locals:
+            value = downcast(item.value) if self.useDynamicType else item.value
+            with OutputSafer(self):
+                self.anonNumber = -1
+
+                type = value.type.unqualified()
+                typeName = str(type)
+
+                # Special handling for char** argv.
+                if type.code == PointerCode \
+                        and item.iname == "local.argv" \
+                        and typeName == "char **":
+                    n = 0
+                    p = value
+                    # p is 0 for "optimized out" cases. Or contains rubbish.
+                    try:
+                        if not isNull(p):
+                            while not isNull(p.dereference()) and n <= 100:
+                                p += 1
+                                n += 1
+                    except:
+                        pass
+
+                    with TopLevelItem(self, item.iname):
+                        self.put('iname="local.argv",name="argv",')
+                        self.putItemCount(n, 100)
+                        self.putType(typeName)
+                        self.putNumChild(n)
+                        if self.currentIName in self.expandedINames:
+                            p = value
+                            with Children(self, n):
+                                for i in xrange(n):
+                                    self.putSubItem(i, p.dereference())
+                                    p += 1
+                    continue
+
+                else:
+                    # A "normal" local variable or parameter.
+                    with TopLevelItem(self, item.iname):
+                        self.put('iname="%s",' % item.iname)
+                        self.put('name="%s",' % item.name)
+                        self.putItem(value)
+
+        #
+        # Watchers
+        #
+        with OutputSafer(self):
+            if len(watchers) > 0:
+                self.put(",")
+                for watcher in watchers.split("##"):
+                    (exp, iname) = watcher.split("#")
+                    self.handleWatch(exp, iname)
+
+        #print('data=[' + locals + sep + watchers + ']\n')
+
+
+    def handleWatch(self, exp, iname):
+        exp = str(exp)
+        escapedExp = base64.b64encode(exp);
+        #warn("HANDLING WATCH %s, INAME: '%s'" % (exp, iname))
+        if exp.startswith("[") and exp.endswith("]"):
+            #warn("EVAL: EXP: %s" % exp)
+            with TopLevelItem(self, iname):
+                self.put('iname="%s",' % iname)
+                self.put('wname="%s",' % escapedExp)
+                try:
+                    list = eval(exp)
+                    self.putValue("")
+                    self.putNoType()
+                    self.putNumChild(len(list))
+                    # This is a list of expressions to evaluate
+                    with Children(self, len(list)):
+                        itemNumber = 0
+                        for item in list:
+                            self.handleWatch(item, "%s.%d" % (iname, itemNumber))
+                            itemNumber += 1
+                except RuntimeError, error:
+                    warn("EVAL: ERROR CAUGHT %s" % error)
+                    self.putValue("<syntax error>")
+                    self.putNoType()
+                    self.putNumChild(0)
+                    self.put("children=[],")
+            return
+
+        with TopLevelItem(self, iname):
+            self.put('iname="%s",' % iname)
+            self.put('wname="%s",' % escapedExp)
+            if len(exp) == 0: # The <Edit> case
+                self.putValue(" ")
+                self.putNoType()
+                self.putNumChild(0)
+            else:
+                try:
+                    value = parseAndEvaluate(exp)
+                    self.putItem(value)
+                except RuntimeError:
+                    self.currentType = " "
+                    self.currentValue = "<no such value>"
+                    self.currentChildNumChild = -1
+                    self.currentNumChild = 0
+                    self.putNumChild(0)
+
+
+    def put(self, value):
+        self.output.append(value)
+
+    def putField(self, name, value):
+        self.put('%s="%s",' % (name, value))
+
+    def childRange(self):
+        if self.currentMaxNumChild is None:
+            return xrange(0, self.currentNumChild)
+        return xrange(min(self.currentMaxNumChild, self.currentNumChild))
+
+    # Convenience function.
+    def putItemCount(self, count, maximum = 1000000000):
+        # This needs to override the default value, so don't use 'put' directly.
+        if count > maximum:
+            self.putValue('<>%s items>' % maximum)
+        else:
+            self.putValue('<%s items>' % count)
+
+    def putType(self, type, priority = 0):
+        # Higher priority values override lower ones.
+        if priority >= self.currentTypePriority:
+            self.currentType = str(type)
+            self.currentTypePriority = priority
+
+    def putNoType(self):
+        # FIXME: replace with something that does not need special handling
+        # in SubItem.__exit__().
+        self.putBetterType(" ")
+
+    def putInaccessible(self):
+        #self.putBetterType(" ")
+        self.putNumChild(0)
+        self.currentValue = None
+
+    def putBetterType(self, type, priority = 0):
+        self.currentType = str(type)
+        self.currentTypePriority = self.currentTypePriority + 1
+
+    def putAddress(self, addr):
+        if self.currentPrintsAddress:
+            try:
+                # addr can be "None", long(None) fails.
+                #self.put('addr="0x%x",' % long(addr))
+                self.currentAddress = 'addr="0x%x",' % long(addr)
+            except:
+                pass
+
+    def putNumChild(self, numchild):
+        #warn("NUM CHILD: '%s' '%s'" % (numchild, self.currentChildNumChild))
+        if numchild != self.currentChildNumChild:
+            self.put('numchild="%s",' % numchild)
+
+    def putEmptyValue(self, priority = -10):
+        if priority >= self.currentValuePriority:
+            self.currentValue = ""
+            self.currentValuePriority = priority
+            self.currentValueEncoding = None
+
+    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
+
+    def putPointerValue(self, value):
+        # Use a lower priority
+        if value is None:
+            self.putEmptyValue(-1)
+        else:
+            self.putValue("0x%x" % value.cast(
+                lookupType("unsigned long")), None, -1)
+
+    def putStringValue(self, value, priority = 0):
+        if not value is None:
+            str = encodeString(value)
+            self.putValue(str, Hex4EncodedLittleEndian, priority)
+
+    def putDisplay(self, format, value = None, cmd = None):
+        self.put('editformat="%s",' % format)
+        if cmd is None:
+            if not value is None:
+                self.put('editvalue="%s",' % value)
+        else:
+            self.put('editvalue="%s|%s",' % (cmd, value))
+
+    def putByteArrayValue(self, value):
+        str = encodeByteArray(value)
+        self.putValue(str, Hex2EncodedLatin1)
+
+    def putName(self, name):
+        self.put('name="%s",' % name)
+
+    def putMapName(self, value):
+        ns = qtNamespace()
+        if str(value.type) == ns + "QString":
+            self.put('key="%s",' % encodeString(value))
+            self.put('keyencoded="%s",' % Hex4EncodedLittleEndian)
+        elif str(value.type) == ns + "QByteArray":
+            self.put('key="%s",' % encodeByteArray(value))
+            self.put('keyencoded="%s",' % Hex2EncodedLatin1)
+        else:
+            self.put('name="%s",' % value)
+
+    def isExpanded(self):
+        #warn("IS EXPANDED: %s in %s: %s" % (self.currentIName,
+        #    self.expandedINames, self.currentIName in self.expandedINames))
+        return self.currentIName in self.expandedINames
+
+    def isExpandedSubItem(self, component):
+        iname = "%s.%s" % (self.currentIName, component)
+        #warn("IS EXPANDED: %s in %s" % (iname, self.expandedINames))
+        return iname in self.expandedINames
+
+    def stripNamespaceFromType(self, typeName):
+        type = stripClassTag(typeName)
+        if len(self.ns) > 0 and type.startswith(self.ns):
+            type = type[len(self.ns):]
+        pos = type.find("<")
+        # FIXME: make it recognize  foo<A>::bar<B>::iterator?
+        while pos != -1:
+            pos1 = type.rfind(">", pos)
+            type = type[0:pos] + type[pos1+1:]
+            pos = type.find("<")
+        return type
+
+    def isMovableType(self, type):
+        if type.code == PointerCode:
+            return True
+        if isSimpleType(type):
+            return True
+        return self.stripNamespaceFromType(str(type)) in movableTypes
+
+    def putIntItem(self, name, value):
+        with SubItem(self, name):
+            self.putValue(value)
+            self.putType("int")
+            self.putNumChild(0)
+
+    def putBoolItem(self, name, value):
+        with SubItem(self, name):
+            self.putValue(value)
+            self.putType("bool")
+            self.putNumChild(0)
+
+    def currentItemFormat(self):
+        format = self.formats.get(self.currentIName)
+        if format is None:
+            format = self.typeformats.get(stripForFormat(str(self.currentType)))
+        return format
+
+    def putSubItem(self, component, value, tryDynamic=True):
+        with SubItem(self, component):
+            self.putItem(value, tryDynamic)
+
+    def putNamedSubItem(self, component, value, name):
+        with SubItem(self, component):
+            self.putName(name)
+            self.putItem(value)
+
+    def tryPutArrayContents(self, typeobj, base, n):
+        if not isSimpleType(typeobj):
+            return False
+        size = n * typeobj.sizeof;
+        self.put('childtype="%s",' % typeobj)
+        self.put('addrbase="0x%x",' % long(base))
+        self.put('addrstep="0x%x",' % long(typeobj.sizeof))
+        self.put('arrayencoding="%s",' % simpleEncoding(typeobj))
+        self.put('arraydata="')
+        self.put(readRawMemory(base, size))
+        self.put('",')
+        return True
+
+    def putPlotData(self, type, base, n, plotFormat):
+        if self.isExpanded():
+            self.putArrayData(type, base, n)
+        if not hasPlot():
+            return
+        if not isSimpleType(type):
+            #self.putValue(self.currentValue + " (not plottable)")
+            self.putValue(self.currentValue)
+            self.putField("plottable", "0")
+            return
+        global gnuplotPipe
+        global gnuplotPid
+        format = self.currentItemFormat()
+        iname = self.currentIName
+        #if False:
+        if format != plotFormat:
+            if iname in gnuplotPipe:
+                os.kill(gnuplotPid[iname], 9)
+                del gnuplotPid[iname]
+                gnuplotPipe[iname].terminate()
+                del gnuplotPipe[iname]
+            return
+        base = base.cast(type.pointer())
+        if not iname in gnuplotPipe:
+            gnuplotPipe[iname] = subprocess.Popen(["gnuplot"],
+                    stdin=subprocess.PIPE)
+            gnuplotPid[iname] = gnuplotPipe[iname].pid
+        f = gnuplotPipe[iname].stdin;
+        f.write("set term wxt noraise\n")
+        f.write("set title 'Data fields'\n")
+        f.write("set xlabel 'Index'\n")
+        f.write("set ylabel 'Value'\n")
+        f.write("set grid\n")
+        f.write("set style data lines;\n")
+        f.write("plot  '-' title '%s'\n" % iname)
+        for i in range(1, n):
+            f.write(" %s\n" % base.dereference())
+            base += 1
+        f.write("e\n")
+
+
+    def putArrayData(self, type, base, n,
+            childNumChild = None, maxNumChild = 10000):
+        base = base.cast(type.pointer())
+        if not self.tryPutArrayContents(type, base, n):
+            with Children(self, n, type, childNumChild, maxNumChild,
+                    base, type.sizeof):
+                for i in self.childRange():
+                    self.putSubItem(i, (base + i).dereference())
+
+
+    def putCallItem(self, name, value, func, *args):
+        result = call2(value, func, args)
+        with SubItem(self, name):
+            self.putItem(result)
+
+    def putItem(self, value, tryDynamic=True):
+        if value is None:
+            # Happens for non-available watchers in gdb versions that
+            # need to use gdb.execute instead of gdb.parse_and_eval
+            self.putValue("<not available>")
+            self.putType("<unknown>")
+            self.putNumChild(0)
+            return
+
+        global qqDumpers, qqFormats
+
+        type = value.type.unqualified()
+        typeName = str(type)
+        tryDynamic &= self.useDynamicType
+        lookupType(typeName) # Fill type cache
+        if tryDynamic:
+            self.putAddress(value.address)
+
+        # FIXME: Gui shows references stripped?
+        #warn(" ")
+        #warn("REAL INAME: %s " % self.currentIName)
+        #warn("REAL TYPE: %s " % value.type)
+        #warn("REAL CODE: %s " % value.type.code)
+        #warn("REAL VALUE: %s " % value)
+
+        if type.code == ReferenceCode:
+            try:
+                # Try to recognize null references explicitly.
+                if long(value.address) == 0:
+                    self.putValue("<null reference>")
+                    self.putType(typeName)
+                    self.putNumChild(0)
+                    return
+            except:
+                pass
+
+            if tryDynamic:
+                try:
+                    # Dynamic references are not supported by gdb, see
+                    # http://sourceware.org/bugzilla/show_bug.cgi?id=14077.
+                    # Find the dynamic type manually using referenced_type.
+                    value = value.referenced_value()
+                    value = value.cast(value.dynamic_type)
+                    self.putItem(value)
+                    self.putBetterType("%s &" % value.type)
+                    return
+                except:
+                    pass
+
+            try:
+                # FIXME: This throws "RuntimeError: Attempt to dereference a
+                # generic pointer." with MinGW's gcc 4.5 when it "identifies"
+                # a "QWidget &" as "void &" and with optimized out code.
+                self.putItem(value.cast(type.target().unqualified()))
+                self.putBetterType(typeName)
+                return
+            except RuntimeError:
+                self.putValue("<optimized out reference>")
+                self.putType(typeName)
+                self.putNumChild(0)
+                return
+
+        if type.code == IntCode or type.code == CharCode or type.code == SimpleValueCode:
+            self.putType(typeName)
+            if value.is_optimized_out:
+                self.putValue("<optimized out>")
+            else:
+                self.putValue(value)
+            self.putNumChild(0)
+            return
+
+        if type.code == FloatCode or type.code == BoolCode:
+            self.putType(typeName)
+            if value.is_optimized_out:
+                self.putValue("<optimized out>")
+            else:
+                self.putValue(value)
+            self.putNumChild(0)
+            return
+
+        if type.code == EnumCode:
+            self.putType(typeName)
+            if value.is_optimized_out:
+                self.putValue("<optimized out>")
+            else:
+                self.putValue("%s (%d)" % (value, value))
+            self.putNumChild(0)
+            return
+
+        if type.code == ComplexCode:
+            self.putType(typeName)
+            if value.is_optimized_out:
+                self.putValue("<optimized out>")
+            else:
+                self.putValue("%s" % value)
+            self.putNumChild(0)
+            return
+
+        if type.code == TypedefCode:
+            if typeName in qqDumpers:
+                self.putType(typeName)
+                qqDumpers[typeName](self, value)
+                return
+
+            type = stripTypedefs(type)
+            # The cast can destroy the address?
+            #self.putAddress(value.address)
+            # Workaround for http://sourceware.org/bugzilla/show_bug.cgi?id=13380
+            if type.code == ArrayCode:
+                value = parseAndEvaluate("{%s}%s" % (type, value.address))
+            else:
+                try:
+                    value = value.cast(type)
+                except:
+                    self.putValue("<optimized out typedef>")
+                    self.putType(typeName)
+                    self.putNumChild(0)
+                    return
+
+            self.putItem(value)
+            self.putBetterType(typeName)
+            return
+
+        if type.code == ArrayCode:
+            qdump____c_style_array__(self, value)
+            return
+
+        if type.code == PointerCode:
+            #warn("POINTER: %s" % value)
+
+            # This could still be stored in a register and
+            # potentially dereferencable.
+            if value.is_optimized_out:
+                self.putValue("<optimized out>")
+
+            try:
+                value.dereference()
+            except:
+                # Failure to dereference a pointer should at least
+                # show the value of a pointer.
+                self.putValue(cleanAddress(value))
+                self.putType(typeName)
+                self.putNumChild(0)
+                return
+
+            if isNull(value):
+                #warn("NULL POINTER")
+                self.putType(typeName)
+                self.putValue("0x0")
+                self.putNumChild(0)
+                return
+
+            innerType = type.target()
+            innerTypeName = str(innerType.unqualified())
+            format = self.formats.get(self.currentIName)
+            if format is None:
+                format = self.typeformats.get(stripForFormat(str(type)))
+
+            if innerType.code == VoidCode:
+                #warn("VOID POINTER: %s" % format)
+                self.putType(typeName)
+                self.putValue(str(value))
+                self.putNumChild(0)
+                return
+
+            if format == None and innerTypeName == "char":
+                # Use Latin1 as default for char *.
+                self.putType(typeName)
+                self.putValue(encodeCharArray(value), Hex2EncodedLatin1)
+                self.putNumChild(0)
+                return
+
+            if format == 0:
+                # Explicitly requested bald pointer.
+                self.putType(typeName)
+                self.putPointerValue(value)
+                self.putNumChild(1)
+                if self.currentIName in self.expandedINames:
+                    with Children(self):
+                        with SubItem(self, '*'):
+                            self.putItem(value.dereference())
+                return
+
+            if format == 1:
+                # Explicitly requested Latin1 formatting.
+                self.putType(typeName)
+                self.putValue(encodeCharArray(value), Hex2EncodedLatin1)
+                self.putNumChild(0)
+                return
+
+            if format == 2:
+                # Explicitly requested UTF-8 formatting.
+                self.putType(typeName)
+                self.putValue(encodeCharArray(value), Hex2EncodedUtf8)
+                self.putNumChild(0)
+                return
+
+            if format == 3:
+                # Explicitly requested local 8 bit formatting.
+                self.putType(typeName)
+                self.putValue(encodeCharArray(value), Hex2EncodedLocal8Bit)
+                self.putNumChild(0)
+                return
+
+            if format == 4:
+                # Explicitly requested UTF-16 formatting.
+                self.putType(typeName)
+                self.putValue(encodeChar2Array(value), Hex4EncodedLittleEndian)
+                self.putNumChild(0)
+                return
+
+            if format == 5:
+                # Explicitly requested UCS-4 formatting.
+                self.putType(typeName)
+                self.putValue(encodeChar4Array(value), Hex8EncodedLittleEndian)
+                self.putNumChild(0)
+                return
+
+            if innerType.code == MethodCode or innerType.code == FunctionCode:
+                # A function pointer with format None.
+                self.putValue(str(value))
+                self.putType(typeName)
+                self.putNumChild(0)
+                return
+
+            #warn("AUTODEREF: %s" % self.autoDerefPointers)
+            #warn("INAME: %s" % self.currentIName)
+            if self.autoDerefPointers or self.currentIName.endswith('.this'):
+                ## Generic pointer type with format None
+                #warn("GENERIC AUTODEREF POINTER: %s AT %s TO %s"
+                #    % (type, value.address, innerTypeName))
+                # Never dereference char types.
+                if innerTypeName != "char" \
+                        and innerTypeName != "signed char" \
+                        and innerTypeName != "unsigned char"  \
+                        and innerTypeName != "wchar_t":
+                    self.putType(innerType)
+                    savedCurrentChildType = self.currentChildType
+                    self.currentChildType = stripClassTag(innerTypeName)
+                    self.putItem(value.dereference())
+                    self.currentChildType = savedCurrentChildType
+                    #self.putPointerValue(value)
+                    self.put('origaddr="%s",' % value.address)
+                    return
+
+            # Fall back to plain pointer printing.
+            #warn("GENERIC PLAIN POINTER: %s" % value.type)
+            #warn("ADDR PLAIN POINTER: %s" % value.address)
+            self.putType(typeName)
+            self.putField("aaa", "1")
+            #self.put('addr="0x%x",' % long(value.address))
+            #self.putAddress(value.address)
+            self.putField("bbb", "1")
+            #self.putPointerValue(value)
+            self.putValue("0x%x" % value.cast(lookupType("unsigned long")))
+            self.putField("ccc", "1")
+            self.putNumChild(1)
+            if self.currentIName in self.expandedINames:
+                with Children(self):
+                    with SubItem(self, "*"):
+                        self.putItem(value.dereference())
+            return
+
+        if type.code == MethodPointerCode \
+                or type.code == MethodCode \
+                or type.code == FunctionCode \
+                or type.code == MemberPointerCode:
+            self.putType(typeName)
+            self.putValue(value)
+            self.putNumChild(0)
+            return
+
+        if typeName.startswith("<anon"):
+            # Anonymous union. We need a dummy name to distinguish
+            # multiple anonymous unions in the struct.
+            self.putType(type)
+            self.putValue("{...}")
+            self.anonNumber += 1
+            with Children(self, 1):
+                self.listAnonymous(value, "#%d" % self.anonNumber, type)
+            return
+
+        if type.code != StructCode and type.code != UnionCode:
+            warn("WRONG ASSUMPTION HERE: %s " % type.code)
+            check(False)
+
+
+        if tryDynamic:
+            self.putItem(expensiveDowncast(value), False)
+            return
+
+        format = self.formats.get(self.currentIName)
+        if format is None:
+            format = self.typeformats.get(stripForFormat(typeName))
+
+        if self.useFancy and (format is None or format >= 1):
+            self.putType(typeName)
+
+            nsStrippedType = self.stripNamespaceFromType(typeName)\
+                .replace("::", "__")
+
+            # The following block is only needed for D.
+            if nsStrippedType.startswith("_A"):
+                # DMD v2.058 encodes string[] as _Array_uns long long.
+                # With spaces.
+                if nsStrippedType.startswith("_Array_"):
+                    qdump_Array(self, value)
+                    return
+                if nsStrippedType.startswith("_AArray_"):
+                    qdump_AArray(self, value)
+                    return
+
+            #warn(" STRIPPED: %s" % nsStrippedType)
+            #warn(" DUMPERS: %s" % qqDumpers)
+            #warn(" DUMPERS: %s" % (nsStrippedType in qqDumpers))
+            dumper = qqDumpers.get(nsStrippedType, None)
+            if not dumper is None:
+                if tryDynamic:
+                    dumper(self, expensiveDowncast(value))
+                else:
+                    dumper(self, value)
+                return
+
+        # D arrays, gdc compiled.
+        if typeName.endswith("[]"):
+            n = value["length"]
+            base = value["ptr"]
+            self.putType(typeName)
+            self.putItemCount(n)
+            if self.isExpanded():
+                self.putArrayData(base.type.target(), base, n)
+            return
+
+        #warn("GENERIC STRUCT: %s" % type)
+        #warn("INAME: %s " % self.currentIName)
+        #warn("INAMES: %s " % self.expandedINames)
+        #warn("EXPANDED: %s " % (self.currentIName in self.expandedINames))
+        self.tryPutObjectNameValue(value)  # Is this too expensive?
+        self.putType(typeName)
+        self.putEmptyValue()
+        self.putNumChild(fieldCount(type))
+
+        if self.currentIName in self.expandedINames:
+            innerType = None
+            with Children(self, 1, childType=innerType):
+                self.putFields(value)
+
+    def putPlainChildren(self, value):
+        self.putEmptyValue(-99)
+        self.putNumChild(1)
+        if self.currentIName in self.expandedINames:
+            with Children(self):
+               self.putFields(value)
+
+    def tryPutObjectNameValue(self, value):
+        try:
+            # Is this derived from QObject?
+            dd = value["d_ptr"]["d"]
+            privateTypeName = self.ns + "QObjectPrivate"
+            privateType = lookupType(privateTypeName)
+            staticMetaObject = value["staticMetaObject"]
+            d_ptr = dd.cast(privateType.pointer()).dereference()
+            objectName = None
+            try:
+                objectName = d_ptr["objectName"]
+            except: # Qt 5
+                p = d_ptr["extraData"]
+                if not isNull(p):
+                    objectName = p.dereference()["objectName"]
+            if not objectName is None:
+                data, size, alloc = qStringData(objectName)
+                if size > 0:
+                    str = readRawMemory(data, 2 * size)
+                    self.putValue(str, Hex4EncodedLittleEndian, 1)
+        except:
+            pass
+
+    def putFields(self, value, dumpBase = True):
+        fields = extractFields(value)
+
+        # FIXME: Merge into this function.
+        if gdbLoaded:
+            self.putFieldsGdb(fields, value, dumpBase)
+            return
+
+        for field in fields:
+            with SubItem(self, field.name):
+                self.putItem(field)
+
+    def putFieldsGdb(self, fields, value, dumpBase):
+            #warn("TYPE: %s" % type)
+            #warn("FIELDS: %s" % fields)
+            baseNumber = 0
+            for field in fields:
+                #warn("FIELD: %s" % field)
+                #warn("  BITSIZE: %s" % field.bitsize)
+                #warn("  ARTIFICIAL: %s" % field.artificial)
+
+                if field.name is None:
+                    type = stripTypedefs(value.type)
+                    innerType = type.target()
+                    p = value.cast(innerType.pointer())
+                    for i in xrange(type.sizeof / innerType.sizeof):
+                        with SubItem(self, i):
+                            self.putItem(p.dereference())
+                        p = p + 1
+                    continue
+
+                # Ignore vtable pointers for virtual inheritance.
+                if field.name.startswith("_vptr."):
+                    with SubItem(self, "[vptr]"):
+                        # int (**)(void)
+                        n = 100
+                        self.putType(" ")
+                        self.putValue(value[field.name])
+                        self.putNumChild(n)
+                        if self.isExpanded():
+                            with Children(self):
+                                p = value[field.name]
+                                for i in xrange(n):
+                                    if long(p.dereference()) != 0:
+                                        with SubItem(self, i):
+                                            self.putItem(p.dereference())
+                                            self.putType(" ")
+                                            p = p + 1
+                    continue
+
+                #warn("FIELD NAME: %s" % field.name)
+                #warn("FIELD TYPE: %s" % field.type)
+                if field.is_base_class:
+                    # Field is base type. We cannot use field.name as part
+                    # of the iname as it might contain spaces and other
+                    # strange characters.
+                    if dumpBase:
+                        baseNumber += 1
+                        with UnnamedSubItem(self, "@%d" % baseNumber):
+                            self.put('iname="%s",' % self.currentIName)
+                            self.put('name="[%s]",' % field.name)
+                            self.putItem(value.cast(field.type), False)
+                elif len(field.name) == 0:
+                    # Anonymous union. We need a dummy name to distinguish
+                    # multiple anonymous unions in the struct.
+                    self.anonNumber += 1
+                    self.listAnonymous(value, "#%d" % self.anonNumber,
+                        field.type)
+                else:
+                    # Named field.
+                    with SubItem(self, field.name):
+                        #bitsize = getattr(field, "bitsize", None)
+                        #if not bitsize is None:
+                        #    self.put("bitsize=\"%s\"" % bitsize)
+                        self.putItem(downcast(value[field.name]))
+
+
+    def listAnonymous(self, value, name, type):
+        for field in type.fields():
+            #warn("FIELD NAME: %s" % field.name)
+            if len(field.name) > 0:
+                with SubItem(self, field.name):
+                    self.putItem(value[field.name])
+            else:
+                # Further nested.
+                self.anonNumber += 1
+                name = "#%d" % self.anonNumber
+                #iname = "%s.%s" % (selitem.iname, name)
+                #child = SameItem(item.value, iname)
+                with SubItem(self, name):
+                    self.put('name="%s",' % name)
+                    self.putEmptyValue()
+                    fieldTypeName = str(field.type)
+                    if fieldTypeName.endswith("<anonymous union>"):
+                        self.putType("<anonymous union>")
+                    elif fieldTypeName.endswith("<anonymous struct>"):
+                        self.putType("<anonymous struct>")
+                    else:
+                        self.putType(fieldTypeName)
+                    with Children(self, 1):
+                        self.listAnonymous(value, name, field.type)
+
+#######################################################################
+#
+# ThreadNames Command
+#
+#######################################################################
+
+def threadnames(arg):
+    ns = qtNamespace()
+    out = '['
+    oldthread = gdb.selected_thread()
+    try:
+        inferior = selectedInferior()
+        for thread in inferior.threads():
+            maximalStackDepth = int(arg)
+            thread.switch()
+            e = gdb.selected_frame ()
+            while True:
+                maximalStackDepth -= 1
+                if maximalStackDepth < 0:
+                    break
+                e = e.older()
+                if e == None or e.name() == None:
+                    break
+                if e.name() == ns + "QThreadPrivate::start":
+                    try:
+                        thrptr = e.read_var("thr").dereference()
+                        obtype = lookupType(ns + "QObjectPrivate").pointer()
+                        d_ptr = thrptr["d_ptr"]["d"].cast(obtype).dereference()
+                        objectName = d_ptr["objectName"]
+                        out += '{valueencoded="';
+                        out += str(Hex4EncodedLittleEndianWithoutQuotes)+'",id="'
+                        out += str(thread.num) + '",value="'
+                        out += encodeString(objectName)
+                        out += '"},'
+                    except:
+                        pass
+    except:
+        pass
+    oldthread.switch()
+    return out + ']'
+
+registerCommand("threadnames", threadnames)
+
+
+#######################################################################
+#
+# Mixed C++/Qml debugging
+#
+#######################################################################
+
+def qmlb(args):
+    # executeCommand(command, to_string=True).split("\n")
+    warm("RUNNING: break -f QScript::FunctionWrapper::proxyCall")
+    output = catchCliOutput("rbreak -f QScript::FunctionWrapper::proxyCall")
+    warn("OUTPUT: %s " % output)
+    bp = output[0]
+    warn("BP: %s " % bp)
+    # BP: ['Breakpoint 3 at 0xf166e7: file .../qscriptfunction.cpp, line 75.\\n'] \n"
+    pos = bp.find(' ') + 1
+    warn("POS: %s " % pos)
+    nr = bp[bp.find(' ') + 1 : bp.find(' at ')]
+    warn("NR: %s " % nr)
+    return bp
+
+registerCommand("qmlb", qmlb)
 gdbLoaded = True
+
 currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
-execfile(os.path.join(currentDir, "dumper.py"))
 execfile(os.path.join(currentDir, "qttypes.py"))
 
 bbsetup()