/*******************************************************************************
 * Copyright (c) 2006, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation
 *
 ******************************************************************************/
package org.eclipse.persistence.tools.mapping;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.persistence.tools.utility.ObjectTools;
import org.eclipse.persistence.tools.utility.StringTools;
import org.eclipse.persistence.tools.utility.TextRange;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * This abstract implementation of an {@link ExternalForm} defines common behavior for accessing and
 * manipulating an XML document.
 * <p>
 * Provisional API: This interface is part of an interim API that is still under development and
 * expected to change significantly before reaching stability. It is available at this early stage
 * to solicit feedback from pioneering adopters on the understanding that any code that uses this
 * API will almost certainly be broken (repeatedly) as the API evolves.<p>
 *
 * @see ExternalForm
 *
 * @version 2.6
 */
@SuppressWarnings("nls")
public abstract class AbstractExternalForm implements ExternalForm {

	/**
	 * A list of attribute names that will be used to insert a property at the right position.
	 */
	private List<String> attributeNamesOrder;

	/**
	 * A list of element names that will be used to insert a new child element at the right position.
	 */
	private List<String> elementNamesOrder;

	/**
	 * The parent of this external form or <code>null</code> if this is the root object.
	 */
	private AbstractExternalForm parent;

	/**
	 * The XML attribute identifier for the XML namespace.
	 */
	public static final String XMLNS_ATTRIBUTE = "xmlns";

	/**
	 * The namespace for all XML attributes.
	 */
	public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";

	/**
	 *
	 */
	public static final String XMLNS_XSI = "xmlns:xsi";

	/**
	 * The namespace of the XML representation of schema components.
	 */
	public static final String XSD_URI = "http://www.w3.org/2001/XMLSchema";

	/**
	 * The attribute name of the child text node for version.
	 */
	public static final String XSD_VERSION = "version";

	/**
	 *
	 */
	public static final String XSI_SCHEMA_LOCATION = "xsi:schemaLocation";

	/**
	 * The namespace of the XML Schema: Structures, which defines several attributes for direct use
	 * in any XML documents.
	 */
	public static final String XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";

	/**
	 * Creates a new <code>AbstractExternalForm</code>.
	 *
	 * @param parent The parent of this external form or <code>null</code> if this is the root object
	 */
	protected AbstractExternalForm(AbstractExternalForm parent) {
		super();
		this.parent = parent;
		this.initialize();
	}

	/**
	 * Acquires a lock before reading the document.
	 */
	public final void acquireReadLock() {
		getHelper().acquireReadLock();
	}

	/**
	 * Adds a new child element to the element represented by the given parent external form. The
	 * child element will be added at the end of the list of children.
	 *
	 * @param parent The external form representing the parent element where the child element will be added
	 * @param elementName The name of the new child element
	 * @return The newly created child element
	 */
	public final Element addChild(AbstractExternalForm parent, String elementName) {

		Element element = parent.getElement();

		if (element == null) {
			element = parent.addSelf();
		}

		return addChild(element, elementName, parent.getElementNamesOrder());
	}

	/**
	 * Adds a new child element to the given element. The child element will be added at the end of
	 * the list of children.
	 *
	 * @param parent The external form representing the parent element where the child element will be added
	 * @param elementName The name of the new child element
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 * @return The newly created child element
	 */
	public final Element addChild(AbstractExternalForm parent,
	                              String elementName,
	                              List<String> elementNamesOrder) {

		Element element = parent.getElement();

		if (element == null) {
			element = parent.addSelf();
		}

		return addChild(element, elementName, elementNamesOrder);
	}

	/**
	 * Adds a new child element to the given element. The child element will be added at the end of
	 * the list of children.
	 *
	 * @param element The element to which a new child element will be added
	 * @param elementName The name of the new child element
	 * @return The newly created child element
	 */
	protected Element addChild(Element element, String elementName) {
		return addChild(element, elementName, getElementNamesOrder());
	}

	/**
	 * Adds a new child element to the given element. The child element will be added at the end of
	 * the list of children.
	 *
	 * @param element The element to which a new child element will be added
	 * @param elementName The name of the new child element
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 * @return The newly created child element
	 */
	public final Element addChild(Element element,
	                              String elementName,
	                              List<String> elementNamesOrder) {

		// Add the child element
		Element childElement = getHelper().addChild(this, element, elementName, elementNamesOrder);

		// Notify the subclass the element has been added
		calculateInsertionIndex(element, childElement, elementName);

		return childElement;
	}

	/**
	 * Adds a new child element to the element represented by this external form. The child element
	 * will be added at the end of the list of element's children.
	 *
	 * @param elementName The name of the new child element
	 * @return The newly created child element
	 */
	public final Element addChild(String elementName) {

		Element element = getElement();

		if (element == null) {
			element = addSelf();
		}

		return addChild(element, elementName);
	}

	/**
	 * Adds a new child element to the element represented by this external form. The child element
	 * will be added at the end of the list of element's children.
	 *
	 * @param elementName The name of the new child element
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 * @return The newly created child element
	 */
	public final Element addChild(String elementName, List<String> elementNamesOrder) {

		Element element = getElement();

		if (element == null) {
			element = addSelf();
		}

		return addChild(element, elementName, elementNamesOrder);
	}

	/**
	 * Adds a child text node to the given parent element.
	 *
	 * @param element The element to which a new child element will be added
	 * @param elementName The name of the new child element
	 * @param value The node's text
	 * @return The newly created element
	 */
	public final Element addChildTextNode(Element element, String elementName, String value) {
		return addChildTextNode(element, elementName, value, getElementNamesOrder());
	}

	/**
	 * Adds a child text node to the given parent element.
	 *
	 * @param element The element to which a new child element will be added
	 * @param elementName The name of the new child element
	 * @param value The node's text
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 * @return The newly created element
	 */
	public final Element addChildTextNode(Element element,
	                                      String elementName,
	                                      String value,
	                                      List<String> elementNamesOrder) {

		return getHelper().addChildTextNode(this, element, elementName, value, elementNamesOrder);
	}

	/**
	 * Adds a child text node to the given parent element.
	 *
	 * @param elementName The name of the new child element
	 * @param value The node's text
	 * @return The newly created element
	 */
	public final Element addChildTextNode(String elementName, String value) {
		return addChildTextNode(elementName, value, getElementNamesOrder());
	}

	/**
	 * Adds a child text node to the given parent element.
	 *
	 * @param elementName The name of the new child element
	 * @param value The node's text
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 * @return The newly created element
	 */
	public final Element addChildTextNode(String elementName,
	                                      String value,
	                                      List<String> elementNamesOrder) {

		Element element = getElement();

		if ((element == null) && (value == null)) {
			return null;
		}

		if (element == null) {
			element = addSelf();
		}

		return addChildTextNode(element, elementName, value, elementNamesOrder);
	}

	/**
	 * Adds a new child element to the parent element that represents this model.
	 *
	 * @return The newly created child element
	 */
	public Element addSelf() {
		return addSelf(getElementName());
	}

	/**
	 * Adds a new child element to the parent element that represents this model.
	 *
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 * @return The newly created child element
	 */
	protected Element addSelf(List<String> elementNamesOrder) {
		return addSelf(getElementName(), elementNamesOrder);
	}

	/**
	 * Adds a new child element to the parent element that represents this model.
	 *
	 * @param elementName The new name of the node
	 * @return The newly created child element
	 */
	protected Element addSelf(String elementName) {
		return addSelf(elementName, getParent().getElementNamesOrder());
	}

	/**
	 * Adds a new child element to the parent element that represents this model.
	 *
	 * @param elementName The new name of the node
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 * @return The newly created child element
	 */
	public Element addSelf(String elementName, List<String> elementNamesOrder) {
		return addChild(getParent(), elementName, elementNamesOrder);
	}

	/**
	 * Adds an xmlns: attribute to the given element to register the given prefix. Does no checking
	 * for uniqueness. Also doesn't handle setting default namespace.
	 */
	public final void addXmlns(Element ownerElement, String prefix, String uri) {
		ownerElement.setAttributeNS(XMLNS_URI, "xmlns:" + prefix, uri);
	}

	/**
	 * Creates a list of attribute names that will be used to insert a property at the right position.
	 *
	 * @return The list of properties specifying the order
	 */
	protected List<String> buildAttributeNamesOrder() {
		return Collections.emptyList();
	}

	/**
	 * Creates a list of element names that will be used to insert a new child element at the right position.
	 *
	 * @return The list of element names specifying the order
	 */
	protected List<String> buildElementNamesOrder() {
		return Collections.emptyList();
	}

	/**
	 * Creates a fully qualified name by prepending the prefix to the given name.
	 *
	 * @param name The name to qualify with the prefix
	 * @return The fully qualified name if a prefix exists; otherwise the given name is returned
	 */
	public final String buildQualifiedName(String name) {

		String prefix = getPrefix();

		if (prefix == null) {
			return name;
		}

		return prefix + ":" + name;
	}

	/**
	 * Notifies this form's element has been added to its parent.
	 *
	 * @param parent The parent element
	 * @param child The child element that was added
	 * @param elementName The name of the new child element
	 */
	protected void calculateInsertionIndex(Element parent, Element child, String elementName) {
	}

	/**
	 * Retrieves the element that should follow the element with the given name by using the list of
	 * ordered element names.
	 *
	 * @param element The element to which a new child element will be added
	 * @param elementName The name of the new child element
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 */
	public final Element elementOfInsertion(Element element,
	                                        String elementName,
	                                        List<String> elementNamesOrder) {

		return (Element) nodeOfInsertion(
			element,
			getChildren(element),
			elementName,
			elementNamesOrder
		);
	}

	/**
	 * Retrieves the {@link Text} node from the given element if one exists.
	 *
	 * @param element The element from which its {@link Text} node will be returned
	 * @return The child {@link Text} node if it exists or <code>null</code> if none was found
	 */
	public final Text findTextNode(Element element) {

		NodeList children = element.getChildNodes();

		if (children == null) {
			return null;
		}

		for (int index = children.getLength(); --index >= 0; ) {
			Node childNode = children.item(index);
			if (isText(childNode)) {
				return (Text) childNode;
			}
		}

		return null;
	}

	/**
	 * Retrieves all the children of the element represented by this external form, elements and
	 * non-elements are included in the list.
	 *
	 * @return The list of children or an empty list if no children are present
	 */
	public final List<Node> getAllChildren() {

		Element element = getElement();

		if (element != null) {
			return getAllChildren(element);
		}

		return Collections.emptyList();
	}

	/**
	 * Retrieves all the children of the given element, elements and non-elements are included in the list.
	 *
	 * @param node The node to retrieve its children
	 * @return The list of children or an empty list if no children are present
	 */
	public final List<Node> getAllChildren(Node node) {

		acquireReadLock();

		try {
			List<Node> children = new ArrayList<Node>();
			NodeList childrenList = node.getChildNodes();

			if (childrenList != null) {
				for (int index = 0, count = childrenList.getLength(); index < count; index++) {
					children.add(childrenList.item(index));
				}
			}

			return children;
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Retrieves the count of the children the element represented by this external form. The count
	 * includes any type of child (elements and comments).
	 *
	 * @return The total count of children
	 */
	public final int getAllChildrenSize() {

		Element element = getElement();

		if (element != null) {
			return getAllChildrenSize(element);
		}

		return 0;
	}

	/**
	 * Retrieves all the children of the given node.
	 *
	 * @param node The parent node for which its children are requested
	 * @return The children of the given node or an empty list is returned if none was found
	 */
	public final int getAllChildrenSize(Node node) {

		acquireReadLock();

		try {
			NodeList childrenList = node.getChildNodes();
			return (childrenList != null) ? childrenList.getLength() : 0;
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Retrieves an attribute's value associated with the given property name from the given element.
	 *
	 * @param element The element used to retrieve the value of one of its properties
	 * @param attributeName The attribute name to retrieve it's value
	 * @return The value mapped to the given property name; an empty string is returned if it
	 * couldn't be retrieved
	 */
	public final String getAttribute(Element element, String attributeName) {

		acquireReadLock();

		try {

			if (element.hasAttribute(attributeName)) {
				return element.getAttribute(attributeName);
			}

			return null;
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Retrieves the attribute's value having the given name from this model's element.
	 *
	 * @param attributeName The name of the attribute
	 * @return The attribute's value
	 */
	public final String getAttribute(String attributeName) {

		Element element = getElement();

		if (element != null) {
			return getAttribute(element, attributeName);
		}

		return null;
	}

	/**
	 * Returns the order of the attributes of the element represented by this external form.
	 *
	 * @return The list of property names that determines the order of insertion
	 */
	public final List<String> getAttributeNamesOrder() {
		return attributeNamesOrder;
	}

	/**
	 * Retrieves an attribute's value associated with the given property name from the given element.
	 *
	 * @param element The element used to retrieve the value of one of its properties
	 * @param attributeName The name of the attribute, which will be prepended by the namespace
	 * @return The value mapped to the given property name; an empty string is returned if it couldn't be retrieved
	 */
	public final String getAttributeNS(Element element, String attributeName) {

		acquireReadLock();

		try {
			if (element.hasAttributeNS(XSI_URI, attributeName)) {
				return element.getAttributeNS(XSI_URI, attributeName);
			}

			return null;
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Retrieves the attribute's value having the given name from this model's element.
	 *
	 * @param attributeName The name of the attribute, which will be prepended by the namespace
	 * @return The attribute's value
	 */
	public final String getAttributeNS(String attributeName) {

		Element element = getElement();

		if (element != null) {
			return getAttributeNS(element, attributeName);
		}

		return null;
	}

	/**
	 * Retrieves the list of attributes for the given element.
	 *
	 * @param element The element to retrieve its list of attributes
	 * @return The attributes for the given element
	 */
	public final List<Attr> getAttributes(Element element) {

		List<Attr> attributes = new ArrayList<Attr>();
		NamedNodeMap map = element.getAttributes();

		if (map != null) {
			for (int index = 0, count = map.getLength(); index < count; index++) {
				Node node = map.item(index);
				if (isAttribute(node)) {
					attributes.add((Attr) node);
				}
			}
		}

		return attributes;
	}

	/**
	 * Retrieves the {@link TextRange} for the given {@link Attr} within the document.
	 *
	 * @param attribute The {@link Attr} to retrieve its {@link TextRange}
	 * @return The {@link TextRange} of the given {@link Attr}'s value
	 */
	public final TextRange getAttributeTextRange(Attr attribute) {

		if (attribute == null) {
			return null;
		}

		return getHelper().getTextRange(this, attribute);
	}

	/**
	 * Retrieves an attribute's {@linkTextRange} associated with the given property name from the
	 * given element.
	 *
	 * @param element The element used to retrieve the value of one of its properties
	 * @param attributeName The attribute name to retrieve it's {@link TextRange}
	 * @return The {@linkTextRange} of the value associated with the given property name or
	 * <code>null</code> is returned if it couldn't be retrieved
	 */
	public final TextRange getAttributeTextRange(Element element, String attributeName) {

		acquireReadLock();

		try {

			if (element.hasAttribute(attributeName)) {
				Attr attribute = element.getAttributeNode(attributeName);
				return getAttributeTextRange(attribute);
			}

			return getTextRange(element);
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Retrieves the attribute's {@link TextRange} having the given name from this model's element.
	 *
	 * @param attributeName The name of the attribute
	 * @return The attribute's {@link TextRange}
	 */
	public final TextRange getAttributeTextRange(String attributeName) {

		Element element = getElement();

		if (element != null) {
			return getAttributeTextRange(element, attributeName);
		}

		return null;
	}

	/**
	 * Retrieves the attribute's value having the given name from this model's element.
	 *
	 * @param element The element where the attribute's value is located
	 * @param attributeName The name of the attribute
	 * @return The attribute's value
	 */
	public final Boolean getBooleanAttribute(Element element, String attributeName) {

		String value = getAttribute(element, attributeName);

		if (value == null) {
			return null;
		}

		return Boolean.valueOf(value);
	}

	/**
	 * Retrieves the attribute's value having the given name from this model's element.
	 *
	 * @param attributeName The name of the attribute
	 * @return The attribute's value
	 */
	public final Boolean getBooleanAttribute(String attributeName) {

		Element element = getElement();

		if (element == null) {
			return null;
		}

		return getBooleanAttribute(element, attributeName);
	}

	/**
	 * Retrieves the element with the given name.
	 *
	 * @param parent The parent of this external form used to retrieve the parent element
	 * @param elementName The name of the child to retrieve if it could not be found
	 */
	public final Element getChild(AbstractExternalForm parent, String elementName) {
		return getChild(parent.getElement(), elementName);
	}

	/**
	 * Retrieves the element with the given name.
	 *
	 * @param parent The parent of this external form used to retrieve the parent element
	 * @param elementName The name of the child to retrieve
	 * @param index The position of the child to retrieve among the children
	 * @return The element with the given name or <code>null</code> if it could not be found
	 */
	public final Element getChild(AbstractExternalForm parent, String elementName, int index) {
		return getChild(parent.getElement(), elementName, index);
	}

	/**
	 * Retrieves the XML element with the given name that is the direct child of the given
	 * parent node.
	 *
	 * @param node The node for which one of its children is requested
	 * @param index The position of the child to retrieve among the children
	 * @return The element at the given position if it was found; <code>null</code> otherwise
	 */
	public final Element getChild(Node node, int index) {

		List<Element> children = getChildren(node);

		if (index >= children.size()) {
			return null;
		}

		return children.get(index);
	}

	/**
	 * Retrieves the XML element with the given name that is the direct child of the given node.
	 *
	 * @param node The parent node for which one of its children is requested
	 * @param elementName The name of the children to retrieve
	 * @return The element with the given name if it was found; <code>null</code> otherwise
	 */
	public final Element getChild(Node node, String elementName) {

		acquireReadLock();

		try {

			for (Element child : getChildren(node)) {
				if (ObjectTools.equals(child.getNodeName(), elementName)) {
					return child;
				}
			}

			return null;
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Retrieves the element with the given name.
	 *
	 * @param node The parent element from which to search for the child element
	 * @param elementName The name of the child to retrieve
	 * @param index The position of the child to retrieve among the children
	 * @return The element with the given name or <code>null</code> if it could not be found
	 */
	public final Element getChild(Node node, String elementName, int index) {

		if (index < 0) {
			return null;
		}

		List<Element> children = getChildren(node, elementName);

		if (index >= children.size()) {
			return null;
		}

		return children.get(index);
	}

	/**
	 * Retrieves the element with the given name that is a child of the element
	 * represented by this model.
	 *
	 * @param elementName The name of the child element to retrieve
	 * @return The element with the given name or <code>null</code> if it could not be found
	 */
	public final Element getChild(String elementName) {

		Element element = getElement();

		if (element != null) {
			element = getChild(element, elementName);
		}

		return element;
	}

	/**
	 * Retrieves the element with the given name that is a child of the element
	 * represented by this model.
	 *
	 * @param elementName The name of the child element to retrieve
	 * @param index
	 * @return The element with the given name or <code>null</code> if it could not be found
	 */
	public final Element getChild(String elementName, int index) {

		Element element = getElement();

		if (element != null) {
			element = getChild(element, elementName, index);
		}

		return element;
	}

	/**
	 * Retrieves the attribute's value associated with the given attribute name that is defined in
	 * the child element with the given name.
	 *
	 * @param childName The name of the child for which the attribute's value is retrieved
	 * @param attributeName The name of the attribute to retrieve its value
	 * @return The value of the attribute
	 */
	public final String getChildAttribute(Node element, String childName, String attributeName) {

		Element childNode = getChild(element, childName);

		if (childNode == null) {
			return null;
		}

		return getAttribute(childNode, attributeName);
	}

	/**
	 * Retrieves the attribute's value associated with the given attribute name that is defined in
	 * the child element with the given name.
	 *
	 * @param childName The name of the child for which the attribute's value is retrieved
	 * @param attributeName The name of the attribute to retrieve its value
	 * @return The value of the attribute
	 */
	public final String getChildAttribute(String childName, String attributeName) {

		Element element = getChild(childName);

		if (element != null) {
			return getAttribute(element, attributeName);
		}

		return null;
	}

	/**
	 * Retrieves the {@link TextRange} of the attribute's value.
	 *
	 * @param childName The name of the child for which the {@link TextRange} of the attribute's
	 * value should be retrieved
	 * @param attributeName The name of the attribute to retrieve the {@link TextRange} of its value
	 * @return The {@link TextRange} of the attribute's value
	 */
	public final TextRange getChildAttributeTextRange(String childName, String attributeName) {

		Element element = getChild(childName);

		if (element != null) {
			return getAttributeTextRange(element, attributeName);
		}

		return null;
	}

	/**
	 * Returns the <code>Boolean</code> representation of the child's attribute.
	 *
	 * @param elementName The name of the child element for which to retrieve its given attribute's value
	 * @param attributeName The name of the attribute to retrieve its value
	 * @return The <code>Boolean</code> value of the child node's value
	 */
	public final Boolean getChildBooleanAttribute(Node element,
	                                              String elementName,
	                                              String attributeName) {

		String value = getChildAttribute(element, elementName, attributeName);

		if (value != null) {
			return Boolean.valueOf(value);
		}

		return null;
	}

	/**
	 * Returns the <code>Boolean</code> representation of the child's attribute.
	 *
	 * @param elementName The name of the child element for which to retrieve its given attribute's value
	 * @param attributeName The name of the attribute to retrieve its value
	 * @return The <code>Boolean</code> value of the child node's value
	 */
	public final Boolean getChildBooleanAttribute(String elementName, String attributeName) {

		Element element = getElement();

		if (element != null) {
			return getChildBooleanAttribute(element, elementName, attributeName);
		}

		return null;
	}

	/**
	 * Returns the <code>Boolean</code> representation of the child node's text.
	 *
	 * @param elementName The name of the child element to retrieve its value
	 * @return The <code>Boolean</code> value of the child node's value
	 */
	public final Boolean getChildBooleanNode(Node element, String elementName) {

		String value = getChildTextNode(element, elementName);

		if (value != null) {
			return Boolean.valueOf(value);
		}

		return null;
	}

	/**
	 * Returns the <code>Boolean</code> representation of the child node's text.
	 *
	 * @param elementName The name of the child element to retrieve its value
	 * @return The <code>Boolean</code> value of the child node's value
	 */
	public final Boolean getChildBooleanNode(String elementName) {

		Element element = getElement();

		if (element != null) {
			return getChildBooleanNode(element, elementName);
		}

		return null;
	}

	/**
	 * Returns the {@link Enum} representation of the child's attribute.
	 *
	 * @param node The parent node to retrieve its child
	 * @param elementName The name of the child element for which to retrieve its given attribute's value
	 * @param attributeName The name of the attribute to retrieve its value
	 * @param enumClass The type of the enumeration used to retrieve the constant
	 * @param <T> The type of the enumeration
	 * @return The {@link Enum} value of the child node's value
	 */
	public final <T extends Enum<T>> T getChildEnumAttribute(Node node,
	                                                         String elementName,
	                                                         String attributeName,
	                                                         Class<T> enumClass) {

		String value = getChildAttribute(node, elementName, attributeName);

		if (value != null) {
			try {
				return Enum.valueOf(enumClass, value);
			}
			catch (Exception e) {
				// Ignore, it's not a valid enum constant
			}
		}

		return null;
	}

	/**
	 * Returns the {@link Enum} representation of the child's attribute.
	 *
	 * @param elementName The name of the child element for which to retrieve its given attribute's value
	 * @param attributeName The name of the attribute to retrieve its value
	 * @param enumClass The type of the enumeration used to retrieve the constant
	 * @param <T> The type of the enumeration
	 * @return The {@link Enum} value of the child node's value
	 */
	public final <T extends Enum<T>> T getChildEnumAttribute(String elementName,
	                                                         String attributeName,
	                                                         Class<T> enumClass) {

		Element element = getElement();

		if (element != null) {
			return getChildEnumAttribute(element, elementName, attributeName, enumClass);
		}

		return null;
	}

	/**
	 * Returns the {@link Enum} representation of the child node's text.
	 *
	 * @param node The parent node to retrieve its child
	 * @param elementName The name of the child to retrieve
	 * @param enumClass The type of the enumeration used to retrieve the constant
	 * @param <T> The type of the enumeration
	 * @return The {@link Enum} value of the child node's value
	 */
	public final <T extends Enum<T>> T getChildEnumNode(Node node,
	                                                       String elementName,
	                                                       Class<T> enumClass) {

		String value = getChildTextNode(node, elementName);

		if (value != null) {
			try {
				return Enum.valueOf(enumClass, value);
			}
			catch (Exception e) {
				// Ignore, it's not a valid enum constant
			}
		}

		return null;
	}

	/**
	 * Returns the {@link Enum} representation of the child node's text.
	 *
	 * @param elementName The name of the child to retrieve
	 * @param enumClass The type of the enumeration used to retrieve the constant
	 * @param <T> The type of the enumeration
	 * @return The {@link Enum} value of the child node's value
	 */
	public final <T extends Enum<T>> T getChildEnumNode(String elementName, Class<T> enumClass) {

		Element element = getElement();

		if (element != null) {
			return getChildEnumNode(element, elementName, enumClass);
		}

		return null;
	}

	/**
	 * Returns the {@link Integer} value of a child text node that is the child of the given element.
	 *
	 * @param element The parent element
	 * @param elementName The name of the child element for which to retrieve its given attribute's value
	 * @param attributeName The name of the attribute to retrieve its value
	 * @return The {@link Integer} of the child element or <code>null</code> if the element is not defined
	 */
	public final Integer getChildIntegerAttribute(Node element,
	                                              String elementName,
	                                              String attributeName) {

		String value = getChildAttribute(element, elementName, attributeName);

		if (value == null) {
			return null;
		}

		try {
			return Integer.valueOf(value);
		}
		catch (Exception e) {
			return null;
		}
	}

	/**
	 * Returns the {@link Integer} value of a child text node that is the child of the element
	 * represented by this external form.
	 *
	 * @param elementName The name of the child element for which to retrieve its given attribute's value
	 * @param attributeName The name of the attribute to retrieve its value
	 * @return The {@link Integer} of the child element or <code>null</code> if the element is not defined
	 */
	public final Integer getChildIntegerAttribute(String elementName, String attributeName) {

		Element element = getElement();

		if (element != null) {
			return getChildIntegerAttribute(element, elementName, attributeName);
		}

		return null;
	}

	/**
	 * Returns the {@link Integer} value of a child text node that is the child of the given element.
	 *
	 * @param element The parent element
	 * @param elementName The name of the child element to retrieve its value
	 * @return The {@link Integer} of the child element or <code>null</code> if the element is not defined
	 */
	public final Integer getChildIntegerNode(Node element, String elementName) {

		String value = getChildTextNode(element, elementName);

		if (value == null) {
			return null;
		}

		try {
			return Integer.valueOf(value);
		}
		catch (Exception e) {
			return null;
		}
	}

	/**
	 * Returns the {@link Integer} value of a child text node that is the child of the element
	 * represented by this external form.
	 *
	 * @param elementName The name of the child element to retrieve its value
	 * @return The {@link Integer} of the child element or <code>null</code> if the element is not defined
	 */
	public final Integer getChildIntegerNode(String elementName) {

		Element element = getElement();

		if (element != null) {
			return getChildIntegerNode(element, elementName);
		}

		return null;
	}

	/**
	 * Retrieves the elements that are the direct children of the given parent node.
	 *
	 * @return The elements that are children of the parent node or an empty list is returned if none was found
	 */
	public final List<Element> getChildren() {

		Element element = getElement();

		if (element != null) {
			return getChildren(element);
		}

		return Collections.emptyList();
	}

	/**
	 * Retrieves the XML elements that are the direct children of the given parent node.
	 *
	 * @param node The node for which its children are requested
	 * @return The elements that are children of the parent node or an empty list is returned if none was found
	 */
	public final List<Element> getChildren(Node node) {

		acquireReadLock();

		try {

			List<Element> children = new ArrayList<Element>();
			NodeList childrenList = node.getChildNodes();

			if (childrenList != null) {
				for (int index = 0, count = childrenList.getLength(); index < count; index++) {
					Node child = childrenList.item(index);
					if (isElement(child)) {
						children.add((Element) child);
					}
				}
			}

			return children;
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Retrieves the XML elements that are the direct children of the given parent node.
	 *
	 * @param node The parent node for which its children are requested
	 * @param elementNames The collection of names that count as a child of the given node
	 * @return The elements that are children of the parent node or an empty list is returned if none was found
	 */
	public final List<Element> getChildren(Node node, Collection<String> elementNames) {

		acquireReadLock();

		try {

			List<Element> children = getChildren(node);

			for (Iterator<Element> iter = children.iterator(); iter.hasNext(); ) {
				Element element = iter.next();
				String elementName = element.getNodeName();

				if (!elementNames.contains(elementName)) {
					iter.remove();
				}
			}

			return children;
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Retrieves the XML elements that are the direct children of the given parent node.
	 *
	 * @param node The parent node for which its children are requested
	 * @param elementName The name of the element to retrieve
	 * @return The elements that are children of the parent node or an empty list is returned if none was found
	 */
	public final List<Element> getChildren(Node node, String elementName) {

		acquireReadLock();

		try {

			List<Element> children = getChildren(node);

			for (Iterator<Element> iter = children.iterator(); iter.hasNext();) {
				Element element = iter.next();

				if (ObjectTools.notEquals(element.getNodeName(), elementName)) {
					iter.remove();
				}
			}

			return children;
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Retrieves the XML elements that are the direct children of the given parent node.
	 *
	 * @param elementName The name of the element to retrieve
	 * @return The elements that are children of the parent node or an empty list is returned if none was found
	 */
	public final List<Element> getChildren(String elementName) {

		Element element = getElement();

		if (element != null) {
			return getChildren(element, elementName);
		}

		return Collections.emptyList();
	}

	/**
	 * Retrieves the XML elements that are the direct children of the given parent node.
	 *
	 * @return The count of child nodes
	 */
	public final int getChildrenSize() {
		return getChildren().size();
	}

	/**
	 * Retrieves the XML elements that are the direct children of the given parent node.
	 *
	 * @param node The count of children for this node
	 * @return The count of child nodes listed under the given node
	 */
	public final int getChildrenSize(Node node) {
		return getChildren(node).size();
	}

	/**
	 * Retrieves the XML elements that are the direct children of the given parent node.
	 *
	 * @param element The parent element to retrieve the count of child nodes it has with the given element name
	 * @param elementNames The collection of names that count as a child of the given node
	 * @return The count of child nodes with the given element name
	 */
	public final int getChildrenSize(Node element, Collection<String> elementNames) {
		return getChildren(element, elementNames).size();
	}

	/**
	 * Retrieves the XML elements that are the direct children of the given parent node.
	 *
	 * @param element The parent element to retrieve the count of child nodes it has with the given element name
	 * @param elementName The name of the element to retrieve
	 * @return The count of child nodes with the given element name
	 */
	public final int getChildrenSize(Node element, String elementName) {
		return getChildren(element, elementName).size();
	}

	/**
	 * Retrieves the XML elements that are the direct children of the given parent node.
	 *
	 * @param elementName The name of the element to retrieve
	 * @return The count of child nodes with the given element name
	 */
	public final int getChildrenSize(String elementName) {
		return getChildren(elementName).size();
	}

	/**
	 * Returns the texts of the text nodes that are the children of the given parent.
	 * <p>
	 * Form: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param node The parent element
	 * @param elementName The name of the child element to retrieve its value
	 * @return The text of the child element or <code>null</code> if the element is not defined
	 */
	public final List<String> getChildrenTextNode(Node node, String elementName) {

		acquireReadLock();

		try {
			List<String> values = new ArrayList<String>();

			for (Element element : getChildren(node, elementName)) {
				values.add(element.getTextContent());
			}

			return values;
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Returns the texts of the text nodes that are the children of the given parent.
	 * <p>
	 * Form: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param elementName The name of the child element to retrieve its value
	 * @return The text of the child element or <code>null</code> if the element is not defined
	 */
	public final List<String> getChildrenTextNode(String elementName) {

		Element element = getElement();

		if (element != null) {
			return getChildrenTextNode(element, elementName);
		}

		return Collections.emptyList();
	}

	/**
	 * Returns the text of a child node that is the child of the given element.
	 * <p>Form: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param node The parent node
	 * @param elementName The name of the child element to retrieve its value
	 * @return The text of the child element or <code>null</code> if the element is not defined
	 */
	public final String getChildTextNode(Node node, String elementName) {

		Element child = getChild(node, elementName);

		if (child != null) {
			return getTextNode(child);
		}

		return null;
	}

	/**
	 * Returns the child node that is the child of the given element with the given text.
	 * <p>Form: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param node The parent node
	 * @param elementName The name of the child element to retrieve its value
	 * @param index The nth child that has the same element name and text value
	 * @return The text of the child element or <code>null</code> if the element is not defined
	 */
	public final String getChildTextNode(Node node, String elementName, int index) {

		Element element = getChild(node, elementName, index);

		if (element != null) {
			return getTextNode(element);
		}

		return null;
	}

	/**
	 * Returns the child node that is the child of the given element with the given text.
	 * <p>Form: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param node The parent node
	 * @param elementName The name of the child element to retrieve its value
	 * @param index The nth child that has the same element name and text value
	 * @param text The text of the child element to retrieve its {@link TextRange}
	 * @return The text of the child element or <code>null</code> if the element is not defined
	 */
	public final Element getChildTextNode(Node node, String elementName, int index, String text) {

		int nodeIndex = 0;

		for (Element child : getChildren(node, elementName)) {
			String childText = getTextNode(child);
			if (childText.equals(text)) {
				if (nodeIndex == index) {
					return child;
				}
				nodeIndex++;
			}
		}

		return null;
	}

	/**
	 * Returns the child node that is the child of the given element with the given text.
	 * <p>Form: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param node The parent node
	 * @param elementName The name of the child element to retrieve its value
	 * @param text The text of the child element to retrieve its {@link TextRange}
	 * @return The text of the child element or <code>null</code> if the element is not defined
	 */
	public final Element getChildTextNode(Node node, String elementName, String text) {

		for (Element child : getChildren(node, elementName)) {
			String childText = getTextNode(child);
			if (childText.equals(text)) {
				return child;
			}
		}

		return null;
	}

	/**
	 * Returns the text of a child node: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param elementName The name of the child element to retrieve its value
	 * @return The text of the child element or <code>null</code> if the element is not defined
	 */
	public final String getChildTextNode(String elementName) {

		Element element = getElement();

		if (element != null) {
			return getChildTextNode(element, elementName);
		}

		return null;
	}

	/**
	 * Returns the text of a child node: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param elementName The name of the child element to retrieve its value
	 * @param index The position of the child to retrieve its value
	 * @return The text of the child element or <code>null</code> if the element is not defined
	 */
	public final String getChildTextNode(String elementName, int index) {

		Element element = getElement();

		if (element != null) {
			return getChildTextNode(element, elementName, index);
		}

		return null;
	}

	/**
	 * Returns the text of a child node that is the child of the given element.
	 * <p>Form: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param childName The child to retrieve it's child text node's value
	 * @param elementName The name of the child element to retrieve its value
	 * @return The text of the child element or <code>null</code> if the element is not defined
	 */
	public final String getChildTextNode(String childName, String elementName) {

		Element child = getChild(childName);

		if (child != null) {
			return getChildTextNode(child, elementName);
		}

		return null;
	}

	/**
	 * Returns the {@link TextRange} of a child node that is the child of the given element.
	 * <p>Form: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param node The parent node
	 * @param elementName The name of the child element to retrieve its value's {@link TextRange}
	 * @return The {@link TextRange} of the child element or <code>null</code> if the element is not defined
	 */
	public final TextRange getChildTextNodeTextRange(Node node, String elementName) {

		Element child = getChild(node, elementName);

		if (child != null) {
			return getTextNodeTextRange(child);
		}

		return null;
	}

	/**
	 * Returns the {@link TextRange} of a child node that is the child of the given element.
	 * <p>Form: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param node The parent node
	 * @param elementName The name of the child element to retrieve its value's {@link TextRange}
	 * @param index The nth child node to retrieve that has the same element name and text node
	 * @param textNode The text of the child element to retrieve its {@link TextRange}
	 * @return The {@link TextRange} of the child element or <code>null</code> if the element is not defined
	 */
	public final TextRange getChildTextNodeTextRange(Node node,
	                                                 String elementName,
	                                                 int index,
	                                                 String textNode) {

		Element child = getChildTextNode(node, elementName, index, textNode);

		if (child != null) {
			return getTextNodeTextRange(child);
		}

		return null;
	}

	/**
	 * Returns the {@link TextRange} of a child node that is the child of the given element.
	 * <p>Form: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param node The parent node
	 * @param elementName The name of the child element to retrieve its value's {@link TextRange}
	 * @param textNode The text of the child element to retrieve its {@link TextRange}
	 * @return The {@link TextRange} of the child element or <code>null</code> if the element is not defined
	 */
	public final TextRange getChildTextNodeTextRange(Node node,
	                                                 String elementName,
	                                                 String textNode) {

		Element child = getChildTextNode(node, elementName, textNode);

		if (child != null) {
			return getTextNodeTextRange(child);
		}

		return null;
	}

	/**
	 * Returns the {@link TextRange} of a child node's value: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param elementName The name of the child element to retrieve its value's {@link TextRange}
	 * @return The {@link TextRange} of the child element or <code>null</code> if the element is not defined
	 */
	public final TextRange getChildTextNodeTextRange(String elementName) {

		Element element = getElement();

		if (element != null) {
			return getChildTextNodeTextRange(element, elementName);
		}

		return null;
	}

	/**
	 * Returns the {@link TextRange} of a child node's value: &lt;elementName&gt;text&lt;/elementName&gt;
	 * at a specific location.
	 *
	 * @param elementName The name of the child element to retrieve its value's {@link TextRange}
	 * @param index The position of the child text node to retrieve its {@link TextRange}
	 * @return The {@link TextRange} of the child element or <code>null</code> if the element is not defined
	 */
	public final TextRange getChildTextNodeTextRange(String elementName, int index) {

		Element element = getChild(elementName, index);

		if (element != null) {
			return getTextNodeTextRange(element);
		}

		return null;
	}

	/**
	 * Returns the {@link TextRange} of a child node's value: &lt;elementName&gt;text&lt;/elementName&gt;
	 * at a specific location.
	 *
	 * @param elementName The name of the child element to retrieve its value's {@link TextRange}
	 * @param index The position of the child text node to retrieve its {@link TextRange}
	 * @param textNode The text of the child element to retrieve its {@link TextRange}
	 * @return The {@link TextRange} of the child element or <code>null</code> if the element is not defined
	 */
	public final TextRange getChildTextNodeTextRange(String elementName,
	                                                    int index,
	                                                    String textNode) {

		Element element = getElement();

		if (element != null) {
			return getChildTextNodeTextRange(element, elementName, index, textNode);
		}

		return null;
	}

	/**
	 * Returns the {@link TextRange} of a child node's value: &lt;elementName&gt;text&lt;/elementName&gt;.
	 *
	 * @param elementName The name of the child element to retrieve its value's {@link TextRange}
	 * @param textNode The text of the child element to retrieve its {@link TextRange}
	 * @return The {@link TextRange} of the child element or <code>null</code> if the element is not defined
	 */
	public final TextRange getChildTextNodeTextRange(String elementName, String textNode) {

		Element element = getElement();

		if (element != null) {
			return getChildTextNodeTextRange(element, elementName, textNode);
		}

		return null;
	}

	/**
	 * Retrieves the {@link TextRange} of the first child with the given name.
	 *
	 * @param childName The name of the child to retrieve its {@link TextRange}
	 * @return The {@link TextRange} of the child node
	 */
	public final TextRange getChildTextRange(String childName) {

		Element element = getChild(childName);

		if (element != null) {
			return getTextRange(element);
		}

		return null;
	}

	/**
	 * Retrieves the XML document.
	 *
	 * @return The XML document
	 */
	public final Document getDocument() {
		return getHelper().getDocument();
	}

	/**
	 * Retrieves the XML element representing this model.
	 *
	 * @return The child element retrieved from its parent element that represents the XML structure
	 * of this model
	 */
	protected Element getElement() {
		return getChild(getParent(), getElementName());
	}

	/**
	 * Returns the name used to store the information in the XML document.
	 *
	 * @return A non-<code>null</code> value used to retrieve the element from the XML document
	 */
	protected abstract String getElementName();

	/**
	 * Returns the order of the child elements.
	 *
	 * @return The list of element names that determines the order of insertion
	 */
	public final List<String> getElementNamesOrder() {
		return elementNamesOrder;
	}

	/**
	 * Retrieves the {@link TextRange} for the name of the given {@link Element} within the document.
	 *
	 * @param attribute The {@link Element} to retrieve the {@link TextRange} for its name
	 * @return The {@link TextRange} of the given {@link Element}'s name
	 */
	public final TextRange getElementNameTextRange(Element element) {

		if (element == null) {
			return null;
		}

		return getHelper().getElementNameTextRange(this, element);
	}

	/**
	 * Retrieves the attribute's value having the given name from this model's
	 * element.
	 *
	 * @param element The element where the attribute's value is located
	 * @param attributeName The name of the attribute
	 * @return The attribute's value
	 */
	public final <T extends Enum<T>> T getEnumAttribute(Element element,
	                                                    String attributeName,
	                                                    Class<T> enumClass) {

		String value = getAttribute(element, attributeName);

		if (value != null) {
			try {
				return Enum.valueOf(enumClass, value);
			}
			catch (Exception e) {
				// Invalid property
			}
		}

		return null;
	}

	/**
	 * Retrieves the attribute's value having the given name from this model's element.
	 *
	 * @param attributeName The name of the attribute
	 * @return The attribute's value
	 */
	public final <T extends Enum<T>> T getEnumAttribute(String attributeName, Class<T> enumClass) {

		Element element = getElement();

		if (element == null) {
			return null;
		}

		return getEnumAttribute(element, attributeName, enumClass);
	}

	/**
	 * Returns the helper that completes the behavior of this form.
	 *
	 * @return The helper that is called when the document needs to be modified
	 */
	protected ExternalFormHelper getHelper() {
		return getRoot().getHelper();
	}

	/**
	 * Retrieves the attribute's value having the given name from this model's element.
	 *
	 * @param element The element where the attribute's value is located
	 * @param attributeName The name of the attribute
	 * @return The attribute's value
	 */
	public final Integer getIntegerAttribute(Element element, String attributeName) {

		String value = getAttribute(attributeName);

		if (value != null) {
			try {
				return Integer.valueOf(value);
			}
			catch (Exception e) {
				// Invalid property
			}
		}

		return null;
	}

	/**
	 * Retrieves the attribute's value having the given name from this model's element.
	 *
	 * @param attributeName The name of the attribute
	 * @return The attribute's value
	 */
	public final Integer getIntegerAttribute(String attributeName) {

		Element element = getElement();

		if (element == null) {
			return null;
		}

		return getIntegerAttribute(element, attributeName);
	}

	/**
	 * Returns the namespace of the root element for this external form.
	 *
	 * @param uri The URI of the namespace
	 */
	public final String getNamespace() {

		Element element = getRootElement();

		if (element != null) {
			return getAttribute(element, XMLNS_ATTRIBUTE);
		}

		return null;
	}

	/**
	 * Retrieves the name of the given node.
	 * <p>
	 * Example: &lt;name&gt;...&lt;/name&gt; where "name" will be returned for the element.
	 * <p>
	 * Example: &lt;node "key"="value"/&gt; where "key" will be returned for the attribute.
	 *
	 * @param node The node to retrieve its name
	 * @return The element name of the given node
	 */
	public final String getNodeName(Node node) {

		acquireReadLock();

		try {
			return node.getNodeName();
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Returns the parent of this object.
	 *
	 * @return The parent of this object, <code>null</code> is never returned
	 */
	public AbstractExternalForm getParent() {
		return parent;
	}

	/**
	 * Retrieves the XML element representing by the parent model.
	 *
	 * @return The element of the parent form
	 */
	public final Element getParentElement() {
		return getParent().getElement();
	}

	/**
	 * Retrieves the prefix representing the XML schema nodes. It is declared in the root element's properties.
	 *
	 * @return The prefix defined in the root element properties or <code>null</code> if it is not defined
	 */
	public final String getPrefix() {

		// The root element needs to be retrieved before acquiring a read lock
		// in case the root element doesn't yet exist
		Element element = getRootElement();

		acquireReadLock();

		try {
			NamedNodeMap attributes = element.getAttributes();

			if (attributes != null) {

				for (int index = attributes.getLength(); --index >= 0; ) {

					Node node = attributes.item(index);
					String localName = node.getNodeName();
					String value = node.getNodeValue();

					if (localName != null &&
					    localName.startsWith("xmlns:") &&
					    XSI_URI.equals(value)) {

						return localName.substring("xmlns:".length());
					}
				}
			}

			return null;
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Retrieves the root of the model object hierarchy.
	 *
	 * @return The top node of the model object hierarchy
	 */
	public final AbstractExternalForm getRoot() {
		return (parent == null) ? this : parent.getRoot();
	}

	/**
	 * Retrieves the root element from the XML document. If the element could not be found, it will
	 * be automatically added.
	 *
	 * @return The root of the XML model hierarchy
	 */
	public final Element getRootElement() {

		Document document = getDocument();
		String rootElementName = getRoot().getElementName();
		Element element = getChild(document, rootElementName);

		if (element == null) {

			// First make sure there are no root element with a different name
			for (Element child : getChildren(document)) {

				if (ObjectTools.notEquals(child.getNodeName(), rootElementName)) {
					// A root element was found, simply rename it to comply
					// with the document's XSD
					setElementName(child, rootElementName);
					return getRootElement();
				}
			}
		}

		return element;
	}

	/**
	 * Returns the schema location defined in the root element of this form.
	 *
	 * @return URI of the XML schema.
	 */
	public final String getSchemaLocation() {
		return getAttribute(XSI_SCHEMA_LOCATION);
	}

	/**
	 * Retrieves the text content from the text node handled by this form.
	 *
	 * @return The text contained within the text node or <code>null</code> if the element does not exist
	 */
	public final String getTextNode() {

		Element element = getElement();

		if (element != null) {
			return getTextNode(element);
		}

		return null;
	}

	/**
	 * Retrieves the text content from the given text node.
	 *
	 * @param element The node from which the text is retrieved
	 * @return The text contained within the given text node
	 */
	public final String getTextNode(Node element) {

		acquireReadLock();

		try {
			return element.getTextContent();
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Retrieves the {@link TextRange} of the given text node's value.
	 *
	 * @param element The node from which the {@link TextRange} is retrieved
	 * @return The {@link TextRange} of the node's text
	 */
	public final TextRange getTextNodeTextRange(Node element) {

		if (element == null) {
			return getParent().getTextRange();
		}

		return getHelper().getTextNodeTextRange(this, element);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final TextRange getTextRange() {

		Element element = getElement();

		if (element != null) {
			return getTextRange(element);
		}

		AbstractExternalForm parent = getParent();

		if (parent != null) {
			return parent.getTextRange();
		}

		return null;
	}

	/**
	 * Retrieves the {@link TextRange} of the given {@link Node}.
	 *
	 * @param element The node from which the {@link TextRange} is retrieved
	 * @return The {@link TextRange} of the given {@link Node}
	 */
	public final TextRange getTextRange(Element element) {
		return getHelper().getTextRange(this, element);
	}

	/**
	 * Returns the version attribute value specified on this form.
	 *
	 * @return The version attribute value specified on this form
	 */
	public final String getVersion() {
		return getAttribute(XSD_VERSION);
	}

	/**
	 * Determines whether the element represented by this external form has any children, which
	 * includes comments and elements.
	 *
	 * @return <code>true</code> if the element is not a leaf and has children; <code>false</code> if
	 * the element is a leaf
	 */
	public final boolean hasAnyChildren() {

		Element element = getElement();

		if (element != null) {
			return hasAnyChildren(element);
		}

		return false;
	}

	/**
	 * Determines whether the given node has any children, which includes comments and elements.
	 *
	 * @param node The node checked for having children
	 * @return <code>true</code> if the element is not a leaf and has children; <code>false</code> if
	 * the element is a leaf
	 */
	public final boolean hasAnyChildren(Node node) {
		return getAllChildrenSize(node) > 0;
	}

	/**
	 * Determines whether the element represented by this external form has anything specified:
	 * elements and attributes.
	 *
	 * @return <code>true</code> if the element has at least one child; <code>false</code> otherwise
	 */
	public final boolean hasAnything() {

		Element element = getElement();

		if (element != null) {
			return hasChildren(element) || hasAttributes(element);
		}

		return false;
	}

	/**
	 * Determines whether the given element has an attribute with the given name.
	 *
	 * @param element The element used to check if an attribute with the given name exists
	 * @param elementName The name of the attribute
	 * @return <code>true</code> if the attribute is present; <code>false</code> otherwise
	 */
	public final boolean hasAttribute(Element element, String elementName) {
		return getAttribute(element, elementName) != null;
	}

	/**
	 * Determines whether the element represented by this external form has an attribute with the
	 * given name.
	 *
	 * @param attributeName The name of the attribute
	 * @return <code>true</code> if the attribute is present; <code>false</code> otherwise
	 */
	public final boolean hasAttribute(String attributeName) {
		return getAttribute(attributeName) != null;
	}

	/**
	 * Determines whether the given element has an attribute NS with the given name.
	 *
	 * @param element The element used to check if an attribute NS with the given name exists
	 * @param elementName The name of the attribute
	 * @return <code>true</code> if the attribute NS is present; <code>false</code> otherwise
	 */
	public final boolean hasAttributeNS(Element element, String elementName) {
		return getAttributeNS(element, elementName) != null;
	}

	/**
	 * Determines whether the element represented by this external form has an attribute NS with the given name.
	 *
	 * @param elementName The name of the attribute
	 * @return <code>true</code> if the attribute NS is present; <code>false</code> otherwise
	 */
	public final boolean hasAttributeNS(String elementName) {
		return getAttributeNS(elementName) != null;
	}

	/**
	 * Determines whether the element represented by this external form has any attributes.
	 *
	 * @return <code>true</code> if there is at least one attribute; <code>false</code> otherwise
	 */
	public final boolean hasAttributes() {

		Element element = getElement();

		if (element != null) {
			return hasAttributes(element);
		}

		return false;
	}

	/**
	 * Determines whether the given element has any attributes.
	 *
	 * @param element The element to check if it has attributes
	 * @return <code>true</code> if there is at least one attribute; <code>false</code> otherwise
	 */
	public final boolean hasAttributes(Element element) {

		NamedNodeMap attributes = element.getAttributes();

		if (attributes == null) {
			return false;
		}

		return attributes.getLength() > 0;
	}

	/**
	 * Determines whether the given element has a child with the given element name.
	 *
	 * @param element The element used to check if it has a child with the given name
	 * @param elementName The name of the element
	 * @return <code>true</code> if a child with the given name was found; <code>false</code> otherwise
	 */
	public final boolean hasChild(Element element, String elementName) {
		return getChild(element, elementName) != null;
	}

	/**
	 * Determines whether the given element has a child with the given element name.
	 *
	 * @param element The element used to check if it has a child with the given name
	 * @param index The position of the child element to check its existence, which is only based on
	 * the count of children of the same type and to make sure the index is smaller than the children size
	 * @param elementName The name of the element
	 * @return <code>true</code> if a child with the given name was found; <code>false</code> otherwise
	 */
	public final boolean hasChild(Element element, String elementName, int index) {
		return getChild(element, elementName, index) != null;
	}

	/**
	 * Determines whether the element represented by this external form has a child with the given element name.
	 *
	 * @param elementName The name of the element
	 * @return <code>true</code> if a child with the given name was found; <code>false</code> otherwise
	 */
	public final boolean hasChild(String elementName) {

		Element element = getElement();

		if (element != null) {
			return hasChild(element, elementName);
		}

		return false;
	}

	/**
	 * Determines whether the element represented by this external form has a child with the given element name.
	 *
	 * @param elementName The name of the element
	 * @param index The position of the child element to check its existence, which is only based on
	 * the count of children of the same type and to make sure the index is smaller than the children size
	 * @return <code>true</code> if a child with the given name was found; <code>false</code> otherwise
	 */
	public final boolean hasChild(String elementName, int index) {

		Element element = getElement();

		if (element != null) {
			return hasChild(element, elementName, index);
		}

		return false;
	}

	/**
	 * Determines whether the element represented by this external form has any children,
	 * non-elements are not included into the check.
	 *
	 * @return <code>true</code> if the element has at least one child; <code>false</code> otherwise
	 */
	public final boolean hasChildren() {

		Element element = getElement();

		if (element != null) {
			return hasChildren(element);
		}

		return false;
	}

	/**
	 * Determines whether the given element has any children, non-elements are not included into the check.
	 *
	 * @param element The element used to check if it has child elements
	 * @return <code>true</code> if the element has at least one child; <code>false</code> otherwise
	 */
	public final boolean hasChildren(Element element) {

		acquireReadLock();

		try {
			NodeList childrenList = element.getChildNodes();
			int count = 0;

			if (childrenList != null) {
				for (int index = childrenList.getLength(); --index >= 0; ) {
					Node child = childrenList.item(index);
					if (isElement(child)) {
						count++;
					}
				}

				return (count > 0);
			}

			return false;
		}
		finally {
			releaseReadLock();
		}
	}

	/**
	 * Determines whether the element represented by this external form is present in the XML document.
	 *
	 * @return <code>true</code> if the element exists; <code>false</code> if it does not
	 */
	public final boolean hasElement() {
		return getElement() != null;
	}

	/**
	 * Returns the position of the given child within the given parent's children of the same element type.
	 *
	 * @param parent The parent element
	 * @param child The child element that was added
	 * @param elementName The name of the new child element
	 * @return The position of the given child
	 */
	protected final int index(Element parent, Element child, String elementName) {
		return getChildren(parent, elementName).indexOf(child);
	}

	/**
	 * Initializes this external form.
	 */
	protected void initialize() {
		attributeNamesOrder = buildAttributeNamesOrder();
		elementNamesOrder   = buildElementNamesOrder();
	}

	/**
	 * Returns true if node is non-null and is of type ATTRIBUTE_NODE.
	 */
	protected final boolean isAttribute(Node node) {
		return isNodeType(node, Node.ATTRIBUTE_NODE);
	}

	/**
	 * Returns true if node is non-null and is of type ELEMENT_NODE.
	 */
	protected final boolean isElement(Node node) {
		return isNodeType(node, Node.ELEMENT_NODE);
	}

	/**
	 * Wrapper around {@link Node#getNodeType} test that returns false for a <code>null</code> node.
	 */
	protected final boolean isNodeType(Node node, int type) {
		return (node != null) && (node.getNodeType() == type);
	}

	/**
	 * Returns true if node is non-null and is of type TEXT_NODE.
	 */
	protected final boolean isText(Node node) {
		return isNodeType(node, Node.TEXT_NODE);
	}

	/**
	 * Retrieves the node that should follow the element with the given name by using the list of
	 * ordered node names.
	 *
	 * @param element The element to which a new child element will be added
	 * @param nodeName The name of the new node
	 * @param namesOrder The list of names used to determine the insertion point
	 * @return The node used to indicate the new node needs to be inserted before that node or
	 * <code>null</code> if no node was found
	 */
	public final Node nodeOfInsertion(Element element,
	                                  List<? extends Node> children,
	                                  String nodeName,
	                                  List<String> namesOrder) {

		if (namesOrder.isEmpty()) {
			return null;
		}

		int count = namesOrder.size();

		for (Node child : children) {
			String childName = getNodeName(child);

			for (int index = namesOrder.indexOf(nodeName) + 1; index < count; index++) {
				String name = namesOrder.get(index);

				if (ObjectTools.equals(childName, name)) {
					return child;
				}
			}
		}

		return null;
	}

	/**
	 * Releases the previously acquired lock from the document.
	 */
	public final void releaseReadLock() {
		getHelper().releaseReadLock();
	}

	/**
	 * Removes the given element from its parent element. The parent element
	 * is the element encapsulated by this model.
	 *
	 * @param element The child element to remove from its parent
	 */
	public final void remove(Element element) {

		Element parent = getElement();

		if (parent != null) {
			remove(parent, element);
		}
	}

	/**
	 * Removes the given element from its parent element.
	 *
	 * @param element The parent of the element to remove
	 * @param childElement The child to remove from its parent
	 */
	public final void remove(Element element, Element childElement) {
		getHelper().remove(this, element, childElement);
	}

	/**
	 * Removes the child element from its parent element at the given position. The parent element is
	 * the element encapsulated by this model.
	 *
	 * @param parent The parent of this external form used to retrieve the parent element
	 * @param elementName The name of the child element to remove
	 * @param index The index of the child that has the given element name to remove
	 */
	public final void removeChild(AbstractExternalForm parent, String elementName, int index) {
		removeChild(parent.getElement(), elementName, index);
	}

	/**
	 * Removes the child element from its parent element at the given position. The parent element is
	 * the element encapsulated by this model.
	 *
	 * @param element The element from which the child at the given index will be removed
	 * @param elementName The name of the child element to remove
	 * @param index The index of the child that has the given element name to remove
	 */
	public final void removeChild(Element element, int index) {

		Element childElement = getChild(element, index);

		if (childElement != null) {
			remove(element, childElement);
		}
	}

	/**
	 * Removes the child element from its parent element at the given position. The parent element is
	 * the element encapsulated by this model.
	 *
	 * @param element The element from which the child with the given name will be removed
	 * @param elementName The name of the child element to remove
	 */
	public final void removeChild(Element element, String elementName) {

		Element childElement = getChild(element, elementName);

		if (childElement != null) {
			remove(element, childElement);
		}
	}

	/**
	 * Removes the child element from its parent element at the given position. The parent element is
	 * the element encapsulated by this model.
	 *
	 * @param element The element from which the child at the given position with the given name will be removed
	 * @param elementName The name of the child element to remove
	 * @param index The index of the child that has the given element name to remove
	 */
	public final void removeChild(Element element, String elementName, int index) {

		Element childElement = getChild(element, elementName, index);

		if (childElement != null) {
			remove(element, childElement);
		}
	}

	/**
	 * Removes the child element from its parent element. The parent element is the element
	 * encapsulated by this model.
	 *
	 * @param elementName The name of the child element to remove
	 */
	public final void removeChild(String elementName) {

		Element element = getChild(elementName);

		if (element != null) {
			remove(getElement(), element);
		}
	}

	/**
	 * Removes the child element from its parent element at the given position. The parent element is
	 * the element encapsulated by this model.
	 *
	 * @param elementName The name of the child element to remove
	 * @param index The index of the child that has the given element name to remove
	 */
	public final void removeChild(String elementName, int index) {
		removeChild(getElement(), elementName, index);
	}

	/**
	 * Removes the child element from its parent element. The parent element is the element
	 * encapsulated by this model.
	 *
	 * @param node The node from which the children with the given name will be removed
	 * @param elementName The name of the child element to remove
	 */
	public final void removeChildren(Node node, String elementName) {
		getHelper().removeChildren(this, node, elementName);
	}

	/**
	 * Removes the child element from its parent element. The parent element is the element
	 * encapsulated by this model.
	 *
	 * @param elementName The name of the child element to remove
	 */
	public final void removeChildren(String elementName) {

		Element element = getElement();

		if (element != null) {
			removeChildren(element, elementName);
		}
	}

	/**
	 * Removes this model's element from its parent element.
	 */
	public void removeSelf() {

		Element element = getElement();

		if ((parent != null) && (element != null)) {
			parent.remove(element);
		}
	}

	/**
	 * Sets an attribute on the given element with the given value.
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttribute(Element element, String attributeName, Boolean value) {
		setAttribute(element, attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the given element with the given value.
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttribute(Element element,
	                               String attributeName,
	                               Boolean value,
	                               List<String> attributeNamesOrder) {

		setAttribute(
			element,
			attributeName,
			(value != null) ? value.toString() : null,
			attributeNamesOrder
		);
	}

	/**
	 * Sets an attribute on the given element with the given value.
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttribute(Element element, String attributeName, Enum<?> value) {
		setAttribute(element, attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the given element with the given value.
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttribute(Element element,
	                               String attributeName,
	                               Enum<?> value,
	                               List<String> attributeNamesOrder) {

		setAttribute(
			element,
			attributeName,
			(value != null) ? value.toString() : null,
			attributeNamesOrder
		);
	}

	/**
	 * Sets an attribute on the given element with the given value.
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttribute(Element element, String attributeName, Number value) {
		setAttribute(element, attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the given element with the given value.
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttribute(Element element,
	                               String attributeName,
	                               Number value,
	                               List<String> attributeNamesOrder) {

		setAttribute(
			element,
			attributeName,
			(value != null) ? value.toString() : null,
			attributeNamesOrder
		);
	}

	/**
	 * Sets an attribute on the given element with the given value.
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttribute(Element element, String attributeName, String value) {
		setAttribute(element, attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the given element with the given value.
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttribute(Element element,
	                               String attributeName,
	                               String value,
	                               List<String> attributeNamesOrder) {

		getHelper().setAttribute(this, element, attributeName, value, attributeNamesOrder);
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value.
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttribute(String attributeName, Boolean value) {
		setAttribute(attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value.
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttribute(String attributeName,
	                               Boolean value,
	                               List<String> attributeNamesOrder) {

		Element element = getElement();

		if ((element == null) && (value == null)) {
			return;
		}

		if (element == null) {
			element = addSelf();
		}

		setAttribute(element, attributeName, value, attributeNamesOrder);
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value.
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttribute(String attributeName, Enum<?> value) {
		setAttribute(attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value.
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttribute(String attributeName,
	                               Enum<?> value,
	                               List<String> attributeNamesOrder) {

		Element element = getElement();

		if ((element == null) && (value == null)) {
			return;
		}

		if (element == null) {
			element = addSelf();
		}

		setAttribute(element, attributeName, value, attributeNamesOrder);
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value.
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttribute(String attributeName, Number value) {
		setAttribute(attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value.
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttribute(String attributeName,
	                               Number value,
	                               List<String> attributeNamesOrder) {

		Element element = getElement();

		if ((element == null) && (value == null)) {
			return;
		}

		if (element == null) {
			element = addSelf();
		}

		setAttribute(element, attributeName, value, attributeNamesOrder);
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value.
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttribute(String attributeName, String value) {
		setAttribute(attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value.
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttribute(String attributeName,
	                               String value,
	                               List<String> attributeNamesOrder) {

		Element element = getElement();

		if ((element == null) && (value == null)) {
			return;
		}

		if (element == null) {
			element = addSelf();
		}

		setAttribute(element, attributeName, value, attributeNamesOrder);
	}

	/**
	 * Sets an attribute on the given element with the given value. The name will be formatted with
	 * the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttributeNS(Element element, String attributeName, Boolean value) {
		setAttributeNS(element, attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the given element with the given value. The name will be formatted with
	 * the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttributeNS(Element element,
	                                 String attributeName,
	                                 Boolean value,
	                                 List<String> attributeNamesOrder) {

		setAttributeNS(
			element,
			attributeName,
			(value != null) ? value.toString() : null,
			attributeNamesOrder
		);
	}

	/**
	 * Sets an attribute on the given element with the given value. The name will be formatted with
	 * the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute
	 * will be removed
	 */
	public final void setAttributeNS(Element element, String attributeName, Enum<?> value) {
		setAttributeNS(element, attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the given element with the given value. The name will be formatted with
	 * the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttributeNS(Element element,
	                                 String attributeName,
	                                 Enum<?> value,
	                                 List<String> attributeNamesOrder) {

		setAttributeNS(
			element,
			attributeName,
			(value != null) ? value.toString() : null,
			attributeNamesOrder
		);
	}

	/**
	 * Sets an attribute on the given element with the given value. The name will be formatted with
	 * the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttributeNS(Element element, String attributeName, Number value) {
		setAttributeNS(element, attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the given element with the given value. The name will be formatted with
	 * the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttributeNS(Element element,
	                                 String attributeName,
	                                 Number value,
	                                 List<String> attributeNamesOrder) {

		setAttributeNS(
			element,
			attributeName,
			(value != null) ? value.toString() : null,
			attributeNamesOrder
		);
	}

	/**
	 * Sets an attribute on the given element with the given value. The name will be formatted with
	 * the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttributeNS(Element element, String attributeName, String value) {
		setAttributeNS(element, attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the given element with the given value. The name will be formatted with
	 * the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param element The element to have one of its attributes updated
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttributeNS(Element element,
	                                 String attributeName,
	                                 String value,
	                                 List<String> attributeNamesOrder) {

		getHelper().setAttributeNS(this, element, attributeName, value, attributeNamesOrder);
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value. The
	 * name will be formatted with the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttributeNS(String attributeName, Boolean value) {
		setAttributeNS(attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value. The
	 * name will be formatted with the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttributeNS(String attributeName,
	                                 Boolean value,
	                                 List<String> attributeNamesOrder) {

		setAttributeNS(attributeName, value != null ? value.toString() : null, attributeNamesOrder);
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value. The
	 * name will be formatted with the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttributeNS(String attributeName, Enum<?> value) {
		setAttributeNS(attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value. The
	 * name will be formatted with the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttributeNS(String attributeName,
	                                 Enum<?> value,
	                                 List<String> attributeNamesOrder) {

		setAttributeNS(attributeName, value != null ? value.toString() : null, attributeNamesOrder);
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value. The
	 * name will be formatted with the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttributeNS(String attributeName, Number value) {
		setAttributeNS(attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value. The
	 * name will be formatted with the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttributeNS(String attributeName,
	                                 Number value,
	                                 List<String> attributeNamesOrder) {

		setAttributeNS(attributeName, value != null ? value.toString() : null, attributeNamesOrder);
	}

	/**
	 * Sets an attribute on the element represented by this external form with the
	 * given value. The name will be formatted with the namespace URI:
	 * "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 */
	public final void setAttributeNS(String attributeName, String value) {
		setAttributeNS(attributeName, value, getAttributeNamesOrder());
	}

	/**
	 * Sets an attribute on the element represented by this external form with the given value. The
	 * name will be formatted with the namespace URI: "&lt;namespaceURI&gt;:attributeName".
	 *
	 * @param attributeName The name of the attribute
	 * @param value The value of the attribute. If the value is <code>null</code>, then the attribute will be removed
	 * @param attributeNamesOrder The list of attribute names used to determine the insertion
	 */
	public final void setAttributeNS(String attributeName,
	                                 String value,
	                                 List<String> attributeNamesOrder) {

		Element element = getElement();

		if ((element == null) && (value == null)) {
			return;
		}

		if (element == null) {
			element = addSelf();
		}

		setAttributeNS(element, attributeName, value, attributeNamesOrder);
	}

	/**
	 * Renames the given element represented by this external form.
	 *
	 * @param element The element to rename
	 * @param elementName The new name of the element
	 */
	public final void setElementName(Element element, String elementName) {
		getHelper().setElementName(this, element, elementName, getElementNamesOrder());
	}

	/**
	 * Sets the namespace with the given one.
	 *
	 * @param uri The URI of the namespace
	 */
	public final void setNamespace(String uri) {
		getHelper().setNamespace(this, uri);
	}

	/**
	 * Sets the schema location with the given one.
	 *
	 * @param uri The URI of the XML schema
	 */
	public final void setSchemaLocation(String uri) {
		getHelper().setSchemaLocation(this, uri);
	}

	/**
	 * Updates the given element's text value.
	 *
	 * @param element The element to update its text value
	 * @param value The new value of the given element
	 */
	public final void setTextNode(Element element, String value) {
		updateTextNode(element, getElementName(), value);
	}

	/**
	 * Updates this external form's element text value.
	 *
	 * @param value The new value of this form's element
	 */
	public final void setTextNode(String value) {
		updateTextNode(
			getParent().getElement(),
			getElementName(),
			value,
			getParent().getElementNamesOrder()
		);
	}

	/**
	 * Sets the version attribute of this element to the provided version.
	 *
	 * @param version version attribute value.
	 */
	public final void setVersion(String version) {
		setAttribute(XSD_VERSION, version);
	}

	/**
	 * Updates the attribute's value of a child element.
	 *
	 * @param childName The name of the child to update one of its attributes
	 * @param attributeName The name of the attribute to update its value
	 * @param value The new value of the attribute
	 */
	public final void updateChildAttribute(String childName, String attributeName, Boolean value) {
		updateChildAttribute(childName, attributeName, (value != null) ? value.toString() : null);
	}

	/**
	 * Updates the attribute's value of a child element.
	 *
	 * @param childName The name of the child to update one of its attributes
	 * @param attributeName The name of the attribute to update its value
	 * @param value The new value of the attribute
	 */
	public final void updateChildAttribute(String childName, String attributeName, Enum<?> value) {
		updateChildAttribute(childName, attributeName, (value != null) ? value.name() : null);
	}

	/**
	 * Updates the attribute's value of a child element.
	 *
	 * @param childName The name of the child to update one of its attributes
	 * @param attributeName The name of the attribute to update its value
	 * @param value The new value of the attribute
	 */
	public final void updateChildAttribute(String childName, String attributeName, Number value) {
		updateChildAttribute(childName, attributeName, (value != null) ? value.toString() : null);
	}

	/**
	 * Updates the attribute's value of a child element.
	 *
	 * @param childName The name of the child to update one of its attributes
	 * @param attributeName The name of the attribute to update its value
	 * @param value The new value of the attribute
	 */
	public final void updateChildAttribute(String childName, String attributeName, String value) {

		Element element = getChild(childName);

		if ((element == null) && (value != null)) {
			element = addChild(childName);
		}

		if (value != null) {
			setAttribute(element, attributeName, value, Collections.<String>emptyList());
		}
		else if (element != null) {
			removeChild(childName);
		}
	}

	/**
	 * Updates the child text node of a child element.
	 *
	 * @param parentChildName The name of the child to retrieve its child with the given child name
	 * @param childName The child of a child to update its text value
	 * @param value The new value of the text node
	 */
	public final void updateChildChildTextNode(String parentChildName,
	                                           String childName,
	                                           Boolean value) {

		updateChildChildTextNode(parentChildName, childName, (value != null) ? value.toString() : null);
	}

	/**
	 * Updates the child text node of a child element.
	 *
	 * @param parentChildName The name of the child to retrieve its child with the given child name
	 * @param childName The child of a child to update its text value
	 * @param value The new value of the text node
	 */
	public final void updateChildChildTextNode(String parentChildName,
	                                           String childName,
	                                           Enum<?> value) {

		updateChildChildTextNode(parentChildName, childName, (value != null) ? value.name() : null);
	}

	/**
	 * Updates the child text node of a child element.
	 *
	 * @param parentChildName The name of the child to retrieve its child with the given child name
	 * @param childName The child of a child to update its text value
	 * @param value The new value of the text node
	 */
	public final void updateChildChildTextNode(String parentChildName,
	                                           String childName,
	                                           Number value) {

		updateChildChildTextNode(parentChildName, childName, (value != null) ? value.toString() : null);
	}

	/**
	 * Updates the child text node of a child element.
	 *
	 * @param parentChildName The name of the child to retrieve its child with the given child name
	 * @param childName The child of a child to update its text value
	 * @param value The new value of the text node
	 */
	public final void updateChildChildTextNode(String parentChildName, String childName, String value) {

		Element element = getChild(parentChildName);

		if ((element == null) && (value != null)) {
			element = addChild(parentChildName);
		}

		updateTextNode(element, childName, value);
	}

	/**
	 * Updates the child element's text with the given value. If the value is <code>null</code>, then
	 * the element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param elementName The child element's name
	 * @param value The new element's text
	 */
	public final void updateChildTextNode(String elementName, Boolean value) {
		updateChildTextNode(elementName, value, getElementNamesOrder());
	}

	/**
	 * Updates the child element's text with the given value. If the value is <code>null</code>, then
	 * the element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param elementName The child element's name
	 * @param value The new element's text
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 */
	public final void updateChildTextNode(String elementName,
	                                      Boolean value,
	                                      List<String> elementNamesOrder) {

		updateChildTextNode(elementName, (value != null) ? value.toString() : null, elementNamesOrder);
	}

	/**
	 * Updates the child element's text with the given value. If the value is <code>null</code>, then
	 * the element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param elementName The child element's name
	 * @param value The new element's text
	 */
	public final void updateChildTextNode(String elementName, Enum<?> value) {
		updateChildTextNode(elementName, value, getElementNamesOrder());
	}

	/**
	 * Updates the child element's text with the given value. If the value is <code>null</code>, then
	 * the element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param elementName The child element's name
	 * @param value The new element's text
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 */
	public final void updateChildTextNode(String elementName,
	                                      Enum<?> value,
	                                      List<String> elementNamesOrder) {

		updateChildTextNode(elementName, (value != null) ? value.toString() : null, elementNamesOrder);
	}

	/**
	 * Updates the child element's text with the given value. If the value is <code>null</code>, then
	 * the element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param elementName The child element's name
	 * @param value The new element's text
	 */
	public final void updateChildTextNode(String elementName, Number value) {
		updateChildTextNode(elementName, value, getElementNamesOrder());
	}

	/**
	 * Updates the child element's text with the given value. If the value is <code>null</code>, then
	 * the element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param elementName The child element's name
	 * @param value The new element's text
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 */
	public final void updateChildTextNode(String elementName,
	                                      Number value,
	                                      List<String> elementNamesOrder) {

		updateChildTextNode(elementName, (value != null) ? value.toString() : null, elementNamesOrder);
	}

	/**
	 * Updates the child element's text with the given value. If the value is <code>null</code>, then
	 * the element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param elementName The child element's name
	 * @param value The new element's text
	 */
	public final void updateChildTextNode(String elementName, String value) {
		updateChildTextNode(elementName, value, getElementNamesOrder());
	}

	/**
	 * Updates the child element's text with the given value. If the value is <code>null</code>, then
	 * the element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param elementName The child element's name
	 * @param value The new element's text
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 */
	public final void updateChildTextNode(String elementName,
	                                      String value,
	                                      List<String> elementNamesOrder) {

		Element element = getElement();

		// Nothing to change
		if ((element == null) && (value == null)) {
			return;
		}

		// Automatically create the element
		if (element == null) {
			element = addSelf();
		}

		// Create or update the child text node
		updateTextNode(element, elementName, value, elementNamesOrder);
	}

	/**
	 * Updates the child text node with the given value. If the value is <code>null</code>, then the
	 * element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param element The parent element used to retrieve the child element
	 * @param elementName The child element's name
	 * @param value The new element's text
	 */
	public final void updateTextNode(Element element, String elementName, Boolean value) {
		updateTextNode(element, elementName, value, getElementNamesOrder());
	}

	/**
	 * Updates the child text node with the given value. If the value is <code>null</code>, then the
	 * element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param element The parent element used to retrieve the child element
	 * @param elementName The child element's name
	 * @param value The new element's text
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 */
	public final void updateTextNode(Element element,
	                                 String elementName,
	                                 Boolean value,
	                                 List<String> elementNamesOrder) {

		updateTextNode(element, elementName, (value == null) ? null : value.toString(), elementNamesOrder);
	}

	/**
	 * Updates the child text node with the given value. If the value is <code>null</code>, then the
	 * element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param element The parent element used to retrieve the child element
	 * @param elementName The child element's name
	 * @param value The new element's text
	 */
	public final void updateTextNode(Element element, String elementName, Enum<?> value) {
		updateTextNode(element, elementName, value, getElementNamesOrder());
	}

	/**
	 * Updates the child text node with the given value. If the value is <code>null</code>, then the
	 * element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param element The parent element used to retrieve the child element
	 * @param elementName The child element's name
	 * @param value The new element's text
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 */
	public final void updateTextNode(Element element,
	                                 String elementName,
	                                 Enum<?> value,
	                                 List<String> elementNamesOrder) {

		updateTextNode(element, elementName, (value != null) ? value.toString() : null, elementNamesOrder);
	}

	/**
	 * Updates the child text node with the given value. If the value is <code>null</code>, then the
	 * element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param element The parent element used to retrieve the child element
	 * @param elementName The child element's name
	 * @param value The new element's text
	 */
	public final void updateTextNode(Element element, String elementName, Number value) {
		updateTextNode(element, elementName, value, getElementNamesOrder());
	}

	 /**
	 * Updates the child text node with the given value. If the value is <code>null</code>, then the
	 * element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param element The parent element used to retrieve the child element
	 * @param elementName The child element's name
	 * @param value The new element's text
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 */
	public final void updateTextNode(Element element,
	                                    String elementName,
	                                    Number value,
	                                    List<String> elementNamesOrder) {

		updateTextNode(element, elementName, (value != null) ? value.toString() : null, elementNamesOrder);
	}

	/**
	 * Updates the child text node with the given value. If the value is <code>null</code>, then the
	 * element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then it will be added.
	 *
	 * @param element The parent element used to retrieve the child element
	 * @param elementName The child element's name
	 * @param value The new element's text
	 */
	public final void updateTextNode(Element element, String elementName, String value) {
		updateTextNode(element, elementName, value, getElementNamesOrder());
	}

	/**
	 * Updates the child text node with the given value. If the value is <code>null</code>, then the
	 * child element will be removed. If the value is not <code>null</code> but the element is
	 * <code>null</code> then the child will be added.
	 *
	 * @param element The parent element used to retrieve the child element
	 * @param elementName The child element's name
	 * @param value The new element's text
	 * @param elementNamesOrder The list of element names used to determine the insertion point
	 */
	public final void updateTextNode(Element element,
	                                 String elementName,
	                                 String value,
	                                 List<String> elementNamesOrder) {

		Element childElement = getChild(element, elementName);

		// Remove the child element if the value is null
		if ((childElement != null) && (value == null)) {
			remove(element, childElement);
			return;
		}

		boolean valueNotEmpty = !StringTools.isBlank(value);

		// Add a text node if the element is null and the value isn't
		if ((childElement == null) && valueNotEmpty) {
			addChildTextNode(element, elementName, value, elementNamesOrder);
		}
		// Update the element's text content
		else if ((childElement != null) && valueNotEmpty) {
			getHelper().updateTextNode(this, elementName, childElement, value);
		}
	}
}