/*
 * Copyright (c) 2005, 2018 IBM Corporation, Embarcadero Technologies, 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 (Embarcadero Technologies) - 204200
 *   Kenn Hussey - 286329, 323181, 519572
 *   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.Classifier;
import org.eclipse.uml2.uml.Comment;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.ExceptionHandler;
import org.eclipse.uml2.uml.InputPin;
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.ReadIsClassifiedObjectAction;
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.VisibilityKind;

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

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Read Is Classified Object Action</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.ReadIsClassifiedObjectActionImpl#getInputs <em>Input</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.ReadIsClassifiedObjectActionImpl#getOutputs <em>Output</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.ReadIsClassifiedObjectActionImpl#getClassifier <em>Classifier</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.ReadIsClassifiedObjectActionImpl#isDirect <em>Is Direct</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.ReadIsClassifiedObjectActionImpl#getObject <em>Object</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.cdo.internal.impl.ReadIsClassifiedObjectActionImpl#getResult <em>Result</em>}</li>
 * </ul>
 *
 * @generated
 */
public class ReadIsClassifiedObjectActionImpl
		extends ActionImpl
		implements ReadIsClassifiedObjectAction {

	/**
	 * The default value of the '{@link #isDirect() <em>Is Direct</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isDirect()
	 * @generated
	 * @ordered
	 */
	protected static final boolean IS_DIRECT_EDEFAULT = false;

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return UMLPackage.Literals.READ_IS_CLASSIFIED_OBJECT_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.READ_IS_CLASSIFIED_OBJECT_ACTION__OUTPUT,
						OUTPUT_ESUBSETS));
			}
			return outputs;
		}
		return new DerivedUnionEObjectEList<OutputPin>(OutputPin.class, this,
			UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OUTPUT,
			OUTPUT_ESUBSETS);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<InputPin> getInputs() {
		CacheAdapter cache = getCacheAdapter();
		if (cache != null) {
			Resource eResource = eResource();
			@SuppressWarnings("unchecked")
			EList<InputPin> inputs = (EList<InputPin>) cache.get(eResource,
				this, UMLPackage.Literals.ACTION__INPUT);
			if (inputs == null) {
				cache.put(eResource, this, UMLPackage.Literals.ACTION__INPUT,
					inputs = new DerivedUnionEObjectEList<InputPin>(
						InputPin.class, this,
						UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__INPUT,
						INPUT_ESUBSETS));
			}
			return inputs;
		}
		return new DerivedUnionEObjectEList<InputPin>(InputPin.class, this,
			UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__INPUT, INPUT_ESUBSETS);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isDirect() {
		return (Boolean) eDynamicGet(
			UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_DIRECT
				- ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_DIRECT,
			true, true);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setIsDirect(boolean newIsDirect) {
		eDynamicSet(
			UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_DIRECT
				- ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_DIRECT,
			newIsDirect);
	}

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setClassifier(Classifier newClassifier) {
		eDynamicSet(
			UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__CLASSIFIER
				- ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.READ_IS_CLASSIFIED_OBJECT_ACTION__CLASSIFIER,
			newClassifier);
	}

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setResult(OutputPin newResult) {
		eDynamicSet(
			UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__RESULT
				- ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.READ_IS_CLASSIFIED_OBJECT_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 InputPin getObject() {
		return (InputPin) eDynamicGet(
			UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OBJECT
				- ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.READ_IS_CLASSIFIED_OBJECT_ACTION__OBJECT, true,
			true);
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetObject(InputPin newObject,
			NotificationChain msgs) {
		msgs = eDynamicInverseAdd((InternalEObject) newObject,
			UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OBJECT, msgs);
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setObject(InputPin newObject) {
		eDynamicSet(
			UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OBJECT
				- ESTATIC_FEATURE_COUNT,
			UMLPackage.Literals.READ_IS_CLASSIFIED_OBJECT_ACTION__OBJECT,
			newObject);
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public InputPin createObject(String name, Type type) {
		return createObject(name, type, UMLPackage.Literals.INPUT_PIN);
	}

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

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__EANNOTATIONS :
				return ((InternalEList<?>) getEAnnotations())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OWNED_COMMENT :
				return ((InternalEList<?>) getOwnedComments())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__NAME_EXPRESSION :
				return basicSetNameExpression(null, msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_INTERRUPTIBLE_REGION :
				return ((InternalEList<?>) getInInterruptibleRegions())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_STRUCTURED_NODE :
				return basicSetInStructuredNode(null, msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__INCOMING :
				return ((InternalEList<?>) getIncomings()).basicRemove(otherEnd,
					msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OUTGOING :
				return ((InternalEList<?>) getOutgoings()).basicRemove(otherEnd,
					msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_PARTITION :
				return ((InternalEList<?>) getInPartitions())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__HANDLER :
				return ((InternalEList<?>) getHandlers()).basicRemove(otherEnd,
					msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__LOCAL_POSTCONDITION :
				return ((InternalEList<?>) getLocalPostconditions())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__LOCAL_PRECONDITION :
				return ((InternalEList<?>) getLocalPreconditions())
					.basicRemove(otherEnd, msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OBJECT :
				return basicSetObject(null, msgs);
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__RESULT :
				return basicSetResult(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.READ_IS_CLASSIFIED_OBJECT_ACTION__EANNOTATIONS :
				return getEAnnotations();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OWNED_COMMENT :
				return getOwnedComments();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OWNED_ELEMENT :
				return getOwnedElements();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OWNER :
				if (resolve)
					return getOwner();
				return basicGetOwner();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__CLIENT_DEPENDENCY :
				return getClientDependencies();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__NAME :
				return getName();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__NAME_EXPRESSION :
				if (resolve)
					return getNameExpression();
				return basicGetNameExpression();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__NAMESPACE :
				if (resolve)
					return getNamespace();
				return basicGetNamespace();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__QUALIFIED_NAME :
				return getQualifiedName();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__VISIBILITY :
				return getVisibility();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_LEAF :
				return isLeaf();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__REDEFINED_ELEMENT :
				return getRedefinedElements();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__REDEFINITION_CONTEXT :
				return getRedefinitionContexts();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__ACTIVITY :
				if (resolve)
					return getActivity();
				return basicGetActivity();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_GROUP :
				return getInGroups();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_INTERRUPTIBLE_REGION :
				return getInInterruptibleRegions();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_STRUCTURED_NODE :
				if (resolve)
					return getInStructuredNode();
				return basicGetInStructuredNode();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__INCOMING :
				return getIncomings();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OUTGOING :
				return getOutgoings();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__REDEFINED_NODE :
				return getRedefinedNodes();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_PARTITION :
				return getInPartitions();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__HANDLER :
				return getHandlers();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__CONTEXT :
				if (resolve)
					return getContext();
				return basicGetContext();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__INPUT :
				return getInputs();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_LOCALLY_REENTRANT :
				return isLocallyReentrant();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__LOCAL_POSTCONDITION :
				return getLocalPostconditions();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__LOCAL_PRECONDITION :
				return getLocalPreconditions();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OUTPUT :
				return getOutputs();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__CLASSIFIER :
				if (resolve)
					return getClassifier();
				return basicGetClassifier();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_DIRECT :
				return isDirect();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OBJECT :
				if (resolve)
					return getObject();
				return basicGetObject();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__RESULT :
				if (resolve)
					return getResult();
				return basicGetResult();
		}
		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.READ_IS_CLASSIFIED_OBJECT_ACTION__EANNOTATIONS :
				getEAnnotations().clear();
				getEAnnotations()
					.addAll((Collection<? extends EAnnotation>) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OWNED_COMMENT :
				getOwnedComments().clear();
				getOwnedComments()
					.addAll((Collection<? extends Comment>) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__NAME :
				setName((String) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__NAME_EXPRESSION :
				setNameExpression((StringExpression) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__VISIBILITY :
				setVisibility((VisibilityKind) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_LEAF :
				setIsLeaf((Boolean) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__ACTIVITY :
				setActivity((Activity) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_INTERRUPTIBLE_REGION :
				getInInterruptibleRegions().clear();
				getInInterruptibleRegions().addAll(
					(Collection<? extends InterruptibleActivityRegion>) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_STRUCTURED_NODE :
				setInStructuredNode((StructuredActivityNode) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__INCOMING :
				getIncomings().clear();
				getIncomings()
					.addAll((Collection<? extends ActivityEdge>) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OUTGOING :
				getOutgoings().clear();
				getOutgoings()
					.addAll((Collection<? extends ActivityEdge>) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__REDEFINED_NODE :
				getRedefinedNodes().clear();
				getRedefinedNodes()
					.addAll((Collection<? extends ActivityNode>) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_PARTITION :
				getInPartitions().clear();
				getInPartitions()
					.addAll((Collection<? extends ActivityPartition>) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__HANDLER :
				getHandlers().clear();
				getHandlers()
					.addAll((Collection<? extends ExceptionHandler>) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_LOCALLY_REENTRANT :
				setIsLocallyReentrant((Boolean) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__LOCAL_POSTCONDITION :
				getLocalPostconditions().clear();
				getLocalPostconditions()
					.addAll((Collection<? extends Constraint>) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__LOCAL_PRECONDITION :
				getLocalPreconditions().clear();
				getLocalPreconditions()
					.addAll((Collection<? extends Constraint>) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__CLASSIFIER :
				setClassifier((Classifier) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_DIRECT :
				setIsDirect((Boolean) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OBJECT :
				setObject((InputPin) newValue);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__RESULT :
				setResult((OutputPin) newValue);
				return;
		}
		eDynamicSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__EANNOTATIONS :
				getEAnnotations().clear();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OWNED_COMMENT :
				getOwnedComments().clear();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__NAME :
				unsetName();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__NAME_EXPRESSION :
				setNameExpression((StringExpression) null);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__VISIBILITY :
				unsetVisibility();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_LEAF :
				setIsLeaf(IS_LEAF_EDEFAULT);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__ACTIVITY :
				setActivity((Activity) null);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_INTERRUPTIBLE_REGION :
				getInInterruptibleRegions().clear();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_STRUCTURED_NODE :
				setInStructuredNode((StructuredActivityNode) null);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__INCOMING :
				getIncomings().clear();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OUTGOING :
				getOutgoings().clear();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__REDEFINED_NODE :
				getRedefinedNodes().clear();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_PARTITION :
				getInPartitions().clear();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__HANDLER :
				getHandlers().clear();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_LOCALLY_REENTRANT :
				setIsLocallyReentrant(IS_LOCALLY_REENTRANT_EDEFAULT);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__LOCAL_POSTCONDITION :
				getLocalPostconditions().clear();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__LOCAL_PRECONDITION :
				getLocalPreconditions().clear();
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__CLASSIFIER :
				setClassifier((Classifier) null);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_DIRECT :
				setIsDirect(IS_DIRECT_EDEFAULT);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OBJECT :
				setObject((InputPin) null);
				return;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__RESULT :
				setResult((OutputPin) null);
				return;
		}
		eDynamicUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__EANNOTATIONS :
				return !getEAnnotations().isEmpty();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OWNED_COMMENT :
				return !getOwnedComments().isEmpty();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OWNED_ELEMENT :
				return isSetOwnedElements();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OWNER :
				return isSetOwner();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__CLIENT_DEPENDENCY :
				return !getClientDependencies().isEmpty();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__NAME :
				return isSetName();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__NAME_EXPRESSION :
				return basicGetNameExpression() != null;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__NAMESPACE :
				return isSetNamespace();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__QUALIFIED_NAME :
				return QUALIFIED_NAME_EDEFAULT == null
					? getQualifiedName() != null
					: !QUALIFIED_NAME_EDEFAULT.equals(getQualifiedName());
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__VISIBILITY :
				return isSetVisibility();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_LEAF :
				return isLeaf() != IS_LEAF_EDEFAULT;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__REDEFINED_ELEMENT :
				return isSetRedefinedElements();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__REDEFINITION_CONTEXT :
				return isSetRedefinitionContexts();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__ACTIVITY :
				return basicGetActivity() != null;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_GROUP :
				return isSetInGroups();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_INTERRUPTIBLE_REGION :
				return !getInInterruptibleRegions().isEmpty();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_STRUCTURED_NODE :
				return basicGetInStructuredNode() != null;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__INCOMING :
				return !getIncomings().isEmpty();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OUTGOING :
				return !getOutgoings().isEmpty();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__REDEFINED_NODE :
				return !getRedefinedNodes().isEmpty();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IN_PARTITION :
				return !getInPartitions().isEmpty();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__HANDLER :
				return !getHandlers().isEmpty();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__CONTEXT :
				return basicGetContext() != null;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__INPUT :
				return isSetInputs();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_LOCALLY_REENTRANT :
				return isLocallyReentrant() != IS_LOCALLY_REENTRANT_EDEFAULT;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__LOCAL_POSTCONDITION :
				return !getLocalPostconditions().isEmpty();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__LOCAL_PRECONDITION :
				return !getLocalPreconditions().isEmpty();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OUTPUT :
				return isSetOutputs();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__CLASSIFIER :
				return basicGetClassifier() != null;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__IS_DIRECT :
				return isDirect() != IS_DIRECT_EDEFAULT;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__OBJECT :
				return basicGetObject() != null;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION__RESULT :
				return basicGetResult() != 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.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_EANNOTATION__STRING :
				return getEAnnotation((String) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_HAS_OWNER__DIAGNOSTICCHAIN_MAP :
				return validateHasOwner((DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_NOT_OWN_SELF__DIAGNOSTICCHAIN_MAP :
				return validateNotOwnSelf((DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___ADD_KEYWORD__STRING :
				return addKeyword((String) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___APPLY_STEREOTYPE__STEREOTYPE :
				return applyStereotype((Stereotype) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___CREATE_EANNOTATION__STRING :
				return createEAnnotation((String) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___DESTROY :
				destroy();
				return null;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_KEYWORDS :
				return getKeywords();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_APPLICABLE_STEREOTYPE__STRING :
				return getApplicableStereotype((String) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_APPLICABLE_STEREOTYPES :
				return getApplicableStereotypes();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_APPLIED_STEREOTYPE__STRING :
				return getAppliedStereotype((String) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_APPLIED_STEREOTYPES :
				return getAppliedStereotypes();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_APPLIED_SUBSTEREOTYPE__STEREOTYPE_STRING :
				return getAppliedSubstereotype((Stereotype) arguments.get(0),
					(String) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_APPLIED_SUBSTEREOTYPES__STEREOTYPE :
				return getAppliedSubstereotypes((Stereotype) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_MODEL :
				return getModel();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_NEAREST_PACKAGE :
				return getNearestPackage();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_RELATIONSHIPS :
				return getRelationships();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_RELATIONSHIPS__ECLASS :
				return getRelationships((EClass) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_REQUIRED_STEREOTYPE__STRING :
				return getRequiredStereotype((String) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_REQUIRED_STEREOTYPES :
				return getRequiredStereotypes();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_SOURCE_DIRECTED_RELATIONSHIPS :
				return getSourceDirectedRelationships();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_SOURCE_DIRECTED_RELATIONSHIPS__ECLASS :
				return getSourceDirectedRelationships(
					(EClass) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_STEREOTYPE_APPLICATION__STEREOTYPE :
				return getStereotypeApplication((Stereotype) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_STEREOTYPE_APPLICATIONS :
				return getStereotypeApplications();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_TARGET_DIRECTED_RELATIONSHIPS :
				return getTargetDirectedRelationships();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_TARGET_DIRECTED_RELATIONSHIPS__ECLASS :
				return getTargetDirectedRelationships(
					(EClass) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_VALUE__STEREOTYPE_STRING :
				return getValue((Stereotype) arguments.get(0),
					(String) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___HAS_KEYWORD__STRING :
				return hasKeyword((String) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___HAS_VALUE__STEREOTYPE_STRING :
				return hasValue((Stereotype) arguments.get(0),
					(String) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___IS_STEREOTYPE_APPLICABLE__STEREOTYPE :
				return isStereotypeApplicable((Stereotype) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___IS_STEREOTYPE_APPLIED__STEREOTYPE :
				return isStereotypeApplied((Stereotype) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___IS_STEREOTYPE_REQUIRED__STEREOTYPE :
				return isStereotypeRequired((Stereotype) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___REMOVE_KEYWORD__STRING :
				return removeKeyword((String) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___SET_VALUE__STEREOTYPE_STRING_OBJECT :
				setValue((Stereotype) arguments.get(0),
					(String) arguments.get(1), arguments.get(2));
				return null;
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___UNAPPLY_STEREOTYPE__STEREOTYPE :
				return unapplyStereotype((Stereotype) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___ALL_OWNED_ELEMENTS :
				return allOwnedElements();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___MUST_BE_OWNED :
				return mustBeOwned();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_VISIBILITY_NEEDS_OWNERSHIP__DIAGNOSTICCHAIN_MAP :
				return validateVisibilityNeedsOwnership(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_HAS_QUALIFIED_NAME__DIAGNOSTICCHAIN_MAP :
				return validateHasQualifiedName(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_HAS_NO_QUALIFIED_NAME__DIAGNOSTICCHAIN_MAP :
				return validateHasNoQualifiedName(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___CREATE_DEPENDENCY__NAMEDELEMENT :
				return createDependency((NamedElement) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___CREATE_USAGE__NAMEDELEMENT :
				return createUsage((NamedElement) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_LABEL :
				return getLabel();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_LABEL__BOOLEAN :
				return getLabel((Boolean) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_NAMESPACE :
				return getNamespace();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___ALL_NAMESPACES :
				return allNamespaces();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___ALL_OWNING_PACKAGES :
				return allOwningPackages();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___IS_DISTINGUISHABLE_FROM__NAMEDELEMENT_NAMESPACE :
				return isDistinguishableFrom((NamedElement) arguments.get(0),
					(Namespace) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_QUALIFIED_NAME :
				return getQualifiedName();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___SEPARATOR :
				return separator();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_CLIENT_DEPENDENCIES :
				return getClientDependencies();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_REDEFINITION_CONSISTENT__DIAGNOSTICCHAIN_MAP :
				return validateRedefinitionConsistent(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_NON_LEAF_REDEFINITION__DIAGNOSTICCHAIN_MAP :
				return validateNonLeafRedefinition(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_REDEFINITION_CONTEXT_VALID__DIAGNOSTICCHAIN_MAP :
				return validateRedefinitionContextValid(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___IS_CONSISTENT_WITH__REDEFINABLEELEMENT :
				return isConsistentWith((RedefinableElement) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___IS_REDEFINITION_CONTEXT_VALID__REDEFINABLEELEMENT :
				return isRedefinitionContextValid(
					(RedefinableElement) arguments.get(0));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___CONTAINING_ACTIVITY :
				return containingActivity();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___GET_CONTEXT :
				return getContext();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___ALL_ACTIONS :
				return allActions();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___ALL_OWNED_NODES :
				return allOwnedNodes();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___CONTAINING_BEHAVIOR :
				return containingBehavior();
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_NO_TYPE__DIAGNOSTICCHAIN_MAP :
				return validateNoType((DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_MULTIPLICITY_OF_OUTPUT__DIAGNOSTICCHAIN_MAP :
				return validateMultiplicityOfOutput(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_BOOLEAN_RESULT__DIAGNOSTICCHAIN_MAP :
				return validateBooleanResult((DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
			case UMLPackage.READ_IS_CLASSIFIED_OBJECT_ACTION___VALIDATE_MULTIPLICITY_OF_INPUT__DIAGNOSTICCHAIN_MAP :
				return validateMultiplicityOfInput(
					(DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
		}
		return eDynamicInvoke(operationID, arguments);
	}

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

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

	/**
	 * 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.READ_IS_CLASSIFIED_OBJECT_ACTION__RESULT};

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

} //ReadIsClassifiedObjectActionImpl
