/*******************************************************************************
 * Copyright (c) 2006, 2012 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 *
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.jpa.core.internal.context.orm;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jpt.common.core.internal.utility.JDTTools;
import org.eclipse.jpt.common.core.resource.java.JavaResourceAbstractType;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.Tools;
import org.eclipse.jpt.common.utility.internal.iterables.CompositeIterable;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable;
import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SingleElementIterable;
import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable;
import org.eclipse.jpt.jpa.core.JpaStructureNode;
import org.eclipse.jpt.jpa.core.JptJpaCorePlugin;
import org.eclipse.jpt.jpa.core.context.AccessType;
import org.eclipse.jpt.jpa.core.context.Generator;
import org.eclipse.jpt.jpa.core.context.PersistentType;
import org.eclipse.jpt.jpa.core.context.Query;
import org.eclipse.jpt.jpa.core.context.orm.EntityMappings;
import org.eclipse.jpt.jpa.core.context.orm.OrmIdClassReference;
import org.eclipse.jpt.jpa.core.context.orm.OrmPersistenceUnitMetadata;
import org.eclipse.jpt.jpa.core.context.orm.OrmPersistentType;
import org.eclipse.jpt.jpa.core.context.orm.OrmQueryContainer;
import org.eclipse.jpt.jpa.core.context.orm.OrmSequenceGenerator;
import org.eclipse.jpt.jpa.core.context.orm.OrmTableGenerator;
import org.eclipse.jpt.jpa.core.context.orm.OrmTypeMapping;
import org.eclipse.jpt.jpa.core.context.orm.OrmTypeMappingDefinition;
import org.eclipse.jpt.jpa.core.context.orm.OrmXml;
import org.eclipse.jpt.jpa.core.internal.context.ContextContainerTools;
import org.eclipse.jpt.jpa.core.internal.validation.DefaultJpaValidationMessages;
import org.eclipse.jpt.jpa.core.internal.validation.JpaValidationMessages;
import org.eclipse.jpt.jpa.core.resource.orm.OrmFactory;
import org.eclipse.jpt.jpa.core.resource.orm.XmlEntityMappings;
import org.eclipse.jpt.jpa.core.resource.orm.XmlSequenceGenerator;
import org.eclipse.jpt.jpa.core.resource.orm.XmlTableGenerator;
import org.eclipse.jpt.jpa.core.resource.orm.XmlTypeMapping;
import org.eclipse.jpt.jpa.db.Catalog;
import org.eclipse.jpt.jpa.db.Database;
import org.eclipse.jpt.jpa.db.Schema;
import org.eclipse.jpt.jpa.db.SchemaContainer;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;

/**
 * <code>orm.xml</code> file
 * <br>
 * <code>entity-mappings</code> element
 */
public abstract class AbstractEntityMappings
	extends AbstractOrmXmlContextNode
	implements EntityMappings
{
	protected final XmlEntityMappings xmlEntityMappings;

	protected String description;

	protected String package_;  // "package" is a Java keyword

	protected AccessType specifiedAccess;
	protected AccessType defaultAccess;

	protected String specifiedCatalog;
	protected String defaultCatalog;

	protected String specifiedSchema;
	protected String defaultSchema;

	protected final OrmPersistenceUnitMetadata persistenceUnitMetadata;

	protected final Vector<OrmPersistentType> persistentTypes = new Vector<OrmPersistentType>();
	protected final PersistentTypeContainerAdapter persistentTypeContainerAdapter = new PersistentTypeContainerAdapter();

	protected final ContextListContainer<OrmSequenceGenerator, XmlSequenceGenerator> sequenceGeneratorContainer;

	protected final ContextListContainer<OrmTableGenerator, XmlTableGenerator> tableGeneratorContainer;

	protected final OrmQueryContainer queryContainer;

	// Lookup of short class name to fully qualified class name for primitives, wrappers, array primitives
	protected static Map<String, String> PRIMITIVE_CLASSES = null;


	protected AbstractEntityMappings(OrmXml parent, XmlEntityMappings xmlEntityMappings) {
		super(parent);
		this.xmlEntityMappings = xmlEntityMappings;

		this.description = this.xmlEntityMappings.getDescription();
		this.package_ = this.xmlEntityMappings.getPackage();

		this.specifiedAccess = this.buildSpecifiedAccess();
		this.specifiedCatalog = this.xmlEntityMappings.getCatalog();
		this.specifiedSchema = this.xmlEntityMappings.getSchema();

		this.persistenceUnitMetadata = this.buildPersistenceUnitMetadata();

		this.initializePersistentTypes();
		this.sequenceGeneratorContainer = this.buildSequenceGeneratorContainer();
		this.tableGeneratorContainer = this.buildTableGeneratorContainer();

		this.queryContainer = this.buildQueryContainer();
	}


	// ********** synchronize/update **********

	@Override
	public void synchronizeWithResourceModel() {
		super.synchronizeWithResourceModel();

		this.setDescription_(this.xmlEntityMappings.getDescription());
		this.setPackage_(this.xmlEntityMappings.getPackage());

		this.setSpecifiedAccess_(this.buildSpecifiedAccess());
		this.setSpecifiedCatalog_(this.xmlEntityMappings.getCatalog());
		this.setSpecifiedSchema_(this.xmlEntityMappings.getSchema());

		this.persistenceUnitMetadata.synchronizeWithResourceModel();

		this.syncPersistentTypes();
		this.syncSequenceGenerators();
		this.syncTableGenerators();

		this.queryContainer.synchronizeWithResourceModel();
	}

	@Override
	public void update() {
		super.update();

		this.setDefaultAccess(this.buildDefaultAccess());
		this.setDefaultCatalog(this.buildDefaultCatalog());
		this.setDefaultSchema(this.buildDefaultSchema());

		this.persistenceUnitMetadata.update();

		this.updateNodes(this.getPersistentTypes());
		this.updateNodes(this.getSequenceGenerators());
		this.updateNodes(this.getTableGenerators());

		this.queryContainer.update();
	}


	// ********** overrides **********

	@Override
	public OrmXml getParent() {
		return (OrmXml) super.getParent();
	}

	// TODO bjv add to interface
	public OrmXml getOrmXml() {
		return this.getParent();
	}

	@Override
	public EntityMappings getMappingFileRoot() {
		return this;
	}


	// ********** JpaStructureNode implementation **********

	public ContextType getContextType() {
		return new ContextType(this);
	}

	public Class<EntityMappings> getType() {
		return EntityMappings.class;
	}

	public JpaStructureNode getStructureNode(int textOffset) {
		for (OrmPersistentType persistentType: this.getPersistentTypes()) {
			if (persistentType.contains(textOffset)) {
				return persistentType.getStructureNode(textOffset);
			}
		}
		return this;
	}

	public TextRange getSelectionTextRange() {
		return this.xmlEntityMappings.getSelectionTextRange();
	}

	public void dispose() {
		for (OrmPersistentType ormPersistentType : this.getPersistentTypes()) {
			ormPersistentType.dispose();
		}
	}


	// ********** PersistentType.Owner implementation **********

	public AccessType getOverridePersistentTypeAccess() {
		return this.isXmlMappingMetadataComplete() ? this.specifiedAccess : null;
	}

	public AccessType getDefaultPersistentTypeAccess() {
		return this.getAccess();
	}

	public String getDefaultPersistentTypePackage() {
		return this.getPackage();
	}

	protected boolean isXmlMappingMetadataComplete() {
		return this.getPersistenceUnit().isXmlMappingMetadataComplete();
	}


	// ********** persistence unit metadata **********

	public OrmPersistenceUnitMetadata getPersistenceUnitMetadata() {
		return this.persistenceUnitMetadata;
	}

	protected OrmPersistenceUnitMetadata buildPersistenceUnitMetadata() {
		return this.getContextNodeFactory().buildOrmPersistenceUnitMetadata(this);
	}


	// ********** misc **********

	public XmlEntityMappings getXmlEntityMappings() {
		return this.xmlEntityMappings;
	}

	public String getVersion() {
		return this.xmlEntityMappings.getVersion();
	}

	public void changeMapping(OrmPersistentType ormPersistentType, OrmTypeMapping oldMapping, OrmTypeMapping newMapping) {
		AccessType savedAccess = ormPersistentType.getSpecifiedAccess();
		int sourceIndex = this.persistentTypes.indexOf(ormPersistentType);
		this.persistentTypes.remove(sourceIndex);
		oldMapping.removeXmlTypeMappingFrom(this.xmlEntityMappings);
		int targetIndex = this.calculateInsertionIndex(ormPersistentType);
		this.persistentTypes.add(targetIndex, ormPersistentType);
		newMapping.addXmlTypeMappingTo(this.xmlEntityMappings);

		newMapping.initializeFrom(oldMapping);
		//not sure where else to put this, need to set the access on the resource model
		ormPersistentType.setSpecifiedAccess(savedAccess);
		this.fireItemMoved(PERSISTENT_TYPES_LIST, targetIndex, sourceIndex);
	}

	public TextRange getValidationTextRange() {
		TextRange textRange = this.xmlEntityMappings.getValidationTextRange();
		return (textRange != null) ? textRange : this.getOrmXml().getValidationTextRange();
	}

	public boolean containsOffset(int textOffset) {
		return (this.xmlEntityMappings != null) && this.xmlEntityMappings.containsOffset(textOffset);
	}


	// ********** description **********

	public String getDescription() {
		return this.description;
	}

	public void setDescription(String description) {
		this.setDescription_(description);
		this.xmlEntityMappings.setDescription(description);
	}

	protected void setDescription_(String description) {
		String old = this.description;
		this.description = description;
		this.firePropertyChanged(DESCRIPTION_PROPERTY, old, description);
	}


	// ********** package **********

	public String getPackage() {
		return this.package_;
	}

	public void setPackage(String package_) {
		this.setPackage_(package_);
		this.xmlEntityMappings.setPackage(package_);
	}

	/**
	 * TODO If the package changes, we should probably clear out all resolved
	 * references to persistent types:<ul>
	 * <li>{@link OrmIdClassReference#getIdClass()}
	 * <li>{@link OrmPersistentType#getJavaPersistentType()}
	 * </ul>
	 */
	protected void setPackage_(String package_) {
		String old = this.package_;
		this.package_ = package_;
		this.firePropertyChanged(PACKAGE_PROPERTY, old, package_);
	}


	// ********** access **********

	public AccessType getAccess() {
		return (this.specifiedAccess != null) ? this.specifiedAccess : this.defaultAccess;
	}

	public AccessType getSpecifiedAccess() {
		return this.specifiedAccess;
	}

	public void setSpecifiedAccess(AccessType access) {
		this.setSpecifiedAccess_(access);
		this.xmlEntityMappings.setAccess(AccessType.toOrmResourceModel(access));
	}

	protected void setSpecifiedAccess_(AccessType access) {
		AccessType old = this.specifiedAccess;
		this.specifiedAccess = access;
		this.firePropertyChanged(SPECIFIED_ACCESS_PROPERTY, old, access);
	}

	protected AccessType buildSpecifiedAccess() {
		return AccessType.fromOrmResourceModel(this.xmlEntityMappings.getAccess(), this.getJpaPlatform(), this.getResourceType());
	}

	public AccessType getDefaultAccess() {
		return this.defaultAccess;
	}

	protected void setDefaultAccess(AccessType access) {
		AccessType old = this.defaultAccess;
		this.defaultAccess = access;
		this.firePropertyChanged(DEFAULT_ACCESS_PROPERTY, old, access);
	}

	protected AccessType buildDefaultAccess() {
		return this.getPersistenceUnit().getDefaultAccess();
	}


	// ********** catalog **********

	public String getCatalog() {
		return (this.specifiedCatalog != null) ? this.specifiedCatalog : this.defaultCatalog;
	}

	public String getSpecifiedCatalog() {
		return this.specifiedCatalog;
	}

	public void setSpecifiedCatalog(String catalog) {
		this.setSpecifiedCatalog_(catalog);
		this.xmlEntityMappings.setCatalog(catalog);
	}

	protected void setSpecifiedCatalog_(String catalog) {
		String old = this.specifiedCatalog;
		this.specifiedCatalog = catalog;
		this.firePropertyChanged(SPECIFIED_CATALOG_PROPERTY, old, catalog);
	}

	public String getDefaultCatalog() {
		return this.defaultCatalog;
	}

	protected void setDefaultCatalog(String catalog) {
		String old = this.defaultCatalog;
		this.defaultCatalog = catalog;
		this.firePropertyChanged(DEFAULT_CATALOG_PROPERTY, old, catalog);
	}

	protected String buildDefaultCatalog() {
		return this.getPersistenceUnit().getDefaultCatalog();
	}

	/**
	 * If we don't have a catalog (i.e. we don't even have a <em>default</em>
	 * catalog), then the database probably does not support catalogs.
	 */
	public Catalog getDbCatalog() {
		String catalog = this.getCatalog();
		return (catalog == null) ? null : this.resolveDbCatalog(catalog);
	}


	// ********** schema **********

	public String getSchema() {
		return (this.specifiedSchema != null) ? this.specifiedSchema : this.defaultSchema;
	}

	public String getSpecifiedSchema() {
		return this.specifiedSchema;
	}

	public void setSpecifiedSchema(String schema) {
		this.setSpecifiedSchema_(schema);
		this.xmlEntityMappings.setSchema(schema);
	}

	protected void setSpecifiedSchema_(String schema) {
		String old = this.specifiedSchema;
		this.specifiedSchema = schema;
		this.firePropertyChanged(SPECIFIED_SCHEMA_PROPERTY, old, schema);
	}

	public String getDefaultSchema() {
		return this.defaultSchema;
	}

	protected void setDefaultSchema(String schema) {
		String old = this.defaultSchema;
		this.defaultSchema = schema;
		this.firePropertyChanged(DEFAULT_SCHEMA_PROPERTY, old, schema);
	}

	protected String buildDefaultSchema() {
		return this.getPersistenceUnit().getDefaultSchema();
	}

	public Schema getDbSchema() {
		SchemaContainer dbSchemaContainer = this.getDbSchemaContainer();
		return (dbSchemaContainer == null) ? null : dbSchemaContainer.getSchemaForIdentifier(this.getSchema());
	}


	// ********** schema container **********

	/**
	 * If we don't have a catalog (i.e. we don't even have a <em>default</em> catalog),
	 * then the database probably does not support catalogs; and we need to
	 * get the schema directly from the database.
	 */
	public SchemaContainer getDbSchemaContainer() {
		String catalog = this.getCatalog();
		return (catalog != null) ? this.resolveDbCatalog(catalog) : this.getDatabase();
	}


	// ********** persistent types **********

	public ListIterable<OrmPersistentType> getPersistentTypes() {
		return new LiveCloneListIterable<OrmPersistentType>(this.persistentTypes);
	}

	public int getPersistentTypesSize() {
		return this.persistentTypes.size();
	}

	public OrmPersistentType getPersistentType(String className) {
		for (OrmPersistentType ormPersistentType : this.getPersistentTypes()) {
			if (ormPersistentType.isFor(className)) {
				return ormPersistentType;
			}
		}
		return null;
	}

	public boolean containsPersistentType(String className) {
		return this.getPersistentType(className) != null;
	}

	public PersistentType resolvePersistentType(String className) {
		return (PersistentType) this.resolveType(PERSISTENT_TYPE_LOOKUP_ADAPTER, className);
	}

	public JavaResourceAbstractType resolveJavaResourceType(String className) {
		return (JavaResourceAbstractType) this.resolveType(RESOURCE_TYPE_LOOKUP_ADAPTER, className);
	}

	public JavaResourceAbstractType resolveJavaResourceType(String className, JavaResourceAbstractType.Kind kind) {
		JavaResourceAbstractType resourceType = this.resolveJavaResourceType(className);
		if (resourceType == null || resourceType.getKind() != kind) {
			return null;
		}
		return resourceType;
	}

	public IType resolveJdtType(String className) {
		return (IType) this.resolveType(JDT_TYPE_LOOKUP_ADAPTER, className);
	}

	/**
	 * className passed in must have - $ for inner class
	 * className is qualified or not qualified
	 * append package if the name is not qualified
	 */
	public String getFullyQualifiedName(String className) {
		if (StringTools.stringIsEmpty(className)) {
			return null;
		}
		String primitiveClassName = getPrimitiveClassName(className);
		if (primitiveClassName != null) {
			return primitiveClassName;
		}

	    //No global package defined or the class name is qualified, use the className. 
		//Otherwise, prepend the global package name.
		if (this.getPackage() != null && className.indexOf('.') == -1) {
			className = this.prependGlobalPackage(className);
		}
		// static inner class listed in orm.xml will use '$', replace with '.'
		className = className.replace('$', '.');
		return className;
	}

	protected Object resolveType(TypeLookupAdapter adapter, String className) {
		if (className == null) {
			return null;
		}
		return adapter.resolveType(this, this.getFullyQualifiedName(className));
	}

	/**
	 * preconditions: 
	 * 		getPackage() is not null
	 * 		unqualifiedClassName is not qualified (contains no '.')
	 */
	protected String prependGlobalPackage(String unqualifiedClassName) {
		// Format of global package is "foo.bar"
		return this.getPackage() + '.' + unqualifiedClassName;
	}

	protected interface TypeLookupAdapter {
		Object resolveType(EntityMappings entityMappings, String className);
	}

	protected static final TypeLookupAdapter PERSISTENT_TYPE_LOOKUP_ADAPTER =
		new TypeLookupAdapter() {
			public Object resolveType(EntityMappings entityMappings, String className) {
				return entityMappings.getPersistenceUnit().getPersistentType(className);
			}
		};

	protected static final TypeLookupAdapter RESOURCE_TYPE_LOOKUP_ADAPTER =
		new TypeLookupAdapter() {
			public Object resolveType(EntityMappings entityMappings, String className) {
				return entityMappings.getJpaProject().getJavaResourceType(className);
			}
		};

	protected static final TypeLookupAdapter JDT_TYPE_LOOKUP_ADAPTER =
		new TypeLookupAdapter() {
			public Object resolveType(EntityMappings entityMappings, String className) {
				IJavaProject javaProject = entityMappings.getJpaProject().getJavaProject();
				return JDTTools.findType(javaProject, className);
			}
		};

	protected static String getPrimitiveClassName(String className) {
		if (PRIMITIVE_CLASSES == null) {
			PRIMITIVE_CLASSES = new HashMap<String, String>();
			PRIMITIVE_CLASSES.put("Boolean", Boolean.class.getName()); //$NON-NLS-1$
			PRIMITIVE_CLASSES.put("Byte", Byte.class.getName()); //$NON-NLS-1$
			PRIMITIVE_CLASSES.put("Character", Character.class.getName()); //$NON-NLS-1$
			PRIMITIVE_CLASSES.put("Double", Double.class.getName()); //$NON-NLS-1$
			PRIMITIVE_CLASSES.put("Float", Float.class.getName()); //$NON-NLS-1$
			PRIMITIVE_CLASSES.put("Integer", Integer.class.getName()); //$NON-NLS-1$
			PRIMITIVE_CLASSES.put("Long", Long.class.getName()); //$NON-NLS-1$
			PRIMITIVE_CLASSES.put("Number", Number.class.getName()); //$NON-NLS-1$
			PRIMITIVE_CLASSES.put("Short", Short.class.getName()); //$NON-NLS-1$
			PRIMITIVE_CLASSES.put("String", String.class.getName()); //$NON-NLS-1$
			PRIMITIVE_CLASSES.put("boolean", "boolean"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("byte", "byte"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("char", "char"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("double", "double"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("float", "float"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("int", "int"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("long", "long"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("short", "short"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("byte[]", "byte[]"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("char[]", "char[]"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("boolean[]", "boolean[]"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("double[]", "double[]"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("float[]", "float[]"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("int[]", "int[]"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("long[]", "long[]"); //$NON-NLS-1$ //$NON-NLS-2$
			PRIMITIVE_CLASSES.put("short[]", "short[]"); //$NON-NLS-1$ //$NON-NLS-2$
        }
        
        return (className == null) ? null : PRIMITIVE_CLASSES.get(className); 
    }

	/**
	 * We have to calculate the new persistent type's index.
	 * We will use the type's short name if the entity mappings's
	 * package is the same as the type's package.
	 */
	public OrmPersistentType addPersistentType(String mappingKey, String className) {
		OrmTypeMappingDefinition md = this.getMappingFileDefinition().getTypeMappingDefinition(mappingKey);
		XmlTypeMapping xmlTypeMapping = md.buildResourceMapping(this.getResourceNodeFactory());

		// adds short name if package name is relevant
		className = this.normalizeClassName(className);
		xmlTypeMapping.setClassName(className);

		OrmPersistentType persistentType = this.buildPersistentType(xmlTypeMapping);
		int index = this.calculateInsertionIndex(persistentType);
		this.addItemToList(index, persistentType, this.persistentTypes, PERSISTENT_TYPES_LIST);

		persistentType.getMapping().addXmlTypeMappingTo(this.xmlEntityMappings);

		return persistentType;
	}

	/**
	 * Shorten the specified class name if it is in the entity mappings's package.
	 */
	protected String normalizeClassName(String className) {
		return ((this.package_ != null) &&
				className.startsWith(this.package_) &&
				(className.charAt(this.package_.length()) == '.') &&
				(className.indexOf('.', this.package_.length() + 1) == -1)) ?
						className.substring(this.package_.length() + 1) :
						className;
	}

	protected OrmPersistentType buildPersistentType(XmlTypeMapping xmlTypeMapping) {
		return this.getContextNodeFactory().buildOrmPersistentType(this, xmlTypeMapping);
	}

	protected int calculateInsertionIndex(OrmPersistentType ormPersistentType) {
		return CollectionTools.insertionIndexOf(this.persistentTypes, ormPersistentType, MAPPING_COMPARATOR);
	}

	protected static final Comparator<OrmPersistentType> MAPPING_COMPARATOR =
		new Comparator<OrmPersistentType>() {
			public int compare(OrmPersistentType o1, OrmPersistentType o2) {
				int o1Sequence = o1.getMapping().getXmlSequence();
				int o2Sequence = o2.getMapping().getXmlSequence();
				if (o1Sequence < o2Sequence) {
					return -1;
				}
				if (o1Sequence == o2Sequence) {
					return 0;
				}
				return 1;
			}
		};

	public void removePersistentType(int index) {
		OrmPersistentType persistentType = this.removePersistentType_(index);
		persistentType.getMapping().removeXmlTypeMappingFrom(this.xmlEntityMappings);
	}

	/**
	 * dispose and return the persistent type
	 */
	protected OrmPersistentType removePersistentType_(int index) {
		OrmPersistentType persistentType = this.removeItemFromList(index, this.persistentTypes, PERSISTENT_TYPES_LIST);
		persistentType.dispose();
		return persistentType;
	}

	public void removePersistentType(OrmPersistentType persistentType) {
		this.removePersistentType(this.persistentTypes.indexOf(persistentType));
	}

	protected void initializePersistentTypes() {
		for (XmlTypeMapping xmlTypeMapping : this.getXmlTypeMappings()) {
			this.persistentTypes.add(this.buildPersistentType(xmlTypeMapping));
		}
	}

	protected void syncPersistentTypes() {
		ContextContainerTools.synchronizeWithResourceModel(this.persistentTypeContainerAdapter);
	}

	protected Iterable<XmlTypeMapping> getXmlTypeMappings() {
		// clone to reduce chance of concurrency problems
		return new LiveCloneIterable<XmlTypeMapping>(this.xmlEntityMappings.getTypeMappings());
	}

	protected void movePersistentType_(int index, OrmPersistentType persistentType) {
		this.moveItemInList(index, persistentType, this.persistentTypes, PERSISTENT_TYPES_LIST);
	}

	protected void addPersistentType_(int index, XmlTypeMapping xmlTypeMapping) {
		this.addItemToList(index, this.buildPersistentType(xmlTypeMapping), this.persistentTypes, PERSISTENT_TYPES_LIST);
	}

	protected void removePersistentType_(OrmPersistentType persistentType) {
		this.removePersistentType_(this.persistentTypes.indexOf(persistentType));
	}

	/**
	 * persistent type container adapter
	 */
	protected class PersistentTypeContainerAdapter
		implements ContextContainerTools.Adapter<OrmPersistentType, XmlTypeMapping>
	{
		public Iterable<OrmPersistentType> getContextElements() {
			return AbstractEntityMappings.this.getPersistentTypes();
		}
		public Iterable<XmlTypeMapping> getResourceElements() {
			return AbstractEntityMappings.this.getXmlTypeMappings();
		}
		public XmlTypeMapping getResourceElement(OrmPersistentType contextElement) {
			return contextElement.getMapping().getXmlTypeMapping();
		}
		public void moveContextElement(int index, OrmPersistentType element) {
			AbstractEntityMappings.this.movePersistentType_(index, element);
		}
		public void addContextElement(int index, XmlTypeMapping resourceElement) {
			AbstractEntityMappings.this.addPersistentType_(index, resourceElement);
		}
		public void removeContextElement(OrmPersistentType element) {
			AbstractEntityMappings.this.removePersistentType_(element);
		}
	}


	// ********** sequence generators **********

	public ListIterable<OrmSequenceGenerator> getSequenceGenerators() {
		return this.sequenceGeneratorContainer.getContextElements();
	}

	public int getSequenceGeneratorsSize() {
		return this.sequenceGeneratorContainer.getContextElementsSize();
	}

	public OrmSequenceGenerator addSequenceGenerator() {
		return this.addSequenceGenerator(this.getSequenceGeneratorsSize());
	}

	public OrmSequenceGenerator addSequenceGenerator(int index) {
		XmlSequenceGenerator xmlGenerator = this.buildXmlSequenceGenerator();
		OrmSequenceGenerator sequenceGenerator = this.sequenceGeneratorContainer.addContextElement(index, xmlGenerator);
		this.xmlEntityMappings.getSequenceGenerators().add(index, xmlGenerator);
		return sequenceGenerator;
	}

	protected XmlSequenceGenerator buildXmlSequenceGenerator() {
		return OrmFactory.eINSTANCE.createXmlSequenceGenerator();
	}

	protected OrmSequenceGenerator buildSequenceGenerator(XmlSequenceGenerator xmlSequenceGenerator) {
		return this.getContextNodeFactory().buildOrmSequenceGenerator(this, xmlSequenceGenerator);
	}

	public void removeSequenceGenerator(OrmSequenceGenerator sequenceGenerator) {
		this.removeSequenceGenerator(this.sequenceGeneratorContainer.indexOfContextElement(sequenceGenerator));
	}

	public void removeSequenceGenerator(int index) {
		this.sequenceGeneratorContainer.removeContextElement(index);
		this.xmlEntityMappings.getSequenceGenerators().remove(index);
	}

	public void moveSequenceGenerator(int targetIndex, int sourceIndex) {
		this.sequenceGeneratorContainer.moveContextElement(targetIndex, sourceIndex);
		this.xmlEntityMappings.getSequenceGenerators().move(targetIndex, sourceIndex);
	}

	protected void syncSequenceGenerators() {
		this.sequenceGeneratorContainer.synchronizeWithResourceModel();
	}

	protected ListIterable<XmlSequenceGenerator> getXmlSequenceGenerators() {
		// clone to reduce chance of concurrency problems
		return new LiveCloneListIterable<XmlSequenceGenerator>(this.xmlEntityMappings.getSequenceGenerators());
	}

	protected ContextListContainer<OrmSequenceGenerator, XmlSequenceGenerator> buildSequenceGeneratorContainer() {
		SequenceGeneratorContainer container = new SequenceGeneratorContainer();
		container.initialize();
		return container;
	}

	/**
	 * sequence generator container
	 */
	protected class SequenceGeneratorContainer
		extends ContextListContainer<OrmSequenceGenerator, XmlSequenceGenerator>
	{
		@Override
		protected String getContextElementsPropertyName() {
			return SEQUENCE_GENERATORS_LIST;
		}
		@Override
		protected OrmSequenceGenerator buildContextElement(XmlSequenceGenerator resourceElement) {
			return AbstractEntityMappings.this.buildSequenceGenerator(resourceElement);
		}
		@Override
		protected ListIterable<XmlSequenceGenerator> getResourceElements() {
			return AbstractEntityMappings.this.getXmlSequenceGenerators();
		}
		@Override
		protected XmlSequenceGenerator getResourceElement(OrmSequenceGenerator contextElement) {
			return contextElement.getXmlGenerator();
		}
	}


	// ********** table generators **********

	public ListIterable<OrmTableGenerator> getTableGenerators() {
		return this.tableGeneratorContainer.getContextElements();
	}

	public int getTableGeneratorsSize() {
		return this.tableGeneratorContainer.getContextElementsSize();
	}

	public OrmTableGenerator addTableGenerator() {
		return this.addTableGenerator(this.getTableGeneratorsSize());
	}

	public OrmTableGenerator addTableGenerator(int index) {
		XmlTableGenerator xmlTableGenerator = this.buildXmlTableGenerator();
		OrmTableGenerator tableGenerator = this.tableGeneratorContainer.addContextElement(index, xmlTableGenerator);
		this.xmlEntityMappings.getTableGenerators().add(index, xmlTableGenerator);
		return tableGenerator;
	}

	protected XmlTableGenerator buildXmlTableGenerator() {
		return OrmFactory.eINSTANCE.createXmlTableGenerator();
	}

	protected OrmTableGenerator buildTableGenerator(XmlTableGenerator xmlTableGenerator) {
		return this.getContextNodeFactory().buildOrmTableGenerator(this, xmlTableGenerator);
	}

	public void removeTableGenerator(OrmTableGenerator tableGenerator) {
		this.removeTableGenerator(this.tableGeneratorContainer.indexOfContextElement(tableGenerator));
	}

	public void removeTableGenerator(int index) {
		this.tableGeneratorContainer.removeContextElement(index);
		this.xmlEntityMappings.getTableGenerators().remove(index);
	}

	public void moveTableGenerator(int targetIndex, int sourceIndex) {
		this.tableGeneratorContainer.moveContextElement(targetIndex, sourceIndex);
		this.xmlEntityMappings.getTableGenerators().move(targetIndex, sourceIndex);
	}

	protected void syncTableGenerators() {
		this.tableGeneratorContainer.synchronizeWithResourceModel();
	}

	protected ListIterable<XmlTableGenerator> getXmlTableGenerators() {
		// clone to reduce chance of concurrency problems
		return new LiveCloneListIterable<XmlTableGenerator>(this.xmlEntityMappings.getTableGenerators());
	}

	protected ContextListContainer<OrmTableGenerator, XmlTableGenerator> buildTableGeneratorContainer() {
		TableGeneratorContainer container = new TableGeneratorContainer();
		container.initialize();
		return container;
	}

	/**
	 * table generator container
	 */
	protected class TableGeneratorContainer
		extends ContextListContainer<OrmTableGenerator, XmlTableGenerator>
	{
		@Override
		protected String getContextElementsPropertyName() {
			return TABLE_GENERATORS_LIST;
		}
		@Override
		protected OrmTableGenerator buildContextElement(XmlTableGenerator resourceElement) {
			return AbstractEntityMappings.this.buildTableGenerator(resourceElement);
		}
		@Override
		protected ListIterable<XmlTableGenerator> getResourceElements() {
			return AbstractEntityMappings.this.getXmlTableGenerators();
		}
		@Override
		protected XmlTableGenerator getResourceElement(OrmTableGenerator contextElement) {
			return contextElement.getXmlGenerator();
		}
	}


	// ********** query container **********

	public OrmQueryContainer getQueryContainer() {
		return this.queryContainer;
	}

	protected OrmQueryContainer buildQueryContainer() {
		return this.getContextNodeFactory().buildOrmQueryContainer(this, this.xmlEntityMappings);
	}


	// ********** queries/generators **********

	@SuppressWarnings("unchecked")
	public Iterable<Query> getMappingFileQueries() {
		return new CompositeIterable<Query>(
					this.queryContainer.getQueries(),
					this.getTypeMappingQueries()
				);
	}

	protected Iterable<Query> getTypeMappingQueries() {
		return new CompositeIterable<Query>(this.getTypeMappingQueryLists());
	}

	protected Iterable<Iterable<Query>> getTypeMappingQueryLists() {
		return new TransformationIterable<OrmTypeMapping, Iterable<Query>>(this.getTypeMappings()) {
					@Override
					protected Iterable<Query> transform(OrmTypeMapping typeMapping) {
						return typeMapping.getQueries();
					}
				};
	}

	@SuppressWarnings("unchecked")
	public Iterable<Generator> getMappingFileGenerators() {
		return new CompositeIterable<Generator>(
					this.getSequenceGenerators(),
					this.getTableGenerators(),
					this.getTypeMappingGenerators()
				);
	}

	protected Iterable<Generator> getTypeMappingGenerators() {
		return new CompositeIterable<Generator>(this.getTypeMappingGeneratorLists());
	}

	protected Iterable<Iterable<Generator>> getTypeMappingGeneratorLists() {
		return new TransformationIterable<OrmTypeMapping, Iterable<Generator>>(this.getTypeMappings()) {
					@Override
					protected Iterable<Generator> transform(OrmTypeMapping typeMapping) {
						return typeMapping.getGenerators();
					}
				};
	}

	protected Iterable<OrmTypeMapping> getTypeMappings() {
		return new TransformationIterable<OrmPersistentType, OrmTypeMapping>(this.getPersistentTypes()) {
					@Override
					protected OrmTypeMapping transform(OrmPersistentType persistentType) {
						return persistentType.getMapping();
					}
				};
	}


	// ********** validation **********

	/**
	 * The generators are validated in the persistence unit.
	 * @see org.eclipse.jpt.jpa.core.internal.context.persistence.AbstractPersistenceUnit#validateGenerators(List, IReporter)
	 */
	@Override
	public void validate(List<IMessage> messages, IReporter reporter) {
		super.validate(messages, reporter);
		this.validateVersion(messages);
		// generators are validated in the persistence unit
		this.queryContainer.validate(messages, reporter);
		for (OrmPersistentType  ormPersistentType : this.getPersistentTypes()) {
			this.validatePersistentType(ormPersistentType, messages, reporter);
		}
	}

	protected void validateVersion(List<IMessage> messages) {
		if (! this.getLatestDocumentVersion().equals(this.xmlEntityMappings.getVersion())) {
			messages.add(
				DefaultJpaValidationMessages.buildMessage(
					IMessage.LOW_SEVERITY,
					JpaValidationMessages.XML_VERSION_NOT_LATEST,
					this,
					this.xmlEntityMappings.getVersionTextRange()
				)
			);
		}
	}

	/**
	 * Return the latest version of the document supported by the platform
	 */
	protected String getLatestDocumentVersion() {
		return this.getJpaPlatform().getMostRecentSupportedResourceType(this.getContentType()).getVersion();
	}

	protected IContentType getContentType() {
		return JptJpaCorePlugin.ORM_XML_CONTENT_TYPE;
	}

	protected void validatePersistentType(OrmPersistentType persistentType, List<IMessage> messages, IReporter reporter) {
		try {
			persistentType.validate(messages, reporter);
		} catch (Throwable exception) {
			JptJpaCorePlugin.log(exception);
		}
	}


	// ********** refactoring **********

	public Iterable<DeleteEdit> createDeleteTypeEdits(final IType type) {
		return new CompositeIterable<DeleteEdit>(
			new TransformationIterable<OrmPersistentType, Iterable<DeleteEdit>>(this.getPersistentTypes()) {
				@Override
				protected Iterable<DeleteEdit> transform(OrmPersistentType persistentType) {
					return persistentType.createDeleteTypeEdits(type);
				}
			}
		);
	}

	public Iterable<ReplaceEdit> createRenameTypeEdits(final IType originalType, final String newName) {
		return new CompositeIterable<ReplaceEdit>(
			new TransformationIterable<OrmPersistentType, Iterable<ReplaceEdit>>(this.getPersistentTypes()) {
				@Override
				protected Iterable<ReplaceEdit> transform(OrmPersistentType persistentType) {
					return persistentType.createRenameTypeEdits(originalType, newName);
				}
			}
		);
	}

	public Iterable<ReplaceEdit> createMoveTypeEdits(final IType originalType, final IPackageFragment newPackage) {
		return new CompositeIterable<ReplaceEdit>(
			new TransformationIterable<OrmPersistentType, Iterable<ReplaceEdit>>(this.getPersistentTypes()) {
				@Override
				protected Iterable<ReplaceEdit> transform(OrmPersistentType persistentType) {
					return persistentType.createMoveTypeEdits(originalType, newPackage);
				}
			}
		);
	}

	@SuppressWarnings("unchecked")
	public Iterable<ReplaceEdit> createRenamePackageEdits(final IPackageFragment originalPackage, final String newName) {
		return new CompositeIterable<ReplaceEdit>(
				this.createPersistentTypeRenamePackageEdits(originalPackage, newName),
				this.createRenamePackageEdit(originalPackage, newName));
	}

	protected Iterable<ReplaceEdit> createPersistentTypeRenamePackageEdits(final IPackageFragment originalPackage, final String newName) {
		return new CompositeIterable<ReplaceEdit>(
			new TransformationIterable<OrmPersistentType, Iterable<ReplaceEdit>>(this.getPersistentTypes()) {
				@Override
				protected Iterable<ReplaceEdit> transform(OrmPersistentType persistentType) {
					return persistentType.createRenamePackageEdits(originalPackage, newName);
				}
			}
		);
	}

	protected Iterable<ReplaceEdit> createRenamePackageEdit(final IPackageFragment originalPackage, final String newName) {
		return Tools.valuesAreEqual(this.package_, originalPackage.getElementName()) ?
				new SingleElementIterable<ReplaceEdit>(this.xmlEntityMappings.createRenamePackageEdit(newName)) :
				EmptyIterable.<ReplaceEdit>instance();
	}
	
	// ************ completion proposals**************
	
	@Override
	public Iterable<String> getXmlCompletionProposals(int pos) {
		Iterable<String> result = super.getXmlCompletionProposals(pos);
		if (result != null) {
			return result;
		}
		result = this.queryContainer.getXmlCompletionProposals(pos);
		if (result != null) {
			return result;
		}
		for (OrmTableGenerator tableGenerator : this.getTableGenerators()) {
			result = tableGenerator.getXmlCompletionProposals(pos);
			if (result != null) {
				return result;
			}
		}
		for (OrmSequenceGenerator seqGenerator : this.getSequenceGenerators()) {
			result = seqGenerator.getXmlCompletionProposals(pos);
			if (result != null) {
				return result;
			}
		}
		result = this.persistenceUnitMetadata.getXmlCompletionProposals(pos);
		if (result != null) {
			return result;
		}
		if (this.packageTouches(pos)) {
			return this.getCandidatePackages();
		}
		for (OrmPersistentType persistentType : this.getPersistentTypes()) {
			result = persistentType.getXmlCompletionProposals(pos);
			if (result != null) {
				return result;
			}
		}
		return null;
	}

	@Override
	protected Iterable<String> getConnectedXmlCompletionProposals(int pos) {
		Iterable<String> result = super.getConnectedXmlCompletionProposals(pos);
		if (result != null) {
			return result;
		}
		if (this.schemaTouches(pos)) {
			return this.getCandidateSchemata();
		}
		if (this.catalogTouches(pos)) {
			return this.getCandidateCatalogs();
		}
		return null;
	}
	
	// ********** content assist: schema

	protected boolean schemaTouches(int pos) {
		return this.getXmlEntityMappings().schemaTouches(pos);
	}

	protected Iterable<String> getCandidateSchemata() {
		SchemaContainer schemaContainer = this.getDbSchemaContainer();
		return (schemaContainer != null) ? schemaContainer.getSortedSchemaIdentifiers() : EmptyIterable.<String> instance();
	}

	// ********** content assist: catalog

	protected boolean catalogTouches(int pos) {
		return this.getXmlEntityMappings().catalogTouches(pos);
	}

	protected Iterable<String> getCandidateCatalogs() {
		Database db = this.getDatabase();
		return (db != null) ? db.getSortedCatalogIdentifiers() : EmptyIterable.<String> instance();
	}
	
	// ********** content assist: package
	
	private boolean packageTouches(int pos) {
		return this.getXmlEntityMappings().packageTouches(pos);
	}
	
	private Iterable<String> getCandidatePackages() {
		return this.getPersistenceUnit().getPackageNames();
	}

}
