def removeNestedGroups(node):
    """
    This walks further and further down the tree, removing groups
    which do not have any attributes or a title/desc child and
    promoting their children up one level
    """
    global _num_elements_removed
    num = 0

    groupsToRemove = []
    # Only consider <g> elements for promotion if this element isn't a <switch>.
    # (partial fix for bug 594930, required by the SVG spec however)
    if not (node.nodeType == Node.ELEMENT_NODE and node.nodeName == 'switch'):
        for child in node.childNodes:
            if child.nodeName == 'g' and child.namespaceURI == NS['SVG'] and len(child.attributes) == 0:
                # only collapse group if it does not have a title or desc as a direct descendant,
                for grandchild in child.childNodes:
                    if grandchild.nodeType == Node.ELEMENT_NODE and grandchild.namespaceURI == NS['SVG'] and \
                            grandchild.nodeName in ['title', 'desc']:
                        break
                else:
                    groupsToRemove.append(child)

    for g in groupsToRemove:
        while g.childNodes.length > 0:
            g.parentNode.insertBefore(g.firstChild, g)
        g.parentNode.removeChild(g)
        _num_elements_removed += 1
        num += 1

    # now recurse for children
    for child in node.childNodes:
        if child.nodeType == Node.ELEMENT_NODE:
            num += removeNestedGroups(child)
    return num