/*
 * 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 - 286329, 323181
 *   Kenn Hussey (CEA) - 327039, 351774, 418466, 451350, 485756
 *
 */
package org.eclipse.uml2.uml.cdo.internal.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Map;

import org.eclipse.emf.common.notify.NotificationChain;

import org.eclipse.emf.common.util.DiagnosticChain;

import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.resource.Resource;

import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.uml2.common.util.CacheAdapter;
import org.eclipse.uml2.common.util.DerivedUnionEObjectEList;

import org.eclipse.uml2.uml.Activity;
import org.eclipse.uml2.uml.ActivityEdge;
import org.eclipse.uml2.uml.ActivityNode;
import org.eclipse.uml2.uml.ActivityPartition;
import org.eclipse.uml2.uml.Comment;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.ExceptionHandler;
import org.eclipse.uml2.uml.InterruptibleActivityRegion;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Namespace;
import org.eclipse.uml2.uml.OutputPin;
import org.eclipse.uml2.uml.RedefinableElement;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.StringExpression;
import org.eclipse.uml2.uml.StructuredActivityNode;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.ValueSpecification;
import org.eclipse.uml2.uml.ValueSpecificationAction;
import org.eclipse.uml2.uml.VisibilityKind;

import org.eclipse.uml2.uml.internal.operations.ValueSpecificationActionOperations;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Value Specification Action</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.ValueSpecificationActionImpl#getOutputs <em>Output</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.ValueSpecificationActionImpl#getOwnedElements <em>Owned Element</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.ValueSpecificationActionImpl#getResult <em>Result</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.ValueSpecificationActionImpl#getValue <em>Value</em>}</li>
 * </ul>
 *
 * @generated
 */
public class ValueSpecificationActionImpl
		extends ActionImpl
		implements ValueSpecificationAction {

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<OutputPin> getOutputs() {
		CacheAdapter cache = getCacheAdapter();
		if (cache != null) {
			Resource eResource = eResource();
			@SuppressWarnings("unchecked")
			EList<OutputPin> outputs = (EList<OutputPin>) cache.get(eResource,
				this, UMLPackage.Literals.ACTION__OUTPUT);
			if (outputs == null) {
				cache.put(eResource, this, UMLPackage.Literals.ACTION__OUTPUT,
					outputs = new DerivedUnionEObjectEList<OutputPin>(
						OutputPin.class, this,
						UMLPackage.VALUE_SPECIFICATION_ACTION__OUTPUT,
						OUTPUT_ESUBSETS));
			}
			return outputs;
		}
		return new DerivedUnionEObjectEList<OutputPin>(OutputPin.class, this,
			UMLPackage.VALUE_SPECIFICATION_ACTION__OUTPUT, OUTPUT_ESUBSETS);
	}

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetValue(ValueSpecification newValue,
			NotificationChain msgs) {
		msgs = eDynamicInverseAdd((InternalEObject) newValue,
			UMLPackage.VALUE_SPECIFICATION_ACTION__VALUE, msgs);
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setValue(ValueSpecification newValue) {
		eDynamicSet(
			UMLPackage.VALUE_SPECIFICATION_ACTION__VALUE
				- ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.VALUE_SPECIFICATION_ACTION__VALUE, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ValueSpecification createValue(String name, Type type,
			EClass eClass) {
		ValueSpecification newValue = (ValueSpecification) create(eClass);
		setValue(newValue);
		if (name != null)
			newValue.setName(name);
		if (type != null)
			newValue.setType(type);
		return newValue;
	}

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetResult(OutputPin newResult,
			NotificationChain msgs) {
		msgs = eDynamicInverseAdd((InternalEObject) newResult,
			UMLPackage.VALUE_SPECIFICATION_ACTION__RESULT, msgs);
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setResult(OutputPin newResult) {
		eDynamicSet(
			UMLPackage.VALUE_SPECIFICATION_ACTION__RESULT
				- ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.VALUE_SPECIFICATION_ACTION__RESULT, newResult);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public OutputPin createResult(String name, Type type) {
		OutputPin newResult = (OutputPin) create(
			UMLPackage.Literals.OUTPUT_PIN);
		setResult(newResult);
		if (name != null)
			newResult.setName(name);
		if (type != null)
			newResult.setType(type);
		return newResult;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean validateCompatibleType(DiagnosticChain diagnostics,
			Map<Object, Object> context) {
		return ValueSpecificationActionOperations.validateCompatibleType(this,
			diagnostics, context);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean validateMultiplicity(DiagnosticChain diagnostics,
			Map<Object, Object> context) {
		return ValueSpecificationActionOperations.validateMultiplicity(this,
			diagnostics, context);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case UMLPackage.VALUE_SPECIFICATION_ACTION__EANNOTATIONS :
				return ((InternalEList<?>) getEAnnotations())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OWNED_COMMENT :
				return ((InternalEList<?>) getOwnedComments())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__NAME_EXPRESSION :
				return basicSetNameExpression(null, msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_INTERRUPTIBLE_REGION :
				return ((InternalEList<?>) getInInterruptibleRegions())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_STRUCTURED_NODE :
				return basicSetInStructuredNode(null, msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__INCOMING :
				return ((InternalEList<?>) getIncomings()).basicRemove(otherEnd,
					msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OUTGOING :
				return ((InternalEList<?>) getOutgoings()).basicRemove(otherEnd,
					msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_PARTITION :
				return ((InternalEList<?>) getInPartitions())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__HANDLER :
				return ((InternalEList<?>) getHandlers()).basicRemove(otherEnd,
					msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_POSTCONDITION :
				return ((InternalEList<?>) getLocalPostconditions())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_PRECONDITION :
				return ((InternalEList<?>) getLocalPreconditions())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__RESULT :
				return basicSetResult(null, msgs);
			case UMLPackage.VALUE_SPECIFICATION_ACTION__VALUE :
				return basicSetValue(null, msgs);
		}
		return eDynamicInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case UMLPackage.VALUE_SPECIFICATION_ACTION__EANNOTATIONS :
				return getEAnnotations();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OWNED_COMMENT :
				return getOwnedComments();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OWNED_ELEMENT :
				return getOwnedElements();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OWNER :
				if (resolve)
					return getOwner();
				return basicGetOwner();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__CLIENT_DEPENDENCY :
				return getClientDependencies();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__NAME :
				return getName();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__NAME_EXPRESSION :
				if (resolve)
					return getNameExpression();
				return basicGetNameExpression();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__NAMESPACE :
				if (resolve)
					return getNamespace();
				return basicGetNamespace();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__QUALIFIED_NAME :
				return getQualifiedName();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__VISIBILITY :
				return getVisibility();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IS_LEAF :
				return isLeaf();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__REDEFINED_ELEMENT :
				return getRedefinedElements();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__REDEFINITION_CONTEXT :
				return getRedefinitionContexts();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__ACTIVITY :
				if (resolve)
					return getActivity();
				return basicGetActivity();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_GROUP :
				return getInGroups();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_INTERRUPTIBLE_REGION :
				return getInInterruptibleRegions();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_STRUCTURED_NODE :
				if (resolve)
					return getInStructuredNode();
				return basicGetInStructuredNode();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__INCOMING :
				return getIncomings();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OUTGOING :
				return getOutgoings();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__REDEFINED_NODE :
				return getRedefinedNodes();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_PARTITION :
				return getInPartitions();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__HANDLER :
				return getHandlers();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__CONTEXT :
				if (resolve)
					return getContext();
				return basicGetContext();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__INPUT :
				return getInputs();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IS_LOCALLY_REENTRANT :
				return isLocallyReentrant();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_POSTCONDITION :
				return getLocalPostconditions();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_PRECONDITION :
				return getLocalPreconditions();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OUTPUT :
				return getOutputs();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__RESULT :
				if (resolve)
					return getResult();
				return basicGetResult();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__VALUE :
				if (resolve)
					return getValue();
				return basicGetValue();
		}
		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.VALUE_SPECIFICATION_ACTION__EANNOTATIONS :
				getEAnnotations().clear();
				getEAnnotations()
					.addAll((Collection<? extends EAnnotation>) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OWNED_COMMENT :
				getOwnedComments().clear();
				getOwnedComments()
					.addAll((Collection<? extends Comment>) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__NAME :
				setName((String) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__NAME_EXPRESSION :
				setNameExpression((StringExpression) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__VISIBILITY :
				setVisibility((VisibilityKind) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IS_LEAF :
				setIsLeaf((Boolean) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__ACTIVITY :
				setActivity((Activity) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_INTERRUPTIBLE_REGION :
				getInInterruptibleRegions().clear();
				getInInterruptibleRegions().addAll(
					(Collection<? extends InterruptibleActivityRegion>) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_STRUCTURED_NODE :
				setInStructuredNode((StructuredActivityNode) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__INCOMING :
				getIncomings().clear();
				getIncomings()
					.addAll((Collection<? extends ActivityEdge>) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OUTGOING :
				getOutgoings().clear();
				getOutgoings()
					.addAll((Collection<? extends ActivityEdge>) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__REDEFINED_NODE :
				getRedefinedNodes().clear();
				getRedefinedNodes()
					.addAll((Collection<? extends ActivityNode>) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_PARTITION :
				getInPartitions().clear();
				getInPartitions()
					.addAll((Collection<? extends ActivityPartition>) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__HANDLER :
				getHandlers().clear();
				getHandlers()
					.addAll((Collection<? extends ExceptionHandler>) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IS_LOCALLY_REENTRANT :
				setIsLocallyReentrant((Boolean) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_POSTCONDITION :
				getLocalPostconditions().clear();
				getLocalPostconditions()
					.addAll((Collection<? extends Constraint>) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_PRECONDITION :
				getLocalPreconditions().clear();
				getLocalPreconditions()
					.addAll((Collection<? extends Constraint>) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__RESULT :
				setResult((OutputPin) newValue);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__VALUE :
				setValue((ValueSpecification) newValue);
				return;
		}
		eDynamicSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case UMLPackage.VALUE_SPECIFICATION_ACTION__EANNOTATIONS :
				getEAnnotations().clear();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OWNED_COMMENT :
				getOwnedComments().clear();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__NAME :
				unsetName();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__NAME_EXPRESSION :
				setNameExpression((StringExpression) null);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__VISIBILITY :
				unsetVisibility();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IS_LEAF :
				setIsLeaf(IS_LEAF_EDEFAULT);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__ACTIVITY :
				setActivity((Activity) null);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_INTERRUPTIBLE_REGION :
				getInInterruptibleRegions().clear();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_STRUCTURED_NODE :
				setInStructuredNode((StructuredActivityNode) null);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__INCOMING :
				getIncomings().clear();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OUTGOING :
				getOutgoings().clear();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__REDEFINED_NODE :
				getRedefinedNodes().clear();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_PARTITION :
				getInPartitions().clear();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__HANDLER :
				getHandlers().clear();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IS_LOCALLY_REENTRANT :
				setIsLocallyReentrant(IS_LOCALLY_REENTRANT_EDEFAULT);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_POSTCONDITION :
				getLocalPostconditions().clear();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_PRECONDITION :
				getLocalPreconditions().clear();
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__RESULT :
				setResult((OutputPin) null);
				return;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__VALUE :
				setValue((ValueSpecification) null);
				return;
		}
		eDynamicUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case UMLPackage.VALUE_SPECIFICATION_ACTION__EANNOTATIONS :
				return !getEAnnotations().isEmpty();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OWNED_COMMENT :
				return !getOwnedComments().isEmpty();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OWNED_ELEMENT :
				return isSetOwnedElements();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OWNER :
				return isSetOwner();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__CLIENT_DEPENDENCY :
				return !getClientDependencies().isEmpty();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__NAME :
				return isSetName();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__NAME_EXPRESSION :
				return basicGetNameExpression() != null;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__NAMESPACE :
				return isSetNamespace();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__QUALIFIED_NAME :
				return QUALIFIED_NAME_EDEFAULT == null
					? getQualifiedName() != null
					: !QUALIFIED_NAME_EDEFAULT.equals(getQualifiedName());
			case UMLPackage.VALUE_SPECIFICATION_ACTION__VISIBILITY :
				return isSetVisibility();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IS_LEAF :
				return isLeaf() != IS_LEAF_EDEFAULT;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__REDEFINED_ELEMENT :
				return isSetRedefinedElements();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__REDEFINITION_CONTEXT :
				return isSetRedefinitionContexts();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__ACTIVITY :
				return basicGetActivity() != null;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_GROUP :
				return isSetInGroups();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_INTERRUPTIBLE_REGION :
				return !getInInterruptibleRegions().isEmpty();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_STRUCTURED_NODE :
				return basicGetInStructuredNode() != null;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__INCOMING :
				return !getIncomings().isEmpty();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OUTGOING :
				return !getOutgoings().isEmpty();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__REDEFINED_NODE :
				return !getRedefinedNodes().isEmpty();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IN_PARTITION :
				return !getInPartitions().isEmpty();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__HANDLER :
				return !getHandlers().isEmpty();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__CONTEXT :
				return basicGetContext() != null;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__INPUT :
				return isSetInputs();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__IS_LOCALLY_REENTRANT :
				return isLocallyReentrant() != IS_LOCALLY_REENTRANT_EDEFAULT;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_POSTCONDITION :
				return !getLocalPostconditions().isEmpty();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_PRECONDITION :
				return !getLocalPreconditions().isEmpty();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__OUTPUT :
				return isSetOutputs();
			case UMLPackage.VALUE_SPECIFICATION_ACTION__RESULT :
				return basicGetResult() != null;
			case UMLPackage.VALUE_SPECIFICATION_ACTION__VALUE :
				return basicGetValue() != null;
		}
		return eDynamicIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	@SuppressWarnings("unchecked")
	public Object eInvoke(int operationID, EList<?> arguments)
			throws InvocationTargetException {
		switch (operationID) {
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_EANNOTATION__STRING :
				return getEAnnotation((String) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___VALIDATE_HAS_OWNER__DIAGNOSTICCHAIN_MAP :
				return validateHasOwner((DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___VALIDATE_NOT_OWN_SELF__DIAGNOSTICCHAIN_MAP :
				return validateNotOwnSelf((DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___ADD_KEYWORD__STRING :
				return addKeyword((String) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___APPLY_STEREOTYPE__STEREOTYPE :
				return applyStereotype((Stereotype) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___CREATE_EANNOTATION__STRING :
				return createEAnnotation((String) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___DESTROY :
				destroy();
				return null;
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_KEYWORDS :
				return getKeywords();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_APPLICABLE_STEREOTYPE__STRING :
				return getApplicableStereotype((String) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_APPLICABLE_STEREOTYPES :
				return getApplicableStereotypes();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_APPLIED_STEREOTYPE__STRING :
				return getAppliedStereotype((String) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_APPLIED_STEREOTYPES :
				return getAppliedStereotypes();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_APPLIED_SUBSTEREOTYPE__STEREOTYPE_STRING :
				return getAppliedSubstereotype((Stereotype) arguments.get(0),
					(String) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_APPLIED_SUBSTEREOTYPES__STEREOTYPE :
				return getAppliedSubstereotypes((Stereotype) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_MODEL :
				return getModel();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_NEAREST_PACKAGE :
				return getNearestPackage();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_RELATIONSHIPS :
				return getRelationships();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_RELATIONSHIPS__ECLASS :
				return getRelationships((EClass) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_REQUIRED_STEREOTYPE__STRING :
				return getRequiredStereotype((String) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_REQUIRED_STEREOTYPES :
				return getRequiredStereotypes();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_SOURCE_DIRECTED_RELATIONSHIPS :
				return getSourceDirectedRelationships();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_SOURCE_DIRECTED_RELATIONSHIPS__ECLASS :
				return getSourceDirectedRelationships(
					(EClass) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_STEREOTYPE_APPLICATION__STEREOTYPE :
				return getStereotypeApplication((Stereotype) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_STEREOTYPE_APPLICATIONS :
				return getStereotypeApplications();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_TARGET_DIRECTED_RELATIONSHIPS :
				return getTargetDirectedRelationships();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_TARGET_DIRECTED_RELATIONSHIPS__ECLASS :
				return getTargetDirectedRelationships(
					(EClass) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_VALUE__STEREOTYPE_STRING :
				return getValue((Stereotype) arguments.get(0),
					(String) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___HAS_KEYWORD__STRING :
				return hasKeyword((String) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___HAS_VALUE__STEREOTYPE_STRING :
				return hasValue((Stereotype) arguments.get(0),
					(String) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___IS_STEREOTYPE_APPLICABLE__STEREOTYPE :
				return isStereotypeApplicable((Stereotype) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___IS_STEREOTYPE_APPLIED__STEREOTYPE :
				return isStereotypeApplied((Stereotype) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___IS_STEREOTYPE_REQUIRED__STEREOTYPE :
				return isStereotypeRequired((Stereotype) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___REMOVE_KEYWORD__STRING :
				return removeKeyword((String) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___SET_VALUE__STEREOTYPE_STRING_OBJECT :
				setValue((Stereotype) arguments.get(0),
					(String) arguments.get(1), arguments.get(2));
				return null;
			case UMLPackage.VALUE_SPECIFICATION_ACTION___UNAPPLY_STEREOTYPE__STEREOTYPE :
				return unapplyStereotype((Stereotype) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___ALL_OWNED_ELEMENTS :
				return allOwnedElements();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___MUST_BE_OWNED :
				return mustBeOwned();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___VALIDATE_VISIBILITY_NEEDS_OWNERSHIP__DIAGNOSTICCHAIN_MAP :
				return validateVisibilityNeedsOwnership(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___VALIDATE_HAS_QUALIFIED_NAME__DIAGNOSTICCHAIN_MAP :
				return validateHasQualifiedName(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___VALIDATE_HAS_NO_QUALIFIED_NAME__DIAGNOSTICCHAIN_MAP :
				return validateHasNoQualifiedName(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___CREATE_DEPENDENCY__NAMEDELEMENT :
				return createDependency((NamedElement) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___CREATE_USAGE__NAMEDELEMENT :
				return createUsage((NamedElement) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_LABEL :
				return getLabel();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_LABEL__BOOLEAN :
				return getLabel((Boolean) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_NAMESPACE :
				return getNamespace();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___ALL_NAMESPACES :
				return allNamespaces();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___ALL_OWNING_PACKAGES :
				return allOwningPackages();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___IS_DISTINGUISHABLE_FROM__NAMEDELEMENT_NAMESPACE :
				return isDistinguishableFrom((NamedElement) arguments.get(0),
					(Namespace) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_QUALIFIED_NAME :
				return getQualifiedName();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___SEPARATOR :
				return separator();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_CLIENT_DEPENDENCIES :
				return getClientDependencies();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___VALIDATE_REDEFINITION_CONSISTENT__DIAGNOSTICCHAIN_MAP :
				return validateRedefinitionConsistent(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___VALIDATE_NON_LEAF_REDEFINITION__DIAGNOSTICCHAIN_MAP :
				return validateNonLeafRedefinition(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___VALIDATE_REDEFINITION_CONTEXT_VALID__DIAGNOSTICCHAIN_MAP :
				return validateRedefinitionContextValid(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___IS_CONSISTENT_WITH__REDEFINABLEELEMENT :
				return isConsistentWith((RedefinableElement) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___IS_REDEFINITION_CONTEXT_VALID__REDEFINABLEELEMENT :
				return isRedefinitionContextValid(
					(RedefinableElement) arguments.get(0));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___CONTAINING_ACTIVITY :
				return containingActivity();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___GET_CONTEXT :
				return getContext();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___ALL_ACTIONS :
				return allActions();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___ALL_OWNED_NODES :
				return allOwnedNodes();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___CONTAINING_BEHAVIOR :
				return containingBehavior();
			case UMLPackage.VALUE_SPECIFICATION_ACTION___VALIDATE_MULTIPLICITY__DIAGNOSTICCHAIN_MAP :
				return validateMultiplicity((DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.VALUE_SPECIFICATION_ACTION___VALIDATE_COMPATIBLE_TYPE__DIAGNOSTICCHAIN_MAP :
				return validateCompatibleType(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
		}
		return eDynamicInvoke(operationID, arguments);
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<Element> getOwnedElements() {
		CacheAdapter cache = getCacheAdapter();
		if (cache != null) {
			Resource eResource = eResource();
			@SuppressWarnings("unchecked")
			EList<Element> ownedElements = (EList<Element>) cache.get(eResource,
				this, UMLPackage.Literals.ELEMENT__OWNED_ELEMENT);
			if (ownedElements == null) {
				cache.put(eResource, this,
					UMLPackage.Literals.ELEMENT__OWNED_ELEMENT,
					ownedElements = new DerivedUnionEObjectEList<Element>(
						Element.class, this,
						UMLPackage.VALUE_SPECIFICATION_ACTION__OWNED_ELEMENT,
						OWNED_ELEMENT_ESUBSETS));
			}
			return ownedElements;
		}
		return new DerivedUnionEObjectEList<Element>(Element.class, this,
			UMLPackage.VALUE_SPECIFICATION_ACTION__OWNED_ELEMENT,
			OWNED_ELEMENT_ESUBSETS);
	}

	/**
	 * The array of subset feature identifiers for the '{@link #getOwnedElements() <em>Owned Element</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getOwnedElements()
	 * @generated
	 * @ordered
	 */
	protected static final int[] OWNED_ELEMENT_ESUBSETS = new int[]{
		UMLPackage.VALUE_SPECIFICATION_ACTION__OWNED_COMMENT,
		UMLPackage.VALUE_SPECIFICATION_ACTION__NAME_EXPRESSION,
		UMLPackage.VALUE_SPECIFICATION_ACTION__HANDLER,
		UMLPackage.VALUE_SPECIFICATION_ACTION__INPUT,
		UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_POSTCONDITION,
		UMLPackage.VALUE_SPECIFICATION_ACTION__LOCAL_PRECONDITION,
		UMLPackage.VALUE_SPECIFICATION_ACTION__OUTPUT,
		UMLPackage.VALUE_SPECIFICATION_ACTION__VALUE};

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

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

} //ValueSpecificationActionImpl
