docs: 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