/**
   * Helper method to recursively insert all XML names for the given {@link ElementDescriptor} into
   * the roots array list. Keeps track of visited nodes to avoid infinite recursion. Also avoids
   * inserting the top {@link DocumentDescriptor} which is generally synthetic and not a valid root
   * element.
   */
  private void initRootElementDescriptor(
      ArrayList<String> roots, ElementDescriptor desc, HashSet<ElementDescriptor> visited) {
    if (!(desc instanceof DocumentDescriptor)) {
      String xmlName = desc.getXmlName();
      if (xmlName != null && xmlName.length() > 0) {
        roots.add(xmlName);
      }
    }

    visited.add(desc);

    for (ElementDescriptor child : desc.getChildren()) {
      if (!visited.contains(child)) {
        initRootElementDescriptor(roots, child, visited);
      }
    }
  }