def unparse(self, indent_step = 4, max_linelen = 72) :
        "returns an XML string description of this Introspection tree."
        out = io.StringIO()
        def to_string(obj, indent) :
            tag_name = obj.tag_name
            attrs = []
            for attrname in obj.tag_attrs :
                attr = getattr(obj, attrname)
                if attr != None :
                    if isinstance(attr, enum.Enum) :
                        attr = attr.value
                    elif isinstance(attr, Type) :
                        attr = unparse_signature(attr)
                    elif not isinstance(attr, str) :
                        raise TypeError("unexpected attribute type %s for %s" % (type(attr).__name__, repr(attr)))
                    attrs.append("%s=%s" % (attrname, quote_xml_attr(attr)))
            has_elts = \
              (
                    sum
                      (
                        len(getattr(obj, attrname))
                        for attrname in
                                tuple(obj.tag_elts.keys())
                            +
                                ((), ("annotations",))
                                    [not isinstance(obj, Introspection.Annotation)]
                      )
                !=
                    0
              )
            out.write(" " * indent + "<" + tag_name)
            if (
                    max_linelen != None
                and
                            indent
                        +
                            len(tag_name)
                        +
                            sum((len(s) + 1) for s in attrs)
                        +
                            2
                        +
                            int(has_elts)
                    >
                        max_linelen
            ) :
                out.write("\n")
                for attr in attrs :
                    out.write(" " * (indent + indent_step))
                    out.write(attr)
                    out.write("\n")
                out.write(" " * indent)
            else :
                for attr in attrs :
                    out.write(" ")
                    out.write(attr)
            if not has_elts :
                out.write("/")
            out.write(">\n")
            if has_elts :
                for attrname in sorted(obj.tag_elts.keys()) + ["annotations"] :
                    for elt in getattr(obj, attrname) :
                        to_string(elt, indent + indent_step)
                out.write(" " * indent + "</" + tag_name + ">\n")
        out.write(DBUS.INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE)
        out.write("<node")
        if self.name != None :
            out.write(" name=%s" % quote_xml_attr(self.name))
        out.write(">\n")
        for elt in self.interfaces :
            to_string(elt, indent_step)
        for elt in self.nodes :
            to_string(elt, indent_step)
        out.write("</node>\n")
        return \
            out.getvalue()