private void merge(Node genNode, Node custNode) {

    NodeList list = custNode.getChildNodes();

    for (int i = 0; i < list.getLength(); i++) {

      Node custChildNode = list.item(i);

      if (custChildNode instanceof Text) {
        continue;
      }

      Node genChildNode = getNode(genNode, custChildNode.getNodeName());

      if (genChildNode != null) {

        String nodePath = getPath(genChildNode);

        if (replaceChildrenTags.contains(nodePath)) {

          merge(genChildNode, custChildNode);

        } else if (addChildrenTags.contains(nodePath)) {

          addChilds(custChildNode, genChildNode);

        } else if (includedInReplaceOrAdd(nodePath)) {

          merge(genChildNode, custChildNode);

        } else {

          // Replace entire node
          Node newNode = genNode.getOwnerDocument().importNode(custChildNode, true);
          genNode.replaceChild(newNode, genChildNode);
        }

      } else {

        // Add new node
        Node newNode = genNode.getOwnerDocument().importNode(custChildNode, true);
        genNode.appendChild(newNode);

      }
    }
  }