diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py
new file mode 100644
index 0000000000000000000000000000000000000000..1de980315742830cc6af1142e97c4c8405d3b7f5
--- /dev/null
+++ b/share/qtcreator/gdbmacros/dumper.py
@@ -0,0 +1,603 @@
+
+#Note: Keep name-type-value-numchild-extra order
+
+#return
+
+import sys
+import traceback
+import gdb
+#import base64
+import types
+import curses.ascii
+
+verbosity = 0
+verbosity = 1
+
+def isSimpleType(typeobj):
+    type = str(typeobj)
+    return type == "bool" \
+        or type == "char" \
+        or type == "double" \
+        or type == "float" \
+        or type == "int" \
+        or type == "long" or type.startswith("long ") \
+        or type == "short" or type.startswith("short ") \
+        or type == "signed" or  type.startswith("signed ") \
+        or type == "unsigned" or type.startswith("unsigned ")
+
+def isStringType(d, typeobj):
+    type = str(typeobj)
+    return type == d.ns + "QString" \
+        or type == d.ns + "QByteArray" \
+        or type == "std::string" \
+        or type == "std::wstring" \
+        or type == "wstring"
+
+def warn(message):
+    if verbosity > 0:
+        print "XXX: %s " % message.encode("latin1")
+    pass
+
+def check(exp):
+    if not exp:
+        raise RuntimeError("Check failed")
+
+#def couldBePointer(p, align):
+#    type = gdb.lookup_type("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 isNull(p):
+    s = str(p)
+    return s == "0x0" or s.startswith("0x0 ")
+
+movableTypes = set([
+    "QBrush", "QBitArray", "QByteArray",
+    "QCustomTypeInfo", "QChar",
+    "QDate", "QDateTime",
+    "QFileInfo", "QFixed", "QFixedPoint", "QFixedSize",
+    "QHashDummyValue",
+    "QIcon", "QImage",
+    "QLine", "QLineF", "QLatin1Char", "QLocal",
+    "QMatrix", "QModelIndex",
+    "QPoint", "QPointF", "QPen", "QPersistentModelIndex",
+    "QResourceRoot", "QRect", "QRectF", "QRegExp",
+    "QSize", "QSizeF", "QString",
+    "QTime", "QTextBlock",
+    "QUrl",
+    "QVariant",
+    "QXmlStreamAttribute", "QXmlStreamNamespaceDeclaration",
+    "QXmlStreamNotationDeclaration", "QXmlStreamEntityDeclaration"])
+
+
+def stripClassTag(type):
+    if type.startswith("class "):
+        return type[6:]
+    return type
+
+def checkPointerRange(p, n):
+    for i in xrange(0, n):
+        checkPointer(p)
+        ++p
+
+def call(value, func):
+    #warn("CALL: %s -> %s" % (value, func))
+    type = stripClassTag(str(value.type))
+    if type.find(':') >= 0:
+        type = "'" + type + "'"
+    exp = "((%s*)%s)->%s" % (type, value.address, func)
+    #warn("CALL: %s" % exp)
+    result = gdb.parse_and_eval(exp)
+    #warn("  -> %s" % result)
+    return result
+
+
+#######################################################################
+#
+# Item
+#
+#######################################################################
+
+class Item:
+    def __init__(self, value, parentiname, iname, name):
+        self.value = value
+        self.iname = parentiname if iname is None else "%s.%s" % (parentiname, iname)
+        self.name = name
+
+
+#######################################################################
+#
+# FrameCommand
+#
+#######################################################################
+
+class FrameCommand(gdb.Command):
+    """Do fancy stuff. Usage bb --verbose expandedINames"""
+
+    def __init__(self):
+        super(FrameCommand, self).__init__("bb", gdb.COMMAND_OBSCURE)
+
+    def invoke(self, arg, from_tty):
+        print('locals={iname="local",name="Locals",value=" ",type=" ",'
+            + 'children=[%s]}' % self.doit(arg).encode("latin1"))
+
+    def doit(self, arg):
+        args = arg.split(' ')
+        #warn("ARG: %s" % arg)
+        #warn("ARGS: %s" % args)
+        useFancy = int(args[0])
+        passExceptions = int(args[1])
+        expandedINames = set()
+        if len(args) > 2:
+            expandedINames = set(args[2].split(','))
+        watchers = set()
+        if len(args) > 3:
+            watchers = set(args[3].split(','))
+        #warn("EXPANDED INAMES: %s" % expandedINames)
+        #warn("WATCHERS: %s" % watchers)
+        module = sys.modules[__name__]
+        self.dumpers = {}
+
+        if useFancy:
+            for key, value in module.__dict__.items():
+                #if callable(value):
+                if key.startswith("qqDump"):
+                    self.dumpers[key[6:]] = value
+            self.dumpers["std__deque"]        = qqDumpStdDeque
+            self.dumpers["std__list"]         = qqDumpStdList
+            self.dumpers["std__map"]          = qqDumpStdMap
+            self.dumpers["std__set"]          = qqDumpStdSet
+            self.dumpers["std__vector"]       = qqDumpStdVector
+            self.dumpers["string"]            = qqDumpStdString
+            self.dumpers["std__string"]       = qqDumpStdString
+            self.dumpers["std__wstring"]      = qqDumpStdString
+            self.dumpers["std__basic_string"] = qqDumpStdString
+            self.dumpers["wstring"]           = qqDumpStdString
+            # Hack to work around gdb bug #10898
+            #self.dumpers["QString::string"]     = qqDumpStdString
+            #warn("DUMPERS: %s " % self.dumpers)
+
+        try:
+            frame = gdb.selected_frame()
+        except RuntimeError as ex:
+            return ""
+
+        d = Dumper()
+        d.dumpers = self.dumpers
+        d.passExceptions = passExceptions
+        block = frame.block()
+
+        # initialize namespace
+        type = str(gdb.parse_and_eval("&QString::null").type.target().unqualified())
+        d.ns = type[0:len(type) - len("QString::Null")]
+        #warn(" NAMESPACE IS: '%s'" % d.ns)
+        #warn("FRAME %s: " % frame)
+
+        while True:
+            if block is None:
+                warn("UNEXPECTED 'None' BLOCK")
+                break
+            for symbol in block:
+                name = symbol.print_name
+                
+                if name == "__in_chrg":
+                    continue
+
+                # "NotImplementedError: Symbol type not yet supported in
+                # Python scripts."
+                #warn("SYMBOL %s: " % symbol.value)
+                #warn("SYMBOL %s  (%s): " % (symbol, name))
+                item = Item(0, "local", name, name)
+                try:
+                    item.value = frame.read_var(name)  # this is a gdb value
+                except RuntimeError:
+                    # happens for  void foo() { std::string s; std::wstring w; }
+                    #warn("  FRAME READ VAR ERROR: %s (%s): " % (symbol, name))
+                    continue
+                #warn("ITEM %s: " % item.value)
+
+                d.expandedINames = expandedINames
+                d.useFancy = useFancy
+                d.beginHash()
+                d.putField("iname", item.iname)
+                d.put(",")
+
+                d.safePutItemHelper(item)
+
+                d.endHash()
+
+            # The outermost block in a function has the function member
+            # FIXME: check whether this is guaranteed.
+            if not block.function is None:
+                break
+
+            block = block.superblock
+
+        d.pushOutput()
+        return d.safeoutput
+
+FrameCommand()
+
+
+
+#######################################################################
+#
+# The Dumper Class
+#
+#######################################################################
+
+class Dumper:
+    def __init__(self):
+        self.output = ""
+        self.safeoutput = ""
+        self.childTypes = [""]
+        self.childNumChilds = [-1]
+
+    def put(self, value):
+        self.output += value
+
+    def putCommaIfNeeded(self):
+        c = self.output[-1:]
+        if c == '}' or c == '"' or c == ']' or c == '\n':
+            self.put(',')
+        #warn("C:'%s' COND:'%d' OUT:'%s'" %
+        #    (c, c == '}' or c == '"' or c == ']' or c == '\n', self.output))
+
+    def putField(self, name, value):
+        self.putCommaIfNeeded()
+        self.put('%s="%s"' % (name, value))
+
+    def beginHash(self):
+        self.putCommaIfNeeded()
+        self.put('{')
+
+    def endHash(self):
+        self.put('}')
+
+    def beginItem(self, name):
+        self.putCommaIfNeeded()
+        self.put(name)
+        self.put('="')
+
+    def endItem(self):
+        self.put('"')
+
+    def beginChildren(self, type = None, children = None):
+        childType = ""
+        childNumChild = -1
+        if not type is None:
+            childType = stripClassTag(str(type))
+            self.putField("childtype", childType)
+            if isSimpleType(type) or isStringType(self, type):
+                self.putField("childnumchild", "0")
+                childNumChild = 0
+            elif type.code == gdb.TYPE_CODE_PTR:
+                self.putField("childnumchild", "1")
+                childNumChild = 1
+        if not children is None:
+            self.putField("childnumchild", children)
+            childNumChild = children
+        self.childTypes.append(childType)
+        self.childNumChilds.append(childNumChild)
+        #warn("BEGIN: %s" % self.childTypes)
+        self.putCommaIfNeeded()
+        self.put("children=[")
+
+    def endChildren(self):
+        #warn("END: %s" % self.childTypes)
+        self.childTypes.pop()
+        self.childNumChilds.pop()
+        self.put(']')
+
+    # convenience
+    def putItemCount(self, count):
+        self.putCommaIfNeeded()
+        self.put('value="<%s items>"' % count)
+
+    def putEllipsis(self):
+        self.putCommaIfNeeded()
+        self.put('{name="<incomplete>",value="",type="",numchild="0"}')
+
+    def putType(self, type):
+        #warn("TYPES: '%s' '%s'" % (type, self.childTypes))
+        #warn("  EQUAL 2: %s " % (str(type) == self.childTypes[-1]))
+        type = stripClassTag(str(type))
+        if len(type) > 0 and type != self.childTypes[-1]:
+            self.putField("type", type)
+            #self.putField("type", str(type.unqualified()))
+
+    def putNumChild(self, numchild):
+        #warn("NUM CHILD: '%s' '%s'" % (numchild, self.childNumChilds[-1]))
+        if int(numchild) != int(self.childNumChilds[-1]):
+            self.putField("numchild", numchild)
+
+    def isExpanded(self, item):
+        #warn("IS EXPANDED: %s in %s" % (item.iname, self.expandedINames))
+        if item.iname is None:
+            raise "Illegal iname 'None'"
+        if item.iname.startswith("None"):
+            raise "Illegal iname '%s'" % item.iname
+        #warn("   --> %s" % (item.iname in self.expandedINames))
+        return item.iname in self.expandedINames
+
+    def isExpandedIName(self, iname):
+        return iname in self.expandedINames
+
+    def unputField(self, name):
+        pos = self.output.rfind(",")
+        if self.output[pos + 1:].startswith(name):
+            self.output = self.output[0:pos]
+
+    def stripNamespaceFromType(self, typeobj):
+        # FIXME: pass ns from plugin
+        type = stripClassTag(str(typeobj))
+        if len(self.ns) > 0 and type.startswith(self.ns):
+            type = type[len(self.ns):]
+        pos = type.find("<")
+        if pos != -1:
+            type = type[0:pos]
+        return type
+
+    def isMovableType(self, type):
+        if type.code == gdb.TYPE_CODE_PTR:
+            return True
+        if isSimpleType(type):
+            return True
+        return self.stripNamespaceFromType(type) in movableTypes
+
+    def putIntItem(self, name, value):
+        self.beginHash()
+        self.putField("name", name)
+        self.putField("value", value)
+        self.putType("int")
+        self.putNumChild(0)
+        self.endHash()
+
+    def putBoolItem(self, name, value):
+        self.beginHash()
+        self.putField("name", name)
+        self.putField("value", value)
+        self.putType("bool")
+        self.putNumChild(0)
+        self.endHash()
+
+    def pushOutput(self):
+        #warn("PUSH OUTPUT: %s " % self.output)
+        self.safeoutput += self.output
+        self.output = ""
+
+    def dumpInnerValueHelper(self, item, field = "value"):
+        if isSimpleType(item.value.type):
+            self.putItemHelper(item, field)
+
+    def safePutItemHelper(self, item):
+        self.pushOutput()
+        # This is only used at the top level to ensure continuation
+        # after failures due to uninitialized or corrupted data.
+        if self.passExceptions:
+            # for debugging reasons propagate errors.
+            self.putItemHelper(item)
+
+        else:
+            try:
+                self.putItemHelper(item)
+
+            except RuntimeError as ex:
+                self.output = ""
+                # FIXME: Only catch debugger related exceptions
+                #exType, exValue, exTraceback = sys.exc_info()
+                #tb = traceback.format_exception(exType, exValue, exTraceback)
+                warn("Exception: %s" % ex.message)
+                # DeprecationWarning: BaseException.message
+                # has been deprecated
+                #warn("Exception.")
+                #for line in tb:
+                #    warn("%s" % line)
+                self.putField("name", item.name)
+                self.putField("value", "<invalid>")
+                self.putField("type", str(item.value.type))
+                self.putField("numchild", "0")
+                #if self.isExpanded(item):
+                self.beginChildren()
+                self.endChildren()
+        self.pushOutput()
+
+    def putItem(self, item):
+        self.beginHash()
+        self.putItemHelper(item)
+        self.endHash()
+
+    def putItemOrPointer(self, item):
+        self.beginHash()
+        self.putItemOrPointerHelper(item)
+        self.endHash()
+    
+    def putCallItem(self, name, item, func):
+        result = call(item.value, func)
+        self.putItem(Item(result, item.iname, name, name))
+
+    def putItemOrPointerHelper(self, item):
+        if item.value.type.code == gdb.TYPE_CODE_PTR \
+                and str(item.value.type.unqualified) != "char":
+            if not isNull(item.value):
+                self.putItemOrPointerHelper(
+                    Item(item.value.dereference(), item.iname, None, None))
+            else:
+                self.putField("value", "(null)")
+                self.putField("numchild", "0")
+        else:
+            self.putItemHelper(item)
+
+
+    def putItemHelper(self, item, field = "value"):
+        name = getattr(item, "name", None)
+        if not name is None:
+            self.putField("name", name)
+
+        self.putType(item.value.type)
+        # FIXME: Gui shows references stripped?
+        #warn("REAL INAME: %s " % item.iname)
+        #warn("REAL TYPE: %s " % item.value.type)
+        #warn("REAL VALUE: %s " % item.value)
+
+        value = item.value
+        type = value.type
+
+        if type.code == gdb.TYPE_CODE_REF:
+            type = type.target()
+            value = value.cast(type)
+
+        if type.code == gdb.TYPE_CODE_TYPEDEF:
+            type = type.target()
+
+        strippedType = self.stripNamespaceFromType(
+            type.strip_typedefs().unqualified()).replace("::", "__")
+        
+        #warn(" STRIPPED: %s" % strippedType)
+        #warn(" DUMPERS: %s" % self.dumpers)
+        #warn(" DUMPERS: %s" % (strippedType in self.dumpers))
+
+        if isSimpleType(type):
+            self.putField(field, value)
+            if field == "value":
+                self.putNumChild(0)
+
+        elif strippedType in self.dumpers:
+            self.dumpers[strippedType](self, item)
+
+        elif type.code == gdb.TYPE_CODE_ENUM:
+            #warn("GENERIC ENUM: %s" % value)
+            self.putField(field, value)
+            self.putNumChild(0)
+            
+
+        elif type.code == gdb.TYPE_CODE_PTR:
+            isHandled = False
+            #warn("GENERIC POINTER: %s" % value)
+            if isNull(value):
+                self.putField(field, "0x0")
+                self.putNumChild(0)
+                isHandled = True
+
+            target = str(type.target().unqualified())
+            #warn("TARGET: %s" % target)
+            if target == "char" and not isHandled:
+                # Display values up to given length directly
+                firstNul = -1
+                p = value
+                for i in xrange(0, 10):
+                    if p.dereference() == 0:
+                        # Found terminating NUL
+                        self.putField("%sencoded" % field, "6")
+                        self.put(',%s="' % field)
+                        p = value
+                        for j in xrange(0, i):
+                            self.put('%02x' % int(p.dereference()))
+                            p += 1
+                        self.put('"')
+                        self.putNumChild(0)
+                        isHandled = True
+                        break
+                    p += 1
+
+            if not isHandled:
+                # Generic pointer type.
+                self.putField(field, str(value.address))
+                self.putNumChild(1)
+                #warn("GENERIC POINTER: %s" % value)
+                if self.isExpanded(item):
+                    self.beginChildren()
+                    child = Item(value.dereference(), item.iname, "*", "*" + name)
+                    self.beginHash()
+                    self.putField("iname", child.iname)
+                    #name = getattr(item, "name", None)
+                    #if not name is None:
+                    #    child.name = "*%s" % name
+                    #    self.putField("name", child.name)
+                    #self.putType(child.value.type)
+                    self.putItemHelper(child)
+                    self.endHash()
+                    self.endChildren()
+
+        else:
+            #warn("COMMON TYPE: %s " % value.type)
+            #warn("INAME: %s " % item.iname)
+            #warn("INAMES: %s " % self.expandedINames)
+            #warn("EXPANDED: %self " % (item.iname in self.expandedINames))
+
+            # insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=10953
+            #fields = value.type.fields()
+            fields = value.type.strip_typedefs().fields()
+
+            self.putField("value", "{...}")
+
+            if False:
+                numfields = 0
+                for field in fields:
+                    bitpos = getattr(field, "bitpos", None)
+                    if not bitpos is None:
+                        ++numfields
+            else:
+                numfields = len(fields)
+            self.putNumChild(numfields)
+
+            if self.isExpanded(item):
+                innerType = None
+                if len(fields) == 1 and fields[0].name is None:
+                    innerType = value.type.target()
+                self.beginChildren(innerType)
+
+                for field in fields:
+                    #warn("FIELD: %s" % field)
+                    #warn("  BITSIZE: %s" % field.bitsize)
+                    #warn("  ARTIFICIAL: %s" % field.artificial)
+                    bitpos = getattr(field, "bitpos", None)
+                    if bitpos is None: # FIXME: Is check correct?
+                        continue  # A static class member(?).
+
+                    if field.name is None:
+                        innerType = value.type.target()
+                        p = value.cast(innerType.pointer())
+                        for i in xrange(0, value.type.sizeof / innerType.sizeof):
+                            self.putItem(Item(p.dereference(), item.iname, i, None))
+                            p = p + 1
+                        continue
+
+                    # ignore vtable pointers for virtual inheritance
+                    if field.name.startswith("_vptr."):
+                        continue
+
+                    child = Item(None, item.iname, field.name, field.name)
+                    #warn("FIELD NAME: %s" % field.name)
+                    #warn("FIELD TYPE: %s" % field.type)
+                    if field.name == stripClassTag(str(field.type)):
+                        # Field is base type.
+                        child.value = value.cast(field.type)
+                    else:
+                        # Data member.
+                        child.value = value[field.name]
+                    if not child.name:
+                        child.name = "<anon>"
+                    self.beginHash()
+                    #d.putField("iname", child.iname)
+                    #d.putField("name", child.name)
+                    #d.putType(child.value.type)
+                    self.putItemHelper(child)
+                    self.endHash()
+                self.endChildren()
+
diff --git a/share/qtcreator/gdbmacros/gdbmacros.py b/share/qtcreator/gdbmacros/gdbmacros.py
new file mode 100644
index 0000000000000000000000000000000000000000..23a8b1b83233e8c2fa05799b6e607379dba65c9b
--- /dev/null
+++ b/share/qtcreator/gdbmacros/gdbmacros.py
@@ -0,0 +1,2004 @@
+
+#Note: Keep name-type-value-numchild-extra order
+
+#######################################################################
+#
+# Dumper Implementations
+#
+#######################################################################
+
+def qqDumpQByteArray(d, item):
+    #struct Data
+    #    QBasicAtomicInt ref;
+    #    int alloc, size;
+    #    char *data;
+    #    char array[1];
+    d_ptr = item.value['d'].dereference()
+    data = d_ptr['data']
+    size = d_ptr['size']
+    alloc = d_ptr['alloc']
+    check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
+    check(d_ptr["ref"]["_q_value"] > 0)
+    if size > 0:
+        checkAccess(data, 4)
+        checkAccess(data + size) == 0
+
+    innerType = gdb.lookup_type("char")
+    p = gdb.Value(data.cast(innerType.pointer()))
+    s = ""
+    for i in xrange(0, size):
+        s += "%02x" % int(p.dereference())
+        p += 1
+    d.putField("valueencoded", "6")
+    d.putField("value", s)
+
+    n = size if size < 1000 else 1000
+    d.putNumChild(n)
+
+    if d.isExpanded(item):
+        d.beginChildren(innerType if n > 0 else None)
+        p = gdb.Value(data.cast(innerType.pointer()))
+        for i in xrange(0, n):
+            d.putItem(Item(p.dereference(), item.iname, i, None))
+            p += 1
+        if n < size:
+            d.putEllipsis()
+        d.endChildren()
+
+
+def qqDumpQChar(d, item):
+    ucs = int(item.value["ucs"])
+    c = ucs if curses.ascii.isprint(ucs) else '?'
+    d.putField("value", "'%c' (%d)" % (c, ucs))
+    d.putNumChild(0)
+
+
+def qqDumpQAbstractItem(d, item):
+    r = item.value["r"]
+    c = item.value["c"]
+    p = item.value["p"]
+    m = item.value["m"]
+    rowCount = call(m, "rowCount(mi)")
+    if rowCount < 0:
+        return
+    columnCount = call(m, "columnCount(mi)")
+    if columnCount < 0:
+        return
+    value = call(m, "data(mi, Qt::DisplayRole).toString()")
+    d.putField("valueencoded", "7")
+    d.putField("value", encodeString(value))
+    d.putField("numchild", rowCount * columnCount)
+    if d.isExpanded(item):
+        innerType = gdb.lookup_type(d.ns + "QAbstractItem")
+        d.beginChildren()
+        for row in xrange(0, rowCount):
+            for column in xrange(0, columnCount):
+                child = call(m, "index(row, column, mi)")
+                d.putField("name", "[%s,%s]" % (row, column))
+                rr = call(m, "rowCount(child)")
+                cc = call(m, "columnCount(child)")
+                d.putField("numchild", rr * cc)
+                d.putField("valueencoded", "6")
+                d.putField("value",
+                    call(m, "data(child, Qt::DisplayRole).toString())"))
+                d.endHash()
+        #d.beginHash()
+        #d.putField("name", "DisplayRole")
+        #d.putField("numchild", 0)
+        #d.putField("value", m->data(mi, Qt::DisplayRole).toString())
+        #d.putField("valueencoded", 2)
+        #d.putField("type", ns + "QString")
+        #d.endHash()
+        d.endChildren()
+
+
+def qqDumpQAbstractItemModel(d, item):
+    rowCount = call(item.value, "rowCount()")
+    if rowCount < 0:
+        return
+    columnCount = call(item.valuem, "columnCount()")
+    if columnCount < 0:
+        return
+
+    d.putField("value", "(%s,%s)" % (rowCount, columnCount))
+    d.putField("numchild", "1")
+    if d.isExpanded(item):
+        d.beginChildren()
+        d.beginHash()
+        d.putField("numchild", "1")
+        d.putField("name", d.ns + "QObject")
+        d.putField("valueencoded", "2")
+        d.putField("value", call(item.value, "objectName()"))
+        d.putField("type", d.ns + "QObject")
+        d.putField("displayedtype", call(item, "m.metaObject()->className()"))
+        d.endHash()
+        for row in xrange(0, rowCount):
+            for column in xrange(0, columnCount):
+                mi = call(m, "index(%s,%s)" % (row, column))
+                d.beginHash()
+                d.putField("name", "[%s,%s]" % (row, column))
+                d.putField("valueencoded", "6")
+                d.putField("value", "m.data(mi, Qt::DisplayRole).toString()")
+                #d.putField("numchild", (m.hasChildren(mi) ? "1" : "0"))
+                d.putField("numchild", "1") #m.rowCount(mi) * m.columnCount(mi))
+                d.putField("type", d.ns + "QAbstractItem")
+                d.endHash()
+        d.endChildren()
+
+
+def qqDumpQDateTime(d, item):
+    date = call(item.value, "toString(%sQt::TextDate)" % d.ns)
+    d.putField("valueencoded", "7")
+    d.putField("value", encodeString(date))
+    d.putField("numchild", "3")
+    if d.isExpanded(item):
+        d.beginChildren()
+        d.putCallItem("isNull", item, "isNull()")
+        d.putCallItem("toTime_t", item, "toTime_t()")
+        d.putCallItem("toString",
+            item, "toString(%sQt::TextDate)" % d.ns)
+        d.putCallItem("(ISO)",
+            item, "toString(%sQt::ISODate)" % d.ns)
+        d.putCallItem("(SystemLocale)",
+            item, "toString(%sQt::SystemLocaleDate)" % d.ns)
+        d.putCallItem("(Locale)",
+            item, "toString(%sQt::LocaleDate)" % d.ns)
+        d.putCallItem("toUTC",
+            item, "toTimeSpec(%sQt::UTC)" % d.ns)
+        d.putCallItem("toLocalTime",
+            item, "toTimeSpec(%sQt::LocalTime)" % d.ns)
+        d.endChildren()
+
+
+def qqDumpQDir(d, item):
+    path = call(item.value, "path()")
+    d.putField("valueencoded", "7")
+    d.putField("value", encodeString(path))
+    d.putField("numchild", "2")
+    if d.isExpanded(item):
+        d.beginChildren()
+        d.putCallItem("absolutePath", item, "absolutePath()")
+        d.putCallItem("canonicalPath", item, "canonicalPath()")
+        d.endChildren()
+
+
+def qqDumpQFile(d, item):
+    fileName = call(item.value, "fileName()")
+    d.putField("valueencoded", "7")
+    d.putField("value", encodeString(fileName))
+    d.putField("numchild", "2")
+    if d.isExpanded(item):
+        d.beginChildren()
+        d.putCallItem("fileName", item, "fileName()")
+        d.putCallItem("exists", item, "exists()")
+        d.endChildren()
+
+
+def qqDumpQFileInfo(d, item):
+    filePath = call(item.value, "filePath()")
+    d.putField("valueencoded", "7")
+    d.putField("value", encodeString(filePath))
+    d.putField("numchild", "3")
+    if d.isExpanded(item):
+        d.beginChildren(gdb.lookup_type(d.ns + "QString"))
+        d.putCallItem("absolutePath", item, "absolutePath()")
+        d.putCallItem("absoluteFilePath", item, "absoluteFilePath()")
+        d.putCallItem("canonicalPath", item, "canonicalPath()")
+        d.putCallItem("canonicalFilePath", item, "canonicalFilePath()")
+        d.putCallItem("completeBaseName", item, "completeBaseName()")
+        d.putCallItem("completeSuffix", item, "completeSuffix()")
+        d.putCallItem("baseName", item, "baseName()")
+        if False:
+            #ifdef Q_OS_MACX
+            d.putCallItem("isBundle", item, "isBundle()")
+            d.putCallItem("bundleName", item, "bundleName()")
+        d.putCallItem("fileName", item, "fileName()")
+        d.putCallItem("filePath", item, "filePath()")
+        # Crashes gdb (archer-tromey-python, at dad6b53fe)
+        #d.putCallItem("group", item, "group()")
+        #d.putCallItem("owner", item, "owner()")
+        d.putCallItem("path", item, "path()")
+
+        d.putCallItem("groupid", item, "groupId()")
+        d.putCallItem("ownerid", item, "ownerId()")
+
+        #QFile::Permissions permissions () const
+        perms = call(item.value, "permissions()")
+        d.beginHash()
+        d.putField("name", "permissions")
+        d.putField("value", " ")
+        d.putField("type", d.ns + "QFile::Permissions")
+        d.putField("numchild", 10)
+        if d.isExpandedIName(item.iname + ".permissions"):
+            d.beginChildren()
+            d.putBoolItem("ReadOwner",  perms & 0x4000)
+            d.putBoolItem("WriteOwner", perms & 0x2000)
+            d.putBoolItem("ExeOwner",   perms & 0x1000)
+            d.putBoolItem("ReadUser",   perms & 0x0400)
+            d.putBoolItem("WriteUser",  perms & 0x0200)
+            d.putBoolItem("ExeUser",    perms & 0x0100)
+            d.putBoolItem("ReadGroup",  perms & 0x0040)
+            d.putBoolItem("WriteGroup", perms & 0x0020)
+            d.putBoolItem("ExeGroup",   perms & 0x0010)
+            d.putBoolItem("ReadOther",  perms & 0x0004)
+            d.putBoolItem("WriteOther", perms & 0x0002)
+            d.putBoolItem("ExeOther",   perms & 0x0001)
+            d.endChildren()
+        d.endHash()
+
+        #QDir absoluteDir () const
+        #QDir dir () const
+        d.putCallItem("caching", item, "caching()")
+        d.putCallItem("exists", item, "exists()")
+        d.putCallItem("isAbsolute", item, "isAbsolute()")
+        d.putCallItem("isDir", item, "isDir()")
+        d.putCallItem("isExecutable", item, "isExecutable()")
+        d.putCallItem("isFile", item, "isFile()")
+        d.putCallItem("isHidden", item, "isHidden()")
+        d.putCallItem("isReadable", item, "isReadable()")
+        d.putCallItem("isRelative", item, "isRelative()")
+        d.putCallItem("isRoot", item, "isRoot()")
+        d.putCallItem("isSymLink", item, "isSymLink()")
+        d.putCallItem("isWritable", item, "isWritable()")
+        d.putCallItem("created", item, "created()")
+        d.putCallItem("lastModified", item, "lastModified()")
+        d.putCallItem("lastRead", item, "lastRead()")
+        d.endChildren()
+
+
+def qqDumpQFlags(d, item):
+    #warn("QFLAGS: %s" % item.value) 
+    i = item.value["i"]
+    enumType = item.value.type.template_argument(0)
+    #warn("QFLAGS: %s" % item.value["i"].cast(enumType)) 
+    d.putField("value", "%s (%s)" % (i.cast(enumType), i))
+    d.putNumChild(0)
+
+
+def qqDumpQHash(d, item):
+
+    def hashDataFirstNode(value):
+        value = value.cast(hashDataType)
+        bucket = value["buckets"]
+        e = value.cast(hashNodeType)
+        for n in xrange(value["numBuckets"] - 1, -1, -1):
+            n = n - 1
+            if n < 0:
+                break
+            if bucket.dereference() != e:
+                return bucket.dereference()
+            bucket = bucket + 1
+        return e;
+
+    def hashDataNextNode(node):
+        next = node["next"]
+        if next["next"]:
+            return next
+        d = node.cast(hashDataType.pointer()).dereference()
+        numBuckets = d["numBuckets"]
+        start = (node["h"] % numBuckets) + 1
+        bucket = d["buckets"] + start
+        for n in xrange(0, numBuckets - start):
+            if bucket.dereference() != next:
+                return bucket.dereference()
+            bucket += 1
+        return node
+
+    keyType = item.value.type.template_argument(0)
+    valueType = item.value.type.template_argument(1)
+
+    d_ptr = item.value["d"]
+    e_ptr = item.value["e"]
+    n = d_ptr["size"]
+
+    hashDataType = d_ptr.type
+    hashNodeType = e_ptr.type
+
+    check(0 <= n and n <= 100 * 1000 * 1000)
+    check(d_ptr["ref"]["_q_value"] > 0)
+
+    d.putItemCount(n)
+    d.putField("numchild", n)
+    if d.isExpanded(item):
+        if n > 1000:
+            n = 1000
+
+        isSimpleKey = isSimpleType(keyType)
+        isSimpleValue = isSimpleType(valueType)
+        node = hashDataFirstNode(item.value)
+
+        innerType = e_ptr.dereference().type
+        inner = valueType if isSimpleKey and isSimpleValue else innerType
+        d.beginChildren(inner if n > 0 else None)
+        for i in xrange(0, n):
+            it = node.dereference().cast(innerType)
+            d.beginHash()
+            key = it["key"]
+            value = it["value"]
+            if isSimpleKey and isSimpleValue:
+                d.putField("name", key)
+                d.putItemHelper(Item(value, item.iname, i, None))
+                d.putType(valueType)
+            else:
+                d.putItemHelper(Item(it, item.iname, i, None))
+            d.endHash()
+            node = hashDataNextNode(node)
+        d.endChildren()
+
+
+def qqDumpQHashNode(d, item):
+    keyType = item.value.type.template_argument(0)
+    valueType = item.value.type.template_argument(1)
+    key = item.value["key"]
+    value = item.value["value"]
+
+    if isSimpleType(valueType):
+        d.dumpInnerValueHelper(Item(value))
+    else:
+        d.putField("value", " ")
+
+    d.putField("numchild", 2)
+    if d.isExpanded(item):
+        d.beginChildren()
+        d.beginHash()
+        d.putField("name", "key")
+        d.putItemHelper(Item(key, None, None, None))
+        d.endHash()
+        d.beginHash()
+        d.putField("name", "value")
+        d.putItemHelper(Item(value, None, None, None))
+        d.endHash()
+        d.endChildren()
+
+
+def qqDumpQList(d, item):
+    d_ptr = item.value["d"]
+    begin = d_ptr["begin"]
+    end = d_ptr["end"]
+    array = d_ptr["array"]
+    check(begin >= 0 and end >= 0 and end <= 1000 * 1000 * 1000)
+    n = end - begin
+    check(n >= 0)
+    #if n > 0:
+    #    checkAccess(&list.front())
+    #    checkAccess(&list.back())
+
+    check(d_ptr["ref"]["_q_value"] > 0)
+
+    # Additional checks on pointer arrays.
+    innerType = item.value.type.template_argument(0)
+    innerTypeIsPointer = innerType.code == gdb.TYPE_CODE_PTR \
+        and str(innerType.target().unqualified()) != "char"
+    if innerTypeIsPointer:
+        p = gdb.Value(array).cast(innerType.pointer()) + begin
+        checkPointerRange(p, n if n < 100 else 100)
+
+    d.putItemCount(n)
+    d.putField("numchild", n)
+    if d.isExpanded(item):
+        # about 0.5s / 1000 items
+        if n > 2000:
+            n = 2000
+
+        innerSize = innerType.sizeof
+        # The exact condition here is:
+        #  QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic
+        # but this data is available neither in the compiled binary nor
+        # in the frontend.
+        # So as first approximation only do the 'isLarge' check:
+        isInternal = innerSize <= d_ptr.type.sizeof and d.isMovableType(innerType)
+        #warn("INTERNAL: %d" % int(isInternal))
+
+        p = gdb.Value(array).cast(innerType.pointer()) + begin
+        inner = innerType.target() if innerTypeIsPointer else innerType
+        d.beginChildren(inner if n > 0 else None)
+        for i in xrange(0, n):
+            if innerTypeIsPointer:
+                if isNull(p.dereference()):
+                    d.beginHash()
+                    d.putField("value", "(null)")
+                    d.putNumChild(0)
+                    d.putType(p.dereference().type)
+                    d.endHash()
+                else:
+                    d.putItemOrPointer(Item(p.dereference(), item.iname, i, None))
+            else:
+                if isInternal:
+                    d.putItem(Item(p.dereference(), item.iname, i, None))
+                else:
+                    pp = p.cast(innerType.pointer().pointer()).dereference()
+                    d.putItem(Item(pp.dereference(), item.iname, i, None))
+            p += 1
+
+        if n < end - begin:
+            d.putEllipsis()
+        d.endChildren()
+
+
+def qqDumpQImage(d, item):
+    painters = item.value["painters"]
+    check(0 <= painters and painters < 1000)
+    d_ptr = item.value["d"]
+    if isNull(d_ptr):
+        d.putField("value", "(null)")
+    else:
+        check(d_ptr["ref"]["_q_value"] > 0)
+        d.putField("value", "(%dx%d)" % (d_ptr["width"], d_ptr["height"]))
+    d.putField("numchild", "0")
+    #    if d.isExpanded(item):
+    #        d.beginChildren()
+    #        d.beginHash()
+    #            d.putField("name", "data")
+    #            d.putField("type", d.ns +  "QImageData")
+    #            d.putField("addr", d.data)
+    #        d.endHash()
+    #        d.endChildren()
+
+
+def qqDumpQImageData(d, item):
+    pass
+#     const QImage &im = *reinterpret_cast<const QImage *>(d.data)
+#     const QByteArray ba(QByteArray::fromRawData((const char*)im.bits(), im.numBytes()))
+#     d.putField("type", d.ns + "QImageData")
+#     d.putField("numchild", "0")
+# #if 1
+#     d.putField("value", "<hover here>")
+#     d.putField("valuetooltipencoded", "1")
+#     d.putField("valuetooltipsize", ba.size())
+#     d.putField("valuetooltip", ba)
+# #else
+#     d.putField("valueencoded", "1")
+#     d.putField("value", ba)
+# #endif
+
+
+def qqDumpQLinkedList(d, item):
+    d_ptr = item.value["d"]
+    e_ptr = item.value["e"]
+    nn = d_ptr["size"]
+    n = nn
+    check(0 <= n and n <= 100*1000*1000)
+    check(d_ptr["ref"]["_q_value"] > 0)
+
+    d.putItemCount(n)
+    d.putField("numchild", n)
+
+    if d.isExpanded(item):
+        innerType = item.value.type.template_argument(0)
+        if n > 1000:
+            n = 1000
+        d.beginChildren(innerType if n > 0 else None)
+        p = e_ptr["n"]
+        for i in xrange(0, n):
+            d.putItemOrPointer(Item(p["t"], None, None, None))
+            p = p["n"]
+        if n < nn:
+            d.putEllipsis()
+        d.endChildren()
+
+
+def qqDumpQLocale(d, item):
+    name = call(item.value, "name()")
+    d.putField("valueencoded", "7")
+    d.putField("value", encodeString(name))
+    d.putField("numchild", "8")
+    if d.isExpanded(item):
+        d.beginChildren(gdb.lookup_type(d.ns + "QChar"), 0)
+        d.putCallItem("country", item, "country()")
+        d.putCallItem("language", item, "language()")
+        d.putCallItem("measurementSystem", item, "measurementSystem()")
+        d.putCallItem("numberOptions", item, "numberOptions()")
+        d.putCallItem("timeFormat_(short)", item,
+            "timeFormat(" + d.ns + "QLocale::ShortFormat)")
+        d.putCallItem("timeFormat_(long)", item,
+            "timeFormat(" + d.ns + "QLocale::LongFormat)")
+        d.putCallItem("decimalPoint", item, "decimalPoint()")
+        d.putCallItem("exponential", item, "exponential()")
+        d.putCallItem("percent", item, "percent()")
+        d.putCallItem("zeroDigit", item, "zeroDigit()")
+        d.putCallItem("groupSeparator", item, "groupSeparator()")
+        d.putCallItem("negativeSign", item, "negativeSign()")
+        d.endChildren()
+
+
+def qqDumpQMapNode(d, item):
+    d.putField("value", " ")
+    d.putField("numchild", 2)
+    if d.isExpanded(item):
+        d.beginChildren()
+        d.beginHash()
+        d.putField("name", "key")
+        d.putItemHelper(Item(item.value["key"], item.iname, "name", None))
+        d.endHash()
+        d.beginHash()
+        d.putField("name", "value")
+        d.putItemHelper(Item(item.value["value"], item.iname, "value", None))
+        d.endHash()
+        d.endChildren()
+
+
+def qqDumpQMap(d, item):
+    d_ptr = item.value["d"].dereference()
+    e_ptr = item.value["e"].dereference()
+    n = d_ptr["size"]
+    check(0 <= n and n <= 100*1000*1000)
+    check(d_ptr["ref"]["_q_value"] > 0)
+
+    d.putItemCount(n)
+    d.putField("numchild", n)
+    if d.isExpanded(item):
+        if n > 1000:
+            n = 1000
+
+        keyType = item.value.type.template_argument(0)
+        valueType = item.value.type.template_argument(1)
+
+        isSimpleKey = isSimpleType(keyType)
+        isSimpleValue = isSimpleType(valueType)
+
+        it = e_ptr["forward"].dereference()
+
+        # QMapPayloadNode is QMapNode except for the 'forward' member, so
+        # its size is most likely the offset of the 'forward' member therein.
+        # Or possibly 2 * sizeof(void *)
+        nodeType = gdb.lookup_type(d.ns + "QMapNode<%s, %s>" % (keyType, valueType))
+        payloadSize = nodeType.sizeof - 2 * gdb.lookup_type("void").pointer().sizeof
+        charPtr = gdb.lookup_type("char").pointer()
+
+        innerType = valueType if isSimpleKey and isSimpleValue else nodeType
+
+        d.beginChildren(innerType if n > 0 else None)
+        for i in xrange(0, n):
+            itd = it.dereference()
+            base = it.cast(charPtr) - payloadSize
+            node = base.cast(nodeType.pointer()).dereference()
+            d.beginHash()
+
+            key = node["key"]
+            value = node["value"]
+            #if isSimpleType(item.value.type): # or isStringType(d, item.value.type):
+            #    d.putItemHelper(item, field)
+            #dumpInnerValueHelper(d, Item(key), "name");
+            #dumpInnerValueHelper(d, Item(value, "value"))
+            if isSimpleKey and isSimpleValue:
+                #d.putType(valueType)
+                d.putField("name", key)
+                d.putItemHelper(Item(value, item.iname, i, None))
+            else:
+                d.putItemHelper(Item(node, item.iname, i, None))
+            d.endHash()
+            it = it.dereference()["forward"].dereference()
+        d.endChildren()
+
+
+def qqDumpMultiMap(d, item):
+    qqDumpMap(d, item)
+
+
+def qqDumpQModelIndex(d, item):
+    r = item.value["r"]
+    c = item.value["c"]
+    p = item.value["p"]
+    m = item.value["m"]
+    if r >= 0 and c >= 0 and not isNull(m):
+        d.putField("value", "(%s, %s)" % (r, c))
+        d.putField("numchild", 5)
+        if d.isExpanded(item):
+            d.beginChildren()
+            d.putIntItem("row", r)
+            d.putIntItem("column", c)
+            d.putCallItem("parent", item, "parent()")
+            d.beginHash()
+            d.putField("name", "model")
+            d.putField("value", m)
+            d.putField("type", d.ns + "QAbstractItemModel*")
+            d.putField("numchild", "1")
+            d.endHash()
+
+            d.endChildren()
+    else:
+        d.putField("value", "(invalid)")
+        d.putField("numchild", 0)
+
+
+def extractCString(table, offset):
+    result = ""
+    while True:
+        d = table[offset]
+        if d == 0:
+            break
+        result += "%c" % d
+        offset += 1
+    return result
+
+
+def qqDumpQObject(d, item):
+    #warn("OBJECT: %s " % item.value)
+    staticMetaObject = item.value["staticMetaObject"]
+    #warn("SMO: %s " % staticMetaObject)
+    privateType = gdb.lookup_type(d.ns + "QObjectPrivate")
+    d_ptr = item.value["d_ptr"]["d"].dereference().cast(privateType)
+    #warn("D_PTR: %s " % d_ptr)
+    objectName = d_ptr["objectName"]
+    #warn("OBJECTNAME: %s " % objectName)
+    #warn("D_PTR: %s " % d_ptr.dereference())
+    mo = d_ptr["metaObject"]
+    type = d.stripNamespaceFromType(item.value.type)
+    if isNull(mo):
+        mo = staticMetaObject
+    #warn("MO: %s " % mo)
+    #warn("MO.D: %s " % mo["d"])
+    metaData = mo["d"]["data"]
+    metaStringData = mo["d"]["stringdata"]
+    #warn("METADATA: %s " % metaData)
+    #warn("STRINGDATA: %s " % metaStringData)
+    #warn("TYPE: %s " % item.value.type)
+    #d.putField("value", "")
+    d.putField("valueencoded", "7")
+    d.putField("value", encodeString(objectName))
+    #QSignalMapper::staticMetaObject
+    #check(d_ptr["ref"]["_q_value"] > 0)
+    d.putNumChild(4)
+    if d.isExpanded(item):
+        d.beginChildren()
+
+        # parent and children
+        d.putItem(Item(d_ptr["parent"], item.iname, "parent", "parent"))
+        d.putItem(Item(d_ptr["children"], item.iname, "children", "children"))
+
+        # properties
+        d.beginHash()
+        propertyCount = metaData[6]
+        propertyData = metaData[7]
+        d.putField("name", "properties")
+        d.putItemCount(propertyCount)
+        d.putField("type", "")
+        d.putField("numchild", propertyCount)
+        if d.isExpandedIName(item.iname + ".properties"):
+            d.beginChildren()
+            for property in xrange(0, propertyCount):
+                d.beginHash()
+                offset = propertyData + 3 * property
+                propertyName = extractCString(metaStringData, metaData[offset])
+                propertyType = extractCString(metaStringData, metaData[offset + 1])
+                d.putField("name", propertyName)
+                #flags = metaData[offset + 2]
+                #warn("FLAGS: %s " % flags)
+                warn("PROPERTY TYPE: %s " % propertyType)
+                # #exp = '((\'%sQObject\'*)%s)->property("%s")' \
+                #     % (d.ns, item.value.address, propertyName)
+                #exp = '"((\'%sQObject\'*)%s)"' % (d.ns, item.value.address,)
+                #warn("EXPRESSION:  %s" % exp)
+                #value = gdb.parse_and_eval(exp)
+                value = call(item.value, 'property("%s")' % propertyName)
+                warn("VALUE:  %s" % value)
+                warn("TYPE:  %s" % value.type)
+                if True and propertyType == "QString":
+                    # FIXME: re-use parts of QVariant dumper
+                    #d.putField("type", d.ns + "QString")
+                    data = value["d"]["data"]["ptr"]
+                    innerType = gdb.lookup_type(d.ns + "QString")
+                    d.putItemHelper(
+                        Item(data.cast(innerType), item.iname, property, None))
+                    #d.putField("numchild", "0")
+                else:
+                    iname = "%s.properties.%s" % (item.iname, propertyName)
+                    d.putItemHelper(Item(value, iname, propertyName))
+                d.endHash()
+            d.endChildren()
+        d.endHash()
+
+        # connections
+        d.beginHash()
+        connectionCount = 0
+        d.putField("name", "connections")
+        d.putItemCount(connectionCount)
+        d.putField("type", "")
+        d.putField("numchild", connectionCount)
+        if connectionCount:
+            d.putField("childtype", "")
+            d.putField("childnumchild", "0")
+
+        if d.isExpandedIName(item.iname + ".connections"):
+            d.beginChildren()
+
+            connectionLists = d_ptr["connectionLists"]
+            warn("CONNECTIONLISTS: %s " % connectionLists)
+
+            for connection in xrange(0, connectionCount):
+                d.beginHash()
+                d.putField("name", "connection %d" % connection)
+                d.putField("value", "")
+                d.endHash()
+            d.endChildren()
+        d.endHash()
+
+        # signals
+        signalCount = metaData[13]
+        d.beginHash()
+        d.putField("name", "signals")
+        d.putItemCount(signalCount)
+        d.putField("type", "")
+        d.putField("numchild", signalCount)
+        if signalCount:
+            # FIXME: empty type does not work for childtype
+            #d.putField("childtype", ".")
+            d.putField("childnumchild", "0")
+        if d.isExpandedIName(item.iname + ".signals"):
+            d.beginChildren()
+            for signal in xrange(0, signalCount):
+                d.beginHash()
+                offset = metaData[14 + 5 * signal]
+                d.putField("name", "signal %d" % signal)
+                d.putField("type", "")
+                d.putField("value", extractCString(metaStringData, offset))
+                d.endHash()
+            d.endChildren()
+        d.endHash()
+
+        # slots
+        d.beginHash()
+        slotCount = metaData[4] - signalCount
+        d.putField("name", "slots")
+        d.putItemCount(slotCount)
+        d.putField("type", "")
+        d.putField("numchild", slotCount)
+        if slotCount:
+            #d.putField("childtype", ".")
+            d.putField("childnumchild", "0")
+        if d.isExpandedIName(item.iname + ".slots"):
+            d.beginChildren()
+            for slot in xrange(0, slotCount):
+                d.beginHash()
+                offset = metaData[14 + 5 * (signalCount + slot)]
+                d.putField("name", "slot %d" % slot)
+                d.putField("type", "")
+                d.putField("value", extractCString(metaStringData, offset))
+                d.endHash()
+            d.endChildren()
+        d.endHash()
+
+        d.endChildren()
+
+
+# QObject
+
+#   static const uint qt_meta_data_QObject[] = {
+
+#   int revision;
+#   int className;
+#   int classInfoCount, classInfoData;
+#   int methodCount, methodData;
+#   int propertyCount, propertyData;
+#   int enumeratorCount, enumeratorData;
+#   int constructorCount, constructorData; //since revision 2
+#   int flags; //since revision 3
+#   int signalCount; //since revision 4
+
+#    // content:
+#          4,       // revision
+#          0,       // classname
+#          0,    0, // classinfo
+#          4,   14, // methods
+#          1,   34, // properties
+#          0,    0, // enums/sets
+#          2,   37, // constructors
+#          0,       // flags
+#          2,       // signalCount
+
+#  /* 14 */
+
+#    // signals: signature, parameters, type, tag, flags
+#          9,    8,    8,    8, 0x05,
+#         29,    8,    8,    8, 0x25,
+
+#  /* 24 */
+#    // slots: signature, parameters, type, tag, flags
+#         41,    8,    8,    8, 0x0a,
+#         55,    8,    8,    8, 0x08,
+
+#  /* 34 */
+#    // properties: name, type, flags
+#         90,   82, 0x0a095103,
+
+#  /* 37 */
+#    // constructors: signature, parameters, type, tag, flags
+#        108,  101,    8,    8, 0x0e,
+#        126,    8,    8,    8, 0x2e,
+
+#          0        // eod
+#   };
+
+#   static const char qt_meta_stringdata_QObject[] = {
+#       "QObject\0\0destroyed(QObject*)\0destroyed()\0"
+#       "deleteLater()\0_q_reregisterTimers(void*)\0"
+#       "QString\0objectName\0parent\0QObject(QObject*)\0"
+#       "QObject()\0"
+#   };
+
+
+# QSignalMapper
+
+#   static const uint qt_meta_data_QSignalMapper[] = {
+
+#    // content:
+#          4,       // revision
+#          0,       // classname
+#          0,    0, // classinfo
+#          7,   14, // methods
+#          0,    0, // properties
+#          0,    0, // enums/sets
+#          0,    0, // constructors
+#          0,       // flags
+#          4,       // signalCount
+
+#    // signals: signature, parameters, type, tag, flags
+#         15,   14,   14,   14, 0x05,
+#         27,   14,   14,   14, 0x05,
+#         43,   14,   14,   14, 0x05,
+#         60,   14,   14,   14, 0x05,
+
+#    // slots: signature, parameters, type, tag, flags
+#         77,   14,   14,   14, 0x0a,
+#         90,   83,   14,   14, 0x0a,
+#        104,   14,   14,   14, 0x08,
+
+#          0        // eod
+#   };
+
+#   static const char qt_meta_stringdata_QSignalMapper[] = {
+#       "QSignalMapper\0\0mapped(int)\0mapped(QString)\0"
+#       "mapped(QWidget*)\0mapped(QObject*)\0"
+#       "map()\0sender\0map(QObject*)\0"
+#       "_q_senderDestroyed()\0"
+#   };
+
+#   const QMetaObject QSignalMapper::staticMetaObject = {
+#       { &QObject::staticMetaObject, qt_meta_stringdata_QSignalMapper,
+#         qt_meta_data_QSignalMapper, 0 }
+#   };
+
+
+
+#     checkAccess(deref(d.data)); // is the d-ptr de-referenceable and valid
+#     const QObject *ob = reinterpret_cast<const QObject *>(d.data)
+#     const QMetaObject *mo = ob->metaObject()
+#     d.putField("value", ob->objectName())
+#     d.putField("valueencoded", "2")
+#     d.putField("type", d.ns + "QObject")
+#     d.putField("displayedtype", mo->className())
+#     d.putField("numchild", 4)
+#     if d.isExpanded(item):
+#         int slotCount = 0
+#         int signalCount = 0
+#         for (int i = mo->methodCount(); --i >= 0; ) {
+#             QMetaMethod::MethodType mt = mo->method(i).methodType()
+#             signalCount += (mt == QMetaMethod::Signal)
+#             slotCount += (mt == QMetaMethod::Slot)
+#         }
+#         d.beginChildren()
+#         d.beginHash()
+#             d.putField("name", "properties")
+#             // using 'addr' does not work in gdb as 'exp' is recreated as
+#             // (type *)addr, and here we have different 'types':
+#             // QObject vs QObjectPropertyList!
+#             d.putField("addr", d.data)
+#             d.putField("type", d.ns + "QObjectPropertyList")
+#             d.putItemCount(mo->propertyCount())
+#             d.putField("numchild", mo->propertyCount())
+#         d.endHash()
+#         d.beginHash()
+#             d.putField("name", "signals")
+#             d.putField("addr", d.data)
+#             d.putField("type", d.ns + "QObjectSignalList")
+#             d.putItemCount(signalCount)
+#             d.putField("numchild", signalCount)
+#         d.endHash()
+#         d.beginHash()
+#             d.putField("name", "slots")
+#             d.putField("addr", d.data)
+#             d.putField("type", d.ns + "QObjectSlotList")
+#             d.putItemCount(slotCount)
+#             d.putField("numchild", slotCount)
+#         d.endHash()
+#         const QObjectList objectChildren = ob->children()
+#         if !objectChildren.empty()) {
+#             d.beginHash()
+#             d.putField("name", "children")
+#             d.putField("addr", d.data)
+#             d.putField("type", ns + "QObjectChildList")
+#             d.putItemCount(objectChildren.size())
+#             d.putField("numchild", objectChildren.size())
+#             d.endHash()
+#         }
+#         d.beginHash()
+#             d.putField("name", "parent")
+#             dumpInnerValueHelper(d, ns + "QObject *", ob->parent())
+#         d.endHash()
+# #if 1
+#         d.beginHash()
+#             d.putField("name", "className")
+#             d.putField("value", ob->metaObject()->className())
+#             d.putField("type", "")
+#             d.putField("numchild", "0")
+#         d.endHash()
+# #endif
+#         d.endChildren()
+
+
+# #if USE_QT_GUI
+# static const char *sizePolicyEnumValue(QSizePolicy::Policy p)
+# {
+#     switch (p) {
+#     case QSizePolicy::Fixed:
+#         return "Fixed"
+#     case QSizePolicy::Minimum:
+#         return "Minimum"
+#     case QSizePolicy::Maximum:
+#         return "Maximum"
+#     case QSizePolicy::Preferred:
+#         return "Preferred"
+#     case QSizePolicy::Expanding:
+#         return "Expanding"
+#     case QSizePolicy::MinimumExpanding:
+#         return "MinimumExpanding"
+#     case QSizePolicy::Ignored:
+#         break
+#     }
+#     return "Ignored"
+# }
+#
+# static QString sizePolicyValue(const QSizePolicy &sp)
+# {
+#     QString rc
+#     QTextStream str(&rc)
+#     // Display as in Designer
+#     str << '[' << sizePolicyEnumValue(sp.horizontalPolicy())
+#         << ", " << sizePolicyEnumValue(sp.verticalPolicy())
+#         << ", " << sp.horizontalStretch() << ", " << sp.verticalStretch() << ']'
+#     return rc
+# }
+# #endif
+#
+# // Meta enumeration helpers
+# static inline void dumpMetaEnumType(QDumper &d, const QMetaEnum &me)
+# {
+#     QByteArray type = me.scope()
+#     if !type.isEmpty())
+#         type += "::"
+#     type += me.name()
+#     d.putField("type", type.constData())
+# }
+#
+# static inline void dumpMetaEnumValue(QDumper &d, const QMetaProperty &mop,
+#                                      int value)
+# {
+#
+#     const QMetaEnum me = mop.enumerator()
+#     dumpMetaEnumType(d, me)
+#     if const char *enumValue = me.valueToKey(value)) {
+#         d.putField("value", enumValue)
+#     } else {
+#         d.putField("value", value)
+#     }
+#     d.putField("numchild", 0)
+# }
+#
+# static inline void dumpMetaFlagValue(QDumper &d, const QMetaProperty &mop,
+#                                      int value)
+# {
+#     const QMetaEnum me = mop.enumerator()
+#     dumpMetaEnumType(d, me)
+#     const QByteArray flagsValue = me.valueToKeys(value)
+#     if flagsValue.isEmpty()) {
+#         d.putField("value", value)
+#     } else {
+#         d.putField("value", flagsValue.constData())
+#     }
+#     d.putField("numchild", 0)
+# }
+#
+# #ifndef QT_BOOTSTRAPPED
+# static void dumpQObjectProperty(QDumper &d)
+# {
+#     const QObject *ob = (const QObject *)d.data
+#     const QMetaObject *mob = ob->metaObject()
+#     // extract "local.Object.property"
+#     QString iname = d.iname
+#     const int dotPos = iname.lastIndexOf(QLatin1Char('.'))
+#     if dotPos == -1)
+#         return
+#     iname.remove(0, dotPos + 1)
+#     const int index = mob->indexOfProperty(iname.toAscii())
+#     if index == -1)
+#         return
+#     const QMetaProperty mop = mob->property(index)
+#     const QVariant value = mop.read(ob)
+#     const bool isInteger = value.type() == QVariant::Int
+#     if isInteger and mop.isEnumType()) {
+#         dumpMetaEnumValue(d, mop, value.toInt())
+#     } elif isInteger and mop.isFlagType()) {
+#         dumpMetaFlagValue(d, mop, value.toInt())
+#     } else {
+#         dumpQVariant(d, &value)
+#     }
+#     d.disarm()
+# }
+#
+# static void dumpQObjectPropertyList(QDumper &d)
+# {
+#     const QObject *ob = (const QObject *)d.data
+#     const QMetaObject *mo = ob->metaObject()
+#     const int propertyCount = mo->propertyCount()
+#     d.putField("addr", "<synthetic>")
+#     d.putField("type", ns + "QObjectPropertyList")
+#     d.putField("numchild", propertyCount)
+#     d.putItemCount(propertyCount)
+#     if d.isExpanded(item):
+#         d.beginChildren()
+#         for (int i = propertyCount; --i >= 0; ) {
+#             const QMetaProperty & prop = mo->property(i)
+#             d.beginHash()
+#             d.putField("name", prop.name())
+#             switch (prop.type()) {
+#             case QVariant::String:
+#                 d.putField("type", prop.typeName())
+#                 d.putField("value", prop.read(ob).toString())
+#                 d.putField("valueencoded", "2")
+#                 d.putField("numchild", "0")
+#                 break
+#             case QVariant::Bool:
+#                 d.putField("type", prop.typeName())
+#                 d.putField("value", (prop.read(ob).toBool() ? "true" : "false"))
+#                 d.putField("numchild", "0")
+#                 break
+#             case QVariant::Int:
+#                 if prop.isEnumType()) {
+#                     dumpMetaEnumValue(d, prop, prop.read(ob).toInt())
+#                 } elif prop.isFlagType()) {
+#                     dumpMetaFlagValue(d, prop, prop.read(ob).toInt())
+#                 } else {
+#                     d.putField("value", prop.read(ob).toInt())
+#                     d.putField("numchild", "0")
+#                 }
+#                 break
+#             default:
+#                 d.putField("addr", d.data)
+#                 d.putField("type", ns + "QObjectProperty")
+#                 d.putField("numchild", "1")
+#                 break
+#             }
+#             d.endHash()
+#         }
+#         d.endChildren()
+#     }
+#     d.disarm()
+# }
+#
+# static void dumpQObjectMethodList(QDumper &d)
+# {
+#     const QObject *ob = (const QObject *)d.data
+#     const QMetaObject *mo = ob->metaObject()
+#     d.putField("addr", "<synthetic>")
+#     d.putField("type", ns + "QObjectMethodList")
+#     d.putField("numchild", mo->methodCount())
+#     if d.isExpanded(item):
+#         d.putField("childtype", ns + "QMetaMethod::Method")
+#         d.putField("childnumchild", "0")
+#         d.beginChildren()
+#         for (int i = 0; i != mo->methodCount(); ++i) {
+#             const QMetaMethod & method = mo->method(i)
+#             int mt = method.methodType()
+#             d.beginHash()
+#             d.beginItem("name")
+#                 d.put(i).put(" ").put(mo->indexOfMethod(method.signature()))
+#                 d.put(" ").put(method.signature())
+#             d.endItem()
+#             d.beginItem("value")
+#                 d.put((mt == QMetaMethod::Signal ? "<Signal>" : "<Slot>"))
+#                 d.put(" (").put(mt).put(")")
+#             d.endItem()
+#             d.endHash()
+#         }
+#         d.endChildren()
+#     }
+#     d.disarm()
+# }
+#
+# def qConnectionType(type):
+#     Qt::ConnectionType connType = static_cast<Qt::ConnectionType>(type)
+#     const char *output = "unknown"
+#     switch (connType) {
+#         case Qt::AutoConnection: output = "auto"; break
+#         case Qt::DirectConnection: output = "direct"; break
+#         case Qt::QueuedConnection: output = "queued"; break
+#         case Qt::BlockingQueuedConnection: output = "blockingqueued"; break
+#         case 3: output = "autocompat"; break
+# #if QT_VERSION >= 0x040600
+#         case Qt::UniqueConnection: break; // Can't happen.
+# #endif
+#     return output
+#
+# #if QT_VERSION >= 0x040400
+# static const ConnectionList &qConnectionList(const QObject *ob, int signalNumber)
+# {
+#     static const ConnectionList emptyList
+#     const ObjectPrivate *p = reinterpret_cast<const ObjectPrivate *>(dfunc(ob))
+#     if !p->connectionLists)
+#         return emptyList
+#     typedef QVector<ConnectionList> ConnLists
+#     const ConnLists *lists = reinterpret_cast<const ConnLists *>(p->connectionLists)
+#     // there's an optimization making the lists only large enough to hold the
+#     // last non-empty item
+#     if signalNumber >= lists->size())
+#         return emptyList
+#     return lists->at(signalNumber)
+# }
+# #endif
+#
+# // Write party involved in a slot/signal element,
+# // avoid to recursion to self.
+# static inline void dumpQObjectConnectionPart(QDumper &d,
+#                                               const QObject *owner,
+#                                               const QObject *partner,
+#                                               int number, const char *namePostfix)
+# {
+#     d.beginHash()
+#     d.beginItem("name")
+#     d.put(number).put(namePostfix)
+#     d.endItem()
+#     if partner == owner) {
+#         d.putField("value", "<this>")
+#         d.putField("type", owner->metaObject()->className())
+#         d.putField("numchild", 0)
+#         d.putField("addr", owner)
+#     } else {
+#         dumpInnerValueHelper(d, ns + "QObject *", partner)
+#     }
+#     d.endHash()
+#
+# static void dumpQObjectSignal(QDumper &d)
+# {
+#     unsigned signalNumber = d.extraInt[0]
+#
+#     d.putField("addr", "<synthetic>")
+#     d.putField("numchild", "1")
+#     d.putField("type", ns + "QObjectSignal")
+#
+# #if QT_VERSION >= 0x040400
+#     if d.isExpanded(item):
+#         const QObject *ob = reinterpret_cast<const QObject *>(d.data)
+#         d.beginChildren()
+#         const ConnectionList &connList = qConnectionList(ob, signalNumber)
+#         for (int i = 0; i != connList.size(); ++i) {
+#             const Connection &conn = connectionAt(connList, i)
+#             dumpQObjectConnectionPart(d, ob, conn.receiver, i, " receiver")
+#             d.beginHash()
+#                 d.beginItem("name")
+#                     d.put(i).put(" slot")
+#                 d.endItem()
+#                 d.putField("type", "")
+#                 if conn.receiver)
+#                     d.putField("value", conn.receiver->metaObject()->method(conn.method).signature())
+#                 else
+#                     d.putField("value", "<invalid receiver>")
+#                 d.putField("numchild", "0")
+#             d.endHash()
+#             d.beginHash()
+#                 d.beginItem("name")
+#                     d.put(i).put(" type")
+#                 d.endItem()
+#                 d.putField("type", "")
+#                 d.beginItem("value")
+#                     d.put("<").put(qConnectionType(conn.connectionType)).put(" connection>")
+#                 d.endItem()
+#                 d.putField("numchild", "0")
+#             d.endHash()
+#         }
+#         d.endChildren()
+#         d.putField("numchild", connList.size())
+# #endif
+#
+# static void dumpQObjectSignalList(QDumper &d)
+# {
+#     const QObject *ob = reinterpret_cast<const QObject *>(d.data)
+#     const QMetaObject *mo = ob->metaObject()
+#     int count = 0
+#     const int methodCount = mo->methodCount()
+#     for (int i = methodCount; --i >= 0; )
+#         count += (mo->method(i).methodType() == QMetaMethod::Signal)
+#     d.putField("type", ns + "QObjectSignalList")
+#     d.putItemCount(count)
+#     d.putField("addr", d.data)
+#     d.putField("numchild", count)
+# #if QT_VERSION >= 0x040400
+#     if d.isExpanded(item):
+#         d.beginChildren()
+#         for (int i = 0; i != methodCount; ++i) {
+#             const QMetaMethod & method = mo->method(i)
+#             if method.methodType() == QMetaMethod::Signal) {
+#                 int k = mo->indexOfSignal(method.signature())
+#                 const ConnectionList &connList = qConnectionList(ob, k)
+#                 d.beginHash()
+#                 d.putField("name", k)
+#                 d.putField("value", method.signature())
+#                 d.putField("numchild", connList.size())
+#                 d.putField("addr", d.data)
+#                 d.putField("type", ns + "QObjectSignal")
+#                 d.endHash()
+# #endif
+#
+# static void dumpQObjectSlot(QDumper &d)
+# {
+#     int slotNumber = d.extraInt[0]
+#
+#     d.putField("addr", d.data)
+#     d.putField("numchild", "1")
+#     d.putField("type", ns + "QObjectSlot")
+#
+# #if QT_VERSION >= 0x040400
+#     if d.isExpanded(item):
+#         d.beginChildren()
+#         int numchild = 0
+#         const QObject *ob = reinterpret_cast<const QObject *>(d.data)
+#         const ObjectPrivate *p = reinterpret_cast<const ObjectPrivate *>(dfunc(ob))
+# #if QT_VERSION >= 0x040600
+#         int s = 0
+#         for (SenderList senderList = p->senders; senderList != 0
+#              senderList = senderList->next, ++s) {
+#             const QObject *sender = senderList->sender
+#             int signal = senderList->method; // FIXME: 'method' is wrong.
+# #else
+#         for (int s = 0; s != p->senders.size(); ++s) {
+#             const QObject *sender = senderAt(p->senders, s)
+#             int signal = signalAt(p->senders, s)
+# #endif
+#             const ConnectionList &connList = qConnectionList(sender, signal)
+#             for (int i = 0; i != connList.size(); ++i) {
+#                 const Connection &conn = connectionAt(connList, i)
+#                 if conn.receiver == ob and conn.method == slotNumber) {
+#                     ++numchild
+#                     const QMetaMethod &method = sender->metaObject()->method(signal)
+#                     dumpQObjectConnectionPart(d, ob, sender, s, " sender")
+#                     d.beginHash()
+#                         d.beginItem("name")
+#                             d.put(s).put(" signal")
+#                         d.endItem()
+#                         d.putField("type", "")
+#                         d.putField("value", method.signature())
+#                         d.putField("numchild", "0")
+#                     d.endHash()
+#                     d.beginHash()
+#                         d.beginItem("name")
+#                             d.put(s).put(" type")
+#                         d.endItem()
+#                         d.putField("type", "")
+#                         d.beginItem("value")
+#                             d.put("<").put(qConnectionType(conn.method))
+#                             d.put(" connection>")
+#                         d.endItem()
+#                         d.putField("numchild", "0")
+#                     d.endHash()
+#                 }
+#             }
+#         }
+#         d.endChildren()
+#         d.putField("numchild", numchild)
+#     }
+# #endif
+#     d.disarm()
+# }
+#
+# static void dumpQObjectSlotList(QDumper &d)
+# {
+#     const QObject *ob = reinterpret_cast<const QObject *>(d.data)
+# #if QT_VERSION >= 0x040400
+#     const ObjectPrivate *p = reinterpret_cast<const ObjectPrivate *>(dfunc(ob))
+# #endif
+#     const QMetaObject *mo = ob->metaObject()
+#
+#     int count = 0
+#     const int methodCount = mo->methodCount()
+#     for (int i = methodCount; --i >= 0; )
+#         count += (mo->method(i).methodType() == QMetaMethod::Slot)
+#
+#     d.putField("numchild", count)
+#     d.putItemCount(count)
+#     d.putField("type", ns + "QObjectSlotList")
+#     if d.isExpanded(item):
+#         d.beginChildren()
+# #if QT_VERSION >= 0x040400
+#         for (int i = 0; i != methodCount; ++i) {
+#             const QMetaMethod & method = mo->method(i)
+#             if method.methodType() == QMetaMethod::Slot) {
+#                 d.beginHash()
+#                 int k = mo->indexOfSlot(method.signature())
+#                 d.putField("name", k)
+#                 d.putField("value", method.signature())
+#
+#                 // count senders. expensive...
+#                 int numchild = 0
+# #if QT_VERSION >= 0x040600
+#                 int s = 0
+#                 for (SenderList senderList = p->senders; senderList != 0
+#                      senderList = senderList->next, ++s) {
+#                     const QObject *sender = senderList->sender
+#                     int signal = senderList->method; // FIXME: 'method' is wrong.
+# #else
+#                 for (int s = 0; s != p->senders.size(); ++s) {
+#                     const QObject *sender = senderAt(p->senders, s)
+#                     int signal = signalAt(p->senders, s)
+# #endif
+#                     const ConnectionList &connList = qConnectionList(sender, signal)
+#                     for (int c = 0; c != connList.size(); ++c) {
+#                         const Connection &conn = connectionAt(connList, c)
+#                         if conn.receiver == ob and conn.method == k)
+#                             ++numchild
+#                     }
+#                 }
+#                 d.putField("numchild", numchild)
+#                 d.putField("addr", d.data)
+#                 d.putField("type", ns + "QObjectSlot")
+#                 d.endHash()
+#             }
+#         }
+# #endif
+#         d.endChildren()
+#     }
+#     d.disarm()
+# }
+#
+# static void dumpQObjectChildList(QDumper &d)
+# {
+#     const QObject *ob = reinterpret_cast<const QObject *>(d.data)
+#     const QObjectList children = ob->children()
+#     const int size = children.size()
+#
+#     d.putField("numchild", size)
+#     d.putItemCount(size)
+#     d.putField("type", ns + "QObjectChildList")
+#     if d.isExpanded(item):
+#         d.beginChildren()
+#         for (int i = 0; i != size; ++i) {
+#             d.beginHash()
+#             dumpInnerValueHelper(d, ns + "QObject *", children.at(i))
+#             d.endHash()
+#         }
+#         d.endChildren()
+#     }
+#     d.disarm()
+# }
+# #endif // QT_BOOTSTRAPPED
+
+
+def qqDumpQPixmap(d, item):
+    painters = item.value["painters"]
+    check(0 <= painters and painters < 1000)
+    d_ptr = item.value["data"]["d"]
+    if isNull(d_ptr):
+        d.putField("value", "(null)")
+    else:
+        check(d_ptr["ref"]["_q_value"] > 0)
+        d.putField("value", "(%dx%d)" % (d_ptr["w"], d_ptr["h"]))
+    d.putField("numchild", "0")
+
+
+def qqDumpQPoint(d, item):
+    x = item.value["xp"]
+    y = item.value["yp"]
+    # should not be needed, but sometimes yield myns::QVariant::Private::Data::qreal
+    x = x.cast(x.type.strip_typedefs())
+    y = y.cast(y.type.strip_typedefs())
+    d.putField("value", "(%s, %s)" % (x, y))
+    d.putNumChild(2)
+    if d.isExpanded(item):
+        d.beginChildren(x.type.strip_typedefs())
+        d.putItem(Item(x, None, None, "x"))
+        d.putItem(Item(y, None, None, "y"))
+        d.endChildren()
+
+
+def qqDumpQPointF(d, item):
+    qqDumpQPoint(d, item)
+
+
+def qqDumpQSize(d, item):
+    w = item.value["wd"]
+    h = item.value["ht"]
+    d.putField("value", "(%s, %s)" % (w, h))
+    d.putNumChild(2)
+    if d.isExpanded(item):
+        d.beginChildren(w.type)
+        d.putItem(Item(w, item.iname, "w", "w"))
+        d.putItem(Item(h, item.iname, "h", "h"))
+        d.endChildren()
+
+
+def qqDumpQSizeF(d, item):
+    qqDumpQSize(d, item)
+
+
+def qqDumpQRect(d, item):
+    def pp(l): return ("+%s" % l) if l >= 0 else l
+    x1 = item.value["x1"]
+    y1 = item.value["y1"]
+    x2 = item.value["x2"]
+    y2 = item.value["y2"]
+    w = x2 - x1 + 1
+    h = y2 - y1 + 1
+    d.putField("value", "%sx%s%s%s" % (w, h, pp(x1), pp(y1)))
+    d.putNumChild(4)
+    if d.isExpanded(item):
+        d.beginChildren(x1.type.strip_typedefs())
+        d.putItem(Item(x1, None, None, "x1"))
+        d.putItem(Item(y1, None, None, "y1"))
+        d.putItem(Item(x2, None, None, "x2"))
+        d.putItem(Item(y2, None, None, "y2"))
+        d.endChildren()
+
+
+def qqDumpQRectF(d, item):
+    def pp(l): return ("+%s" % l) if l >= 0 else l
+    x = item.value["xp"]
+    y = item.value["yp"]
+    w = item.value["w"]
+    h = item.value["h"]
+    # FIXME: workaround, see QPoint
+    x = x.cast(x.type.strip_typedefs())
+    y = y.cast(y.type.strip_typedefs())
+    w = w.cast(w.type.strip_typedefs())
+    h = h.cast(h.type.strip_typedefs())
+    d.putField("value", "%sx%s%s%s" % (w, h, pp(x), pp(y)))
+    d.putNumChild(4)
+    if d.isExpanded(item):
+        d.beginChildren(x.type.strip_typedefs())
+        d.putItem(Item(x, None, None, "x"))
+        d.putItem(Item(y, None, None, "y"))
+        d.putItem(Item(w, None, None, "w"))
+        d.putItem(Item(h, None, None, "h"))
+        d.endChildren()
+
+
+def encodeString(value):
+    d_ptr = value['d'].dereference()
+    data = d_ptr['data']
+    size = d_ptr['size']
+    alloc = d_ptr['alloc']
+    check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
+    if size > 0:
+        checkAccess(data, 4)
+        checkAccess(data + size * 2) == 0
+    check(d_ptr["ref"]["_q_value"] > 0)
+    p = gdb.Value(d_ptr["data"])
+    s = ""
+    for i in xrange(0, size):
+        val = int(p.dereference())
+        s += "%02x" % (val % 256)
+        s += "%02x" % (val / 256)
+        p += 1
+    return s
+
+
+def qqDumpQString(d, item):
+    str = encodeString(item.value)
+    d.putField("valueencoded", "7")
+    d.putField("value", str)
+    d.putNumChild(0)
+
+
+def qqDumpQStringList(d, item):
+    d_ptr = item.value['d']
+    begin = d_ptr['begin']
+    end = d_ptr['end']
+    n = end - begin
+    check(n >= 0)
+    check(n <= 10 * 1000 * 1000)
+    #    checkAccess(&list.front())
+    #    checkAccess(&list.back())
+    check(d_ptr["ref"]["_q_value"] > 0)
+    d.putItemCount(n)
+    d.putNumChild(n)
+    if d.isExpanded(item):
+        if n > 1000:
+            n = 1000
+        innerType = gdb.lookup_type(d.ns + "QString")
+        ptr = gdb.Value(d_ptr["array"]).cast(innerType.pointer())
+        d.beginChildren(innerType if n > 0 else None)
+        for i in xrange(0, n):
+            d.putItem(Item(ptr.dereference(), item.iname, i, None))
+            ptr += 1
+        if n < end - begin:
+            d.putEllipsis()
+        d.endChildren()
+
+
+def qqDumpQSet(d, item):
+
+    def hashDataFirstNode(value):
+        value = value.cast(hashDataType)
+        bucket = value["buckets"]
+        e = value.cast(hashNodeType)
+        for n in xrange(value["numBuckets"] - 1, -1, -1):
+            n = n - 1
+            if n < 0:
+                break
+            if bucket.dereference() != e:
+                return bucket.dereference()
+            bucket = bucket + 1
+        return e;
+
+    def hashDataNextNode(node):
+        next = node["next"]
+        if next["next"]:
+            return next
+        d = node.cast(hashDataType.pointer()).dereference()
+        numBuckets = d["numBuckets"]
+        start = (node["h"] % numBuckets) + 1
+        bucket = d["buckets"] + start
+        for n in xrange(0, numBuckets - start):
+            if bucket.dereference() != next:
+                return bucket.dereference()
+            bucket += 1
+        return node
+
+    keyType = item.value.type.template_argument(0)
+
+    d_ptr = item.value["q_hash"]["d"]
+    e_ptr = item.value["q_hash"]["e"]
+    n = d_ptr["size"]
+
+    hashDataType = d_ptr.type
+    hashNodeType = e_ptr.type
+
+    check(0 <= n and n <= 100 * 1000 * 1000)
+    check(d_ptr["ref"]["_q_value"] > 0)
+
+    d.putItemCount(n)
+    d.putField("numchild", n)
+    if d.isExpanded(item):
+        if n > 1000:
+            n = 1000
+
+        isSimpleKey = isSimpleType(keyType)
+
+        node = hashDataFirstNode(item.value)
+
+        innerType = e_ptr.dereference().type
+        d.beginChildren(keyType if n > 0 else None)
+        for i in xrange(0, n):
+            it = node.dereference().cast(innerType)
+            d.beginHash()
+            key = it["key"]
+            if isSimpleKey:
+                d.putType(keyType)
+                d.putItemHelper(Item(key, None, None, None), "value")
+            else:
+                d.putItemHelper(Item(key, item.iname, i, None))
+            d.endHash()
+            node = hashDataNextNode(node)
+        d.endChildren()
+
+
+def qqDumpQSharedPointer(d, item):
+    qqDumpQWeakPointer(d, item)
+
+
+def qqDumpQStack(d, item):
+    qqDumpQVector(d, item)
+
+
+def qqDumpQTemporaryFile(d, item):
+    qqDumpQFile(d, item)
+
+
+#FIXME: X(..)
+def qqDumpQTextCodecX(d, item):
+    #checkPointer(deref(d.data))
+    warn("VALUE: %s " % item.value)
+    #const QTextCodec &codec = *reinterpret_cast<const QTextCodec *>(d.data)
+    #d.putField("valueencoded", "1")
+    #d.putField("value", codec.name())
+    d.putField("type", d.ns + "QTextCodec")
+    d.putField("numchild", "2")
+    if d.isExpanded(item):
+        d.beginChildren()
+        #d.putCallItem("name", codec.name())
+        #d.putCallItem("mibEnum", codec.mibEnum())
+        d.endChildren()
+
+
+def qqDumpQVariant(d, item):
+    union = item.value["d"]
+    data = union["data"]
+    variantType = int(union["type"])
+    #warn("VARIANT TYPE: %s : " % variantType)
+    inner = ""
+    innert = ""
+    if variantType == 0: # QVariant::Invalid
+        d.putField("value", "(invalid)")
+        d.putNumChild(0)
+    elif variantType == 1: # QVariant::Bool
+        d.putField("value", "true" if data["b"] else "false")
+        d.putNumChild(0)
+    elif variantType == 2: # QVariant::Int
+        d.putField("value", data["i"])
+        d.putNumChild(0)
+    elif variantType == 3: # uint
+        d.putField("value", data["u"])
+        d.putNumChild(0)
+    elif variantType == 4: # qlonglong
+        d.putField("value", data["ll"])
+        d.putNumChild(0)
+    elif variantType == 5: # qulonglong
+        d.putField("value", data["ull"])
+        d.putNumChild(0)
+    elif variantType == 6: # QVariant::Double
+        value = data["d"]
+        d.putField("value", data["d"])
+        d.putNumChild(0)
+    elif variantType == 7: # QVariant::QChar
+        inner = d.ns + "QChar"
+    elif variantType == 8: # QVariant::VariantMap
+        inner = d.ns + "QMap<" + d.ns + "QString, " + d.ns + "QVariant>"
+        innert = d.ns + "QVariantMap"
+    elif variantType == 9: # QVariant::VariantList
+        inner = d.ns + "QList<" + d.ns + "QVariant>"
+        innert = d.ns + "QVariantList"
+    elif variantType == 10: # QVariant::String
+        inner = d.ns + "QString"
+    elif variantType == 11: # QVariant::StringList
+        inner = d.ns + "QStringList"
+    elif variantType == 12: # QVariant::ByteArray
+        inner = d.ns + "QByteArray"
+    elif variantType == 13: # QVariant::BitArray
+        inner = d.ns + "QBitArray"
+    elif variantType == 14: # QVariant::Date
+        inner = d.ns + "QDate"
+    elif variantType == 15: # QVariant::Time
+        inner = d.ns + "QTime"
+    elif variantType == 16: # QVariant::DateTime
+        inner = d.ns + "QDateTime"
+    elif variantType == 17: # QVariant::Url
+        inner = d.ns + "QUrl"
+    elif variantType == 18: # QVariant::Locale
+        inner = d.ns + "QLocale"
+    elif variantType == 19: # QVariant::Rect
+        inner = d.ns + "QRect"
+    elif variantType == 20: # QVariant::RectF
+        inner = d.ns + "QRectF"
+    elif variantType == 21: # QVariant::Size
+        inner = d.ns + "QSize"
+    elif variantType == 22: # QVariant::SizeF
+        inner = d.ns + "QSizeF"
+    elif variantType == 23: # QVariant::Line
+        inner = d.ns + "QLine"
+    elif variantType == 24: # QVariant::LineF
+        inner = d.ns + "QLineF"
+    elif variantType == 25: # QVariant::Point
+        inner = d.ns + "QPoint"
+    elif variantType == 26: # QVariant::PointF
+        inner = d.ns + "QPointF"
+    elif variantType == 27: # QVariant::RegExp
+        inner = d.ns + "QRegExp"
+    elif variantType == 28: # QVariant::VariantHash
+        inner = d.ns + "QHash<" + d.ns + "QString, " + d.ns + "QVariant>"
+        innert = d.ns + "QVariantHash"
+    elif variantType == 64: # QVariant::Font
+        inner = d.ns + "QFont"
+    elif variantType == 67: # QVariant::Color
+        inner = d.ns + "QColor"
+    elif variantType == 71: # QVariant::Polygon and PointArray
+        inner = d.ns + "QPointArray"
+    elif variantType == 75: # QVariant::SizePolicy
+        inner = d.ns + "QSizePolicy"
+    elif variantType == 76: # QVariant::KeySequence
+        inner = d.ns + "QKeySequence"
+    elif variantType == 76: # QVariant::Quadernion
+        inner = d.ns + "QQuadernion"
+    else:
+        # FIXME: handle User types
+        d.putField("value", "(unknown type %d)" % variantType)
+        # typeName = QMetaType::typeName(typ)
+        # exp =  "'qVariantValue<%s >'(*('"NS"QVariant'*)%p)"
+        d.putNumChild(0)
+
+    if len(inner):
+        if len(innert) == 0:
+            innert = inner
+        d.putField("value", "(%s)" % innert)
+        d.putNumChild(1)
+        if d.isExpanded(item):
+            innerType = gdb.lookup_type(inner)
+            d.beginChildren()
+            d.beginHash()
+            #d.putField("name", "data")
+            #d.putField("type", innert)
+            val = gdb.Value(data["ptr"]).cast(innerType)
+            d.putItemHelper(Item(val, item.iname, "data", "data"))
+            d.endHash()
+            d.endChildren()
+
+
+def qqDumpQVector(d, item):
+    #   QBasicAtomicInt ref;
+    #   int alloc;
+    #   int size;
+    #   uint sharable : 1;
+    #   uint capacity : 1;
+    d_ptr = item.value["d"]
+    p_ptr = item.value["p"]
+    alloc = d_ptr["alloc"]
+    size = d_ptr["size"]
+
+    check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000)
+    check(d_ptr["ref"]["_q_value"] > 0)
+
+    # Check pointers
+    innerType = item.value.type.template_argument(0)
+    #if innerType.code == gdb.TYPE_CODE_PTR and nn > 0:
+    #  for (int i = 0; i != size; ++i)
+    #       if const void *p = addOffset(v, i * innersize + typeddatasize))
+    #             checkAccess(deref(p))
+
+    d.putItemCount(size)
+    d.putNumChild(size)
+    if d.isExpanded(item):
+        n = size
+        if n > 10000:
+            n = 10000
+        p = gdb.Value(p_ptr["array"]).cast(innerType.pointer())
+        d.beginChildren(innerType if n > 0 else None)
+        for i in xrange(0, n):
+            d.putItemOrPointer(Item(p.dereference(), item.iname, i, None))
+            p += 1
+        if n < size:
+            d.putEllipsis()
+        d.endChildren()
+
+
+def qqDumpQWeakPointer(d, item):
+    d_ptr = item.value["d"]
+    value = item.value["value"]
+    if isNull(d_ptr) and isNull(value):
+        d.putField("value", "(null)")
+        d.putNumChild(0)
+        return
+    if isNull(value) or isNull(value):
+        d.putField("value", "<invalid>")
+        d.putNumChild(0)
+        return
+    weakref = d_ptr["weakref"]["_q_value"]
+    strongref = d_ptr["strongref"]["_q_value"]
+    check(0 < int(strongref))
+    check(int(strongref) <= int(weakref))
+    check(int(weakref) <= 10*1000*1000)
+
+    innerType = item.value.type.template_argument(0)
+    if isSimpleType(value.dereference()):
+        d.putItemHelper(Item(value.dereference(), item.iname, None, None))
+    else:
+        d.putField("value", "")
+
+    d.putField("numchild", 3)
+    if d.isExpanded(item):
+        d.beginChildren()
+        d.putItem(Item(value.dereference(), item.iname, "data", "data"))
+        d.putIntItem("weakref", weakref)
+        d.putIntItem("strongref", strongref)
+        d.endChildren()
+
+
+
+#######################################################################
+#
+# Standard Library dumper
+#
+#######################################################################
+
+def qqDumpStdDeque(d, item):
+    impl = item.value["_M_impl"]
+    start = impl["_M_start"]
+    n = impl["_M_finish"]["_M_cur"] - start["_M_cur"]
+    d.putItemCount(n)
+    d.putNumChild(n)
+    if d.isExpanded(item):
+        innerType = item.value.type.template_argument(0)
+        innerSize = innerType.sizeof
+        bufsize = 512 / innerSize if innerSize < 512 else 1
+        d.beginChildren(innerType if n > 0 else None)
+        pcur = start["_M_cur"]
+        pfirst = start["_M_first"]
+        plast = start["_M_last"]
+        pnode = start["_M_node"]
+        for i in xrange(0, n):
+            d.putItemOrPointer(Item(pcur.dereference(), item.iname, i, None))
+            pcur += 1
+            if pcur == plast:
+                newnode = pnode + 1
+                pnode = newnode
+                pfirst = newnode.dereference()
+                plast = pfirst + bufsize
+                pcur = pfirst
+            
+        if n > 1000:
+            d.putEllipsis()
+        d.endChildren()
+
+
+def qqDumpStdList(d, item):
+    impl = item.value["_M_impl"]
+    node = impl["_M_node"]
+    head = node.address
+    n = 0
+    p = node["_M_next"]
+    while p != head and n <= 1001:
+        n += 1
+        p = p["_M_next"]
+
+    d.putItemCount(n if n <= 1000 else "> 1000")
+    d.putNumChild(n)
+
+    if d.isExpanded(item):
+        p = node["_M_next"]
+        innerType = item.value.type.template_argument(0)
+        d.beginChildren(innerType if n > 0 else None)
+        for i in xrange(0, n):
+            innerPointer = innerType.pointer()
+            value = (p + 1).cast(innerPointer).dereference()
+            d.putItemOrPointer(Item(value, item.iname, i, None))
+            p = p["_M_next"]
+        if n > 1000:
+            d.putEllipsis()
+        d.endChildren()
+
+
+def qqDumpStdMap(d, item):
+    impl = item.value["_M_t"]["_M_impl"]
+    n = impl["_M_node_count"]
+    check(0 <= n and n <= 100*1000*1000)
+    d.putItemCount(n)
+    d.putNumChild(n)
+
+    if d.isExpanded(item):
+        keyType = item.value.type.template_argument(0)
+        valueType = item.value.type.template_argument(1)
+        pairType = item.value.type.template_argument(3).template_argument(0)
+        isSimpleKey = isSimpleType(keyType)
+        isSimpleValue = isSimpleType(valueType)
+        innerType = valueType if isSimpleKey and isSimpleValue else pairType
+        pairPointer = pairType.pointer()
+        node = impl["_M_header"]["_M_left"]
+        d.beginChildren(innerType if n > 0 else pairType,
+            None if isSimpleKey and isSimpleValue else 2)
+        for i in xrange(0, n if n < 1000 else 1000):
+            pair = (node + 1).cast(pairPointer).dereference()
+
+            d.beginHash()
+            if isSimpleKey and isSimpleValue:
+                d.putField("name", str(pair["first"]))
+                d.putItemHelper(Item(pair["second"], item.iname, i, None))
+            else:
+                d.putField("value", " ")
+                if d.isExpandedIName("%s.%d" % (item.iname, i)):
+                    d.beginChildren(None)
+                    iname = "%s.%d." % (item.iname, i)
+                    keyItem = Item(pair["first"], iname + "key", "key", "first")
+                    valueItem = Item(pair["second"], iname + "value", "value", "second")
+                    d.putItem(keyItem)
+                    d.putItem(valueItem)
+                    d.endChildren()
+            d.endHash()
+
+            if isNull(node["_M_right"]):
+                parent = node["_M_parent"]
+                while node == parent["_M_right"]:
+                    node = parent
+                    parent = parent["_M_parent"]
+                if node["_M_right"] != parent:
+                    node = parent
+            else:
+                node = node["_M_right"]
+                while not isNull(node["_M_left"]):
+                    node = node["_M_left"]
+
+        if n >= 1000:
+            d.putEllipsis()
+        d.endChildren()
+
+
+def qqDumpStdSet(d, item):
+    impl = item.value["_M_t"]["_M_impl"]
+    n = impl["_M_node_count"]
+    check(0 <= n and n <= 100*1000*1000)
+    d.putItemCount(n)
+    d.putNumChild(n)
+    if d.isExpanded(item):
+        valueType = item.value.type.template_argument(0)
+        node = impl["_M_header"]["_M_left"]
+        d.beginChildren(valueType if n > 0 else None)
+        for i in xrange(0, n if n < 1000 else 1000):
+            element = (node + 1).cast(valueType.pointer()).dereference()
+            d.putItem(Item(element, item.iname, i, None))
+
+            if isNull(node["_M_right"]):
+                parent = node["_M_parent"]
+                while node == parent["_M_right"]:
+                    node = parent
+                    parent = parent["_M_parent"]
+                if node["_M_right"] != parent:
+                    node = parent
+            else:
+                node = node["_M_right"]
+                while not isNull(node["_M_left"]):
+                    node = node["_M_left"]
+        if n >= 1000:
+            d.putEllipsis()
+        d.endChildren()
+
+
+def qqDumpStdString(d, item):
+    data = item.value["_M_dataplus"]["_M_p"]
+    baseType = item.value.type.unqualified().strip_typedefs()
+    charType = baseType.template_argument(0)
+    repType = gdb.lookup_type("%s::_Rep" % baseType).pointer()
+    rep = (data.cast(repType) - 1).dereference()
+    size = rep['_M_length']
+    alloc = rep['_M_capacity']
+    check(rep['_M_refcount'] >= 0)
+    check(0 <= size and size <= alloc and alloc <= 100*1000*1000)
+    d.unputField("type")
+    if str(charType) == "char":
+        d.putType("std::string")
+    elif str(charType) == "wchar_t":
+        d.putType("std::string")
+    else:
+        d.putType(baseType)
+    p = gdb.Value(data.cast(charType.pointer()))
+    s = ""
+    format = "%%0%dx" % (2 * charType.sizeof)
+    n = size if size < 1000 else 10000
+    for i in xrange(0, size):
+        s += format % int(p.dereference())
+        p += 1
+    d.putField("valueencoded", "6")
+    d.putField("value", s)
+    d.putField("numchild", 0)
+
+
+def qqDumpStdVector(d, item):
+    impl = item.value["_M_impl"]
+    start = impl["_M_start"]
+    finish = impl["_M_finish"]
+    alloc = impl["_M_end_of_storage"]
+    size = finish - start
+
+    check(0 <= size and size <= 1000 * 1000 * 1000)
+    check(finish <= alloc)
+    checkPointer(start)
+    checkPointer(finish)
+    checkPointer(alloc)
+
+    d.putItemCount(size)
+    d.putNumChild(size)
+    if d.isExpanded(item):
+        n = size
+        if n > 10000:
+            n = 10000
+        p = start
+        innerType = item.value.type.template_argument(0)
+        d.beginChildren(innerType if n > 0 else None)
+        for i in xrange(0, n):
+            d.putItemOrPointer(Item(p.dereference(), item.iname, i, None))
+            p += 1
+        if n < size:
+            d.putEllipsis()
+        d.endChildren()
+
+
+# needed
+#gdb.pretty_printers.append(QStringPrinter)
+
+#gdb.pretty_printers["^QStringList$"] = QStringPrinter
+#gdb.pretty_printers["^myns::QList<myns::QString>$"] = QStringPrinter
+#gdb.pretty_printers["^myns::QCoreApplication$"] = QStringPrinter
+