code: private static List<Object> createEqualityKey(Node node) {
          List<Object> values = new ArrayList<Object>();
          values.add(node.getNodeType());
          values.add(node.getNodeName());
          values.add(node.getLocalName());
          values.add(node.getNamespaceURI());
          values.add(node.getPrefix());
          values.add(node.getNodeValue());
          for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
              values.add(child);
          }
  
          switch (node.getNodeType()) {
              case DOCUMENT_TYPE_NODE:
                  DocumentTypeImpl doctype = (DocumentTypeImpl) node;
                  values.add(doctype.getPublicId());
                  values.add(doctype.getSystemId());
                  values.add(doctype.getInternalSubset());
                  values.add(doctype.getEntities());
                  values.add(doctype.getNotations());
                  break;
  
              case ELEMENT_NODE:
                  Element element = (Element) node;
                  values.add(element.getAttributes());
                  break;
          }
  
          return values;
      }
docs: Returns a list of objects such that two nodes are equal if their lists
  are equal. Be careful: the lists may contain NamedNodeMaps and Nodes,
  neither of which override Object.equals(). Such values must be compared
  manually.