/*
 * Copyright (c) 2014, 2018 CEA and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   Kenn Hussey (CEA) - initial API and implementation
 *   Kenn Hussey (CEA) - 451350
 *   Kenn Hussey - 535301
 *
 */
package org.eclipse.uml2.uml.profile.standard.cdo;

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

import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.internal.cdo.CDOObjectImpl;
import org.eclipse.uml2.uml.BehavioralFeature;
import org.eclipse.uml2.uml.Usage;
import org.eclipse.uml2.uml.profile.standard.Create;
import org.eclipse.uml2.uml.profile.standard.StandardPackage;
import org.eclipse.uml2.uml.profile.standard.internal.operations.CreateOperations;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Create</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.uml2.uml.profile.standard.cdo.CreateImpl#getBase_BehavioralFeature <em>Base Behavioral Feature</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.profile.standard.cdo.CreateImpl#getBase_Usage <em>Base Usage</em>}</li>
 * </ul>
 *
 * @generated
 */
public class CreateImpl extends CDOObjectImpl implements Create {

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected int eStaticFeatureCount() {
		return 0;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public BehavioralFeature getBase_BehavioralFeature() {
		return (BehavioralFeature) eDynamicGet(StandardPackage.CREATE__BASE_BEHAVIORAL_FEATURE,
				StandardPackage.Literals.CREATE__BASE_BEHAVIORAL_FEATURE, true, true);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public BehavioralFeature basicGetBase_BehavioralFeature() {
		return (BehavioralFeature) eDynamicGet(StandardPackage.CREATE__BASE_BEHAVIORAL_FEATURE,
				StandardPackage.Literals.CREATE__BASE_BEHAVIORAL_FEATURE, false, true);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setBase_BehavioralFeature(BehavioralFeature newBase_BehavioralFeature) {
		eDynamicSet(StandardPackage.CREATE__BASE_BEHAVIORAL_FEATURE,
				StandardPackage.Literals.CREATE__BASE_BEHAVIORAL_FEATURE, newBase_BehavioralFeature);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Usage getBase_Usage() {
		return (Usage) eDynamicGet(StandardPackage.CREATE__BASE_USAGE, StandardPackage.Literals.CREATE__BASE_USAGE,
				true, true);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Usage basicGetBase_Usage() {
		return (Usage) eDynamicGet(StandardPackage.CREATE__BASE_USAGE, StandardPackage.Literals.CREATE__BASE_USAGE,
				false, true);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setBase_Usage(Usage newBase_Usage) {
		eDynamicSet(StandardPackage.CREATE__BASE_USAGE, StandardPackage.Literals.CREATE__BASE_USAGE, newBase_Usage);
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
		case StandardPackage.CREATE__BASE_BEHAVIORAL_FEATURE:
			if (resolve)
				return getBase_BehavioralFeature();
			return basicGetBase_BehavioralFeature();
		case StandardPackage.CREATE__BASE_USAGE:
			if (resolve)
				return getBase_Usage();
			return basicGetBase_Usage();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
		case StandardPackage.CREATE__BASE_BEHAVIORAL_FEATURE:
			setBase_BehavioralFeature((BehavioralFeature) newValue);
			return;
		case StandardPackage.CREATE__BASE_USAGE:
			setBase_Usage((Usage) newValue);
			return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
		case StandardPackage.CREATE__BASE_BEHAVIORAL_FEATURE:
			setBase_BehavioralFeature((BehavioralFeature) null);
			return;
		case StandardPackage.CREATE__BASE_USAGE:
			setBase_Usage((Usage) null);
			return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
		case StandardPackage.CREATE__BASE_BEHAVIORAL_FEATURE:
			return basicGetBase_BehavioralFeature() != null;
		case StandardPackage.CREATE__BASE_USAGE:
			return basicGetBase_Usage() != null;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	@SuppressWarnings("unchecked")
	public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException {
		switch (operationID) {
		case StandardPackage.CREATE___VALIDATE_CLIENT_AND_SUPPLIER_ARE_CLASSIFIERS__DIAGNOSTICCHAIN_MAP:
			return validateClientAndSupplierAreClassifiers((DiagnosticChain) arguments.get(0),
					(Map<Object, Object>) arguments.get(1));
		}
		return super.eInvoke(operationID, arguments);
	}

} //CreateImpl
