/*******************************************************************************
 * Copyright (c) 2006, 2012 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.orm.dom;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.persistence.annotations.ChangeTrackingType;
import org.eclipse.persistence.tools.mapping.orm.ExternalAccessMethods;
import org.eclipse.persistence.tools.mapping.orm.ExternalBasicCollectionMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalBasicMapMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalBasicMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalCloneCopyPolicy;
import org.eclipse.persistence.tools.mapping.orm.ExternalConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalCopyPolicy;
import org.eclipse.persistence.tools.mapping.orm.ExternalElementCollectionMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddableEntity;
import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddedMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalIDMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalInstantiationCopyPolicy;
import org.eclipse.persistence.tools.mapping.orm.ExternalManyToManyMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalManyToOneMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalNoSql;
import org.eclipse.persistence.tools.mapping.orm.ExternalObjectTypeConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalOneToManyMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalOneToOneMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalProperty;
import org.eclipse.persistence.tools.mapping.orm.ExternalStructConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalTransientMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalTypeConverter;
import org.eclipse.persistence.tools.utility.NameTools;
import org.eclipse.persistence.tools.utility.ObjectTools;
import org.eclipse.persistence.tools.utility.collection.ListTools;
import org.eclipse.persistence.tools.utility.iterable.EmptyListIterable;
import org.eclipse.persistence.tools.utility.iterable.ListIterable;
import org.eclipse.persistence.tools.utility.iterable.ListListIterable;
import org.w3c.dom.Element;

/**
 * The external form of an embeddable entity, which is a child of an ORM configuration.
 *
 * @see ORMConfiguration
 *
 * @version 2.5
 * @author Les Davis
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
class EmbeddableEntity extends AbstractExternalForm
                       implements ExternalEmbeddableEntity {

	/**
	 * The position of the element within the list of children with the same type owned by the parent.
	 */
	private int index;

	/**
	 * The order of the mapping element names in the <code>attributes</code> 
	 * element.
	 */
	private List<String> mappingElementNamesOrder;
	
	/**
	 * The attribute name used to store and retrieve the access property.
	 */
	static final String ACCESS = "access";

	/**
	 * The element name used to store and retrieve the change-tracking child node.
	 */
	static final String CHANGE_TRACKING = "change-tracking";

	/**
	 * The attribute name used to store and retrieve the class property or the element name used to
	 * store and retrieve the class child text node of the customizer child node.
	 */
	static final String CLASS = "class";

	/**
	 * The element name used to store and retrieve the customizer child node.
	 */
	static final String CUSTOMIZER = "customizer";

	/**
	 * The element name used to store and retrieve the description child text node.
	 */
	static final String DESCRIPTION = "description";

	/**
	 * The node name used to store and retrieve the {@link Element} encapsulated by this external form.
	 */
	static final String EMBEDDABLE = "embeddable";

	/**
	 * The attribute name used to store and retrieve the exclude-default-mappings property.
	 */
	static final String EXCLUDE_DEFAULT_MAPPINGS = "exclude-default-mappings";

	/**
	 * The attribute name used to store and retrieve the metadata-complete property.
	 */
	static final String METADATA_COMPLETE = "metadata-complete";

	/**
	 * The attribute name used to store and retrieve the type child text node of the change-tracking
	 * child node.
	 */
	static final String TYPE = "type";

	/**
	 * Creates a new <code>EmbeddableEntity</code>.
	 *
	 * @param parent The parent of this external form
	 * @param index The position of the element within the list of children with the same type owned
	 * by the parent
	 */
	EmbeddableEntity(ORMConfiguration parent, int index) {
		super(parent);
		this.index = index;
		this.mappingElementNamesOrder = buildMappingElementNamesOrder();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void addAccessMethods(String getMethodName, String setMethodName) {
		AccessMethods accessMethods = buildAccessMethods();
		accessMethods.addSelf();
		accessMethods.setGetMethod(getMethodName);
		accessMethods.setSetMethod(setMethodName);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalBasicCollectionMapping addBasicCollectionMapping(String name) {
		BasicCollectionMapping mapping = buildBasicCollectionMapping(mappingsSize());
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalBasicMapMapping addBasicMapMapping(String name) {
		BasicMapMapping mapping = buildBasicMapMapping(mappingsSize());
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalBasicMapping addBasicMapping(String name) {
		BasicMapping mapping = buildBasicMapping(mappingsSize());
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalCloneCopyPolicy addCloneCopyPolicy() {
		CloneCopyPolicy cloneCopyPolicy = buildCloneCopyPolicy();
		cloneCopyPolicy.addSelf();
		return cloneCopyPolicy;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalConverter addConverter(int index, String name) {
		Converter converter = buildConverter(index);
		converter.addSelf();
		converter.setName(name);
		return converter;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalCopyPolicy addCopyPolicy() {
		CopyPolicy copyPolicy = buildCopyPolicy();
		copyPolicy.addSelf();
		return copyPolicy;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalElementCollectionMapping addElementCollectionMapping(String name) {
		ElementCollectionMapping mapping = buildElementCollectionMapping(mappingsSize());
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalEmbeddedMapping addEmbeddedMapping(String name) {
		EmbeddedMapping mapping = buildEmbeddedMapping(mappingsSize());
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * Embeddables don't currently support ID, but the implementation
	 * is here for convenience.
	 *
	 * {@inheritDoc}
	 */
	@Override
	public ExternalIDMapping addIdMapping(String name) {
		throw new UnsupportedOperationException();
	}


	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalInstantiationCopyPolicy addInstantiationCopyPolicy() {
		InstantiationCopyPolicy instantiationCopyPolicy = buildInstantiationCopyPolicy();
		instantiationCopyPolicy.addSelf();
		return instantiationCopyPolicy;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalManyToManyMapping addManyToManyMapping(String name) {
		ManyToManyMapping mapping = buildManyToManyMapping(mappingsSize());
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalManyToOneMapping addManyToOneMapping(String name) {
		ManyToOneMapping mapping = buildManyToOneMapping(mappingsSize());
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalNoSql addNoSql() {
		NoSql noSql = new NoSql(this);
		noSql.addSelf();
		return noSql;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalObjectTypeConverter addObjectTypeConverter(int index, String name) {
		ObjectTypeConverter converter = buildObjectTypeConverter(index);
		converter.addSelf();
		converter.setName(name);
		return converter;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalOneToManyMapping addOneToManyMapping(String name) {
		OneToManyMapping mapping = buildOneToManyMapping(mappingsSize());
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalOneToOneMapping addOneToOneMapping(String name) {
		OneToOneMapping mapping = buildOneToOneMapping(mappingsSize());
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void addProperty(int index, String name, String value) {
		Property property = buildProperty(index);
		property.addSelf();
		property.setName(name);
		property.setValue(value);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected final Element addSelf(String elementName) {
		return addChild(getParent(), elementName, index, getParent().getElementNamesOrder());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalStructConverter addStructConverter(int index, String name) {
		StructConverter converter = buildStructConverter(index);
		converter.addSelf();
		converter.setName(name);
		return converter;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalTransientMapping addTransientMapping(String name) {
		TransientMapping mapping = buildTransientMapping(mappingsSize());
		mapping.addSelf();
		mapping.setName(name);
		return mapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalTypeConverter addTypeConverter(int index, String name) {
		TypeConverter converter = buildTypeConverter(index);
		converter.addSelf();
		converter.setName(name);
		return converter;
	}

	private AccessMethods buildAccessMethods() {
		return new AccessMethods(this);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected List<String> buildAttributeNamesOrder() {
		List<String> names = new ArrayList<String>();
		names.add(CLASS);
		names.add(ACCESS);
		names.add(METADATA_COMPLETE);
		names.add(EXCLUDE_DEFAULT_MAPPINGS);
		return names;
	}

	private BasicCollectionMapping buildBasicCollectionMapping(int index) {
		return new BasicCollectionMapping(this, index);
	}

	private BasicMapMapping buildBasicMapMapping(int index) {
		return new BasicMapMapping(this, index);
	}

	private BasicMapping buildBasicMapping(int index) {
		return new BasicMapping(this, index);
	}

	private CloneCopyPolicy buildCloneCopyPolicy() {
		return new CloneCopyPolicy(this);
	}

	private Converter buildConverter(int index) {
		return new Converter(this, index);
	}

	private CopyPolicy buildCopyPolicy() {
		return new CopyPolicy(this);
	}

	private ElementCollectionMapping buildElementCollectionMapping(int index) {
		return new ElementCollectionMapping(this, index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected List<String> buildElementNamesOrder() {

		List<String> names = new ArrayList<String>();
		names.add(DESCRIPTION);
		names.add(AccessMethods.ACCESS_METHODS);
		names.add(CUSTOMIZER);
		names.add(CHANGE_TRACKING);
		names.add(NoSql.NO_SQL);
		names.add(Converter.CONVERTER);
		names.add(TypeConverter.TYPE_CONVERTER);
		names.add(ObjectTypeConverter.OBJECT_TYPE_CONVERTER);
		names.add(StructConverter.STRUCT_CONVERTER);
		names.add(Property.PROPERTY);
		names.add(CopyPolicy.COPY_POLICY);
		names.add(InstantiationCopyPolicy.INSTANTIATION_COPY_POLICY);
		names.add(CloneCopyPolicy.CLONE_COPY_POLICY);
		names.add(Mapping.ATTRIBUTES);
		return names;
	}

	private EmbeddedMapping buildEmbeddedMapping(int index) {
		return new EmbeddedMapping(this, index);
	}

	private InstantiationCopyPolicy buildInstantiationCopyPolicy() {
		return new InstantiationCopyPolicy(this);
	}

	private ManyToManyMapping buildManyToManyMapping(int index) {
		return new ManyToManyMapping(this, index);
	}

	private ManyToOneMapping buildManyToOneMapping(int index) {
		return new ManyToOneMapping(this, index);
	}

	Mapping buildMapping(String elementName, int index) {

		// Basic
		if (ObjectTools.equals(elementName, BasicMapping.BASIC)) {
			return buildBasicMapping(index);
		}

		// Basic Collection
		if (ObjectTools.equals(elementName, BasicCollectionMapping.BASIC_COLLECTION)) {
			return buildBasicCollectionMapping(index);
		}

		// Basic Map
		if (ObjectTools.equals(elementName, BasicMapMapping.BASIC_MAP)) {
			return buildBasicMapMapping(index);
		}

		// Embedded
		if (ObjectTools.equals(elementName, EmbeddedMapping.EMBEDDED)) {
			return buildEmbeddedMapping(index);
		}

		// Element Collection
		if (ObjectTools.equals(elementName, ElementCollectionMapping.ELEMENT_COLLECTION)) {
			return buildElementCollectionMapping(index);
		}

		// M:M
		if (ObjectTools.equals(elementName, ManyToManyMapping.MANY_TO_MANY)) {
			return buildManyToManyMapping(index);
		}

		// M:1
		if (ObjectTools.equals(elementName, ManyToOneMapping.MANY_TO_ONE)) {
			return buildManyToOneMapping(index);
		}

		// 1:M
		if (ObjectTools.equals(elementName, OneToManyMapping.ONE_TO_MANY)) {
			return buildOneToManyMapping(index);
		}

		// 1:1
		if (ObjectTools.equals(elementName, OneToOneMapping.ONE_TO_ONE)) {
			return buildOneToOneMapping(index);
		}

		// Transient
		if (ObjectTools.equals(elementName, TransientMapping.TRANSIENT)) {
			return buildTransientMapping(index);
		}

		return null;
	}

	/**
	 * Creates a collection of element names for the supported mappings.
	 *
	 * @return The mapping names
	 */
	List<String> buildMappingElementNamesOrder() {

		List<String> names = new ArrayList<String>();
		names.add(IdMapping.ID);
		names.add(EmbeddedIDMapping.EMBEDDED_ID);
		names.add(BasicMapping.BASIC);
		names.add(BasicCollectionMapping.BASIC_COLLECTION);
		names.add(BasicMapMapping.BASIC_MAP);
		names.add(VersionMapping.VERSION);
		names.add(ManyToOneMapping.MANY_TO_ONE);
		names.add(OneToManyMapping.ONE_TO_MANY);
		names.add(OneToOneMapping.ONE_TO_ONE);
		names.add(VariableOneToOneMapping.VARIABLE_ONE_TO_ONE);
		names.add(ManyToManyMapping.MANY_TO_MANY);
		names.add(ElementCollectionMapping.ELEMENT_COLLECTION);
		names.add(EmbeddedMapping.EMBEDDED);
		names.add(TransformationMapping.TRANSFORMATION);
		names.add(TransientMapping.TRANSIENT);
		
		return names;
	}
	
	protected List<String> getMappingElementNamesOrder() {
		return this.mappingElementNamesOrder;
	}

	private ObjectTypeConverter buildObjectTypeConverter(int index) {
		return new ObjectTypeConverter(this, index);
	}

	private OneToManyMapping buildOneToManyMapping(int index) {
		return new OneToManyMapping(this, index);
	}

	private OneToOneMapping buildOneToOneMapping(int index) {
		return new OneToOneMapping(this, index);
	}

	private Property buildProperty(int index) {
		return new Property(this, index);
	}

	private StructConverter buildStructConverter(int index) {
		return new StructConverter(this, index);
	}

	private TransientMapping buildTransientMapping(int index) {
		return new TransientMapping(this, index);
	}

	private TypeConverter buildTypeConverter(int index) {
		return new TypeConverter(this, index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ListIterable<ExternalConverter> converters() {

		int count = convertersSize();
		List<ExternalConverter> converters = new ArrayList<ExternalConverter>(count);

		for (int index = count; --index >= 0;) {
			ExternalConverter converter = buildConverter(index);
			converters.add(0, converter);
		}

		return new ListListIterable<ExternalConverter>(converters);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int convertersSize() {
		return getChildrenSize(Converter.CONVERTER);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalAccessMethods getAccessMethods() {

		Element element = getChild(AccessMethods.ACCESS_METHODS);

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

		return buildAccessMethods();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getAccessType() {
		return getAttribute(ACCESS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ChangeTrackingType getChangeTrackingType() {

		Element element = getChild(CHANGE_TRACKING);

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

		return getEnumAttribute(element, TYPE, ChangeTrackingType.class);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getClassName() {
		return getAttribute(CLASS);
	}
	
	public final String getClassShortName() {
		return NameTools.shortNameForClassNamed(getClassName());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalCloneCopyPolicy getCloneCopyPolicy() {

		Element element = getChild(CloneCopyPolicy.CLONE_COPY_POLICY);

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

		return buildCloneCopyPolicy();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalConverter getConverter(int index) {

		Element element = getChild(Converter.CONVERTER, index);

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

		return buildConverter(index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalCopyPolicy getCopyPolicy() {

		Element element = getChild(CopyPolicy.COPY_POLICY);

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

		return buildCopyPolicy();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getCustomizerClassName() {
		return getChildAttribute(CUSTOMIZER, CLASS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getDescription() {
		return getChildTextNode(DESCRIPTION);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final Element getElement() {
		return getChild(getParent(), getElementName(), index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected String getElementName() {
		return EMBEDDABLE;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int getIndex() {
		return index;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalInstantiationCopyPolicy getInstantiationCopyPolicy() {

		Element element = getChild(InstantiationCopyPolicy.INSTANTIATION_COPY_POLICY);

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

		return buildInstantiationCopyPolicy();
	}

	public final List<ExternalMapping> getMappings() {
		return ListTools.list(mappings());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final Mapping getMapping(String name) {

		// TODO: Speed up by creating a helper method that will retrieve the node directly
		for (ExternalMapping mapping : mappings()) {
			if (ObjectTools.equals(name, mapping.getName())) {
				return (Mapping) mapping;
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalNoSql getNoSql() {

		if (hasChild(NoSql.NO_SQL)) {
			return new NoSql(this);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalObjectTypeConverter getObjectTypeConverter(int index) {

		Element element = getChild(ObjectTypeConverter.OBJECT_TYPE_CONVERTER, index);

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

		return buildObjectTypeConverter(index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected final ORMConfiguration getParent() {
		return (ORMConfiguration) super.getParent();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalProperty getProperty(int index) {

		Element element = getChild(Property.PROPERTY, index);

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

		return buildProperty(index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalStructConverter getStructConverter(int index) {

		Element element = getChild(StructConverter.STRUCT_CONVERTER, index);

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

		return buildStructConverter(index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ExternalTypeConverter getTypeConverter(int index) {

		Element element = getChild(TypeConverter.TYPE_CONVERTER, index);

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

		return buildTypeConverter(index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ListIterable<ExternalIDMapping> idMappings() {
		List<ExternalIDMapping> idMappings = new ArrayList<ExternalIDMapping>();
		for (ExternalMapping mapping : mappings()) {
			if (mapping instanceof ExternalIDMapping) {
				idMappings.add((ExternalIDMapping)mapping);
			}
		}
		return new ListListIterable<ExternalIDMapping>(idMappings);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final Boolean isExcludeDefaultMappings() {
		return getBooleanAttribute(EXCLUDE_DEFAULT_MAPPINGS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final Boolean isMetadataComplete() {
		return getBooleanAttribute(METADATA_COMPLETE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ListIterable<ExternalMapping> mappings() {

		Element element = getChild(Mapping.ATTRIBUTES);

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

		return EmptyListIterable.instance();
	}

	private ListIterable<ExternalMapping> mappings(Element element) {

		List<ExternalMapping> mappings = new ArrayList<ExternalMapping>();
		int index = 0;

		for (Element childElement : getChildren(element)) {
			String elementName = getNodeName(childElement);
			ExternalMapping mapping = buildMapping(elementName, index++);

			if (mapping != null) {
				mappings.add(mapping);
			}
		}

		return new ListListIterable<ExternalMapping>(mappings);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int mappingsSize() {

		Element attributes = getChild(Mapping.ATTRIBUTES);

		if (attributes != null) {
			return getChildrenSize(attributes, getMappingElementNamesOrder());
		}

		return 0;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ListIterable<ExternalObjectTypeConverter> objectTypeConverters() {

		int count = objectTypeConvertersSize();
		List<ExternalObjectTypeConverter> converters = new ArrayList<ExternalObjectTypeConverter>(count);

		for (int index = count; --index >= 0;) {
			ExternalObjectTypeConverter converter = buildObjectTypeConverter(index);
			converters.add(0, converter);
		}

		return new ListListIterable<ExternalObjectTypeConverter>(converters);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int objectTypeConvertersSize() {
		return getChildrenSize(ObjectTypeConverter.OBJECT_TYPE_CONVERTER);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ListIterable<ExternalProperty> properties() {

		int count = propertiesSize();
		List<ExternalProperty> converters = new ArrayList<ExternalProperty>(count);

		for (int index = count; --index >= 0;) {
			ExternalProperty converter = buildProperty(index);
			converters.add(0, converter);
		}

		return new ListListIterable<ExternalProperty>(converters);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int propertiesSize() {
		return getChildrenSize(Property.PROPERTY);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeAccessMethods() {
		removeChild(AccessMethods.ACCESS_METHODS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeCloneCopyPolicy() {
		CloneCopyPolicy policy = buildCloneCopyPolicy();
		policy.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeConverter(int index) {
		Converter converter = buildConverter(index);
		converter.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeCopyPolicy() {
		CopyPolicy policy = buildCopyPolicy();
		policy.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeInstantiationCopyPolicy() {
		InstantiationCopyPolicy policy = buildInstantiationCopyPolicy();
		policy.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeMapping(String name) {

		Mapping mapping = getMapping(name);

		if (mapping != null) {
			mapping.removeSelf();
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeNoSql() {
		NoSql noSql = new NoSql(this);
		noSql.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeObjectTypeConverter(int index) {
		ObjectTypeConverter converter = buildObjectTypeConverter(index);
		converter.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeProperty(int index) {
		Property converter = buildProperty(index);
		converter.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeSelf() {
		removeChild(getParent(), getElementName(), index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeStructConverter(int index) {
		StructConverter converter = buildStructConverter(index);
		converter.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void removeTypeConverter(int index) {
		TypeConverter converter = buildTypeConverter(index);
		converter.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setAccessType(String type) {
		setAttribute(ACCESS, type);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setChangeTrackingType(ChangeTrackingType type) {

		Element element = getChild(CHANGE_TRACKING);

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

		if ((element == null) && (type != null)) {
			element = addChild(CHANGE_TRACKING);
		}

		if (type != null) {
			setAttribute(element, TYPE, type);
		}
		else if (element != null) {
			removeChild(CHANGE_TRACKING);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setClassName(String className) {
		setAttribute(CLASS, className);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setCustomizerClassName(String name) {

		Element element = getChild(CUSTOMIZER);

		if ((element == null) && (name != null)) {
			element = addChild(CUSTOMIZER);
		}

		if (name != null) {
			setAttribute(element, CLASS, name);
		}
		else if (element != null) {
			removeChild(CUSTOMIZER);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setDescription(String description) {
		updateChildTextNode(DESCRIPTION, description);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setExcludeDefaultMappings(Boolean excludeDefaultMappings) {
		setAttribute(EXCLUDE_DEFAULT_MAPPINGS, excludeDefaultMappings);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setMetadataComplete(Boolean metaDataComplete) {
		setAttribute(METADATA_COMPLETE, metaDataComplete);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ListIterable<ExternalStructConverter> structConverters() {

		int count = structConvertersSize();
		List<ExternalStructConverter> converters = new ArrayList<ExternalStructConverter>(count);

		for (int index = count; --index >= 0;) {
			ExternalStructConverter converter = buildStructConverter(index);
			converters.add(0, converter);
		}

		return new ListListIterable<ExternalStructConverter>(converters);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int structConvertersSize() {
		return getChildrenSize(StructConverter.STRUCT_CONVERTER);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final ListIterable<ExternalTypeConverter> typeConverters() {

		int count = typeConvertersSize();
		List<ExternalTypeConverter> converters = new ArrayList<ExternalTypeConverter>(count);

		for (int index = count; --index >= 0;) {
			ExternalTypeConverter converter = buildTypeConverter(index);
			converters.add(0, converter);
		}

		return new ListListIterable<ExternalTypeConverter>(converters);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final int typeConvertersSize() {
		return getChildrenSize(TypeConverter.TYPE_CONVERTER);
	}
}