/*******************************************************************************
 * Copyright (c) 2006, 2007 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.core.internal.content.orm;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EObjectEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.jpt.core.internal.IMappingKeys;
import org.eclipse.jpt.core.internal.IPersistentAttribute;
import org.eclipse.jpt.core.internal.IPersistentType;
import org.eclipse.jpt.core.internal.ITextRange;
import org.eclipse.jpt.core.internal.ITypeMapping;
import org.eclipse.jpt.core.internal.jdtutility.Type;
import org.eclipse.jpt.core.internal.mappings.IAssociationOverride;
import org.eclipse.jpt.core.internal.mappings.IAttributeOverride;
import org.eclipse.jpt.core.internal.mappings.IDiscriminatorColumn;
import org.eclipse.jpt.core.internal.mappings.IEntity;
import org.eclipse.jpt.core.internal.mappings.INamedNativeQuery;
import org.eclipse.jpt.core.internal.mappings.INamedQuery;
import org.eclipse.jpt.core.internal.mappings.IOverride;
import org.eclipse.jpt.core.internal.mappings.IPrimaryKeyJoinColumn;
import org.eclipse.jpt.core.internal.mappings.ISecondaryTable;
import org.eclipse.jpt.core.internal.mappings.ISequenceGenerator;
import org.eclipse.jpt.core.internal.mappings.ITable;
import org.eclipse.jpt.core.internal.mappings.ITableGenerator;
import org.eclipse.jpt.core.internal.mappings.InheritanceType;
import org.eclipse.jpt.core.internal.mappings.JpaCoreMappingsPackage;
import org.eclipse.jpt.core.internal.platform.BaseJpaPlatform;
import org.eclipse.jpt.core.internal.platform.DefaultsContext;
import org.eclipse.jpt.db.internal.Schema;
import org.eclipse.jpt.db.internal.Table;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.iterators.CompositeIterator;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Xml Entity</b></em>'.
 * <!-- end-user-doc -->
 *
 *
 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlEntityInternal()
 * @model kind="class"
 * @generated
 */
public class XmlEntityInternal extends XmlTypeMapping
	implements XmlEntityForXml, XmlEntity
{
	/**
	 * The cached value of the '{@link #getIdClassForXml() <em>Id Class For Xml</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIdClassForXml()
	 * @generated
	 * @ordered
	 */
	protected XmlIdClass idClassForXml;

	/**
	 * The cached value of the '{@link #getInheritanceForXml() <em>Inheritance For Xml</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getInheritanceForXml()
	 * @generated
	 * @ordered
	 */
	protected XmlInheritance inheritanceForXml;

	/**
	 * The default value of the '{@link #getSpecifiedName() <em>Specified Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSpecifiedName()
	 * @generated
	 * @ordered
	 */
	protected static final String SPECIFIED_NAME_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getSpecifiedName() <em>Specified Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSpecifiedName()
	 * @generated
	 * @ordered
	 */
	protected String specifiedName = SPECIFIED_NAME_EDEFAULT;

	/**
	 * The default value of the '{@link #getDefaultName() <em>Default Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultName()
	 * @generated
	 * @ordered
	 */
	protected static final String DEFAULT_NAME_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getDefaultName() <em>Default Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultName()
	 * @generated
	 * @ordered
	 */
	protected String defaultName = DEFAULT_NAME_EDEFAULT;

	/**
	 * The cached value of the '{@link #getTable() <em>Table</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTable()
	 * @generated
	 * @ordered
	 */
	protected ITable table;

	/**
	 * The cached value of the '{@link #getSpecifiedSecondaryTables() <em>Specified Secondary Tables</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSpecifiedSecondaryTables()
	 * @generated
	 * @ordered
	 */
	protected EList<ISecondaryTable> specifiedSecondaryTables;

	/**
	 * The cached value of the '{@link #getSpecifiedPrimaryKeyJoinColumns() <em>Specified Primary Key Join Columns</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSpecifiedPrimaryKeyJoinColumns()
	 * @generated
	 * @ordered
	 */
	protected EList<IPrimaryKeyJoinColumn> specifiedPrimaryKeyJoinColumns;

	/**
	 * The cached value of the '{@link #getDefaultPrimaryKeyJoinColumns() <em>Default Primary Key Join Columns</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultPrimaryKeyJoinColumns()
	 * @generated
	 * @ordered
	 */
	protected EList<IPrimaryKeyJoinColumn> defaultPrimaryKeyJoinColumns;

	/**
	 * The default value of the '{@link #getInheritanceStrategy() <em>Inheritance Strategy</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getInheritanceStrategy()
	 * @generated
	 * @ordered
	 */
	protected static final InheritanceType INHERITANCE_STRATEGY_EDEFAULT = InheritanceType.DEFAULT;

	/**
	 * The cached value of the '{@link #getInheritanceStrategy() <em>Inheritance Strategy</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getInheritanceStrategy()
	 * @generated
	 * @ordered
	 */
	protected InheritanceType inheritanceStrategy = INHERITANCE_STRATEGY_EDEFAULT;

	/**
	 * The default value of the '{@link #getDefaultDiscriminatorValue() <em>Default Discriminator Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultDiscriminatorValue()
	 * @generated
	 * @ordered
	 */
	protected static final String DEFAULT_DISCRIMINATOR_VALUE_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getDefaultDiscriminatorValue() <em>Default Discriminator Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultDiscriminatorValue()
	 * @generated
	 * @ordered
	 */
	protected String defaultDiscriminatorValue = DEFAULT_DISCRIMINATOR_VALUE_EDEFAULT;

	/**
	 * The default value of the '{@link #getSpecifiedDiscriminatorValue() <em>Specified Discriminator Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSpecifiedDiscriminatorValue()
	 * @generated
	 * @ordered
	 */
	protected static final String SPECIFIED_DISCRIMINATOR_VALUE_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getSpecifiedDiscriminatorValue() <em>Specified Discriminator Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSpecifiedDiscriminatorValue()
	 * @generated
	 * @ordered
	 */
	protected String specifiedDiscriminatorValue = SPECIFIED_DISCRIMINATOR_VALUE_EDEFAULT;

	/**
	 * The default value of the '{@link #getDiscriminatorValue() <em>Discriminator Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDiscriminatorValue()
	 * @generated
	 * @ordered
	 */
	protected static final String DISCRIMINATOR_VALUE_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getDiscriminatorColumn() <em>Discriminator Column</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDiscriminatorColumn()
	 * @generated
	 * @ordered
	 */
	protected IDiscriminatorColumn discriminatorColumn;

	/**
	 * The cached value of the '{@link #getSequenceGenerator() <em>Sequence Generator</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSequenceGenerator()
	 * @generated
	 * @ordered
	 */
	protected ISequenceGenerator sequenceGenerator;

	/**
	 * The cached value of the '{@link #getTableGenerator() <em>Table Generator</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTableGenerator()
	 * @generated
	 * @ordered
	 */
	protected ITableGenerator tableGenerator;

	/**
	 * The cached value of the '{@link #getSpecifiedAttributeOverrides() <em>Specified Attribute Overrides</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSpecifiedAttributeOverrides()
	 * @generated
	 * @ordered
	 */
	protected EList<IAttributeOverride> specifiedAttributeOverrides;

	/**
	 * The cached value of the '{@link #getDefaultAttributeOverrides() <em>Default Attribute Overrides</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultAttributeOverrides()
	 * @generated
	 * @ordered
	 */
	protected EList<IAttributeOverride> defaultAttributeOverrides;

	/**
	 * The cached value of the '{@link #getSpecifiedAssociationOverrides() <em>Specified Association Overrides</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSpecifiedAssociationOverrides()
	 * @generated
	 * @ordered
	 */
	protected EList<IAssociationOverride> specifiedAssociationOverrides;

	/**
	 * The cached value of the '{@link #getDefaultAssociationOverrides() <em>Default Association Overrides</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultAssociationOverrides()
	 * @generated
	 * @ordered
	 */
	protected EList<IAssociationOverride> defaultAssociationOverrides;

	/**
	 * The cached value of the '{@link #getNamedQueries() <em>Named Queries</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNamedQueries()
	 * @generated
	 * @ordered
	 */
	protected EList<INamedQuery> namedQueries;

	/**
	 * The cached value of the '{@link #getNamedNativeQueries() <em>Named Native Queries</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNamedNativeQueries()
	 * @generated
	 * @ordered
	 */
	protected EList<INamedNativeQuery> namedNativeQueries;

	/**
	 * The default value of the '{@link #getIdClass() <em>Id Class</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIdClass()
	 * @generated
	 * @ordered
	 */
	protected static final String ID_CLASS_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getIdClass() <em>Id Class</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIdClass()
	 * @generated
	 * @ordered
	 */
	protected String idClass = ID_CLASS_EDEFAULT;

	/**
	 * The cached value of the '{@link #getVirtualSecondaryTables() <em>Virtual Secondary Tables</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getVirtualSecondaryTables()
	 * @generated
	 * @ordered
	 */
	protected EList<ISecondaryTable> virtualSecondaryTables;

	protected XmlEntityInternal() {
		super();
		this.table = OrmFactory.eINSTANCE.createXmlTable(buildTableOwner());
		((InternalEObject) this.table).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - OrmPackage.XML_ENTITY_INTERNAL__TABLE, null, null);
		this.discriminatorColumn = OrmFactory.eINSTANCE.createXmlDiscriminatorColumn(new IDiscriminatorColumn.Owner(this));
		((InternalEObject) this.discriminatorColumn).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN, null, null);
		this.getDefaultPrimaryKeyJoinColumns().add(this.createPrimaryKeyJoinColumn(0));
		this.eAdapters().add(this.buildListener());
	}

	protected Adapter buildListener() {
		return new AdapterImpl() {
			@Override
			public void notifyChanged(Notification notification) {
				XmlEntityInternal.this.notifyChanged(notification);
			}
		};
	}

	protected void notifyChanged(Notification notification) {
		switch (notification.getFeatureID(IEntity.class)) {
			case JpaCoreMappingsPackage.IENTITY__ID_CLASS :
				idClassChanged();
				break;
			case JpaCoreMappingsPackage.IENTITY__INHERITANCE_STRATEGY :
				inheritanceStrategyChanged();
				break;
			default :
				break;
		}
		switch (notification.getFeatureID(XmlEntityForXml.class)) {
			case OrmPackage.XML_ENTITY_FOR_XML__ID_CLASS_FOR_XML :
				xmlIdClassChanged();
				break;
			case OrmPackage.XML_ENTITY_FOR_XML__INHERITANCE_FOR_XML :
				xmlInheritanceChanged();
				break;
			default :
				break;
		}
	}

	protected void inheritanceStrategyChanged() {
		if (getInheritanceStrategy() == InheritanceType.DEFAULT) {
			setInheritanceForXml(null);
		}
		else {
			if (getInheritanceForXml() == null) {
				setInheritanceForXml(OrmFactory.eINSTANCE.createXmlInheritance());
			}
			getInheritanceForXml().setStrategy(getInheritanceStrategy());
		}
	}

	protected void xmlInheritanceChanged() {
		if (getInheritanceForXml() == null) {
			setInheritanceStrategy(null);
		}
	}

	@Override
	protected void addInsignificantFeatureIdsTo(Set<Integer> insignificantFeatureIds) {
		super.addInsignificantFeatureIdsTo(insignificantFeatureIds);
		insignificantFeatureIds.add(OrmPackage.XML_ENTITY_INTERNAL__SECONDARY_TABLES);
		insignificantFeatureIds.add(OrmPackage.XML_ENTITY_INTERNAL__ATTRIBUTE_OVERRIDES);
		insignificantFeatureIds.add(OrmPackage.XML_ENTITY_INTERNAL__ASSOCIATION_OVERRIDES);
	}

	private ITable.Owner buildTableOwner() {
		return new ITable.Owner() {
			public ITextRange validationTextRange() {
				return XmlEntityInternal.this.validationTextRange();
			}

			public ITypeMapping getTypeMapping() {
				return XmlEntityInternal.this;
			}
		};
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return OrmPackage.Literals.XML_ENTITY_INTERNAL;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public String getName() {
		return (this.getSpecifiedName() == null) ? getDefaultName() : this.getSpecifiedName();
	}

	/**
	 * Returns the value of the '<em><b>Specified Name</b></em>' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Specified Name</em>' attribute.
	 * @see #setSpecifiedName(String)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_SpecifiedName()
	 * @model
	 * @generated
	 */
	public String getSpecifiedName() {
		return specifiedName;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal#getSpecifiedName <em>Specified Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Specified Name</em>' attribute.
	 * @see #getSpecifiedName()
	 * @generated
	 */
	public void setSpecifiedName(String newSpecifiedName) {
		String oldSpecifiedName = specifiedName;
		specifiedName = newSpecifiedName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_NAME, oldSpecifiedName, specifiedName));
	}

	/**
	 * Returns the value of the '<em><b>Default Name</b></em>' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Default Name</em>' attribute.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_DefaultName()
	 * @model changeable="false"
	 * @generated
	 */
	public String getDefaultName() {
		return defaultName;
	}

	/**
	 * Returns the value of the '<em><b>Table</b></em>' containment reference.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Table</em>' containment reference isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Table</em>' containment reference.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_Table()
	 * @model containment="true" required="true" changeable="false"
	 * @generated
	 */
	public ITable getTable() {
		return table;
	}

	private XmlTable getTableInternal() {
		return (XmlTable) getTable();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetTable(ITable newTable, NotificationChain msgs) {
		ITable oldTable = table;
		table = newTable;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__TABLE, oldTable, newTable);
			if (msgs == null)
				msgs = notification;
			else
				msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * Returns the value of the '<em><b>Secondary Tables</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.mappings.ISecondaryTable}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Secondary Tables</em>' containment reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Secondary Tables</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlEntity_SecondaryTables()
	 * @model type="org.eclipse.jpt.core.internal.mappings.ISecondaryTable" containment="true" transient="true" changeable="false" volatile="true"
	 * @generated NOT
	 */
	public EList<ISecondaryTable> getSecondaryTables() {
		EList<ISecondaryTable> list = new EObjectEList<ISecondaryTable>(ISecondaryTable.class, this, OrmPackage.XML_ENTITY_INTERNAL__SECONDARY_TABLES);
		list.addAll(getSpecifiedSecondaryTables());
		list.addAll(getVirtualSecondaryTables());
		return list;
	}

	/**
	 * Returns the value of the '<em><b>Virtual Secondary Tables</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.mappings.ISecondaryTable}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Virtual Secondary Tables</em>' containment reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Virtual Secondary Tables</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlEntity_VirtualSecondaryTables()
	 * @model containment="true"
	 * @generated
	 */
	public EList<ISecondaryTable> getVirtualSecondaryTables() {
		if (virtualSecondaryTables == null) {
			virtualSecondaryTables = new EObjectContainmentEList<ISecondaryTable>(ISecondaryTable.class, this, OrmPackage.XML_ENTITY_INTERNAL__VIRTUAL_SECONDARY_TABLES);
		}
		return virtualSecondaryTables;
	}

	protected void xmlIdClassChanged() {
		if (getIdClassForXml() == null) {
			setIdClass(null);
		}
	}

	public boolean containsSecondaryTable(String name) {
		return containsSecondaryTable(name, getSecondaryTables());
	}

	public boolean containsSpecifiedSecondaryTable(String name) {
		return containsSecondaryTable(name, getSpecifiedSecondaryTables());
	}

	private boolean containsSecondaryTable(String name, List<ISecondaryTable> secondaryTables) {
		for (ISecondaryTable secondaryTable : secondaryTables) {
			String secondaryTableName = secondaryTable.getName();
			if (secondaryTableName != null && secondaryTableName.equals(name)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Returns the value of the '<em><b>Specified Secondary Tables</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.mappings.ISecondaryTable}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Specified Secondary Tables</em>' containment reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Specified Secondary Tables</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_SpecifiedSecondaryTables()
	 * @model containment="true"
	 * @generated
	 */
	public EList<ISecondaryTable> getSpecifiedSecondaryTables() {
		if (specifiedSecondaryTables == null) {
			specifiedSecondaryTables = new EObjectContainmentEList<ISecondaryTable>(ISecondaryTable.class, this, OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_SECONDARY_TABLES);
		}
		return specifiedSecondaryTables;
	}

	/**
	 * Returns the value of the '<em><b>Inheritance Strategy</b></em>' attribute.
	 * The literals are from the enumeration {@link org.eclipse.jpt.core.internal.mappings.InheritanceType}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Inheritance Strategy</em>' attribute isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Inheritance Strategy</em>' attribute.
	 * @see org.eclipse.jpt.core.internal.mappings.InheritanceType
	 * @see #setInheritanceStrategy(InheritanceType)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_InheritanceStrategy()
	 * @model
	 * @generated
	 */
	public InheritanceType getInheritanceStrategy() {
		return inheritanceStrategy;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal#getInheritanceStrategy <em>Inheritance Strategy</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Inheritance Strategy</em>' attribute.
	 * @see org.eclipse.jpt.core.internal.mappings.InheritanceType
	 * @see #getInheritanceStrategy()
	 * @generated
	 */
	public void setInheritanceStrategy(InheritanceType newInheritanceStrategy) {
		InheritanceType oldInheritanceStrategy = inheritanceStrategy;
		inheritanceStrategy = newInheritanceStrategy == null ? INHERITANCE_STRATEGY_EDEFAULT : newInheritanceStrategy;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_STRATEGY, oldInheritanceStrategy, inheritanceStrategy));
	}

	//	public void setInheritanceStrategy(InheritanceType newInheritanceStrategy) {
	//		setInheritanceStrategyGen(newInheritanceStrategy);
	//		if (newInheritanceStrategy != INHERITANCE_STRATEGY_EDEFAULT) {
	//			//makeInheritanceForXmlNonNull();
	//		}
	//		setInheritanceStrategyForXml(newInheritanceStrategy);
	//		if (isAllFeaturesUnset()) {
	//			//makeInheritanceForXmlNull();
	//		}
	//	}
	/**
	 * Returns the value of the '<em><b>Discriminator Column</b></em>' containment reference.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Discriminator Column</em>' containment reference isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Discriminator Column</em>' containment reference.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_DiscriminatorColumn()
	 * @model containment="true" changeable="false"
	 * @generated
	 */
	public IDiscriminatorColumn getDiscriminatorColumn() {
		return discriminatorColumn;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetDiscriminatorColumn(IDiscriminatorColumn newDiscriminatorColumn, NotificationChain msgs) {
		IDiscriminatorColumn oldDiscriminatorColumn = discriminatorColumn;
		discriminatorColumn = newDiscriminatorColumn;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN, oldDiscriminatorColumn, newDiscriminatorColumn);
			if (msgs == null)
				msgs = notification;
			else
				msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * Returns the value of the '<em><b>Sequence Generator</b></em>' containment reference.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Sequence Generator</em>' containment reference isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Sequence Generator</em>' containment reference.
	 * @see #setSequenceGenerator(ISequenceGenerator)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_SequenceGenerator()
	 * @model containment="true"
	 * @generated
	 */
	public ISequenceGenerator getSequenceGenerator() {
		return sequenceGenerator;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetSequenceGenerator(ISequenceGenerator newSequenceGenerator, NotificationChain msgs) {
		ISequenceGenerator oldSequenceGenerator = sequenceGenerator;
		sequenceGenerator = newSequenceGenerator;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__SEQUENCE_GENERATOR, oldSequenceGenerator, newSequenceGenerator);
			if (msgs == null)
				msgs = notification;
			else
				msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal#getSequenceGenerator <em>Sequence Generator</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Sequence Generator</em>' containment reference.
	 * @see #getSequenceGenerator()
	 * @generated
	 */
	public void setSequenceGenerator(ISequenceGenerator newSequenceGenerator) {
		if (newSequenceGenerator != sequenceGenerator) {
			NotificationChain msgs = null;
			if (sequenceGenerator != null)
				msgs = ((InternalEObject) sequenceGenerator).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - OrmPackage.XML_ENTITY_INTERNAL__SEQUENCE_GENERATOR, null, msgs);
			if (newSequenceGenerator != null)
				msgs = ((InternalEObject) newSequenceGenerator).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - OrmPackage.XML_ENTITY_INTERNAL__SEQUENCE_GENERATOR, null, msgs);
			msgs = basicSetSequenceGenerator(newSequenceGenerator, msgs);
			if (msgs != null)
				msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__SEQUENCE_GENERATOR, newSequenceGenerator, newSequenceGenerator));
	}

	/**
	 * Returns the value of the '<em><b>Table Generator</b></em>' containment reference.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Table Generator</em>' containment reference isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Table Generator</em>' containment reference.
	 * @see #setTableGenerator(ITableGenerator)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_TableGenerator()
	 * @model containment="true"
	 * @generated
	 */
	public ITableGenerator getTableGenerator() {
		return tableGenerator;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetTableGenerator(ITableGenerator newTableGenerator, NotificationChain msgs) {
		ITableGenerator oldTableGenerator = tableGenerator;
		tableGenerator = newTableGenerator;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__TABLE_GENERATOR, oldTableGenerator, newTableGenerator);
			if (msgs == null)
				msgs = notification;
			else
				msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal#getTableGenerator <em>Table Generator</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Table Generator</em>' containment reference.
	 * @see #getTableGenerator()
	 * @generated
	 */
	public void setTableGenerator(ITableGenerator newTableGenerator) {
		if (newTableGenerator != tableGenerator) {
			NotificationChain msgs = null;
			if (tableGenerator != null)
				msgs = ((InternalEObject) tableGenerator).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - OrmPackage.XML_ENTITY_INTERNAL__TABLE_GENERATOR, null, msgs);
			if (newTableGenerator != null)
				msgs = ((InternalEObject) newTableGenerator).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - OrmPackage.XML_ENTITY_INTERNAL__TABLE_GENERATOR, null, msgs);
			msgs = basicSetTableGenerator(newTableGenerator, msgs);
			if (msgs != null)
				msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__TABLE_GENERATOR, newTableGenerator, newTableGenerator));
	}

	/**
	 * Returns the value of the '<em><b>Default Discriminator Value</b></em>' attribute.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Default Discriminator Value</em>' attribute isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Default Discriminator Value</em>' attribute.
	 * @see #setDefaultDiscriminatorValue(String)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_DefaultDiscriminatorValue()
	 * @model
	 * @generated
	 */
	public String getDefaultDiscriminatorValue() {
		return defaultDiscriminatorValue;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal#getDefaultDiscriminatorValue <em>Default Discriminator Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Default Discriminator Value</em>' attribute.
	 * @see #getDefaultDiscriminatorValue()
	 * @generated
	 */
	public void setDefaultDiscriminatorValue(String newDefaultDiscriminatorValue) {
		String oldDefaultDiscriminatorValue = defaultDiscriminatorValue;
		defaultDiscriminatorValue = newDefaultDiscriminatorValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_DISCRIMINATOR_VALUE, oldDefaultDiscriminatorValue, defaultDiscriminatorValue));
	}

	/**
	 * Returns the value of the '<em><b>Specified Discriminator Value</b></em>' attribute.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Specified Discriminator Value</em>' attribute isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Specified Discriminator Value</em>' attribute.
	 * @see #setSpecifiedDiscriminatorValue(String)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_SpecifiedDiscriminatorValue()
	 * @model
	 * @generated
	 */
	public String getSpecifiedDiscriminatorValue() {
		return specifiedDiscriminatorValue;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal#getSpecifiedDiscriminatorValue <em>Specified Discriminator Value</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Specified Discriminator Value</em>' attribute.
	 * @see #getSpecifiedDiscriminatorValue()
	 * @generated
	 */
	public void setSpecifiedDiscriminatorValue(String newSpecifiedDiscriminatorValue) {
		String oldSpecifiedDiscriminatorValue = specifiedDiscriminatorValue;
		specifiedDiscriminatorValue = newSpecifiedDiscriminatorValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_DISCRIMINATOR_VALUE, oldSpecifiedDiscriminatorValue, specifiedDiscriminatorValue));
	}

	/**
	 * Returns the value of the '<em><b>Discriminator Value</b></em>' attribute.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Discriminator Value</em>' reference isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Discriminator Value</em>' attribute.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_DiscriminatorValue()
	 * @model transient="true" changeable="false" volatile="true" derived="true"
	 * @generated NOT
	 */
	public String getDiscriminatorValue() {
		return (this.getSpecifiedDiscriminatorValue() == null) ? getDefaultDiscriminatorValue() : this.getSpecifiedDiscriminatorValue();
	}

	public EList<IPrimaryKeyJoinColumn> getPrimaryKeyJoinColumns() {
		return this.getSpecifiedPrimaryKeyJoinColumns().isEmpty() ? this.getDefaultPrimaryKeyJoinColumns() : this.getSpecifiedPrimaryKeyJoinColumns();
	}

	/**
	 * Returns the value of the '<em><b>Specified Primary Key Join Columns</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.mappings.IPrimaryKeyJoinColumn}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Specified Primary Key Join Columns</em>' containment reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Specified Primary Key Join Columns</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_SpecifiedPrimaryKeyJoinColumns()
	 * @model containment="true"
	 * @generated
	 */
	public EList<IPrimaryKeyJoinColumn> getSpecifiedPrimaryKeyJoinColumns() {
		if (specifiedPrimaryKeyJoinColumns == null) {
			specifiedPrimaryKeyJoinColumns = new EObjectContainmentEList<IPrimaryKeyJoinColumn>(IPrimaryKeyJoinColumn.class, this, OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS);
		}
		return specifiedPrimaryKeyJoinColumns;
	}

	/**
	 * Returns the value of the '<em><b>Default Primary Key Join Columns</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.mappings.IPrimaryKeyJoinColumn}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Default Primary Key Join Columns</em>' containment reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Default Primary Key Join Columns</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_DefaultPrimaryKeyJoinColumns()
	 * @model containment="true"
	 * @generated
	 */
	public EList<IPrimaryKeyJoinColumn> getDefaultPrimaryKeyJoinColumns() {
		if (defaultPrimaryKeyJoinColumns == null) {
			defaultPrimaryKeyJoinColumns = new EObjectContainmentEList<IPrimaryKeyJoinColumn>(IPrimaryKeyJoinColumn.class, this, OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_PRIMARY_KEY_JOIN_COLUMNS);
		}
		return defaultPrimaryKeyJoinColumns;
	}

	public EList<IAttributeOverride> getAttributeOverrides() {
		EList<IAttributeOverride> list = new EObjectEList<IAttributeOverride>(IAttributeOverride.class, this, OrmPackage.XML_ENTITY_INTERNAL__ATTRIBUTE_OVERRIDES);
		list.addAll(getSpecifiedAttributeOverrides());
		list.addAll(getDefaultAttributeOverrides());
		return list;
	}

	/**
	 * Returns the value of the '<em><b>Specified Attribute Overrides</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.mappings.IAttributeOverride}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Specified Attribute Overrides</em>' reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Specified Attribute Overrides</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_SpecifiedAttributeOverrides()
	 * @model containment="true"
	 * @generated
	 */
	public EList<IAttributeOverride> getSpecifiedAttributeOverrides() {
		if (specifiedAttributeOverrides == null) {
			specifiedAttributeOverrides = new EObjectContainmentEList<IAttributeOverride>(IAttributeOverride.class, this, OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ATTRIBUTE_OVERRIDES);
		}
		return specifiedAttributeOverrides;
	}

	/**
	 * Returns the value of the '<em><b>Default Attribute Overrides</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.mappings.IAttributeOverride}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Default Attribute Overrides</em>' reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Default Attribute Overrides</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_DefaultAttributeOverrides()
	 * @model containment="true"
	 * @generated
	 */
	public EList<IAttributeOverride> getDefaultAttributeOverrides() {
		if (defaultAttributeOverrides == null) {
			defaultAttributeOverrides = new EObjectContainmentEList<IAttributeOverride>(IAttributeOverride.class, this, OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ATTRIBUTE_OVERRIDES);
		}
		return defaultAttributeOverrides;
	}

	public EList<IAssociationOverride> getAssociationOverrides() {
		EList<IAssociationOverride> list = new EObjectEList<IAssociationOverride>(IAssociationOverride.class, this, OrmPackage.XML_ENTITY_INTERNAL__ASSOCIATION_OVERRIDES);
		list.addAll(getSpecifiedAssociationOverrides());
		list.addAll(getDefaultAssociationOverrides());
		return list;
	}

	/**
	 * Returns the value of the '<em><b>Specified Association Overrides</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.mappings.IAssociationOverride}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Specified Association Overrides</em>' reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Specified Association Overrides</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_SpecifiedAssociationOverrides()
	 * @model containment="true"
	 * @generated
	 */
	public EList<IAssociationOverride> getSpecifiedAssociationOverrides() {
		if (specifiedAssociationOverrides == null) {
			specifiedAssociationOverrides = new EObjectContainmentEList<IAssociationOverride>(IAssociationOverride.class, this, OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ASSOCIATION_OVERRIDES);
		}
		return specifiedAssociationOverrides;
	}

	/**
	 * Returns the value of the '<em><b>Default Association Overrides</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.mappings.IAssociationOverride}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Default Association Overrides</em>' reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Default Association Overrides</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_DefaultAssociationOverrides()
	 * @model containment="true"
	 * @generated
	 */
	public EList<IAssociationOverride> getDefaultAssociationOverrides() {
		if (defaultAssociationOverrides == null) {
			defaultAssociationOverrides = new EObjectContainmentEList<IAssociationOverride>(IAssociationOverride.class, this, OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ASSOCIATION_OVERRIDES);
		}
		return defaultAssociationOverrides;
	}

	/**
	 * Returns the value of the '<em><b>Named Queries</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.mappings.INamedQuery}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Named Queries</em>' containment reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Named Queries</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_NamedQueries()
	 * @model containment="true"
	 * @generated
	 */
	public EList<INamedQuery> getNamedQueries() {
		if (namedQueries == null) {
			namedQueries = new EObjectContainmentEList<INamedQuery>(INamedQuery.class, this, OrmPackage.XML_ENTITY_INTERNAL__NAMED_QUERIES);
		}
		return namedQueries;
	}

	/**
	 * Returns the value of the '<em><b>Named Native Queries</b></em>' containment reference list.
	 * The list contents are of type {@link org.eclipse.jpt.core.internal.mappings.INamedNativeQuery}.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Named Native Queries</em>' containment reference list isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Named Native Queries</em>' containment reference list.
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_NamedNativeQueries()
	 * @model containment="true"
	 * @generated
	 */
	public EList<INamedNativeQuery> getNamedNativeQueries() {
		if (namedNativeQueries == null) {
			namedNativeQueries = new EObjectContainmentEList<INamedNativeQuery>(INamedNativeQuery.class, this, OrmPackage.XML_ENTITY_INTERNAL__NAMED_NATIVE_QUERIES);
		}
		return namedNativeQueries;
	}

	/**
	 * Returns the value of the '<em><b>Id Class</b></em>' attribute.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Id Class</em>' attribute isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Id Class</em>' attribute.
	 * @see #setIdClass(String)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getIEntity_IdClass()
	 * @model
	 * @generated
	 */
	public String getIdClass() {
		return idClass;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal#getIdClass <em>Id Class</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Id Class</em>' attribute.
	 * @see #getIdClass()
	 * @generated
	 */
	public void setIdClass(String newIdClass) {
		String oldIdClass = idClass;
		idClass = newIdClass;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS, oldIdClass, idClass));
	}

	protected void idClassChanged() {
		if (getIdClass() == null) {
			setIdClassForXml(null);
		}
		else {
			if (getIdClassForXml() == null) {
				setIdClassForXml(OrmFactory.eINSTANCE.createXmlIdClass());
			}
			getIdClassForXml().setValue(getIdClass());
		}
	}

	public boolean discriminatorValueIsAllowed() {
		Type type = getPersistentType().findType();
		return (type == null) ? false : !type.isAbstract();
	}

	public IEntity parentEntity() {
		for (Iterator<IPersistentType> i = getPersistentType().inheritanceHierarchy(); i.hasNext();) {
			ITypeMapping typeMapping = i.next().getMapping();
			if (typeMapping != this && typeMapping instanceof IEntity) {
				return (IEntity) typeMapping;
			}
		}
		return this;
	}

	public IEntity rootEntity() {
		IEntity rootEntity = null;
		for (Iterator<IPersistentType> i = getPersistentType().inheritanceHierarchy(); i.hasNext();) {
			IPersistentType persistentType = i.next();
			if (persistentType.getMapping() instanceof IEntity) {
				rootEntity = (IEntity) persistentType.getMapping();
			}
		}
		return rootEntity;
	}

	/**
	 * Returns the value of the '<em><b>Table For Xml</b></em>' reference.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Table For Xml</em>' reference isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Table For Xml</em>' reference.
	 * @see #setTableForXml(XmlTable)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlEntityForXml_TableForXml()
	 * @model resolveProxies="false" volatile="true"
	 * @generated NOT
	 */
	public XmlTable getTableForXml() {
		if (getTableInternal().isAllFeaturesUnset()) {
			return null;
		}
		return getTableInternal();
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal#getTableForXml <em>Table For Xml</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Table For Xml</em>' reference.
	 * @see #getTableForXml()
	 * @generated NOT
	 */
	public void setTableForXmlGen(XmlTable newTableForXml) {
		XmlTable oldValue = newTableForXml == null ? (XmlTable) getTable() : null;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__TABLE_FOR_XML, oldValue, newTableForXml));
	}

	public void setTableForXml(XmlTable newTableForXml) {
		setTableForXmlGen(newTableForXml);
		if (newTableForXml == null) {
			getTableInternal().unsetAllAttributes();
		}
	}

	/**
	 * Returns the value of the '<em><b>Discriminator Column For Xml</b></em>' reference.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Discriminator Column For Xml</em>' reference isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Discriminator Column For Xml</em>' reference.
	 * @see #setDiscriminatorColumnForXml(XmlDiscriminatorColumn)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlEntityForXml_DiscriminatorColumnForXml()
	 * @model resolveProxies="false" volatile="true"
	 * @generated NOT
	 */
	public XmlDiscriminatorColumn getDiscriminatorColumnForXml() {
		if (getDiscriminatorColumnInternal().isAllFeaturesUnset()) {
			return null;
		}
		return getDiscriminatorColumnInternal();
	}

	private XmlDiscriminatorColumn getDiscriminatorColumnInternal() {
		return (XmlDiscriminatorColumn) getDiscriminatorColumn();
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal#getDiscriminatorColumnForXml <em>Discriminator Column For Xml</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Discriminator Column For Xml</em>' reference.
	 * @see #getDiscriminatorColumnForXml()
	 * @generated NOT
	 */
	public void setDiscriminatorColumnForXmlGen(XmlDiscriminatorColumn newDiscriminatorColumnForXml) {
		XmlDiscriminatorColumn oldValue = newDiscriminatorColumnForXml == null ? (XmlDiscriminatorColumn) getDiscriminatorColumn() : null;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN_FOR_XML, oldValue, newDiscriminatorColumnForXml));
	}

	public void setDiscriminatorColumnForXml(XmlDiscriminatorColumn newDiscriminatorColumnForXml) {
		setDiscriminatorColumnForXmlGen(newDiscriminatorColumnForXml);
		if (newDiscriminatorColumnForXml == null) {
			getDiscriminatorColumnInternal().unsetAllAttributes();
		}
	}

	/**
	 * Returns the value of the '<em><b>Id Class For Xml</b></em>' containment reference.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Id Class For Xml</em>' containment reference isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Id Class For Xml</em>' containment reference.
	 * @see #setIdClassForXml(XmlIdClass)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlEntityForXml_IdClassForXml()
	 * @model containment="true"
	 * @generated
	 */
	public XmlIdClass getIdClassForXml() {
		return idClassForXml;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetIdClassForXml(XmlIdClass newIdClassForXml, NotificationChain msgs) {
		XmlIdClass oldIdClassForXml = idClassForXml;
		idClassForXml = newIdClassForXml;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS_FOR_XML, oldIdClassForXml, newIdClassForXml);
			if (msgs == null)
				msgs = notification;
			else
				msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal#getIdClassForXml <em>Id Class For Xml</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Id Class For Xml</em>' containment reference.
	 * @see #getIdClassForXml()
	 * @generated
	 */
	public void setIdClassForXml(XmlIdClass newIdClassForXml) {
		if (newIdClassForXml != idClassForXml) {
			NotificationChain msgs = null;
			if (idClassForXml != null)
				msgs = ((InternalEObject) idClassForXml).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS_FOR_XML, null, msgs);
			if (newIdClassForXml != null)
				msgs = ((InternalEObject) newIdClassForXml).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS_FOR_XML, null, msgs);
			msgs = basicSetIdClassForXml(newIdClassForXml, msgs);
			if (msgs != null)
				msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS_FOR_XML, newIdClassForXml, newIdClassForXml));
	}

	/**
	 * Returns the value of the '<em><b>Inheritance For Xml</b></em>' containment reference.
	 * <!-- begin-user-doc -->
	 * <p>
	 * If the meaning of the '<em>Inheritance For Xml</em>' containment reference isn't clear,
	 * there really should be more of a description here...
	 * </p>
	 * <!-- end-user-doc -->
	 * @return the value of the '<em>Inheritance For Xml</em>' containment reference.
	 * @see #setInheritanceForXml(XmlInheritance)
	 * @see org.eclipse.jpt.core.internal.content.orm.OrmPackage#getXmlEntityForXml_InheritanceForXml()
	 * @model containment="true"
	 * @generated
	 */
	public XmlInheritance getInheritanceForXml() {
		return inheritanceForXml;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetInheritanceForXml(XmlInheritance newInheritanceForXml, NotificationChain msgs) {
		XmlInheritance oldInheritanceForXml = inheritanceForXml;
		inheritanceForXml = newInheritanceForXml;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_FOR_XML, oldInheritanceForXml, newInheritanceForXml);
			if (msgs == null)
				msgs = notification;
			else
				msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * Sets the value of the '{@link org.eclipse.jpt.core.internal.content.orm.XmlEntityInternal#getInheritanceForXml <em>Inheritance For Xml</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param value the new value of the '<em>Inheritance For Xml</em>' containment reference.
	 * @see #getInheritanceForXml()
	 * @generated
	 */
	public void setInheritanceForXml(XmlInheritance newInheritanceForXml) {
		if (newInheritanceForXml != inheritanceForXml) {
			NotificationChain msgs = null;
			if (inheritanceForXml != null)
				msgs = ((InternalEObject) inheritanceForXml).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_FOR_XML, null, msgs);
			if (newInheritanceForXml != null)
				msgs = ((InternalEObject) newInheritanceForXml).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_FOR_XML, null, msgs);
			msgs = basicSetInheritanceForXml(newInheritanceForXml, msgs);
			if (msgs != null)
				msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_FOR_XML, newInheritanceForXml, newInheritanceForXml));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS_FOR_XML :
				return basicSetIdClassForXml(null, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_FOR_XML :
				return basicSetInheritanceForXml(null, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE :
				return basicSetTable(null, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_SECONDARY_TABLES :
				return ((InternalEList<?>) getSpecifiedSecondaryTables()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__PRIMARY_KEY_JOIN_COLUMNS :
				return ((InternalEList<?>) getPrimaryKeyJoinColumns()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS :
				return ((InternalEList<?>) getSpecifiedPrimaryKeyJoinColumns()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_PRIMARY_KEY_JOIN_COLUMNS :
				return ((InternalEList<?>) getDefaultPrimaryKeyJoinColumns()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN :
				return basicSetDiscriminatorColumn(null, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__SEQUENCE_GENERATOR :
				return basicSetSequenceGenerator(null, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE_GENERATOR :
				return basicSetTableGenerator(null, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__ATTRIBUTE_OVERRIDES :
				return ((InternalEList<?>) getAttributeOverrides()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ATTRIBUTE_OVERRIDES :
				return ((InternalEList<?>) getSpecifiedAttributeOverrides()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ATTRIBUTE_OVERRIDES :
				return ((InternalEList<?>) getDefaultAttributeOverrides()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__ASSOCIATION_OVERRIDES :
				return ((InternalEList<?>) getAssociationOverrides()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ASSOCIATION_OVERRIDES :
				return ((InternalEList<?>) getSpecifiedAssociationOverrides()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ASSOCIATION_OVERRIDES :
				return ((InternalEList<?>) getDefaultAssociationOverrides()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__NAMED_QUERIES :
				return ((InternalEList<?>) getNamedQueries()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__NAMED_NATIVE_QUERIES :
				return ((InternalEList<?>) getNamedNativeQueries()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__SECONDARY_TABLES :
				return ((InternalEList<?>) getSecondaryTables()).basicRemove(otherEnd, msgs);
			case OrmPackage.XML_ENTITY_INTERNAL__VIRTUAL_SECONDARY_TABLES :
				return ((InternalEList<?>) getVirtualSecondaryTables()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	protected void setDefaultName(String newDefaultName) {
		String oldDefaultName = this.defaultName;
		this.defaultName = newDefaultName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_NAME, oldDefaultName, defaultName));
	}

	@Override
	public void refreshDefaults(DefaultsContext defaultsContext) {
		super.refreshDefaults(defaultsContext);
		setDefaultName((String) defaultsContext.getDefault(BaseJpaPlatform.DEFAULT_ENTITY_NAME_KEY));
	}

	public String getKey() {
		return IMappingKeys.ENTITY_TYPE_MAPPING_KEY;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE_FOR_XML :
				return getTableForXml();
			case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN_FOR_XML :
				return getDiscriminatorColumnForXml();
			case OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS_FOR_XML :
				return getIdClassForXml();
			case OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_FOR_XML :
				return getInheritanceForXml();
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_NAME :
				return getSpecifiedName();
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_NAME :
				return getDefaultName();
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE :
				return getTable();
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_SECONDARY_TABLES :
				return getSpecifiedSecondaryTables();
			case OrmPackage.XML_ENTITY_INTERNAL__PRIMARY_KEY_JOIN_COLUMNS :
				return getPrimaryKeyJoinColumns();
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS :
				return getSpecifiedPrimaryKeyJoinColumns();
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_PRIMARY_KEY_JOIN_COLUMNS :
				return getDefaultPrimaryKeyJoinColumns();
			case OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_STRATEGY :
				return getInheritanceStrategy();
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_DISCRIMINATOR_VALUE :
				return getDefaultDiscriminatorValue();
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_DISCRIMINATOR_VALUE :
				return getSpecifiedDiscriminatorValue();
			case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_VALUE :
				return getDiscriminatorValue();
			case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN :
				return getDiscriminatorColumn();
			case OrmPackage.XML_ENTITY_INTERNAL__SEQUENCE_GENERATOR :
				return getSequenceGenerator();
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE_GENERATOR :
				return getTableGenerator();
			case OrmPackage.XML_ENTITY_INTERNAL__ATTRIBUTE_OVERRIDES :
				return getAttributeOverrides();
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ATTRIBUTE_OVERRIDES :
				return getSpecifiedAttributeOverrides();
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ATTRIBUTE_OVERRIDES :
				return getDefaultAttributeOverrides();
			case OrmPackage.XML_ENTITY_INTERNAL__ASSOCIATION_OVERRIDES :
				return getAssociationOverrides();
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ASSOCIATION_OVERRIDES :
				return getSpecifiedAssociationOverrides();
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ASSOCIATION_OVERRIDES :
				return getDefaultAssociationOverrides();
			case OrmPackage.XML_ENTITY_INTERNAL__NAMED_QUERIES :
				return getNamedQueries();
			case OrmPackage.XML_ENTITY_INTERNAL__NAMED_NATIVE_QUERIES :
				return getNamedNativeQueries();
			case OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS :
				return getIdClass();
			case OrmPackage.XML_ENTITY_INTERNAL__SECONDARY_TABLES :
				return getSecondaryTables();
			case OrmPackage.XML_ENTITY_INTERNAL__VIRTUAL_SECONDARY_TABLES :
				return getVirtualSecondaryTables();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE_FOR_XML :
				setTableForXml((XmlTable) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN_FOR_XML :
				setDiscriminatorColumnForXml((XmlDiscriminatorColumn) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS_FOR_XML :
				setIdClassForXml((XmlIdClass) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_FOR_XML :
				setInheritanceForXml((XmlInheritance) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_NAME :
				setSpecifiedName((String) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_SECONDARY_TABLES :
				getSpecifiedSecondaryTables().clear();
				getSpecifiedSecondaryTables().addAll((Collection<? extends ISecondaryTable>) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS :
				getSpecifiedPrimaryKeyJoinColumns().clear();
				getSpecifiedPrimaryKeyJoinColumns().addAll((Collection<? extends IPrimaryKeyJoinColumn>) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_PRIMARY_KEY_JOIN_COLUMNS :
				getDefaultPrimaryKeyJoinColumns().clear();
				getDefaultPrimaryKeyJoinColumns().addAll((Collection<? extends IPrimaryKeyJoinColumn>) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_STRATEGY :
				setInheritanceStrategy((InheritanceType) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_DISCRIMINATOR_VALUE :
				setDefaultDiscriminatorValue((String) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_DISCRIMINATOR_VALUE :
				setSpecifiedDiscriminatorValue((String) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SEQUENCE_GENERATOR :
				setSequenceGenerator((ISequenceGenerator) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE_GENERATOR :
				setTableGenerator((ITableGenerator) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ATTRIBUTE_OVERRIDES :
				getSpecifiedAttributeOverrides().clear();
				getSpecifiedAttributeOverrides().addAll((Collection<? extends IAttributeOverride>) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ATTRIBUTE_OVERRIDES :
				getDefaultAttributeOverrides().clear();
				getDefaultAttributeOverrides().addAll((Collection<? extends IAttributeOverride>) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ASSOCIATION_OVERRIDES :
				getSpecifiedAssociationOverrides().clear();
				getSpecifiedAssociationOverrides().addAll((Collection<? extends IAssociationOverride>) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ASSOCIATION_OVERRIDES :
				getDefaultAssociationOverrides().clear();
				getDefaultAssociationOverrides().addAll((Collection<? extends IAssociationOverride>) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__NAMED_QUERIES :
				getNamedQueries().clear();
				getNamedQueries().addAll((Collection<? extends INamedQuery>) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__NAMED_NATIVE_QUERIES :
				getNamedNativeQueries().clear();
				getNamedNativeQueries().addAll((Collection<? extends INamedNativeQuery>) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS :
				setIdClass((String) newValue);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__VIRTUAL_SECONDARY_TABLES :
				getVirtualSecondaryTables().clear();
				getVirtualSecondaryTables().addAll((Collection<? extends ISecondaryTable>) newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE_FOR_XML :
				setTableForXml((XmlTable) null);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN_FOR_XML :
				setDiscriminatorColumnForXml((XmlDiscriminatorColumn) null);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS_FOR_XML :
				setIdClassForXml((XmlIdClass) null);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_FOR_XML :
				setInheritanceForXml((XmlInheritance) null);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_NAME :
				setSpecifiedName(SPECIFIED_NAME_EDEFAULT);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_SECONDARY_TABLES :
				getSpecifiedSecondaryTables().clear();
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS :
				getSpecifiedPrimaryKeyJoinColumns().clear();
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_PRIMARY_KEY_JOIN_COLUMNS :
				getDefaultPrimaryKeyJoinColumns().clear();
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_STRATEGY :
				setInheritanceStrategy(INHERITANCE_STRATEGY_EDEFAULT);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_DISCRIMINATOR_VALUE :
				setDefaultDiscriminatorValue(DEFAULT_DISCRIMINATOR_VALUE_EDEFAULT);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_DISCRIMINATOR_VALUE :
				setSpecifiedDiscriminatorValue(SPECIFIED_DISCRIMINATOR_VALUE_EDEFAULT);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SEQUENCE_GENERATOR :
				setSequenceGenerator((ISequenceGenerator) null);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE_GENERATOR :
				setTableGenerator((ITableGenerator) null);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ATTRIBUTE_OVERRIDES :
				getSpecifiedAttributeOverrides().clear();
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ATTRIBUTE_OVERRIDES :
				getDefaultAttributeOverrides().clear();
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ASSOCIATION_OVERRIDES :
				getSpecifiedAssociationOverrides().clear();
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ASSOCIATION_OVERRIDES :
				getDefaultAssociationOverrides().clear();
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__NAMED_QUERIES :
				getNamedQueries().clear();
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__NAMED_NATIVE_QUERIES :
				getNamedNativeQueries().clear();
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS :
				setIdClass(ID_CLASS_EDEFAULT);
				return;
			case OrmPackage.XML_ENTITY_INTERNAL__VIRTUAL_SECONDARY_TABLES :
				getVirtualSecondaryTables().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE_FOR_XML :
				return getTableForXml() != null;
			case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN_FOR_XML :
				return getDiscriminatorColumnForXml() != null;
			case OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS_FOR_XML :
				return idClassForXml != null;
			case OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_FOR_XML :
				return inheritanceForXml != null;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_NAME :
				return SPECIFIED_NAME_EDEFAULT == null ? specifiedName != null : !SPECIFIED_NAME_EDEFAULT.equals(specifiedName);
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_NAME :
				return DEFAULT_NAME_EDEFAULT == null ? defaultName != null : !DEFAULT_NAME_EDEFAULT.equals(defaultName);
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE :
				return table != null;
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_SECONDARY_TABLES :
				return specifiedSecondaryTables != null && !specifiedSecondaryTables.isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__PRIMARY_KEY_JOIN_COLUMNS :
				return !getPrimaryKeyJoinColumns().isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS :
				return specifiedPrimaryKeyJoinColumns != null && !specifiedPrimaryKeyJoinColumns.isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_PRIMARY_KEY_JOIN_COLUMNS :
				return defaultPrimaryKeyJoinColumns != null && !defaultPrimaryKeyJoinColumns.isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_STRATEGY :
				return inheritanceStrategy != INHERITANCE_STRATEGY_EDEFAULT;
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_DISCRIMINATOR_VALUE :
				return DEFAULT_DISCRIMINATOR_VALUE_EDEFAULT == null ? defaultDiscriminatorValue != null : !DEFAULT_DISCRIMINATOR_VALUE_EDEFAULT.equals(defaultDiscriminatorValue);
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_DISCRIMINATOR_VALUE :
				return SPECIFIED_DISCRIMINATOR_VALUE_EDEFAULT == null ? specifiedDiscriminatorValue != null : !SPECIFIED_DISCRIMINATOR_VALUE_EDEFAULT.equals(specifiedDiscriminatorValue);
			case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_VALUE :
				return DISCRIMINATOR_VALUE_EDEFAULT == null ? getDiscriminatorValue() != null : !DISCRIMINATOR_VALUE_EDEFAULT.equals(getDiscriminatorValue());
			case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN :
				return discriminatorColumn != null;
			case OrmPackage.XML_ENTITY_INTERNAL__SEQUENCE_GENERATOR :
				return sequenceGenerator != null;
			case OrmPackage.XML_ENTITY_INTERNAL__TABLE_GENERATOR :
				return tableGenerator != null;
			case OrmPackage.XML_ENTITY_INTERNAL__ATTRIBUTE_OVERRIDES :
				return !getAttributeOverrides().isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ATTRIBUTE_OVERRIDES :
				return specifiedAttributeOverrides != null && !specifiedAttributeOverrides.isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ATTRIBUTE_OVERRIDES :
				return defaultAttributeOverrides != null && !defaultAttributeOverrides.isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__ASSOCIATION_OVERRIDES :
				return !getAssociationOverrides().isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ASSOCIATION_OVERRIDES :
				return specifiedAssociationOverrides != null && !specifiedAssociationOverrides.isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ASSOCIATION_OVERRIDES :
				return defaultAssociationOverrides != null && !defaultAssociationOverrides.isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__NAMED_QUERIES :
				return namedQueries != null && !namedQueries.isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__NAMED_NATIVE_QUERIES :
				return namedNativeQueries != null && !namedNativeQueries.isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS :
				return ID_CLASS_EDEFAULT == null ? idClass != null : !ID_CLASS_EDEFAULT.equals(idClass);
			case OrmPackage.XML_ENTITY_INTERNAL__SECONDARY_TABLES :
				return !getSecondaryTables().isEmpty();
			case OrmPackage.XML_ENTITY_INTERNAL__VIRTUAL_SECONDARY_TABLES :
				return virtualSecondaryTables != null && !virtualSecondaryTables.isEmpty();
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
		if (baseClass == XmlEntityForXml.class) {
			switch (derivedFeatureID) {
				case OrmPackage.XML_ENTITY_INTERNAL__TABLE_FOR_XML :
					return OrmPackage.XML_ENTITY_FOR_XML__TABLE_FOR_XML;
				case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN_FOR_XML :
					return OrmPackage.XML_ENTITY_FOR_XML__DISCRIMINATOR_COLUMN_FOR_XML;
				case OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS_FOR_XML :
					return OrmPackage.XML_ENTITY_FOR_XML__ID_CLASS_FOR_XML;
				case OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_FOR_XML :
					return OrmPackage.XML_ENTITY_FOR_XML__INHERITANCE_FOR_XML;
				default :
					return -1;
			}
		}
		if (baseClass == IEntity.class) {
			switch (derivedFeatureID) {
				case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_NAME :
					return JpaCoreMappingsPackage.IENTITY__SPECIFIED_NAME;
				case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_NAME :
					return JpaCoreMappingsPackage.IENTITY__DEFAULT_NAME;
				case OrmPackage.XML_ENTITY_INTERNAL__TABLE :
					return JpaCoreMappingsPackage.IENTITY__TABLE;
				case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_SECONDARY_TABLES :
					return JpaCoreMappingsPackage.IENTITY__SPECIFIED_SECONDARY_TABLES;
				case OrmPackage.XML_ENTITY_INTERNAL__PRIMARY_KEY_JOIN_COLUMNS :
					return JpaCoreMappingsPackage.IENTITY__PRIMARY_KEY_JOIN_COLUMNS;
				case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS :
					return JpaCoreMappingsPackage.IENTITY__SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS;
				case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_PRIMARY_KEY_JOIN_COLUMNS :
					return JpaCoreMappingsPackage.IENTITY__DEFAULT_PRIMARY_KEY_JOIN_COLUMNS;
				case OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_STRATEGY :
					return JpaCoreMappingsPackage.IENTITY__INHERITANCE_STRATEGY;
				case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_DISCRIMINATOR_VALUE :
					return JpaCoreMappingsPackage.IENTITY__DEFAULT_DISCRIMINATOR_VALUE;
				case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_DISCRIMINATOR_VALUE :
					return JpaCoreMappingsPackage.IENTITY__SPECIFIED_DISCRIMINATOR_VALUE;
				case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_VALUE :
					return JpaCoreMappingsPackage.IENTITY__DISCRIMINATOR_VALUE;
				case OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN :
					return JpaCoreMappingsPackage.IENTITY__DISCRIMINATOR_COLUMN;
				case OrmPackage.XML_ENTITY_INTERNAL__SEQUENCE_GENERATOR :
					return JpaCoreMappingsPackage.IENTITY__SEQUENCE_GENERATOR;
				case OrmPackage.XML_ENTITY_INTERNAL__TABLE_GENERATOR :
					return JpaCoreMappingsPackage.IENTITY__TABLE_GENERATOR;
				case OrmPackage.XML_ENTITY_INTERNAL__ATTRIBUTE_OVERRIDES :
					return JpaCoreMappingsPackage.IENTITY__ATTRIBUTE_OVERRIDES;
				case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ATTRIBUTE_OVERRIDES :
					return JpaCoreMappingsPackage.IENTITY__SPECIFIED_ATTRIBUTE_OVERRIDES;
				case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ATTRIBUTE_OVERRIDES :
					return JpaCoreMappingsPackage.IENTITY__DEFAULT_ATTRIBUTE_OVERRIDES;
				case OrmPackage.XML_ENTITY_INTERNAL__ASSOCIATION_OVERRIDES :
					return JpaCoreMappingsPackage.IENTITY__ASSOCIATION_OVERRIDES;
				case OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ASSOCIATION_OVERRIDES :
					return JpaCoreMappingsPackage.IENTITY__SPECIFIED_ASSOCIATION_OVERRIDES;
				case OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ASSOCIATION_OVERRIDES :
					return JpaCoreMappingsPackage.IENTITY__DEFAULT_ASSOCIATION_OVERRIDES;
				case OrmPackage.XML_ENTITY_INTERNAL__NAMED_QUERIES :
					return JpaCoreMappingsPackage.IENTITY__NAMED_QUERIES;
				case OrmPackage.XML_ENTITY_INTERNAL__NAMED_NATIVE_QUERIES :
					return JpaCoreMappingsPackage.IENTITY__NAMED_NATIVE_QUERIES;
				case OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS :
					return JpaCoreMappingsPackage.IENTITY__ID_CLASS;
				default :
					return -1;
			}
		}
		if (baseClass == XmlEntity.class) {
			switch (derivedFeatureID) {
				case OrmPackage.XML_ENTITY_INTERNAL__SECONDARY_TABLES :
					return OrmPackage.XML_ENTITY__SECONDARY_TABLES;
				case OrmPackage.XML_ENTITY_INTERNAL__VIRTUAL_SECONDARY_TABLES :
					return OrmPackage.XML_ENTITY__VIRTUAL_SECONDARY_TABLES;
				default :
					return -1;
			}
		}
		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
		if (baseClass == XmlEntityForXml.class) {
			switch (baseFeatureID) {
				case OrmPackage.XML_ENTITY_FOR_XML__TABLE_FOR_XML :
					return OrmPackage.XML_ENTITY_INTERNAL__TABLE_FOR_XML;
				case OrmPackage.XML_ENTITY_FOR_XML__DISCRIMINATOR_COLUMN_FOR_XML :
					return OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN_FOR_XML;
				case OrmPackage.XML_ENTITY_FOR_XML__ID_CLASS_FOR_XML :
					return OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS_FOR_XML;
				case OrmPackage.XML_ENTITY_FOR_XML__INHERITANCE_FOR_XML :
					return OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_FOR_XML;
				default :
					return -1;
			}
		}
		if (baseClass == IEntity.class) {
			switch (baseFeatureID) {
				case JpaCoreMappingsPackage.IENTITY__SPECIFIED_NAME :
					return OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_NAME;
				case JpaCoreMappingsPackage.IENTITY__DEFAULT_NAME :
					return OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_NAME;
				case JpaCoreMappingsPackage.IENTITY__TABLE :
					return OrmPackage.XML_ENTITY_INTERNAL__TABLE;
				case JpaCoreMappingsPackage.IENTITY__SPECIFIED_SECONDARY_TABLES :
					return OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_SECONDARY_TABLES;
				case JpaCoreMappingsPackage.IENTITY__PRIMARY_KEY_JOIN_COLUMNS :
					return OrmPackage.XML_ENTITY_INTERNAL__PRIMARY_KEY_JOIN_COLUMNS;
				case JpaCoreMappingsPackage.IENTITY__SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS :
					return OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS;
				case JpaCoreMappingsPackage.IENTITY__DEFAULT_PRIMARY_KEY_JOIN_COLUMNS :
					return OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_PRIMARY_KEY_JOIN_COLUMNS;
				case JpaCoreMappingsPackage.IENTITY__INHERITANCE_STRATEGY :
					return OrmPackage.XML_ENTITY_INTERNAL__INHERITANCE_STRATEGY;
				case JpaCoreMappingsPackage.IENTITY__DEFAULT_DISCRIMINATOR_VALUE :
					return OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_DISCRIMINATOR_VALUE;
				case JpaCoreMappingsPackage.IENTITY__SPECIFIED_DISCRIMINATOR_VALUE :
					return OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_DISCRIMINATOR_VALUE;
				case JpaCoreMappingsPackage.IENTITY__DISCRIMINATOR_VALUE :
					return OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_VALUE;
				case JpaCoreMappingsPackage.IENTITY__DISCRIMINATOR_COLUMN :
					return OrmPackage.XML_ENTITY_INTERNAL__DISCRIMINATOR_COLUMN;
				case JpaCoreMappingsPackage.IENTITY__SEQUENCE_GENERATOR :
					return OrmPackage.XML_ENTITY_INTERNAL__SEQUENCE_GENERATOR;
				case JpaCoreMappingsPackage.IENTITY__TABLE_GENERATOR :
					return OrmPackage.XML_ENTITY_INTERNAL__TABLE_GENERATOR;
				case JpaCoreMappingsPackage.IENTITY__ATTRIBUTE_OVERRIDES :
					return OrmPackage.XML_ENTITY_INTERNAL__ATTRIBUTE_OVERRIDES;
				case JpaCoreMappingsPackage.IENTITY__SPECIFIED_ATTRIBUTE_OVERRIDES :
					return OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ATTRIBUTE_OVERRIDES;
				case JpaCoreMappingsPackage.IENTITY__DEFAULT_ATTRIBUTE_OVERRIDES :
					return OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ATTRIBUTE_OVERRIDES;
				case JpaCoreMappingsPackage.IENTITY__ASSOCIATION_OVERRIDES :
					return OrmPackage.XML_ENTITY_INTERNAL__ASSOCIATION_OVERRIDES;
				case JpaCoreMappingsPackage.IENTITY__SPECIFIED_ASSOCIATION_OVERRIDES :
					return OrmPackage.XML_ENTITY_INTERNAL__SPECIFIED_ASSOCIATION_OVERRIDES;
				case JpaCoreMappingsPackage.IENTITY__DEFAULT_ASSOCIATION_OVERRIDES :
					return OrmPackage.XML_ENTITY_INTERNAL__DEFAULT_ASSOCIATION_OVERRIDES;
				case JpaCoreMappingsPackage.IENTITY__NAMED_QUERIES :
					return OrmPackage.XML_ENTITY_INTERNAL__NAMED_QUERIES;
				case JpaCoreMappingsPackage.IENTITY__NAMED_NATIVE_QUERIES :
					return OrmPackage.XML_ENTITY_INTERNAL__NAMED_NATIVE_QUERIES;
				case JpaCoreMappingsPackage.IENTITY__ID_CLASS :
					return OrmPackage.XML_ENTITY_INTERNAL__ID_CLASS;
				default :
					return -1;
			}
		}
		if (baseClass == XmlEntity.class) {
			switch (baseFeatureID) {
				case OrmPackage.XML_ENTITY__SECONDARY_TABLES :
					return OrmPackage.XML_ENTITY_INTERNAL__SECONDARY_TABLES;
				case OrmPackage.XML_ENTITY__VIRTUAL_SECONDARY_TABLES :
					return OrmPackage.XML_ENTITY_INTERNAL__VIRTUAL_SECONDARY_TABLES;
				default :
					return -1;
			}
		}
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy())
			return super.toString();
		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (specifiedName: ");
		result.append(specifiedName);
		result.append(", defaultName: ");
		result.append(defaultName);
		result.append(", inheritanceStrategy: ");
		result.append(inheritanceStrategy);
		result.append(", defaultDiscriminatorValue: ");
		result.append(defaultDiscriminatorValue);
		result.append(", specifiedDiscriminatorValue: ");
		result.append(specifiedDiscriminatorValue);
		result.append(", idClass: ");
		result.append(idClass);
		result.append(')');
		return result.toString();
	}

	@Override
	public String getTableName() {
		return getTable().getName();
	}

	public void makeTableForXmlNull() {
		setTableForXmlGen(null);
	}

	public void makeTableForXmlNonNull() {
		setTableForXmlGen(getTableForXml());
	}

	public void makeDiscriminatorColumnForXmlNull() {
		setDiscriminatorColumnForXmlGen(null);
	}

	//um, this is an object on XmlInheritance, but a tag on entity in the xml, how to handle???
	public void makeDiscriminatorColumnForXmlNonNull() {
		setDiscriminatorColumnForXmlGen(getDiscriminatorColumnForXml());
	}

	public String primaryKeyColumnName() {
		String pkColumnName = null;
		for (Iterator<IPersistentAttribute> stream = getPersistentType().allAttributes(); stream.hasNext();) {
			IPersistentAttribute attribute = stream.next();
			String name = attribute.primaryKeyColumnName();
			if (pkColumnName == null) {
				pkColumnName = name;
			}
			else if (name != null) {
				// if we encounter a composite primary key, return null
				return null;
			}
		}
		// if we encounter only a single primary key column name, return it
		return pkColumnName;
	}

	public String primaryKeyAttributeName() {
		String pkColumnName = null;
		String pkAttributeName = null;
		for (Iterator<IPersistentAttribute> stream = getPersistentType().allAttributes(); stream.hasNext();) {
			IPersistentAttribute attribute = stream.next();
			String name = attribute.primaryKeyColumnName();
			if (pkColumnName == null) {
				pkColumnName = name;
				pkAttributeName = attribute.getName();
			}
			else if (name != null) {
				// if we encounter a composite primary key, return null
				return null;
			}
		}
		// if we encounter only a single primary key column name, return it
		return pkAttributeName;
	}

	public boolean tableNameIsInvalid(String tableName) {
		return !CollectionTools.contains(this.associatedTableNamesIncludingInherited(), tableName);
	}

	private Iterator<String> tableNames(Iterator<ITable> tables) {
		return new TransformationIterator(tables) {
			@Override
			protected Object transform(Object next) {
				return ((ITable) next).getName();
			}
		};
	}

	public Iterator<String> associatedTableNamesIncludingInherited() {
		return this.nonNullTableNames(this.associatedTablesIncludingInherited());
	}

	private Iterator<String> nonNullTableNames(Iterator<ITable> tables) {
		return new FilteringIterator(this.tableNames(tables)) {
			@Override
			protected boolean accept(Object o) {
				return o != null;
			}
		};
	}

	public Iterator<ITable> associatedTables() {
		return new CompositeIterator(this.getTable(), this.getSecondaryTables().iterator());
	}

	public Iterator<ITable> associatedTablesIncludingInherited() {
		return new CompositeIterator(new TransformationIterator(this.inheritanceHierarchy()) {
			@Override
			protected Object transform(Object next) {
				return new FilteringIterator(((ITypeMapping) next).associatedTables()) {
					@Override
					protected boolean accept(Object o) {
						return true;
						//TODO
						//filtering these out so as to avoid the duplicate table, root and children share the same table
						//return !(o instanceof SingleTableInheritanceChildTableImpl);
					}
				};
			}
		});
	}

	@Override
	public Table primaryDbTable() {
		return getTable().dbTable();
	}

	@Override
	public Table dbTable(String tableName) {
		for (Iterator<ITable> stream = this.associatedTablesIncludingInherited(); stream.hasNext();) {
			Table dbTable = stream.next().dbTable();
			if (dbTable != null && dbTable.matchesShortJavaClassName(tableName)) {
				return dbTable;
			}
		}
		return null;
	}

	@Override
	public Schema dbSchema() {
		return getTable().dbSchema();
	}

	@Override
	public int xmlSequence() {
		return 1;
	}

	/**
	 * Return an iterator of Entities, each which inherits from the one before,
	 * and terminates at the root entity (or at the point of cyclicity).
	 */
	private Iterator<ITypeMapping> inheritanceHierarchy() {
		return new TransformationIterator(getPersistentType().inheritanceHierarchy()) {
			@Override
			protected Object transform(Object next) {
				return ((IPersistentType) next).getMapping();
			}
		};
		//TODO once we support inheritance, which of these should we use??
		//return this.getInheritance().typeMappingLineage();
	}

	public Iterator<String> allOverridableAttributeNames() {
		return new CompositeIterator(new TransformationIterator(this.inheritanceHierarchy()) {
			protected Object transform(Object next) {
				return ((ITypeMapping) next).overridableAttributeNames();
			}
		});
	}

	public Iterator<String> allOverridableAssociationNames() {
		return new CompositeIterator(new TransformationIterator(this.inheritanceHierarchy()) {
			protected Object transform(Object next) {
				return ((ITypeMapping) next).overridableAssociationNames();
			}
		});
	}

	public IAttributeOverride createAttributeOverride(int index) {
		return OrmFactory.eINSTANCE.createXmlAttributeOverride(new IEntity.AttributeOverrideOwner(this));
	}

	public IAssociationOverride createAssociationOverride(int index) {
		return OrmFactory.eINSTANCE.createXmlAssociationOverride(new IEntity.AssociationOverrideOwner(this));
	}

	public IAttributeOverride attributeOverrideNamed(String name) {
		return (IAttributeOverride) overrideNamed(name, getAttributeOverrides());
	}

	public boolean containsAttributeOverride(String name) {
		return containsOverride(name, getAttributeOverrides());
	}

	public boolean containsSpecifiedAttributeOverride(String name) {
		return containsOverride(name, getSpecifiedAttributeOverrides());
	}

	public boolean containsAssociationOverride(String name) {
		return containsOverride(name, getAssociationOverrides());
	}

	public boolean containsSpecifiedAssociationOverride(String name) {
		return containsOverride(name, getSpecifiedAssociationOverrides());
	}

	private IOverride overrideNamed(String name, List<? extends IOverride> overrides) {
		for (IOverride override : overrides) {
			String overrideName = override.getName();
			if (overrideName == null && name == null) {
				return override;
			}
			if (overrideName != null && overrideName.equals(name)) {
				return override;
			}
		}
		return null;
	}

	private boolean containsOverride(String name, List<? extends IOverride> overrides) {
		return overrideNamed(name, overrides) != null;
	}

	public ISecondaryTable createSecondaryTable(int index) {
		return OrmFactory.eINSTANCE.createXmlSecondaryTable(buildSecondaryTableOwner());
	}

	private ITable.Owner buildSecondaryTableOwner() {
		return new ITable.Owner() {
			public ITextRange validationTextRange() {
				return XmlEntityInternal.this.validationTextRange();
			}

			public ITypeMapping getTypeMapping() {
				return XmlEntityInternal.this;
			}
		};
	}

	public boolean containsSpecifiedPrimaryKeyJoinColumns() {
		return !this.getSpecifiedPrimaryKeyJoinColumns().isEmpty();
	}

	public IPrimaryKeyJoinColumn createPrimaryKeyJoinColumn(int index) {
		return OrmFactory.eINSTANCE.createXmlPrimaryKeyJoinColumn(new IEntity.PrimaryKeyJoinColumnOwner(this));
	}

	public INamedQuery createNamedQuery(int index) {
		return OrmFactory.eINSTANCE.createXmlNamedQuery();
	}

	public INamedNativeQuery createNamedNativeQuery(int index) {
		return OrmFactory.eINSTANCE.createXmlNamedNativeQuery();
	}
}
