/**
 * Copyright (c) 2022 CEA LIST and others.
 *  
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-2.0/
 * 
 *   SPDX-License-Identifier: EPL-2.0
 *  
 *  Contributors:
 *  	CEA LIST - Initial API and implementation
 */
package org.eclipse.papyrus.aas.impl;

import java.util.Collection;

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

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

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

import org.eclipse.emf.ecore.impl.ENotificationImpl;

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

import org.eclipse.papyrus.aas.AASPackage;
import org.eclipse.papyrus.aas.Endpoint;
import org.eclipse.papyrus.aas.HasDataSpecification;
import org.eclipse.papyrus.aas.HasKind;
import org.eclipse.papyrus.aas.HasSemantics;
import org.eclipse.papyrus.aas.ModelingKind;
import org.eclipse.papyrus.aas.NodeId;
import org.eclipse.papyrus.aas.Reference;
import org.eclipse.papyrus.aas.SubmodelElement;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Submodel Element</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.papyrus.aas.impl.SubmodelElementImpl#getKind <em>Kind</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aas.impl.SubmodelElementImpl#getBase_HasKind_Class <em>Base Has Kind Class</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aas.impl.SubmodelElementImpl#getSemanticId <em>Semantic Id</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aas.impl.SubmodelElementImpl#getBase_HasSemantics_Class <em>Base Has Semantics Class</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aas.impl.SubmodelElementImpl#getDataSpecification <em>Data Specification</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aas.impl.SubmodelElementImpl#isDynamic <em>Is Dynamic</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aas.impl.SubmodelElementImpl#getEndPoint <em>End Point</em>}</li>
 *   <li>{@link org.eclipse.papyrus.aas.impl.SubmodelElementImpl#getNodeId <em>Node Id</em>}</li>
 * </ul>
 *
 * @generated
 */
public abstract class SubmodelElementImpl extends ReferableImpl implements SubmodelElement {
	/**
	 * The default value of the '{@link #getKind() <em>Kind</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getKind()
	 * @generated
	 * @ordered
	 */
	protected static final ModelingKind KIND_EDEFAULT = ModelingKind.TEMPLATE;

	/**
	 * The cached value of the '{@link #getKind() <em>Kind</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getKind()
	 * @generated
	 * @ordered
	 */
	protected ModelingKind kind = KIND_EDEFAULT;

	/**
	 * The cached value of the '{@link #getBase_HasKind_Class() <em>Base Has Kind Class</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBase_HasKind_Class()
	 * @generated
	 * @ordered
	 */
	protected org.eclipse.uml2.uml.Class base_HasKind_Class;

	/**
	 * The cached value of the '{@link #getSemanticId() <em>Semantic Id</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSemanticId()
	 * @generated
	 * @ordered
	 */
	protected Reference semanticId;

	/**
	 * The cached value of the '{@link #getBase_HasSemantics_Class() <em>Base Has Semantics Class</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBase_HasSemantics_Class()
	 * @generated
	 * @ordered
	 */
	protected org.eclipse.uml2.uml.Class base_HasSemantics_Class;

	/**
	 * The cached value of the '{@link #getDataSpecification() <em>Data Specification</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDataSpecification()
	 * @generated
	 * @ordered
	 */
	protected EList<Reference> dataSpecification;

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

	/**
	 * The cached value of the '{@link #isDynamic() <em>Is Dynamic</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isDynamic()
	 * @generated
	 * @ordered
	 */
	protected boolean isDynamic = IS_DYNAMIC_EDEFAULT;

	/**
	 * The cached value of the '{@link #getEndPoint() <em>End Point</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEndPoint()
	 * @generated
	 * @ordered
	 */
	protected Endpoint endPoint;

	/**
	 * The cached value of the '{@link #getNodeId() <em>Node Id</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNodeId()
	 * @generated
	 * @ordered
	 */
	protected NodeId nodeId;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public ModelingKind getKind() {
		return kind;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setKind(ModelingKind newKind) {
		ModelingKind oldKind = kind;
		kind = newKind == null ? KIND_EDEFAULT : newKind;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AASPackage.SUBMODEL_ELEMENT__KIND, oldKind, kind));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public org.eclipse.uml2.uml.Class getBase_HasKind_Class() {
		if (base_HasKind_Class != null && base_HasKind_Class.eIsProxy()) {
			InternalEObject oldBase_HasKind_Class = (InternalEObject)base_HasKind_Class;
			base_HasKind_Class = (org.eclipse.uml2.uml.Class)eResolveProxy(oldBase_HasKind_Class);
			if (base_HasKind_Class != oldBase_HasKind_Class) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, AASPackage.SUBMODEL_ELEMENT__BASE_HAS_KIND_CLASS, oldBase_HasKind_Class, base_HasKind_Class));
			}
		}
		return base_HasKind_Class;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public org.eclipse.uml2.uml.Class basicGetBase_HasKind_Class() {
		return base_HasKind_Class;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setBase_HasKind_Class(org.eclipse.uml2.uml.Class newBase_HasKind_Class) {
		org.eclipse.uml2.uml.Class oldBase_HasKind_Class = base_HasKind_Class;
		base_HasKind_Class = newBase_HasKind_Class;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AASPackage.SUBMODEL_ELEMENT__BASE_HAS_KIND_CLASS, oldBase_HasKind_Class, base_HasKind_Class));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Reference getSemanticId() {
		if (semanticId != null && semanticId.eIsProxy()) {
			InternalEObject oldSemanticId = (InternalEObject)semanticId;
			semanticId = (Reference)eResolveProxy(oldSemanticId);
			if (semanticId != oldSemanticId) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, AASPackage.SUBMODEL_ELEMENT__SEMANTIC_ID, oldSemanticId, semanticId));
			}
		}
		return semanticId;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Reference basicGetSemanticId() {
		return semanticId;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setSemanticId(Reference newSemanticId) {
		Reference oldSemanticId = semanticId;
		semanticId = newSemanticId;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AASPackage.SUBMODEL_ELEMENT__SEMANTIC_ID, oldSemanticId, semanticId));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public org.eclipse.uml2.uml.Class getBase_HasSemantics_Class() {
		if (base_HasSemantics_Class != null && base_HasSemantics_Class.eIsProxy()) {
			InternalEObject oldBase_HasSemantics_Class = (InternalEObject)base_HasSemantics_Class;
			base_HasSemantics_Class = (org.eclipse.uml2.uml.Class)eResolveProxy(oldBase_HasSemantics_Class);
			if (base_HasSemantics_Class != oldBase_HasSemantics_Class) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, AASPackage.SUBMODEL_ELEMENT__BASE_HAS_SEMANTICS_CLASS, oldBase_HasSemantics_Class, base_HasSemantics_Class));
			}
		}
		return base_HasSemantics_Class;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public org.eclipse.uml2.uml.Class basicGetBase_HasSemantics_Class() {
		return base_HasSemantics_Class;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setBase_HasSemantics_Class(org.eclipse.uml2.uml.Class newBase_HasSemantics_Class) {
		org.eclipse.uml2.uml.Class oldBase_HasSemantics_Class = base_HasSemantics_Class;
		base_HasSemantics_Class = newBase_HasSemantics_Class;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AASPackage.SUBMODEL_ELEMENT__BASE_HAS_SEMANTICS_CLASS, oldBase_HasSemantics_Class, base_HasSemantics_Class));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<Reference> getDataSpecification() {
		if (dataSpecification == null) {
			dataSpecification = new EObjectResolvingEList<Reference>(Reference.class, this, AASPackage.SUBMODEL_ELEMENT__DATA_SPECIFICATION);
		}
		return dataSpecification;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean isDynamic() {
		return isDynamic;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setIsDynamic(boolean newIsDynamic) {
		boolean oldIsDynamic = isDynamic;
		isDynamic = newIsDynamic;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AASPackage.SUBMODEL_ELEMENT__IS_DYNAMIC, oldIsDynamic, isDynamic));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Endpoint getEndPoint() {
		return endPoint;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetEndPoint(Endpoint newEndPoint, NotificationChain msgs) {
		Endpoint oldEndPoint = endPoint;
		endPoint = newEndPoint;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, AASPackage.SUBMODEL_ELEMENT__END_POINT, oldEndPoint, newEndPoint);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setEndPoint(Endpoint newEndPoint) {
		if (newEndPoint != endPoint) {
			NotificationChain msgs = null;
			if (endPoint != null)
				msgs = ((InternalEObject)endPoint).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - AASPackage.SUBMODEL_ELEMENT__END_POINT, null, msgs);
			if (newEndPoint != null)
				msgs = ((InternalEObject)newEndPoint).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - AASPackage.SUBMODEL_ELEMENT__END_POINT, null, msgs);
			msgs = basicSetEndPoint(newEndPoint, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AASPackage.SUBMODEL_ELEMENT__END_POINT, newEndPoint, newEndPoint));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NodeId getNodeId() {
		return nodeId;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetNodeId(NodeId newNodeId, NotificationChain msgs) {
		NodeId oldNodeId = nodeId;
		nodeId = newNodeId;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, AASPackage.SUBMODEL_ELEMENT__NODE_ID, oldNodeId, newNodeId);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setNodeId(NodeId newNodeId) {
		if (newNodeId != nodeId) {
			NotificationChain msgs = null;
			if (nodeId != null)
				msgs = ((InternalEObject)nodeId).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - AASPackage.SUBMODEL_ELEMENT__NODE_ID, null, msgs);
			if (newNodeId != null)
				msgs = ((InternalEObject)newNodeId).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - AASPackage.SUBMODEL_ELEMENT__NODE_ID, null, msgs);
			msgs = basicSetNodeId(newNodeId, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AASPackage.SUBMODEL_ELEMENT__NODE_ID, newNodeId, newNodeId));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case AASPackage.SUBMODEL_ELEMENT__END_POINT:
				return basicSetEndPoint(null, msgs);
			case AASPackage.SUBMODEL_ELEMENT__NODE_ID:
				return basicSetNodeId(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case AASPackage.SUBMODEL_ELEMENT__KIND:
				return getKind();
			case AASPackage.SUBMODEL_ELEMENT__BASE_HAS_KIND_CLASS:
				if (resolve) return getBase_HasKind_Class();
				return basicGetBase_HasKind_Class();
			case AASPackage.SUBMODEL_ELEMENT__SEMANTIC_ID:
				if (resolve) return getSemanticId();
				return basicGetSemanticId();
			case AASPackage.SUBMODEL_ELEMENT__BASE_HAS_SEMANTICS_CLASS:
				if (resolve) return getBase_HasSemantics_Class();
				return basicGetBase_HasSemantics_Class();
			case AASPackage.SUBMODEL_ELEMENT__DATA_SPECIFICATION:
				return getDataSpecification();
			case AASPackage.SUBMODEL_ELEMENT__IS_DYNAMIC:
				return isDynamic();
			case AASPackage.SUBMODEL_ELEMENT__END_POINT:
				return getEndPoint();
			case AASPackage.SUBMODEL_ELEMENT__NODE_ID:
				return getNodeId();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case AASPackage.SUBMODEL_ELEMENT__KIND:
				setKind((ModelingKind)newValue);
				return;
			case AASPackage.SUBMODEL_ELEMENT__BASE_HAS_KIND_CLASS:
				setBase_HasKind_Class((org.eclipse.uml2.uml.Class)newValue);
				return;
			case AASPackage.SUBMODEL_ELEMENT__SEMANTIC_ID:
				setSemanticId((Reference)newValue);
				return;
			case AASPackage.SUBMODEL_ELEMENT__BASE_HAS_SEMANTICS_CLASS:
				setBase_HasSemantics_Class((org.eclipse.uml2.uml.Class)newValue);
				return;
			case AASPackage.SUBMODEL_ELEMENT__DATA_SPECIFICATION:
				getDataSpecification().clear();
				getDataSpecification().addAll((Collection<? extends Reference>)newValue);
				return;
			case AASPackage.SUBMODEL_ELEMENT__IS_DYNAMIC:
				setIsDynamic((Boolean)newValue);
				return;
			case AASPackage.SUBMODEL_ELEMENT__END_POINT:
				setEndPoint((Endpoint)newValue);
				return;
			case AASPackage.SUBMODEL_ELEMENT__NODE_ID:
				setNodeId((NodeId)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case AASPackage.SUBMODEL_ELEMENT__KIND:
				setKind(KIND_EDEFAULT);
				return;
			case AASPackage.SUBMODEL_ELEMENT__BASE_HAS_KIND_CLASS:
				setBase_HasKind_Class((org.eclipse.uml2.uml.Class)null);
				return;
			case AASPackage.SUBMODEL_ELEMENT__SEMANTIC_ID:
				setSemanticId((Reference)null);
				return;
			case AASPackage.SUBMODEL_ELEMENT__BASE_HAS_SEMANTICS_CLASS:
				setBase_HasSemantics_Class((org.eclipse.uml2.uml.Class)null);
				return;
			case AASPackage.SUBMODEL_ELEMENT__DATA_SPECIFICATION:
				getDataSpecification().clear();
				return;
			case AASPackage.SUBMODEL_ELEMENT__IS_DYNAMIC:
				setIsDynamic(IS_DYNAMIC_EDEFAULT);
				return;
			case AASPackage.SUBMODEL_ELEMENT__END_POINT:
				setEndPoint((Endpoint)null);
				return;
			case AASPackage.SUBMODEL_ELEMENT__NODE_ID:
				setNodeId((NodeId)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case AASPackage.SUBMODEL_ELEMENT__KIND:
				return kind != KIND_EDEFAULT;
			case AASPackage.SUBMODEL_ELEMENT__BASE_HAS_KIND_CLASS:
				return base_HasKind_Class != null;
			case AASPackage.SUBMODEL_ELEMENT__SEMANTIC_ID:
				return semanticId != null;
			case AASPackage.SUBMODEL_ELEMENT__BASE_HAS_SEMANTICS_CLASS:
				return base_HasSemantics_Class != null;
			case AASPackage.SUBMODEL_ELEMENT__DATA_SPECIFICATION:
				return dataSpecification != null && !dataSpecification.isEmpty();
			case AASPackage.SUBMODEL_ELEMENT__IS_DYNAMIC:
				return isDynamic != IS_DYNAMIC_EDEFAULT;
			case AASPackage.SUBMODEL_ELEMENT__END_POINT:
				return endPoint != null;
			case AASPackage.SUBMODEL_ELEMENT__NODE_ID:
				return nodeId != null;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
		if (baseClass == HasKind.class) {
			switch (derivedFeatureID) {
				case AASPackage.SUBMODEL_ELEMENT__KIND: return AASPackage.HAS_KIND__KIND;
				case AASPackage.SUBMODEL_ELEMENT__BASE_HAS_KIND_CLASS: return AASPackage.HAS_KIND__BASE_HAS_KIND_CLASS;
				default: return -1;
			}
		}
		if (baseClass == HasSemantics.class) {
			switch (derivedFeatureID) {
				case AASPackage.SUBMODEL_ELEMENT__SEMANTIC_ID: return AASPackage.HAS_SEMANTICS__SEMANTIC_ID;
				case AASPackage.SUBMODEL_ELEMENT__BASE_HAS_SEMANTICS_CLASS: return AASPackage.HAS_SEMANTICS__BASE_HAS_SEMANTICS_CLASS;
				default: return -1;
			}
		}
		if (baseClass == HasDataSpecification.class) {
			switch (derivedFeatureID) {
				case AASPackage.SUBMODEL_ELEMENT__DATA_SPECIFICATION: return AASPackage.HAS_DATA_SPECIFICATION__DATA_SPECIFICATION;
				default: return -1;
			}
		}
		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
		if (baseClass == HasKind.class) {
			switch (baseFeatureID) {
				case AASPackage.HAS_KIND__KIND: return AASPackage.SUBMODEL_ELEMENT__KIND;
				case AASPackage.HAS_KIND__BASE_HAS_KIND_CLASS: return AASPackage.SUBMODEL_ELEMENT__BASE_HAS_KIND_CLASS;
				default: return -1;
			}
		}
		if (baseClass == HasSemantics.class) {
			switch (baseFeatureID) {
				case AASPackage.HAS_SEMANTICS__SEMANTIC_ID: return AASPackage.SUBMODEL_ELEMENT__SEMANTIC_ID;
				case AASPackage.HAS_SEMANTICS__BASE_HAS_SEMANTICS_CLASS: return AASPackage.SUBMODEL_ELEMENT__BASE_HAS_SEMANTICS_CLASS;
				default: return -1;
			}
		}
		if (baseClass == HasDataSpecification.class) {
			switch (baseFeatureID) {
				case AASPackage.HAS_DATA_SPECIFICATION__DATA_SPECIFICATION: return AASPackage.SUBMODEL_ELEMENT__DATA_SPECIFICATION;
				default: return -1;
			}
		}
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuilder result = new StringBuilder(super.toString());
		result.append(" (kind: ");
		result.append(kind);
		result.append(", isDynamic: ");
		result.append(isDynamic);
		result.append(')');
		return result.toString();
	}

} //SubmodelElementImpl
