/*******************************************************************************
 * 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.orm.dom;

import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.eclipse.persistence.tools.mapping.AbstractExternalForm;
import org.eclipse.persistence.tools.mapping.ExternalFormHelper;
import org.eclipse.persistence.tools.mapping.orm.AccessType;
import org.eclipse.persistence.tools.mapping.orm.ExternalBasicNamedQuery;
import org.eclipse.persistence.tools.mapping.orm.ExternalConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalEmbeddable;
import org.eclipse.persistence.tools.mapping.orm.ExternalEntity;
import org.eclipse.persistence.tools.mapping.orm.ExternalMappedSuperClass;
import org.eclipse.persistence.tools.mapping.orm.ExternalNamedQuery;
import org.eclipse.persistence.tools.mapping.orm.ExternalNativeQuery;
import org.eclipse.persistence.tools.mapping.orm.ExternalORMConfiguration;
import org.eclipse.persistence.tools.mapping.orm.ExternalObjectTypeConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalPersistenceUnit;
import org.eclipse.persistence.tools.mapping.orm.ExternalSequenceGenerator;
import org.eclipse.persistence.tools.mapping.orm.ExternalSQLResultSetMapping;
import org.eclipse.persistence.tools.mapping.orm.ExternalStoredProcedureQuery;
import org.eclipse.persistence.tools.mapping.orm.ExternalStructConverter;
import org.eclipse.persistence.tools.mapping.orm.ExternalTableGenerator;
import org.eclipse.persistence.tools.mapping.orm.ExternalTenantDiscriminatorColumn;
import org.eclipse.persistence.tools.mapping.orm.ExternalTypeConverter;
import org.eclipse.persistence.tools.mapping.orm.ORMDocumentType;
import org.eclipse.persistence.tools.utility.ObjectTools;
import org.eclipse.persistence.tools.utility.TextRange;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import static org.eclipse.persistence.tools.mapping.orm.ORMXmlConstants.*;
import static org.eclipse.persistence.tools.mapping.orm.XmlConstants.*;

/**
 * The external form interacting with the XML document for the ORM Configuration file.
 *
 * @version 2.6
 */
@SuppressWarnings({"nls", "unused"}) // unused used for the import statement: see bug 330740
public final class ORMConfiguration extends AbstractExternalForm
                                    implements ExternalORMConfiguration {

	/**
	 * The helper is used when the document needs to be modified.
	 */
	private final ExternalFormHelper helper;

	/**
	 * Creates a new <code>ORMConfiguration</code>.
	 *
	 * @param helper The helper is used when the document needs to be modified
	 */
	public ORMConfiguration(ExternalFormHelper helper) {
		super(null);
		this.helper = helper;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalConverter addConverter() {
		Converter converter = buildConverter(-1);
		converter.addSelf();
		return converter;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalTenantDiscriminatorColumn addDiscriminatorColumn() {
		TenantDiscriminatorColumn column = buildDiscriminatorColumn(-1);
		column.addSelf();
		return column;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEmbeddable addEmbeddable(String className) {
		Embeddable embeddable = buildEmbeddable(-1);
		embeddable.addSelf();
		embeddable.setClassName(className);
		return embeddable;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEntity addEntity(String className) {
		Entity entity = buildEntity(-1);
		entity.addSelf();
		entity.setClassName(className);
		return entity;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalMappedSuperClass addMappedSuperClass(String className) {
		MappedSuperClassEntity mappedSuperclass = buildMappedSuperclass(-1);
		mappedSuperclass.addSelf();
		mappedSuperclass.setClassName(className);
		return mappedSuperclass;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalNativeQuery addNamedNativeQuery(String name) {
		NamedNativeQuery query = buildNamedNativeQuery(-1);
		query.addSelf();
		query.setName(name);
		return query;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalNamedQuery addNamedQuery(String name) {
		NamedQuery query = buildNamedQuery(-1);
		query.addSelf();
		query.setName(name);
		return query;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalObjectTypeConverter addObjectTypeConverter() {
		ObjectTypeConverter converter = buildObjectTypeConverter(-1);
		converter.addSelf();
		return converter;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalPersistenceUnit addPersistenceUnitMetaData() {
		PersistenceUnit persistenceUnit = buildPersistenceUnit();
		persistenceUnit.addSelf();
		return persistenceUnit;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected Element addSelf(String elementName) {
		return addSelf(elementName, Collections.<String>emptyList());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Element addSelf(String elementName, List<String> elementNamesOrder) {
		return helper.buildORMConfiguration(this);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalSequenceGenerator addSequenceGenerator(String name) {
		SequenceGenerator sequenceGenerator = buildSequenceGenerator(-1);
		sequenceGenerator.addSelf();
		sequenceGenerator.setName(name);
		return sequenceGenerator;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalSQLResultSetMapping addSqlResultSetMapping(String name) {
		SQLResultSetMapping sqlResultSetMapping = buildSqlResultSetMapping(-1);
		sqlResultSetMapping.addSelf();
		sqlResultSetMapping.setName(name);
		return sqlResultSetMapping;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalStoredProcedureQuery addStoredProcedureQuery(String name, String procedureName) {
		NamedStoredProcedureQuery query = buildStoredProcedureQuery(-1);
		query.addSelf();
		query.setName(name);
		query.setProcedureName(procedureName);
		return query;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalStructConverter addStructConverter() {
		StructConverter converter = buildStructConverter(-1);
		converter.addSelf();
		return converter;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalTableGenerator addTableGenerator(String name) {
		TableGenerator generator = buildTableGenerator(-1);
		generator.addSelf();
		generator.setName(name);
		return generator;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalTypeConverter addTypeConverter() {
		TypeConverter converter = buildTypeConverter(-1);
		converter.addSelf();
		return converter;
	}

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

	private TenantDiscriminatorColumn buildDiscriminatorColumn(int index) {
		return new TenantDiscriminatorColumn(this, index);
	}

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

		List<String> names = new ArrayList<String>();
		names.add(DESCRIPTION);
		names.add(PersistenceUnit.PERSISTENCE_UNIT_METADATA);
		names.add(PACKAGE);
		names.add(SCHEMA);
		names.add(CATALOG);
		names.add(ACCESS);
		names.add(Converter.CONVERTER);
		names.add(TypeConverter.TYPE_CONVERTER);
		names.add(ObjectTypeConverter.OBJECT_TYPE_CONVERTER);
		names.add(StructConverter.STRUCT_CONVERTER);
		names.add(SequenceGenerator.SEQUENCE_GENERATOR);
		names.add(TableGenerator.TABLE_GENERATOR);
		names.add(NamedQuery.NAMED_QUERY);
		names.add(NamedNativeQuery.NAMED_NATIVE_QUERY);
		names.add(NamedStoredProcedureQuery.NAMED_STORED_PROCEDURE_QUERY);
		names.add(SQLResultSetMapping.SQL_RESULT_SET_MAPPING);
		names.add(MappedSuperClassEntity.MAPPED_SUPERCLASS);
		names.add(Entity.ENTITY);
		names.add(Embeddable.EMBEDDABLE);
		return names;
	}

	private Embeddable buildEmbeddable(int index) {
		return new Embeddable(this, index);
	}

	private Entity buildEntity(int index) {
		return new Entity(this, index);
	}

	private MappedSuperClassEntity buildMappedSuperclass(int index) {
		return new MappedSuperClassEntity(this, index);
	}

	private NamedNativeQuery buildNamedNativeQuery(int index) {
		return new NamedNativeQuery(this, index);
	}

	private NamedQuery buildNamedQuery(int index) {
		return new NamedQuery(this, index);
	}

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

	private PersistenceUnit buildPersistenceUnit() {
		return new PersistenceUnit(this);
	}

	public String buildSchemaLocation(ORMDocumentType version) {

		StringBuilder sb = new StringBuilder();
		sb.append(version.getXmlNamespace());
		sb.append(" ");
		sb.append(version.getSchemaURI());

		return sb.toString();
	}

	private SequenceGenerator buildSequenceGenerator(int index) {
		return new SequenceGenerator(this, index);
	}

	private SQLResultSetMapping buildSqlResultSetMapping(int index) {
		return new SQLResultSetMapping(this, index);
	}

	private NamedStoredProcedureQuery buildStoredProcedureQuery(int index) {
		return new NamedStoredProcedureQuery(this, index);
	}

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

	private TableGenerator buildTableGenerator(int index) {
		return new TableGenerator(this, index);
	}

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

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

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

		for (int index = 0; index < count; index++) {
			converters.add(buildConverter(index));
		}

		return converters;
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalTenantDiscriminatorColumn> discriminatorColumns() {

		int count = discriminatorColumnSize();
		List<ExternalTenantDiscriminatorColumn> columns = new ArrayList<ExternalTenantDiscriminatorColumn>(count);

		for (int index = 0; index < count; index++) {
			columns.add(buildDiscriminatorColumn(index));
		}

		return columns;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int discriminatorColumnSize() {
		return getChildrenSize(TenantDiscriminatorColumn.TENANT_DISCRIMINATOR_COLUMN);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalEmbeddable> embeddables() {

		int count = embeddablesSize();
		List<ExternalEmbeddable> embeddables = new ArrayList<ExternalEmbeddable>(count);

		for (int index = 0; index < count; index++) {
			embeddables.add(buildEmbeddable(index));
		}

		return embeddables;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int embeddablesSize() {
		return getChildrenSize(Embeddable.EMBEDDABLE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalEntity> entities() {

		int count = entitiesSize();
		List<ExternalEntity> entities = new ArrayList<ExternalEntity>(count);

		for (int index = 0; index < count; index++) {
			entities.add(buildEntity(index));
		}

		return entities;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int entitiesSize() {
		return getChildrenSize(Entity.ENTITY);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public AccessType getAccessType() {
		return getChildEnumNode(ACCESS, AccessType.class);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getAccessTypeTextRange() {
		return getChildTextNodeTextRange(ACCESS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getBuildVersion() {
		return VERSION_2_0;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getCatalogName() {
		return getChildTextNode(CATALOG);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getCatalogNameTextRange() {
		return getChildTextNodeTextRange(CATALOG);
	}

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

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

		if (element != null) {
			return buildConverter(index);
		}

		return null;
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalTenantDiscriminatorColumn getDiscriminatorColumn(int index) {

		if (hasChild(TenantDiscriminatorColumn.TENANT_DISCRIMINATOR_COLUMN, index)) {
			return buildDiscriminatorColumn(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ORMDocumentType getDocumentType() {
		return ORMDocumentType.value(getNamespace(), getVersion(), getSchemaLocation());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Element getElement() {
		return getRootElement();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getElementName() {
		return ENTITY_MAPPINGS;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEmbeddable getEmbeddable(int index) {

		Element element = getChild(Embeddable.EMBEDDABLE, index);

		if (element != null) {
			return buildEmbeddable(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEmbeddable getEmbeddable(String className) {

		for (ExternalEmbeddable embeddable : embeddables()) {
			if (ObjectTools.equals(embeddable.getClassName(), className)) {
				return embeddable;
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEntity getEntity(int index) {

		Element element = getChild(Entity.ENTITY, index);

		if (element != null) {
			return buildEntity(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalEntity getEntity(String className) {

		for (ExternalEntity entity : entities()) {
			if (ObjectTools.equals(entity.getClassName(), className)) {
				return entity;
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected ExternalFormHelper getHelper() {
		return helper;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public URL getLocation() {
		return helper.getLocation();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalMappedSuperClass getMappedSuperClass(int index) {

		Element element = getChild(MappedSuperClassEntity.MAPPED_SUPERCLASS, index);

		if (element != null) {
			return buildMappedSuperclass(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalMappedSuperClass getMappedSuperClass(String className) {

		for (ExternalMappedSuperClass entity : mappedSuperClasses()) {
			if (ObjectTools.equals(entity.getClassName(), className)) {
				return entity;
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalNativeQuery getNamedNativeQuery(int index) {

		Element element = getChild(NamedNativeQuery.NAMED_NATIVE_QUERY, index);

		if (element != null) {
			return buildNamedNativeQuery(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalNativeQuery getNamedNativeQuery(String queryName) {

		for (ExternalNativeQuery namedQuery : namedNativeQueries()) {
			if (namedQuery.getName().equals(queryName)) {
				return namedQuery;
			}
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalBasicNamedQuery getNamedQuery(int index) {

		Element element = getChild(NamedQuery.NAMED_QUERY, index);

		if (element != null) {
			return buildNamedQuery(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalBasicNamedQuery getNamedQuery(String queryName) {

		for (ExternalNamedQuery namedQuery : namedQueries()) {
			if (namedQuery.getName().equals(queryName)) {
				return (ExternalBasicNamedQuery) namedQuery;
			}
		}

		return null;
	}

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

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

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

		return buildObjectTypeConverter(index);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getPackageName() {
		return getChildTextNode(PACKAGE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getPackageNameTextRange() {
		return getChildTextNodeTextRange(PACKAGE);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public PersistenceUnit getPersistenceUnitMetaData() {

		Element element = getChild(PersistenceUnit.PERSISTENCE_UNIT_METADATA);

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

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getRootElementTextRange() {
		return getElementNameTextRange(getRootElement());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getSchemaName() {
		return getChildTextNode(SCHEMA);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public TextRange getSchemaNameTextRange() {
		return getChildTextNodeTextRange(SCHEMA);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalSequenceGenerator getSequenceGenerator(int index) {

		Element element = getChild(SequenceGenerator.SEQUENCE_GENERATOR, index);

		if (element != null) {
			return buildSequenceGenerator(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalSQLResultSetMapping getSqlResultSetMapping(int index) {

		Element element = getChild(SQLResultSetMapping.SQL_RESULT_SET_MAPPING, index);

		if (element != null) {
			return buildSqlResultSetMapping(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalStoredProcedureQuery getStoredProcedureQuery(int index) {

		Element element = getChild(NamedStoredProcedureQuery.NAMED_STORED_PROCEDURE_QUERY, index);

		if (element != null) {
			return buildStoredProcedureQuery(index);
		}

		return null;
	}

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

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

		if (element != null) {
			return buildStructConverter(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ExternalTableGenerator getTableGenerator(int index) {

		Element element = getChild(TableGenerator.TABLE_GENERATOR, index);

		if (element != null) {
			return buildTableGenerator(index);
		}

		return null;
	}

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

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

		if (element != null) {
			return buildTypeConverter(index);
		}

		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getXML() {

		try {

			// write the content into xml file
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			javax.xml.transform.Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(getDocument());
			ByteArrayOutputStream ouput = new ByteArrayOutputStream();
			StreamResult result = new StreamResult(ouput);

			transformer.transform(source, result);

			return ouput.toString();

		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalMappedSuperClass> mappedSuperClasses() {

		int count = mappedSuperClassesSize();
		List<ExternalMappedSuperClass> mappedSuperclasses = new ArrayList<ExternalMappedSuperClass>(count);

		for (int index = 0; index < count; index++) {
			mappedSuperclasses.add(buildMappedSuperclass(index));
		}

		return mappedSuperclasses;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int mappedSuperClassesSize() {
		return getChildrenSize(MappedSuperClassEntity.MAPPED_SUPERCLASS);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalNativeQuery> namedNativeQueries() {

		int count = namedNativeQueriesSize();
		List<ExternalNativeQuery> nativeQueries = new ArrayList<ExternalNativeQuery>(count);

		for (int index = 0; index < count; index++) {
			nativeQueries.add(buildNamedNativeQuery(index));
		}

		return nativeQueries;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int namedNativeQueriesSize() {
		return getChildrenSize(NamedNativeQuery.NAMED_NATIVE_QUERY);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalNamedQuery> namedQueries() {

		int count = namedQueriesSize();
		List<ExternalNamedQuery> namedQueries = new ArrayList<ExternalNamedQuery>(count);

		for (int index = 0; index < count; index++) {
			namedQueries.add(buildNamedQuery(index));
		}

		return namedQueries;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int namedQueriesSize() {
		return getChildrenSize(NamedQuery.NAMED_QUERY);
	}

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

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

		for (int index = 0; index < count; index++) {
			converters.add(buildObjectTypeConverter(index));
		}

		return converters;
	}

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

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeDiscriminatorColumn(int index) {
		TenantDiscriminatorColumn column = buildDiscriminatorColumn(index);
		column.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeEmbeddable(int index) {
		Embeddable entity = buildEmbeddable(index);
		entity.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeEntity(int index) {
		Entity entity = buildEntity(index);
		entity.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeEntity(String entityClassName) {
		for (ExternalEntity entity : entities()) {
			if (entity.getClassName().equals(entityClassName)) {
				((Entity)entity).removeSelf();

				return;
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeMappedSuperClass(int index) {
		MappedSuperClassEntity entity = buildMappedSuperclass(index);
		entity.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeNamedQuery(int index) {
		NamedQuery namedQuery = buildNamedQuery(index);
		namedQuery.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeNamedQuery(String queryName) {

		for (ExternalNamedQuery query : namedQueries()) {
			if (ObjectTools.equals(query.getName(), queryName)) {
				((NamedQuery)query).removeSelf();
				break;
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeNativeQuery(int index) {
		NamedNativeQuery namedNativeQuery = buildNamedNativeQuery(index);
		namedNativeQuery.removeSelf();
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removePersistenceUnitMetaData() {
		PersistenceUnit persistenceUnit = buildPersistenceUnit();
		persistenceUnit.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeSequenceGenerator(int index) {
		SequenceGenerator sequenceGenerator = buildSequenceGenerator(index);
		sequenceGenerator.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeSqlResultSetMapping(int index) {
		SQLResultSetMapping sqlResultSetMapping = buildSqlResultSetMapping(index);
		sqlResultSetMapping.removeSelf();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeStoredProcedureQuery(int index) {
		NamedStoredProcedureQuery storedProcedureQuery = buildStoredProcedureQuery(index);
		storedProcedureQuery.removeSelf();
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void removeTableGenerator(int index) {
		TableGenerator tableGenerator = buildTableGenerator(index);
		tableGenerator.removeSelf();
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalSequenceGenerator> sequenceGenerators() {

		int count = sequenceGeneratorsSize();
		List<ExternalSequenceGenerator> generators = new ArrayList<ExternalSequenceGenerator>(count);

		for (int index = 0; index < count; index++) {
			generators.add(buildSequenceGenerator(index));
		}

		return generators;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int sequenceGeneratorsSize() {
		return getChildrenSize(SequenceGenerator.SEQUENCE_GENERATOR);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setAccessType(AccessType type) {
		updateChildTextNode(ACCESS, type);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setCatalogName(String catalog) {
		updateChildTextNode(CATALOG, catalog);
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setDocumentType(ORMDocumentType version) {
		setVersion(version.getVersion());
		setSchemaLocation(buildSchemaLocation(version));
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setPackageName(String packageName) {
		updateChildTextNode(PACKAGE, packageName);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setSchemaName(String schema) {
		updateChildTextNode(SCHEMA, schema);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalSQLResultSetMapping> sqlResultSetMappings() {

		int count = sqlResultSetMappingsSize();
		List<ExternalSQLResultSetMapping> sqlResultSetMappings = new ArrayList<ExternalSQLResultSetMapping>(count);

		for (int index = 0; index < count; index++) {
			sqlResultSetMappings.add(buildSqlResultSetMapping(index));
		}

		return sqlResultSetMappings;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int sqlResultSetMappingsSize() {
		return getChildrenSize(SQLResultSetMapping.SQL_RESULT_SET_MAPPING);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalStoredProcedureQuery> storedProcedureQueries() {

		int count = storedProcedureQueriesSize();
		List<ExternalStoredProcedureQuery> storedProcedureQueries = new ArrayList<ExternalStoredProcedureQuery>(count);

		for (int index = 0; index < count; index++) {
			storedProcedureQueries.add(buildStoredProcedureQuery(index));
		}

		return storedProcedureQueries;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int storedProcedureQueriesSize() {
		return getChildrenSize(NamedStoredProcedureQuery.NAMED_STORED_PROCEDURE_QUERY);
	}

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

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

		for (int index = 0; index < count; index++) {
			converters.add(buildStructConverter(index));
		}

		return converters;
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<ExternalTableGenerator> tableGenerators() {

		int count = tableGeneratorsSize();
		List<ExternalTableGenerator> generators = new ArrayList<ExternalTableGenerator>(count);

		for (int index = 0; index < count; index++) {
			generators.add(buildTableGenerator(index));
		}

		return generators;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int tableGeneratorsSize() {
		return getChildrenSize(TableGenerator.TABLE_GENERATOR);
	}

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

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

		for (int index = 0; index < count; index++) {
			converters.add(buildTypeConverter(index));
		}

		return converters;
	}

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