/*******************************************************************************
 * Copyright (c) 2007, 2010 BMW Car IT, Technische Universitaet Muenchen, and others.
 * 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:
 * BMW Car IT - Initial API and implementation
 * Technische Universitaet Muenchen - Major refactoring and extension
 *******************************************************************************/
package org.eclipse.emf.edapt.spi.migration.impl;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.EClassImpl;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.ecore.util.EContentsEList;
import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
import org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.edapt.internal.migration.impl.ModelValidator;
import org.eclipse.emf.edapt.internal.migration.impl.UpdatingList;
import org.eclipse.emf.edapt.migration.MigrationException;
import org.eclipse.emf.edapt.spi.migration.AttributeSlot;
import org.eclipse.emf.edapt.spi.migration.Instance;
import org.eclipse.emf.edapt.spi.migration.Metamodel;
import org.eclipse.emf.edapt.spi.migration.MigrationFactory;
import org.eclipse.emf.edapt.spi.migration.MigrationPackage;
import org.eclipse.emf.edapt.spi.migration.Model;
import org.eclipse.emf.edapt.spi.migration.ModelResource;
import org.eclipse.emf.edapt.spi.migration.ReferenceSlot;
import org.eclipse.emf.edapt.spi.migration.Slot;
import org.eclipse.emf.edapt.spi.migration.Type;
import org.eclipse.ocl.OCL;
import org.eclipse.ocl.ParserException;
import org.eclipse.ocl.Query;
import org.eclipse.ocl.ecore.Constraint;
import org.eclipse.ocl.ecore.EcoreEnvironmentFactory;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.helper.OCLHelper;

/**
 * <!-- begin-user-doc --> An implementation of the model object ' <em><b>Instance</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 * <li>{@link org.eclipse.emf.edapt.spi.migration.impl.InstanceImpl#getSlots <em>Slots</em>}</li>
 * <li>{@link org.eclipse.emf.edapt.spi.migration.impl.InstanceImpl#getType <em>Type</em>}</li>
 * <li>{@link org.eclipse.emf.edapt.spi.migration.impl.InstanceImpl#getReferences <em>References</em>}</li>
 * <li>{@link org.eclipse.emf.edapt.spi.migration.impl.InstanceImpl#getUri <em>Uri</em>}</li>
 * <li>{@link org.eclipse.emf.edapt.spi.migration.impl.InstanceImpl#getUuid <em>Uuid</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class InstanceImpl extends EObjectImpl implements Instance {
	/**
	 * The cached value of the '{@link #getSlots() <em>Slots</em>}' containment reference list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getSlots()
	 * @generated
	 * @ordered
	 */
	protected EList<Slot> slots;

	/**
	 * The cached value of the '{@link #getReferences() <em>References</em>}' reference list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getReferences()
	 * @generated
	 * @ordered
	 */
	protected EList<ReferenceSlot> references;

	/**
	 * The default value of the '{@link #getUri() <em>Uri</em>}' attribute. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getUri()
	 * @generated
	 * @ordered
	 */
	protected static final URI URI_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getUri() <em>Uri</em>}' attribute. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getUri()
	 * @generated
	 * @ordered
	 */
	protected URI uri = URI_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getUuid() <em>Uuid</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getUuid()
	 * @generated
	 * @ordered
	 */
	protected String uuid = UUID_EDEFAULT;

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	protected InstanceImpl() {
		super();
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public EList<Slot> getSlots() {
		if (slots == null) {
			slots = new EObjectContainmentWithInverseEList<Slot>(Slot.class, this, MigrationPackage.INSTANCE__SLOTS,
				MigrationPackage.SLOT__INSTANCE);
		}
		return slots;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public Type getType() {
		if (eContainerFeatureID() != MigrationPackage.INSTANCE__TYPE) {
			return null;
		}
		return (Type) eContainer();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public NotificationChain basicSetType(Type newType, NotificationChain msgs) {
		msgs = eBasicSetContainer((InternalEObject) newType, MigrationPackage.INSTANCE__TYPE, msgs);
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void setType(Type newType) {
		if (newType != eInternalContainer()
			|| eContainerFeatureID() != MigrationPackage.INSTANCE__TYPE && newType != null) {
			if (EcoreUtil.isAncestor(this, (EObject) newType)) {
				throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); //$NON-NLS-1$
			}
			NotificationChain msgs = null;
			if (eInternalContainer() != null) {
				msgs = eBasicRemoveFromContainer(msgs);
			}
			if (newType != null) {
				msgs = ((InternalEObject) newType)
					.eInverseAdd(this, MigrationPackage.TYPE__INSTANCES, Type.class, msgs);
			}
			msgs = basicSetType(newType, msgs);
			if (msgs != null) {
				msgs.dispatch();
			}
		}
		else if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, MigrationPackage.INSTANCE__TYPE, newType, newType));
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public EList<ReferenceSlot> getReferences() {
		if (references == null) {
			references = new EObjectWithInverseResolvingEList.ManyInverse<ReferenceSlot>(ReferenceSlot.class, this,
				MigrationPackage.INSTANCE__REFERENCES, MigrationPackage.REFERENCE_SLOT__VALUES);
		}
		return references;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public URI getUri() {
		return uri;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void setUri(URI newUri) {
		final URI oldUri = uri;
		uri = newUri;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, MigrationPackage.INSTANCE__URI, oldUri, uri));
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public String getUuid() {
		return uuid;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void setUuid(String newUuid) {
		final String oldUuid = uuid;
		uuid = newUuid;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, MigrationPackage.INSTANCE__UUID, oldUuid, uuid));
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public <V> V get(EStructuralFeature feature) {
		if (feature instanceof EAttribute) {
			return this.getAttributeValue((EAttribute) feature);
		} else if (feature instanceof EReference) {
			return this.getReferenceValue((EReference) feature);
		}
		return null;
	}

	/**
	 * Get the value of an instance's attribute
	 *
	 * @param <V>
	 * @param attribute
	 * @return Value
	 */
	@SuppressWarnings("unchecked")
	private <V> V getAttributeValue(EAttribute attribute) {
		final Slot slot = getSlot(attribute);
		if (slot == null) {
			if (attribute.isMany()) {
				return (V) new UpdatingList(this, attribute);
			} else if (attribute.getDefaultValue() != null) {
				return (V) attribute.getDefaultValue();
			}
			return null;
		}
		final EList<Object> values = new UpdatingList(this, attribute,
			((AttributeSlot) slot).getValues());
		if (attribute.isMany()) {
			return (V) values;
		} else if (!values.isEmpty()) {
			return (V) values.get(0);
		}
		return null;
	}

	/**
	 * Get the value of an instance's reference
	 *
	 * @param <V>
	 * @param reference
	 * @return Value
	 */
	@SuppressWarnings("unchecked")
	<V> V getReferenceValue(EReference reference) {
		final Slot slot = getSlot(reference);
		if (slot == null) {
			if (reference.isMany()) {
				return (V) new UpdatingList(this, reference);
			} else if (reference.getDefaultValue() != null) {
				return (V) reference.getDefaultValue();
			}
			return null;
		}
		final EList<Instance> values = new UpdatingList(this, reference,
			((ReferenceSlot) slot).getValues());
		if (reference.isMany()) {
			return (V) values;
		} else if (!values.isEmpty()) {
			return (V) values.get(0);
		}
		return null;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void set(EStructuralFeature feature, Object newValue) {
		if (feature.isMany()) {
			final Collection<?> oldValues = (Collection<?>) this.get(feature);
			for (final Object value : oldValues) {
				this.remove(feature, value);
			}
			final Collection<?> newValues = (Collection<?>) newValue;
			for (final Object value : newValues) {
				this.add(feature, value);
			}
		} else {
			if (newValue instanceof List<?>) {
				throw new IllegalArgumentException("Single value expected, but list found"); //$NON-NLS-1$
			}
			final Object oldValue = this.get(feature);
			if (oldValue != newValue || feature.isUnsettable()) {
				if (isSet(feature) && oldValue != null) {
					this.remove(feature, oldValue);
				}
				if (newValue != null) {
					this.add(feature, newValue);
				}
			}
		}

	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public Slot getSlot(EStructuralFeature feature) {
		for (final Slot slot : getSlots()) {
			if (feature == slot.getEFeature()) {
				return slot;
			}
		}
		return null;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	@SuppressWarnings("unchecked")
	public <V> V evaluate(String expression) throws MigrationException {
		final Model model = getType().getModel();
		enableReflection();

		OCL<?, EClassifier, ?, ?, ?, ?, ?, ?, ?, Constraint, EClass, EObject> ocl;
		ocl = OCL.newInstance(EcoreEnvironmentFactory.INSTANCE);
		final OCLHelper<EClassifier, ?, ?, Constraint> helper = ocl.createOCLHelper();

		helper.setContext(eClass());
		OCLExpression<EClassifier> query;
		try {
			query = helper.createQuery(expression);
		} catch (final ParserException e) {
			throw new MigrationException("OCL expression '" + expression //$NON-NLS-1$
				+ "' could not be parsed", e); //$NON-NLS-1$
		}
		ocl.setExtentMap((Map) model.createExtentMap());

		// create a Query to evaluate our query expression
		final Query<EClassifier, EClass, EObject> queryEval = ocl.createQuery(query);
		final Object result = queryEval.evaluate(this);

		disableReflection();
		return (V) result;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public EReference getContainerReference() {
		for (final ReferenceSlot slot : getReferences()) {
			if (slot.getEReference().isContainment()) {
				return slot.getEReference();
			}
		}
		return null;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public ModelResource getResource() {
		final Model model = getType().getModel();
		Instance instance = this;
		while (instance.getContainer() != null) {
			for (final ModelResource resource : model.getResources()) {
				if (resource.getRootInstances().contains(instance)) {
					return resource;
				}
			}
			instance = instance.getContainer();
		}
		for (final ModelResource resource : model.getResources()) {
			if (resource.getRootInstances().contains(instance)) {
				return resource;
			}
		}
		return null;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public boolean isProxy() {
		return getUri() != null;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void migrate(String className) {
		final EClass eClass = checkAndGetClass(className);
		migrate(eClass);
	}

	private EClass checkAndGetClass(String className) {
		final Metamodel metamodel = getType().getModel().getMetamodel();
		final EClass eClass = metamodel.getEClass(className);
		if (eClass == null) {
			throw new IllegalArgumentException("Class " + className + " not found."); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return eClass;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public EList<Instance> getInverse(String referenceName) {
		final EReference reference = checkAndGetReference(referenceName);
		return getInverse(reference);
	}

	private EReference checkAndGetReference(String referenceName) {
		final EReference reference = getType().getModel().getMetamodel()
			.getEReference(referenceName);
		if (reference == null) {
			throw new IllegalArgumentException("Reference " + referenceName + " not found."); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return reference;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public Instance getLink(String referenceName) {
		return (Instance) get(referenceName);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@SuppressWarnings("unchecked")
	@Override
	public EList<Instance> getLinks(String referenceName) {
		return (EList<Instance>) get(referenceName);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public boolean instanceOf(String className) {
		final EClass eClass = checkAndGetClass(className);
		return instanceOf(eClass);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void add(String featureName, Object value) {
		final EStructuralFeature feature = checkAndGetFeature(featureName);
		add(feature, value);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void remove(String featureName, Object value) {
		final EStructuralFeature feature = checkAndGetFeature(featureName);
		remove(feature, value);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void add(String featureName, int index, Object value) {
		final EStructuralFeature feature = checkAndGetFeature(featureName);
		add(feature, index, value);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public Instance getLink(EReference reference) {
		return (Instance) get(reference);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@SuppressWarnings("unchecked")
	@Override
	public EList<Instance> getLinks(EReference reference) {
		return (EList<Instance>) get(reference);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public Instance copy() {

		// mapping of originals to copies
		final Map<Instance, Instance> map = new HashMap<Instance, Instance>();

		// copy tree structure
		final Instance copy = copyTree(this, map);
		// copy cross references
		copyReferences(this, map);

		return copy;
	}

	/** Copy the tree structure with an instance as root. */
	private Instance copyTree(Instance original, Map<Instance, Instance> map) {
		final EClass eClass = original.getEClass();
		final Instance copi = getType().getModel().newInstance(eClass);
		for (final EReference reference : eClass.getEAllReferences()) {
			if (reference.isContainment()) {
				if (reference.isMany()) {
					for (final Instance child : original.getLinks(reference)) {
						copi.add(reference, copyTree(child, map));
					}
				} else {
					final Instance child = original.get(reference);
					if (child != null) {
						copi.set(reference, copyTree(child, map));
					}
				}
			}
		}
		for (final EAttribute attribute : eClass.getEAllAttributes()) {
			copi.set(attribute, original.get(attribute));
		}
		map.put(original, copi);
		return copi;
	}

	/** Copy cross references of an instance. */
	private void copyReferences(Instance original, Map<Instance, Instance> map) {
		final EClass eClass = original.getEClass();
		final Instance copi = map.get(original);
		for (final EReference reference : eClass.getEAllReferences()) {
			if (!reference.isContainment()) {
				if (reference.isMany()) {
					if (reference.getEOpposite() == null
						|| reference.getEOpposite().isMany()) {
						for (Instance ref : original.getLinks(reference)) {
							if (map.get(ref) != null) {
								ref = map.get(ref);
							}
							copi.add(reference, ref);
						}
					}
				} else {
					if (reference.getEOpposite() == null
						|| !reference.getEOpposite().isContainment()) {
						Instance ref = original.get(reference);
						if (ref != null) {
							if (map.get(ref) != null) {
								ref = map.get(ref);
							}
							copi.set(reference, ref);
						}
					}
				}
			}
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public EList<Instance> getInverse(EReference reference) {
		final List<ReferenceSlot> slots = getReferences();
		final EList<Instance> instances = new BasicEList<Instance>();
		for (final ReferenceSlot slot : slots) {
			if (reference == slot.getEReference()) {
				instances.add(slot.getInstance());
			}
		}
		return instances;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void migrate(EClass eClass) {
		final Type oldType = getType();
		if (eClass != oldType.getEClass()) {
			final ModelImpl model = (ModelImpl) oldType.getModel();
			model.removeDeleteType(oldType, this);
			final Type type = model.getCreateType(eClass);
			type.getInstances().add(this);
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public <V> V unset(EStructuralFeature feature) {
		final V value = this.get(feature);
		if (isSet(feature)) {
			if (feature.isMany()) {
				this.set(feature, Collections.EMPTY_LIST);
			} else {
				this.set(feature, null);
			}
		}
		return value;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void add(EStructuralFeature feature, int index, Object value) {
		if (feature instanceof EAttribute) {
			final EAttribute attribute = (EAttribute) feature;
			final AttributeSlot attributeSlot = getCreateAttributeSlot(attribute);
			if (!attribute.isUnique()
				|| !attributeSlot.getValues().contains(value)) {
				attributeSlot.getValues().add(index, value);
			}
		} else {
			final EReference reference = (EReference) feature;
			final Instance target = (Instance) value;
			if (reference.isUnique() && contains(reference, target)) {
				return;
			}
			final EReference opposite = reference.getEOpposite();
			if (opposite != null && reference.eContainer() != null) {
				// if opposite is single-valued, unset it before
				if (!opposite.isMany()) {
					target.unset(opposite);
				}
				final ReferenceSlot oppositeSlot = ((InstanceImpl) target)
					.getCreateReferenceSlot(opposite);
				oppositeSlot.getValues().add(this);
			}
			final ReferenceSlot referenceSlot = getCreateReferenceSlot(reference);
			referenceSlot.getValues().add(index, target);
		}
	}

	/**
	 * Get the slot for an instance's attribute (create one if there is none)
	 *
	 * @param attribute
	 * @return Slot
	 */
	private AttributeSlot getCreateAttributeSlot(EAttribute attribute) {

		AttributeSlot attributeSlot = (AttributeSlot) getSlot(attribute);
		if (attributeSlot == null) {
			attributeSlot = MigrationFactory.eINSTANCE.createAttributeSlot();
			attributeSlot.setEAttribute(attribute);
			getSlots().add(attributeSlot);
		}
		return attributeSlot;
	}

	/**
	 * Get the slot for an instance's reference (create one if there is none)
	 *
	 * @param reference
	 * @return Slot
	 */
	ReferenceSlot getCreateReferenceSlot(EReference reference) {

		ReferenceSlot referenceSlot = (ReferenceSlot) getSlot(reference);
		if (referenceSlot == null) {
			referenceSlot = MigrationFactory.eINSTANCE.createReferenceSlot();
			referenceSlot.setEReference(reference);
			getSlots().add(referenceSlot);
		}
		return referenceSlot;
	}

	/**
	 * Determine whether a value is contained in an instance's reference
	 *
	 * @param reference
	 * @param value
	 * @return true if it is contained, false otherwise
	 */
	private boolean contains(EReference reference, Instance value) {
		final ReferenceSlot referenceSlot = (ReferenceSlot) getSlot(reference);
		if (referenceSlot != null) {
			return referenceSlot.getValues().contains(value);
		}
		return false;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void remove(EStructuralFeature feature, Object value) {
		final SlotImpl slot = (SlotImpl) getSlot(feature);
		final int index = slot != null ? slot.getValues().indexOf(value) : 0;
		if (index >= 0) {
			this.remove(feature, index);
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public EClass getEClass() {
		return ((Instance) this).getType().getEClass();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void validate() {
		final BasicDiagnostic chain = new BasicDiagnostic();
		this.validate(chain);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public boolean validate(DiagnosticChain chain) {
		final ModelValidator validator = new ModelValidator(getType()
			.getModel());
		final Diagnostician diagnostician = new Diagnostician() {
			@Override
			public String getObjectLabel(EObject eObject) {
				final EClass eClass = eObject.eClass();
				final StringBuffer result = new StringBuffer(eClass.getName());
				if (eClass.getInstanceClassName() == null) {
					result.append('/');
					result.append(eClass.getEPackage().getNsURI());
					result.append('#');
					result.append(eClass.getName());
				}
				result.append('@');
				result.append(Integer.toHexString(eObject.hashCode()));

				return result.toString();
			}

			@Override
			public boolean validate(EClass eClass, EObject eObject,
				DiagnosticChain diagnostics, Map<Object, Object> context) {
				boolean result = validator.validate(eClass, eObject,
					diagnostics, context);
				if (result || diagnostics != null) {
					result &= doValidateContents(eObject, diagnostics, context);
				}
				return result;
			}
		};
		enableReflection();
		final boolean result = diagnostician.validate(this, chain);
		disableReflection();
		return result;
	}

	/**
	 * Disable reflection
	 */
	private void disableReflection() {
		getType().getModel().setReflection(false);
	}

	/**
	 * Enable reflection
	 */
	private void enableReflection() {
		getType().getModel().setReflection(true);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public <V> V get(String featureName) {
		final EStructuralFeature feature = checkAndGetFeature(featureName);
		return this.get(feature);
	}

	private EStructuralFeature checkAndGetFeature(String featureName) {
		final EStructuralFeature feature = getEClass().getEStructuralFeature(
			featureName);
		if (feature == null) {
			throw new IllegalArgumentException("Feature " + featureName + " not found."); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return feature;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void set(String featureName, Object value) {
		final EStructuralFeature feature = checkAndGetFeature(featureName);
		this.set(feature, value);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public boolean isSet(EStructuralFeature feature) {
		return getSlot(feature) != null;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public boolean instanceOf(EClass eClass) {
		return getEClass() == eClass
			|| getEClass().getEAllSuperTypes().contains(eClass);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public Instance getContainer() {
		for (final ReferenceSlot slot : getReferences()) {
			if (slot.getEReference().isContainment()) {
				return slot.getInstance();
			}
		}
		return null;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public EList<Instance> getContents() {
		final EList<Instance> contents = new BasicEList<Instance>();
		for (final Slot slot : getSlots()) {
			if (slot instanceof ReferenceSlot) {
				final ReferenceSlot referenceSlot = (ReferenceSlot) slot;
				if (referenceSlot.getEReference().isContainment()) {
					contents.addAll(referenceSlot.getValues());
				}
			}
		}
		return contents;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void add(EStructuralFeature feature, Object value) {
		final SlotImpl slot = (SlotImpl) getSlot(feature);
		final int index = slot != null ? slot.getValues().size() : 0;
		this.add(feature, index, value);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public void remove(EStructuralFeature feature, int index) {
		if (feature instanceof EAttribute) {
			final EAttribute attribute = (EAttribute) feature;
			removeDeleteAttribute(attribute, index);
		} else {
			final EReference reference = (EReference) feature;
			final EReference opposite = reference.getEOpposite();
			if (opposite != null && reference.eContainer() != null) {
				final ReferenceSlot referenceSlot = (ReferenceSlot) getSlot(reference);
				final Instance target = referenceSlot.getValues().get(index);
				final int oppositeIndex = ((ReferenceSlot) target.getSlot(opposite))
					.getValues().indexOf(this);
				((InstanceImpl) target).removeDeleteReference(opposite,
					oppositeIndex);
			}
			removeDeleteReference(reference, index);
		}
	}

	/**
	 * Remove a value from an instance's attribute (delete slot if it is empty)
	 *
	 * @param attribute
	 * @param index
	 */
	private void removeDeleteAttribute(EAttribute attribute, int index) {
		final AttributeSlot attributeSlot = (AttributeSlot) getSlot(attribute);
		attributeSlot.getValues().remove(index);
		if (attributeSlot.getValues().isEmpty()) {
			getSlots().remove(attributeSlot);
		}
	}

	/**
	 * Remove a value from an instance's reference (delete slot if it is empty)
	 *
	 * @param reference
	 * @param index
	 */
	void removeDeleteReference(EReference reference, int index) {

		final ReferenceSlot referenceSlot = (ReferenceSlot) getSlot(reference);
		referenceSlot.getValues().remove(index);
		if (referenceSlot.getValues().isEmpty()) {
			getSlots().remove(referenceSlot);
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd,
		int featureID, NotificationChain msgs) {
		switch (featureID) {
		case MigrationPackage.INSTANCE__SLOTS:
			return ((InternalEList<InternalEObject>) (InternalEList<?>) getSlots()).basicAdd(otherEnd, msgs);
		case MigrationPackage.INSTANCE__TYPE:
			if (eInternalContainer() != null) {
				msgs = eBasicRemoveFromContainer(msgs);
			}
			return basicSetType((Type) otherEnd, msgs);
		case MigrationPackage.INSTANCE__REFERENCES:
			return ((InternalEList<InternalEObject>) (InternalEList<?>) getReferences()).basicAdd(otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
		int featureID, NotificationChain msgs) {
		switch (featureID) {
		case MigrationPackage.INSTANCE__SLOTS:
			return ((InternalEList<?>) getSlots()).basicRemove(otherEnd, msgs);
		case MigrationPackage.INSTANCE__TYPE:
			return basicSetType(null, msgs);
		case MigrationPackage.INSTANCE__REFERENCES:
			return ((InternalEList<?>) getReferences()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public NotificationChain eBasicRemoveFromContainerFeature(
		NotificationChain msgs) {
		switch (eContainerFeatureID()) {
		case MigrationPackage.INSTANCE__TYPE:
			return eInternalContainer().eInverseRemove(this, MigrationPackage.TYPE__INSTANCES, Type.class, msgs);
		}
		return super.eBasicRemoveFromContainerFeature(msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
		case MigrationPackage.INSTANCE__SLOTS:
			return getSlots();
		case MigrationPackage.INSTANCE__TYPE:
			return getType();
		case MigrationPackage.INSTANCE__REFERENCES:
			return getReferences();
		case MigrationPackage.INSTANCE__URI:
			return getUri();
		case MigrationPackage.INSTANCE__UUID:
			return getUuid();
		}
		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 MigrationPackage.INSTANCE__SLOTS:
			getSlots().clear();
			getSlots().addAll((Collection<? extends Slot>) newValue);
			return;
		case MigrationPackage.INSTANCE__TYPE:
			setType((Type) newValue);
			return;
		case MigrationPackage.INSTANCE__REFERENCES:
			getReferences().clear();
			getReferences().addAll((Collection<? extends ReferenceSlot>) newValue);
			return;
		case MigrationPackage.INSTANCE__URI:
			setUri((URI) newValue);
			return;
		case MigrationPackage.INSTANCE__UUID:
			setUuid((String) newValue);
			return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
		case MigrationPackage.INSTANCE__SLOTS:
			getSlots().clear();
			return;
		case MigrationPackage.INSTANCE__TYPE:
			setType((Type) null);
			return;
		case MigrationPackage.INSTANCE__REFERENCES:
			getReferences().clear();
			return;
		case MigrationPackage.INSTANCE__URI:
			setUri(URI_EDEFAULT);
			return;
		case MigrationPackage.INSTANCE__UUID:
			setUuid(UUID_EDEFAULT);
			return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
		case MigrationPackage.INSTANCE__SLOTS:
			return slots != null && !slots.isEmpty();
		case MigrationPackage.INSTANCE__TYPE:
			return getType() != null;
		case MigrationPackage.INSTANCE__REFERENCES:
			return references != null && !references.isEmpty();
		case MigrationPackage.INSTANCE__URI:
			return URI_EDEFAULT == null ? uri != null : !URI_EDEFAULT.equals(uri);
		case MigrationPackage.INSTANCE__UUID:
			return UUID_EDEFAULT == null ? uuid != null : !UUID_EDEFAULT.equals(uuid);
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated NOT
	 */
	@Override
	public String toString() {
		if (eIsProxy()) {
			return super.toString();
		}

		final StringBuffer result = new StringBuffer();
		result.append("Instance of "); //$NON-NLS-1$
		result.append(getType().getEClass().getName());
		if (getUri() != null) {
			result.append(" (proxy: " + getUri() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
		} else if (getUuid() != null) {
			result.append(" (uuid: " + getUuid() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return result.toString();
	}

	// overwritten

	/**
	 * {@inheritDoc}
	 */
	@Override
	public EClass eClass() {
		if (getType().getModel().isReflection()) {
			return getEClass();
		}
		return super.eClass();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Object eGet(EStructuralFeature feature, boolean resolve,
		boolean coreType) {
		if (getType().getModel().isReflection()) {
			return get(feature);
		}
		return super.eGet(feature, resolve, coreType);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean eIsSet(EStructuralFeature feature) {
		if (getType().getModel().isReflection()) {
			return getSlot(feature) != null;
		}
		return super.eIsSet(feature);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public EList<EObject> eContents() {
		if (getType().getModel().isReflection()) {
			final EStructuralFeature[] features = ((EClassImpl.FeatureSubsetSupplier) getEClass()
				.getEAllStructuralFeatures()).containments();
			return new EContentsEList<EObject>(this, features);
		}
		return super.eContents();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public EList<EObject> eCrossReferences() {
		if (getType().getModel().isReflection()) {
			final EStructuralFeature[] features = ((EClassImpl.FeatureSubsetSupplier) getEClass()
				.getEAllStructuralFeatures()).crossReferences();
			return new EContentsEList<EObject>(this, features);
		}
		return super.eCrossReferences();
	}
} // InstanceImpl
