/*******************************************************************************
 * 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 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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 || feature.isUnsettable()) {
					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;
			}

			@Override
			protected boolean doValidateContents(EObject eObject, DiagnosticChain diagnostics,
				Map<Object, Object> context) {
				return super.doValidateContents(eObject, diagnostics, context);
			}
		};
		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
