/*
 * Copyright (c) 2005, 2016 IBM Corporation, CEA, 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:
 *   IBM - initial API and implementation
 *   Kenn Hussey (CEA) - 327039, 418466, 451350, 485756
 *
 */
package org.eclipse.uml2.uml.cdo.internal.impl;

import java.util.Collection;

import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.uml2.uml.cdo.internal.util.SubsetSupersetEObjectResolvingEList;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Comment;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.OpaqueExpression;
import org.eclipse.uml2.uml.StringExpression;
import org.eclipse.uml2.uml.Substitution;
import org.eclipse.uml2.uml.TemplateParameter;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.VisibilityKind;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Substitution</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.SubstitutionImpl#getOwner <em>Owner</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.SubstitutionImpl#getSuppliers <em>Supplier</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.SubstitutionImpl#getClients <em>Client</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.SubstitutionImpl#getContract <em>Contract</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.SubstitutionImpl#getSubstitutingClassifier <em>Substituting Classifier</em>}</li>
 * </ul>
 *
 * @generated
 */
public class SubstitutionImpl
		extends RealizationImpl
		implements Substitution {

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

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

	@Override
	protected EList<?> createList(EStructuralFeature eStructuralFeature) {
		EList<?> result = createSpecialList(eStructuralFeature);
		if (result != null) {
			return result;
		}
		
		return super.createList(eStructuralFeature);
	}
	
	private EList<?> createSpecialList(EStructuralFeature eStructuralFeature) {
		if (eStructuralFeature == UMLPackage.Literals.DEPENDENCY__CLIENT) {
			return createClientsList();
		}

		if (eStructuralFeature == UMLPackage.Literals.DEPENDENCY__SUPPLIER) {
			return createSuppliersList();
		}

		return null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Element getOwner() {
		Element owner = basicGetOwner();
		return owner != null && owner.eIsProxy()
			? (Element) eResolveProxy((InternalEObject) owner)
			: owner;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Element basicGetOwner() {
		Classifier substitutingClassifier = basicGetSubstitutingClassifier();
		if (substitutingClassifier != null) {
			return substitutingClassifier;
		}
		return super.basicGetOwner();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	@SuppressWarnings("unchecked")
	public EList<NamedElement> getSuppliers() {
		return (EList<NamedElement>) eDynamicGet(
			UMLPackage.SUBSTITUTION__SUPPLIER - ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.DEPENDENCY__SUPPLIER, true, true);
	}

	private EList<NamedElement> createSuppliersList() {
		return new SubsetSupersetEObjectResolvingEList<NamedElement>(
			NamedElement.class, this, UMLPackage.SUBSTITUTION__SUPPLIER, null,
			SUPPLIER_ESUBSETS);
	}

	/**
	 * The array of subset feature identifiers for the '{@link #getSuppliers() <em>Supplier</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSuppliers()
	 * @generated
	 * @ordered
	 */
	protected static final int[] SUPPLIER_ESUBSETS = new int[]{
		UMLPackage.SUBSTITUTION__CONTRACT};

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	@SuppressWarnings("unchecked")
	public EList<NamedElement> getClients() {
		return (EList<NamedElement>) eDynamicGet(
			UMLPackage.SUBSTITUTION__CLIENT - ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.DEPENDENCY__CLIENT, true, true);
	}

	private EList<NamedElement> createClientsList() {
		return new SubsetSupersetEObjectResolvingEList<NamedElement>(
			NamedElement.class, this, UMLPackage.SUBSTITUTION__CLIENT, null,
			CLIENT_ESUBSETS);
	}

	/**
	 * The array of subset feature identifiers for the '{@link #getClients() <em>Client</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getClients()
	 * @generated
	 * @ordered
	 */
	protected static final int[] CLIENT_ESUBSETS = new int[]{
		UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER};

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Classifier getContract() {
		return (Classifier) eDynamicGet(
			UMLPackage.SUBSTITUTION__CONTRACT - ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.SUBSTITUTION__CONTRACT, true, true);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Classifier basicGetContract() {
		return (Classifier) eDynamicGet(
			UMLPackage.SUBSTITUTION__CONTRACT - ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.SUBSTITUTION__CONTRACT, false, true);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setContract(Classifier newContract) {
		eDynamicSet(UMLPackage.SUBSTITUTION__CONTRACT - ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.SUBSTITUTION__CONTRACT, newContract);
		Resource.Internal eInternalResource = eInternalResource();
		if (eInternalResource == null || !eInternalResource.isLoading()) {
			if (newContract != null) {
				EList<NamedElement> suppliers = getSuppliers();
				if (!suppliers.contains(newContract)) {
					suppliers.add(newContract);
				}
			}
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Classifier getSubstitutingClassifier() {
		return (Classifier) eDynamicGet(
			UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER
				- ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.SUBSTITUTION__SUBSTITUTING_CLASSIFIER, true,
			true);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Classifier basicGetSubstitutingClassifier() {
		return (Classifier) eDynamicGet(
			UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER
				- ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.SUBSTITUTION__SUBSTITUTING_CLASSIFIER, false,
			true);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetSubstitutingClassifier(
			Classifier newSubstitutingClassifier, NotificationChain msgs) {
		msgs = eBasicSetContainer((InternalEObject) newSubstitutingClassifier,
			UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER, msgs);
		Resource.Internal eInternalResource = eInternalResource();
		if (eInternalResource == null || !eInternalResource.isLoading()) {
			if (newSubstitutingClassifier != null) {
				EList<NamedElement> clients = getClients();
				if (!clients.contains(newSubstitutingClassifier)) {
					clients.add(newSubstitutingClassifier);
				}
			}
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSubstitutingClassifier(
			Classifier newSubstitutingClassifier) {
		eDynamicSet(
			UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER
				- ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.SUBSTITUTION__SUBSTITUTING_CLASSIFIER,
			newSubstitutingClassifier);
		Resource.Internal eInternalResource = eInternalResource();
		if (eInternalResource == null || !eInternalResource.isLoading()) {
			if (newSubstitutingClassifier != null) {
				EList<NamedElement> clients = getClients();
				if (!clients.contains(newSubstitutingClassifier)) {
					clients.add(newSubstitutingClassifier);
				}
			}
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case UMLPackage.SUBSTITUTION__EANNOTATIONS :
				return ((InternalEList<InternalEObject>) (InternalEList<?>) getEAnnotations())
					.basicAdd(otherEnd, msgs);
			case UMLPackage.SUBSTITUTION__OWNING_TEMPLATE_PARAMETER :
				if (eInternalContainer() != null)
					msgs = eBasicRemoveFromContainer(msgs);
				return basicSetOwningTemplateParameter(
					(TemplateParameter) otherEnd, msgs);
			case UMLPackage.SUBSTITUTION__TEMPLATE_PARAMETER :
				TemplateParameter templateParameter = basicGetTemplateParameter();
				if (templateParameter != null)
					msgs = ((InternalEObject) templateParameter).eInverseRemove(
						this,
						UMLPackage.TEMPLATE_PARAMETER__PARAMETERED_ELEMENT,
						TemplateParameter.class, msgs);
				return basicSetTemplateParameter((TemplateParameter) otherEnd,
					msgs);
			case UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER :
				if (eInternalContainer() != null)
					msgs = eBasicRemoveFromContainer(msgs);
				return basicSetSubstitutingClassifier((Classifier) otherEnd,
					msgs);
		}
		return eDynamicInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case UMLPackage.SUBSTITUTION__EANNOTATIONS :
				return ((InternalEList<?>) getEAnnotations())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.SUBSTITUTION__OWNED_COMMENT :
				return ((InternalEList<?>) getOwnedComments())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.SUBSTITUTION__NAME_EXPRESSION :
				return basicSetNameExpression(null, msgs);
			case UMLPackage.SUBSTITUTION__OWNING_TEMPLATE_PARAMETER :
				return basicSetOwningTemplateParameter(null, msgs);
			case UMLPackage.SUBSTITUTION__TEMPLATE_PARAMETER :
				return basicSetTemplateParameter(null, msgs);
			case UMLPackage.SUBSTITUTION__MAPPING :
				return basicSetMapping(null, msgs);
			case UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER :
				return basicSetSubstitutingClassifier(null, msgs);
		}
		return eDynamicInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eBasicRemoveFromContainerFeature(
			NotificationChain msgs) {
		switch (eContainerFeatureID()) {
			case UMLPackage.SUBSTITUTION__OWNING_TEMPLATE_PARAMETER :
				return eInternalContainer().eInverseRemove(this,
					UMLPackage.TEMPLATE_PARAMETER__OWNED_PARAMETERED_ELEMENT,
					TemplateParameter.class, msgs);
			case UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER :
				return eInternalContainer().eInverseRemove(this,
					UMLPackage.CLASSIFIER__SUBSTITUTION, Classifier.class,
					msgs);
		}
		return eDynamicBasicRemoveFromContainer(msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case UMLPackage.SUBSTITUTION__EANNOTATIONS :
				return getEAnnotations();
			case UMLPackage.SUBSTITUTION__OWNED_COMMENT :
				return getOwnedComments();
			case UMLPackage.SUBSTITUTION__OWNED_ELEMENT :
				return getOwnedElements();
			case UMLPackage.SUBSTITUTION__OWNER :
				if (resolve)
					return getOwner();
				return basicGetOwner();
			case UMLPackage.SUBSTITUTION__CLIENT_DEPENDENCY :
				return getClientDependencies();
			case UMLPackage.SUBSTITUTION__NAME :
				return getName();
			case UMLPackage.SUBSTITUTION__NAME_EXPRESSION :
				if (resolve)
					return getNameExpression();
				return basicGetNameExpression();
			case UMLPackage.SUBSTITUTION__NAMESPACE :
				if (resolve)
					return getNamespace();
				return basicGetNamespace();
			case UMLPackage.SUBSTITUTION__QUALIFIED_NAME :
				return getQualifiedName();
			case UMLPackage.SUBSTITUTION__VISIBILITY :
				return getVisibility();
			case UMLPackage.SUBSTITUTION__OWNING_TEMPLATE_PARAMETER :
				if (resolve)
					return getOwningTemplateParameter();
				return basicGetOwningTemplateParameter();
			case UMLPackage.SUBSTITUTION__TEMPLATE_PARAMETER :
				if (resolve)
					return getTemplateParameter();
				return basicGetTemplateParameter();
			case UMLPackage.SUBSTITUTION__RELATED_ELEMENT :
				return getRelatedElements();
			case UMLPackage.SUBSTITUTION__SOURCE :
				return getSources();
			case UMLPackage.SUBSTITUTION__TARGET :
				return getTargets();
			case UMLPackage.SUBSTITUTION__CLIENT :
				return getClients();
			case UMLPackage.SUBSTITUTION__SUPPLIER :
				return getSuppliers();
			case UMLPackage.SUBSTITUTION__MAPPING :
				if (resolve)
					return getMapping();
				return basicGetMapping();
			case UMLPackage.SUBSTITUTION__CONTRACT :
				if (resolve)
					return getContract();
				return basicGetContract();
			case UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER :
				if (resolve)
					return getSubstitutingClassifier();
				return basicGetSubstitutingClassifier();
		}
		return eDynamicGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case UMLPackage.SUBSTITUTION__EANNOTATIONS :
				getEAnnotations().clear();
				getEAnnotations()
					.addAll((Collection<? extends EAnnotation>) newValue);
				return;
			case UMLPackage.SUBSTITUTION__OWNED_COMMENT :
				getOwnedComments().clear();
				getOwnedComments()
					.addAll((Collection<? extends Comment>) newValue);
				return;
			case UMLPackage.SUBSTITUTION__NAME :
				setName((String) newValue);
				return;
			case UMLPackage.SUBSTITUTION__NAME_EXPRESSION :
				setNameExpression((StringExpression) newValue);
				return;
			case UMLPackage.SUBSTITUTION__VISIBILITY :
				setVisibility((VisibilityKind) newValue);
				return;
			case UMLPackage.SUBSTITUTION__OWNING_TEMPLATE_PARAMETER :
				setOwningTemplateParameter((TemplateParameter) newValue);
				return;
			case UMLPackage.SUBSTITUTION__TEMPLATE_PARAMETER :
				setTemplateParameter((TemplateParameter) newValue);
				return;
			case UMLPackage.SUBSTITUTION__CLIENT :
				getClients().clear();
				getClients()
					.addAll((Collection<? extends NamedElement>) newValue);
				return;
			case UMLPackage.SUBSTITUTION__SUPPLIER :
				getSuppliers().clear();
				getSuppliers()
					.addAll((Collection<? extends NamedElement>) newValue);
				return;
			case UMLPackage.SUBSTITUTION__MAPPING :
				setMapping((OpaqueExpression) newValue);
				return;
			case UMLPackage.SUBSTITUTION__CONTRACT :
				setContract((Classifier) newValue);
				return;
			case UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER :
				setSubstitutingClassifier((Classifier) newValue);
				return;
		}
		eDynamicSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case UMLPackage.SUBSTITUTION__EANNOTATIONS :
				getEAnnotations().clear();
				return;
			case UMLPackage.SUBSTITUTION__OWNED_COMMENT :
				getOwnedComments().clear();
				return;
			case UMLPackage.SUBSTITUTION__NAME :
				unsetName();
				return;
			case UMLPackage.SUBSTITUTION__NAME_EXPRESSION :
				setNameExpression((StringExpression) null);
				return;
			case UMLPackage.SUBSTITUTION__VISIBILITY :
				unsetVisibility();
				return;
			case UMLPackage.SUBSTITUTION__OWNING_TEMPLATE_PARAMETER :
				setOwningTemplateParameter((TemplateParameter) null);
				return;
			case UMLPackage.SUBSTITUTION__TEMPLATE_PARAMETER :
				setTemplateParameter((TemplateParameter) null);
				return;
			case UMLPackage.SUBSTITUTION__CLIENT :
				getClients().clear();
				return;
			case UMLPackage.SUBSTITUTION__SUPPLIER :
				getSuppliers().clear();
				return;
			case UMLPackage.SUBSTITUTION__MAPPING :
				setMapping((OpaqueExpression) null);
				return;
			case UMLPackage.SUBSTITUTION__CONTRACT :
				setContract((Classifier) null);
				return;
			case UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER :
				setSubstitutingClassifier((Classifier) null);
				return;
		}
		eDynamicUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case UMLPackage.SUBSTITUTION__EANNOTATIONS :
				return !getEAnnotations().isEmpty();
			case UMLPackage.SUBSTITUTION__OWNED_COMMENT :
				return !getOwnedComments().isEmpty();
			case UMLPackage.SUBSTITUTION__OWNED_ELEMENT :
				return isSetOwnedElements();
			case UMLPackage.SUBSTITUTION__OWNER :
				return isSetOwner();
			case UMLPackage.SUBSTITUTION__CLIENT_DEPENDENCY :
				return !getClientDependencies().isEmpty();
			case UMLPackage.SUBSTITUTION__NAME :
				return isSetName();
			case UMLPackage.SUBSTITUTION__NAME_EXPRESSION :
				return basicGetNameExpression() != null;
			case UMLPackage.SUBSTITUTION__NAMESPACE :
				return isSetNamespace();
			case UMLPackage.SUBSTITUTION__QUALIFIED_NAME :
				return QUALIFIED_NAME_EDEFAULT == null
					? getQualifiedName() != null
					: !QUALIFIED_NAME_EDEFAULT.equals(getQualifiedName());
			case UMLPackage.SUBSTITUTION__VISIBILITY :
				return isSetVisibility();
			case UMLPackage.SUBSTITUTION__OWNING_TEMPLATE_PARAMETER :
				return basicGetOwningTemplateParameter() != null;
			case UMLPackage.SUBSTITUTION__TEMPLATE_PARAMETER :
				return basicGetTemplateParameter() != null;
			case UMLPackage.SUBSTITUTION__RELATED_ELEMENT :
				return isSetRelatedElements();
			case UMLPackage.SUBSTITUTION__SOURCE :
				return isSetSources();
			case UMLPackage.SUBSTITUTION__TARGET :
				return isSetTargets();
			case UMLPackage.SUBSTITUTION__CLIENT :
				return !getClients().isEmpty();
			case UMLPackage.SUBSTITUTION__SUPPLIER :
				return !getSuppliers().isEmpty();
			case UMLPackage.SUBSTITUTION__MAPPING :
				return basicGetMapping() != null;
			case UMLPackage.SUBSTITUTION__CONTRACT :
				return basicGetContract() != null;
			case UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER :
				return basicGetSubstitutingClassifier() != null;
		}
		return eDynamicIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean isSetOwner() {
		return super.isSetOwner()
			|| eIsSet(UMLPackage.SUBSTITUTION__SUBSTITUTING_CLASSIFIER);
	}

} //SubstitutionImpl
