private Object handeRootElementReplacement(
     final Object proxy, final Method method, final Document document, final Object valueToSet) {
   int count = document.getDocumentElement() == null ? 0 : 1;
   if (valueToSet == null) {
     DOMHelper.setDocumentElement(document, null);
     return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(count));
   }
   if (valueToSet instanceof Element) {
     Element clone = (Element) ((Element) valueToSet).cloneNode(true);
     document.adoptNode(clone);
     if (document.getDocumentElement() == null) {
       document.appendChild(clone);
       return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(1));
     }
     document.replaceChild(document.getDocumentElement(), clone);
     return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(1));
   }
   if (!(valueToSet instanceof DOMAccess)) {
     throw new IllegalArgumentException(
         "Method "
             + method
             + " was invoked as setter changing the document root element. Expected value type was a projection so I can determine a element name. But you provided a "
             + valueToSet);
   }
   DOMAccess projection = (DOMAccess) valueToSet;
   Element element = projection.getDOMBaseElement();
   assert element != null;
   DOMHelper.setDocumentElement(document, element);
   return getProxyReturnValueForMethod(proxy, method, Integer.valueOf(count));
 }
    /**
     * @param typeToSet
     * @param iterable
     * @param parentElement
     * @param duplexExpression
     * @param elementSelector
     */
    private int applyIterableSetOnElement(
        final Iterable<?> iterable,
        final Element parentElement,
        final DuplexExpression duplexExpression) {
      int changeCount = 0;
      for (Object o : iterable) {
        if (o == null) {
          continue;
        }
        if (!isStructureChangingValue(o)) {
          final Node newElement = duplexExpression.createChildWithPredicate(parentElement);
          final String asString =
              projector
                  .config()
                  .getStringRenderer()
                  .render(o.getClass(), o, duplexExpression.getExpressionFormatPattern());
          newElement.setTextContent(asString);
          ++changeCount;
          continue;
        }
        Element elementToAdd;

        if (o instanceof Node) {
          final Node n = (Node) o;
          elementToAdd =
              (Element)
                  (Node.DOCUMENT_NODE != n.getNodeType()
                      ? n
                      : n.getOwnerDocument() == null
                          ? null
                          : n.getOwnerDocument().getDocumentElement());
        } else {
          final DOMAccess p = (DOMAccess) o;
          elementToAdd = p.getDOMBaseElement();
        }
        if (elementToAdd == null) {
          continue;
        }

        Element clone = (Element) elementToAdd.cloneNode(true);
        Element childWithPredicate =
            (Element) duplexExpression.createChildWithPredicate(parentElement);
        final String elementName = childWithPredicate.getNodeName();
        if (!elementName.equals(clone.getNodeName())) {
          if (!"*".equals(elementName)) {
            clone = DOMHelper.renameElement(clone, elementName);
          }
        }
        DOMHelper.replaceElement(childWithPredicate, clone);
        ++changeCount;
      }
      return changeCount;
    }