/*******************************************************************************
 * 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.Collection;
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.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 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;
	}

	/**
	 * {@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
	 */
	Collection<String> buildMappingNames() {

		Collection<String> names = new ArrayList<String>();
		names.add(BasicMapping.BASIC);
		names.add(BasicCollectionMapping.BASIC_COLLECTION);
		names.add(BasicMapMapping.BASIC_MAP);
		names.add(EmbeddedMapping.EMBEDDED);
		names.add(ElementCollectionMapping.ELEMENT_COLLECTION);
		names.add(ManyToManyMapping.MANY_TO_MANY);
		names.add(ManyToOneMapping.MANY_TO_ONE);
		names.add(OneToManyMapping.ONE_TO_MANY);
		names.add(OneToOneMapping.ONE_TO_ONE);
		names.add(TransientMapping.TRANSIENT);
		return names;
	}

	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);
	}

	/**
	 * {@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, buildMappingNames());
		}

		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);
	}
}