docs: def merge(a, b):
      """Merge two unicode Robot Framework reports so that report 'b' is merged
      into report 'a'. This merge may not be complete and may be is lossy. Still,
      note that the original single test reports will remain untouched.
  
      """
      global loglevel
  
      # Iterate throughout the currently merged node set
      for child in b.iterchildren():
  
          # Merge suites
          if child.tag == 'suite':
              source = child.get('source')
              suites = a.xpath('suite[@source="%s"]' % source)
              # When matching suite is found, merge
              if suites:
                  merge(suites[0], child)
              # When no matching suite is found, append and fix ids
              else:
                  suites = a.xpath('suite')
                  child_id = child.get('id')
                  parent_id = a.get('id', '')
                  if parent_id:
                      suite_id = '%s-s%s' % (parent_id, str(len(suites) + 1))
                  else:
                      suite_id = 's%s' % str(len(suites) + 1)
                  for node in child.xpath('//*[contains(@id, "%s")]' % child_id):
                      node.set('id', re.sub('^%s' % child_id, suite_id,
                                            node.get('id')))
                  a.append(child)
                  # Gather separate top-level suites into a single top-level
                  # suite
              if a.tag == 'robot' and a.xpath('suite[@source]'):
                  for merge_root in a.xpath('suite[not(@source)]'):
                      mergeable = etree.Element('robot')
                      for suite in a.xpath('suite[@source]'):
                          mergeable.append(suite)
                      merge(merge_root, mergeable)
          # Merge keywords
          elif child.tag == 'kw':
              name = child.get('name')
              type_ = child.get('type')
              keywords = a.xpath('kw[@name="%s" and @type="%s"]' % (name, type_))
              # When matching keyword is found, merge
              if len(keywords) == 1:
                  merge(keywords[0], child)
              # When multiple matching keywords is found, merge with position
              elif len(keywords) > 1:
                  child_keywords = child.getparent().xpath(
                      'kw[@name="%s" and @type="%s"]' % (name, type_))
                  child_position = child_keywords.index(child)
                  merge(keywords[min(child_position, len(keywords) - 1)], child)
              # When no matching suite is found, append
              else:
                  a.append(child)
  
          # Merge (append) tests
          elif child.tag == 'test':
              tests = a.xpath('test')
              child.set('id', '%s-t%s' % (a.get('id'), str(len(tests) + 1)))
              a.append(child)
  
          # Merge (append) statuses
          elif child.tag == 'status':
              a.append(child)
  
          # Merge statistics
          elif child.tag == 'statistics':
              statistics = a.xpath('statistics')
              # When no statistics are found, append to root
              if not statistics:
                  a.append(child)
              # When statistics are found, merge matching or append
              else:
                  for grandchild in child.xpath('total'):
                      totals = a.xpath('statistics/total')
                      if totals:
                          merge(totals[0], grandchild)
                      else:
                          statistics.append(child)
                  for grandchild in child.xpath('suite'):
                      suites = a.xpath('statistics/suite')
                      if suites:
                          merge(suites[0], grandchild)
                      else:
                          statistics.append(child)
  
          # Merge individual statistics
          elif child.tag == 'stat':
              stats = a.xpath('stat[text() = "%s"]' % child.text)
              if stats:
                  stats[0].set('fail', str(int(stats[0].get('fail'))
                                           + int(child.get('fail'))))
                  stats[0].set('pass', str(int(stats[0].get('pass'))
                                           + int(child.get('pass'))))
              else:
                  suites = a.xpath('//suite[@name="%s"]' % child.get('name'))
                  if suites:
                      child.set('id', suites[0].get('id'))
                  a.append(child)
  
          # Merge errors
          elif child.tag == 'errors':
              errors = a.xpath('errors')
              # Filter by loglevel
              for grandchild in tuple(child.iterchildren()):
                  try:
                      level = int(getattr(logging, grandchild.get('level')))
                  except (TypeError, AttributeError, ValueError):
                      level = 0
                  if level < loglevel:
                      child.remove(grandchild)
              # When no errors are found, append to root
              if not errors:
                  a.append(child)
              # When errors are found, append the children
              else:
                  for grandchild in child.iterchildren():
                      errors[0].append(grandchild)