/**
   * Ensure that the element cloning handling of processChildren correctly copies and element to the
   * target element, including making sure that document references are properly cleaned up and
   * user_data in the original content does not refer to the target document
   *
   * @throws Exception
   */
  @Test
  public void testSafeCrossDocumentCloning() throws Exception {
    String template = "<test:Bar text='${foo.title}' data='${user}'/>";
    executeTemplate(template, "xmlns:test='" + TEST_NS + '\'');
    executeTemplate(template, "xmlns:test='" + TEST_NS + '\'');

    // This is a little hacky but is fine for testing purposes. Assumes that DOM implementation
    // is based on Xerces which will always has a userData hashtable
    Document doc = singletonElementHandler.elem.getOwnerDocument();
    Class<?> docClass = doc.getClass();
    Field userDataField = null;
    while (userDataField == null) {
      try {
        userDataField = docClass.getDeclaredField("userData");
      } catch (NoSuchFieldException nsfe) {
        // Ignore. Try the parent
      }
      docClass = docClass.getSuperclass();
    }
    // Access is typically protected so just bypass
    userDataField.setAccessible(true);
    Hashtable<?, ?> userDataMap = (Hashtable<?, ?>) userDataField.get(doc);

    // There should be only one element in the user data map, if there are more then the
    // cloning process has put them there which can be a nasty source of memory leaks. Consider
    // the case of this test where the singleton template is a shared and re-used template where
    // the  template documents userData starts to accumulate cloned nodes for every time that
    // template is rendered
    assertEquals(1, userDataMap.size());
  }
 public void setXmlVersion(String arg0) throws DOMException {
   // dynamic load to support jre 1.4 and 1.5
   try {
     Method m = doc.getClass().getMethod("setXmlVersion", new Class[] {arg0.getClass()});
     m.invoke(doc, new Object[] {arg0});
   } catch (Exception e) {
     throw new PageRuntimeException(Caster.toPageException(e));
   }
 }
 public void setStrictErrorChecking(boolean arg0) {
   // dynamic load to support jre 1.4 and 1.5
   try {
     Method m = doc.getClass().getMethod("setStrictErrorChecking", new Class[] {boolean.class});
     m.invoke(doc, new Object[] {Caster.toBoolean(arg0)});
   } catch (Exception e) {
     throw new PageRuntimeException(Caster.toPageException(e));
   }
 }
 public void setXmlStandalone(boolean arg0) throws DOMException {
   // dynamic load to support jre 1.4 and 1.5
   try {
     Method m = doc.getClass().getMethod("setXmlStandalone", new Class[] {boolean.class});
     m.invoke(doc, new Object[] {Caster.toBoolean(arg0)});
   } catch (Exception e) {
     throw new PageRuntimeException(Caster.toPageException(e));
   }
 }
 public void normalizeDocument() {
   // dynamic load to support jre 1.4 and 1.5
   try {
     Method m = doc.getClass().getMethod("normalizeDocument", new Class[] {});
     m.invoke(doc, ArrayUtil.OBJECT_EMPTY);
   } catch (Exception e) {
     throw new PageRuntimeException(Caster.toPageException(e));
   }
 }
 public String getXmlVersion() {
   // dynamic load to support jre 1.4 and 1.5
   try {
     Method m = doc.getClass().getMethod("getXmlVersion", new Class[] {});
     return Caster.toString(m.invoke(doc, ArrayUtil.OBJECT_EMPTY));
   } catch (Exception e) {
     throw new PageRuntimeException(Caster.toPageException(e));
   }
 }
 public boolean getXmlStandalone() {
   // dynamic load to support jre 1.4 and 1.5
   try {
     Method m = doc.getClass().getMethod("getXmlStandalone", new Class[] {});
     return Caster.toBooleanValue(m.invoke(doc, ArrayUtil.OBJECT_EMPTY));
   } catch (Exception e) {
     throw new PageRuntimeException(Caster.toPageException(e));
   }
 }
 public DOMConfiguration getDomConfig() {
   // dynamic load to support jre 1.4 and 1.5
   try {
     Method m = doc.getClass().getMethod("getDomConfig", new Class[] {});
     return (DOMConfiguration) m.invoke(doc, ArrayUtil.OBJECT_EMPTY);
   } catch (Exception e) {
     throw new PageRuntimeException(Caster.toPageException(e));
   }
 }
 public Node adoptNode(Node arg0) throws DOMException {
   // dynamic load to support jre 1.4 and 1.5
   try {
     Method m = doc.getClass().getMethod("adoptNode", new Class[] {arg0.getClass()});
     return Caster.toNode(m.invoke(doc, new Object[] {arg0}));
   } catch (Exception e) {
     throw new PageRuntimeException(Caster.toPageException(e));
   }
 }