docs: def moveCommonAttributesToParentGroup(elem, referencedElements):
      """
      This recursively calls this function on all children of the passed in element
      and then iterates over all child elements and removes common inheritable attributes
      from the children and places them in the parent group.  But only if the parent contains
      nothing but element children and whitespace.  The attributes are only removed from the
      children if the children are not referenced by other elements in the document.
      """
      num = 0
  
      childElements = []
      # recurse first into the children (depth-first)
      for child in elem.childNodes:
          if child.nodeType == Node.ELEMENT_NODE:
              # only add and recurse if the child is not referenced elsewhere
              if not child.getAttribute('id') in referencedElements:
                  childElements.append(child)
                  num += moveCommonAttributesToParentGroup(child, referencedElements)
          # else if the parent has non-whitespace text children, do not
          # try to move common attributes
          elif child.nodeType == Node.TEXT_NODE and child.nodeValue.strip():
              return num
  
      # only process the children if there are more than one element
      if len(childElements) <= 1:
          return num
  
      commonAttrs = {}
      # add all inheritable properties of the first child element
      # FIXME: Note there is a chance that the first child is a set/animate in which case
      # its fill attribute is not what we want to look at, we should look for the first
      # non-animate/set element
      attrList = childElements[0].attributes
      for index in range(attrList.length):
          attr = attrList.item(index)
          # this is most of the inheritable properties from http://www.w3.org/TR/SVG11/propidx.html
          # and http://www.w3.org/TR/SVGTiny12/attributeTable.html
          if attr.nodeName in ['clip-rule',
                               'display-align',
                               'fill', 'fill-opacity', 'fill-rule',
                               'font', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch',
                               'font-style', 'font-variant', 'font-weight',
                               'letter-spacing',
                               'pointer-events', 'shape-rendering',
                               'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin',
                               'stroke-miterlimit', 'stroke-opacity', 'stroke-width',
                               'text-anchor', 'text-decoration', 'text-rendering', 'visibility',
                               'word-spacing', 'writing-mode']:
              # we just add all the attributes from the first child
              commonAttrs[attr.nodeName] = attr.nodeValue
  
      # for each subsequent child element
      for childNum in range(len(childElements)):
          # skip first child
          if childNum == 0:
              continue
  
          child = childElements[childNum]
          # if we are on an animateXXX/set element, ignore it (due to the 'fill' attribute)
          if child.localName in ['set', 'animate', 'animateColor', 'animateTransform', 'animateMotion']:
              continue
  
          distinctAttrs = []
          # loop through all current 'common' attributes
          for name in commonAttrs:
              # if this child doesn't match that attribute, schedule it for removal
              if child.getAttribute(name) != commonAttrs[name]:
                  distinctAttrs.append(name)
          # remove those attributes which are not common
          for name in distinctAttrs:
              del commonAttrs[name]
  
      # commonAttrs now has all the inheritable attributes which are common among all child elements
      for name in commonAttrs:
          for child in childElements:
              child.removeAttribute(name)
          elem.setAttribute(name, commonAttrs[name])
  
      # update our statistic (we remove N*M attributes and add back in M attributes)
      num += (len(childElements) - 1) * len(commonAttrs)
      return num