/**
 * *******************************************************************************
 *  Copyright (c) 2015-2021 Robert Bosch GmbH and others.
 * 
 *  This program and the accompanying materials are made
 *  available under the terms of the Eclipse Public License 2.0
 *  which is available at https://www.eclipse.org/legal/epl-2.0/
 * 
 *  SPDX-License-Identifier: EPL-2.0
 * 
 *     Generated using Eclipse EMF
 * 
 * *******************************************************************************
 */
package org.eclipse.app4mc.amalthea.model.impl;

import java.lang.reflect.InvocationTargetException;

import java.util.Collection;
import org.eclipse.app4mc.amalthea.model.AmaltheaExtensions;
import org.eclipse.app4mc.amalthea.model.AmaltheaPackage;
import org.eclipse.app4mc.amalthea.model.Channel;
import org.eclipse.app4mc.amalthea.model.ComponentInterface;
import org.eclipse.app4mc.amalthea.model.Connector;
import org.eclipse.app4mc.amalthea.model.INamed;
import org.eclipse.app4mc.amalthea.model.ISystem;
import org.eclipse.app4mc.amalthea.model.ITaggable;
import org.eclipse.app4mc.amalthea.model.Namespace;
import org.eclipse.app4mc.amalthea.model.QualifiedPort;
import org.eclipse.app4mc.amalthea.model.Tag;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;

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

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

import org.eclipse.emf.ecore.util.EObjectResolvingEList;
import org.eclipse.emf.ecore.util.EcoreEMap;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.ecore.xcore.lib.XcoreCollectionLiterals;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Connector</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.ConnectorImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.ConnectorImpl#getQualifiedName <em>Qualified Name</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.ConnectorImpl#getTags <em>Tags</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.ConnectorImpl#getContainingSystem <em>Containing System</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.ConnectorImpl#getSourcePort <em>Source Port</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.ConnectorImpl#getTargetPort <em>Target Port</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.model.impl.ConnectorImpl#getImplementedInterfaces <em>Implemented Interfaces</em>}</li>
 * </ul>
 *
 * @generated
 */
public class ConnectorImpl extends BaseObjectImpl implements Connector {
	/**
	 * The default value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected static final String NAME_EDEFAULT = "";

	/**
	 * The cached value of the '{@link #getName() <em>Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getName()
	 * @generated
	 * @ordered
	 */
	protected String name = NAME_EDEFAULT;

	/**
	 * The default value of the '{@link #getQualifiedName() <em>Qualified Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getQualifiedName()
	 * @generated
	 * @ordered
	 */
	protected static final String QUALIFIED_NAME_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getTags() <em>Tags</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTags()
	 * @generated
	 * @ordered
	 */
	protected EList<Tag> tags;

	/**
	 * The cached value of the '{@link #getSourcePort() <em>Source Port</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSourcePort()
	 * @generated
	 * @ordered
	 */
	protected QualifiedPort sourcePort;

	/**
	 * The cached value of the '{@link #getTargetPort() <em>Target Port</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTargetPort()
	 * @generated
	 * @ordered
	 */
	protected QualifiedPort targetPort;

	/**
	 * The cached value of the '{@link #getImplementedInterfaces() <em>Implemented Interfaces</em>}' map.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getImplementedInterfaces()
	 * @generated
	 * @ordered
	 */
	protected EMap<ComponentInterface, Channel> implementedInterfaces;

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return AmaltheaPackage.eINSTANCE.getConnector();
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setName(String newName) {
		String oldName = name;
		name = newName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AmaltheaPackage.CONNECTOR__NAME, oldName, name));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getQualifiedName() {
		return AmaltheaExtensions.toPlainString(this.getQualifiedNameSegments(), this.getDefaultNameSeparator());
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<Tag> getTags() {
		if (tags == null) {
			tags = new EObjectResolvingEList<Tag>(Tag.class, this, AmaltheaPackage.CONNECTOR__TAGS);
		}
		return tags;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public ISystem getContainingSystem() {
		if (eContainerFeatureID() != AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM) return null;
		return (ISystem)eContainer();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ISystem basicGetContainingSystem() {
		if (eContainerFeatureID() != AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM) return null;
		return (ISystem)eInternalContainer();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetContainingSystem(ISystem newContainingSystem, NotificationChain msgs) {
		msgs = eBasicSetContainer((InternalEObject)newContainingSystem, AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM, msgs);
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setContainingSystem(ISystem newContainingSystem) {
		if (newContainingSystem != eInternalContainer() || (eContainerFeatureID() != AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM && newContainingSystem != null)) {
			if (EcoreUtil.isAncestor(this, newContainingSystem))
				throw new IllegalArgumentException("Recursive containment not allowed for " + toString());
			NotificationChain msgs = null;
			if (eInternalContainer() != null)
				msgs = eBasicRemoveFromContainer(msgs);
			if (newContainingSystem != null)
				msgs = ((InternalEObject)newContainingSystem).eInverseAdd(this, AmaltheaPackage.ISYSTEM__CONNECTORS, ISystem.class, msgs);
			msgs = basicSetContainingSystem(newContainingSystem, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM, newContainingSystem, newContainingSystem));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetSourcePort(QualifiedPort newSourcePort, NotificationChain msgs) {
		QualifiedPort oldSourcePort = sourcePort;
		sourcePort = newSourcePort;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, AmaltheaPackage.CONNECTOR__SOURCE_PORT, oldSourcePort, newSourcePort);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setSourcePort(QualifiedPort newSourcePort) {
		if (newSourcePort != sourcePort) {
			NotificationChain msgs = null;
			if (sourcePort != null)
				msgs = ((InternalEObject)sourcePort).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - AmaltheaPackage.CONNECTOR__SOURCE_PORT, null, msgs);
			if (newSourcePort != null)
				msgs = ((InternalEObject)newSourcePort).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - AmaltheaPackage.CONNECTOR__SOURCE_PORT, null, msgs);
			msgs = basicSetSourcePort(newSourcePort, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AmaltheaPackage.CONNECTOR__SOURCE_PORT, newSourcePort, newSourcePort));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetTargetPort(QualifiedPort newTargetPort, NotificationChain msgs) {
		QualifiedPort oldTargetPort = targetPort;
		targetPort = newTargetPort;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, AmaltheaPackage.CONNECTOR__TARGET_PORT, oldTargetPort, newTargetPort);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void setTargetPort(QualifiedPort newTargetPort) {
		if (newTargetPort != targetPort) {
			NotificationChain msgs = null;
			if (targetPort != null)
				msgs = ((InternalEObject)targetPort).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - AmaltheaPackage.CONNECTOR__TARGET_PORT, null, msgs);
			if (newTargetPort != null)
				msgs = ((InternalEObject)newTargetPort).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - AmaltheaPackage.CONNECTOR__TARGET_PORT, null, msgs);
			msgs = basicSetTargetPort(newTargetPort, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, AmaltheaPackage.CONNECTOR__TARGET_PORT, newTargetPort, newTargetPort));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EMap<ComponentInterface, Channel> getImplementedInterfaces() {
		if (implementedInterfaces == null) {
			implementedInterfaces = new EcoreEMap<ComponentInterface,Channel>(AmaltheaPackage.eINSTANCE.getInterfaceChannel(), InterfaceChannelImpl.class, this, AmaltheaPackage.CONNECTOR__IMPLEMENTED_INTERFACES);
		}
		return implementedInterfaces;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public INamed getNamedContainer() {
		INamed _xifexpression = null;
		EObject _eContainer = this.eContainer();
		if ((_eContainer instanceof INamed)) {
			EObject _eContainer_1 = this.eContainer();
			_xifexpression = ((INamed) _eContainer_1);
		}
		else {
			_xifexpression = null;
		}
		return _xifexpression;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getNamePrefix() {
		String _xifexpression = null;
		Namespace _namespace = this.getNamespace();
		boolean _tripleEquals = (_namespace == null);
		if (_tripleEquals) {
			return "";
		}
		else {
			_xifexpression = AmaltheaExtensions.toPlainString(this.getNamePrefixSegments(), this.getDefaultNameSeparator());
		}
		return _xifexpression;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<String> getQualifiedNameSegments() {
		final EList<String> segments = this.getNamePrefixSegments();
		String _name = this.getName();
		boolean _tripleNotEquals = (_name != null);
		if (_tripleNotEquals) {
			segments.add(this.getName());
		}
		return segments;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getDefaultNameSeparator() {
		return ".";
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public EList<String> getNamePrefixSegments() {
		EList<String> _elvis = null;
		Namespace _namespace = this.getNamespace();
		EList<String> _qualifiedNameSegments = null;
		if (_namespace!=null) {
			_qualifiedNameSegments=_namespace.getQualifiedNameSegments();
		}
		if (_qualifiedNameSegments != null) {
			_elvis = _qualifiedNameSegments;
		} else {
			BasicEList<String> _newBasicEList = XcoreCollectionLiterals.<String>newBasicEList();
			_elvis = _newBasicEList;
		}
		return _elvis;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM:
				if (eInternalContainer() != null)
					msgs = eBasicRemoveFromContainer(msgs);
				return basicSetContainingSystem((ISystem)otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM:
				return basicSetContainingSystem(null, msgs);
			case AmaltheaPackage.CONNECTOR__SOURCE_PORT:
				return basicSetSourcePort(null, msgs);
			case AmaltheaPackage.CONNECTOR__TARGET_PORT:
				return basicSetTargetPort(null, msgs);
			case AmaltheaPackage.CONNECTOR__IMPLEMENTED_INTERFACES:
				return ((InternalEList<?>)getImplementedInterfaces()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) {
		switch (eContainerFeatureID()) {
			case AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM:
				return eInternalContainer().eInverseRemove(this, AmaltheaPackage.ISYSTEM__CONNECTORS, ISystem.class, msgs);
		}
		return super.eBasicRemoveFromContainerFeature(msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case AmaltheaPackage.CONNECTOR__NAME:
				return getName();
			case AmaltheaPackage.CONNECTOR__QUALIFIED_NAME:
				return getQualifiedName();
			case AmaltheaPackage.CONNECTOR__TAGS:
				return getTags();
			case AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM:
				if (resolve) return getContainingSystem();
				return basicGetContainingSystem();
			case AmaltheaPackage.CONNECTOR__SOURCE_PORT:
				return getSourcePort();
			case AmaltheaPackage.CONNECTOR__TARGET_PORT:
				return getTargetPort();
			case AmaltheaPackage.CONNECTOR__IMPLEMENTED_INTERFACES:
				if (coreType) return getImplementedInterfaces();
				else return getImplementedInterfaces().map();
		}
		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 AmaltheaPackage.CONNECTOR__NAME:
				setName((String)newValue);
				return;
			case AmaltheaPackage.CONNECTOR__TAGS:
				getTags().clear();
				getTags().addAll((Collection<? extends Tag>)newValue);
				return;
			case AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM:
				setContainingSystem((ISystem)newValue);
				return;
			case AmaltheaPackage.CONNECTOR__SOURCE_PORT:
				setSourcePort((QualifiedPort)newValue);
				return;
			case AmaltheaPackage.CONNECTOR__TARGET_PORT:
				setTargetPort((QualifiedPort)newValue);
				return;
			case AmaltheaPackage.CONNECTOR__IMPLEMENTED_INTERFACES:
				((EStructuralFeature.Setting)getImplementedInterfaces()).set(newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case AmaltheaPackage.CONNECTOR__NAME:
				setName(NAME_EDEFAULT);
				return;
			case AmaltheaPackage.CONNECTOR__TAGS:
				getTags().clear();
				return;
			case AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM:
				setContainingSystem((ISystem)null);
				return;
			case AmaltheaPackage.CONNECTOR__SOURCE_PORT:
				setSourcePort((QualifiedPort)null);
				return;
			case AmaltheaPackage.CONNECTOR__TARGET_PORT:
				setTargetPort((QualifiedPort)null);
				return;
			case AmaltheaPackage.CONNECTOR__IMPLEMENTED_INTERFACES:
				getImplementedInterfaces().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case AmaltheaPackage.CONNECTOR__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case AmaltheaPackage.CONNECTOR__QUALIFIED_NAME:
				return QUALIFIED_NAME_EDEFAULT == null ? getQualifiedName() != null : !QUALIFIED_NAME_EDEFAULT.equals(getQualifiedName());
			case AmaltheaPackage.CONNECTOR__TAGS:
				return tags != null && !tags.isEmpty();
			case AmaltheaPackage.CONNECTOR__CONTAINING_SYSTEM:
				return basicGetContainingSystem() != null;
			case AmaltheaPackage.CONNECTOR__SOURCE_PORT:
				return sourcePort != null;
			case AmaltheaPackage.CONNECTOR__TARGET_PORT:
				return targetPort != null;
			case AmaltheaPackage.CONNECTOR__IMPLEMENTED_INTERFACES:
				return implementedInterfaces != null && !implementedInterfaces.isEmpty();
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
		if (baseClass == INamed.class) {
			switch (derivedFeatureID) {
				case AmaltheaPackage.CONNECTOR__NAME: return AmaltheaPackage.INAMED__NAME;
				case AmaltheaPackage.CONNECTOR__QUALIFIED_NAME: return AmaltheaPackage.INAMED__QUALIFIED_NAME;
				default: return -1;
			}
		}
		if (baseClass == ITaggable.class) {
			switch (derivedFeatureID) {
				case AmaltheaPackage.CONNECTOR__TAGS: return AmaltheaPackage.ITAGGABLE__TAGS;
				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 == INamed.class) {
			switch (baseFeatureID) {
				case AmaltheaPackage.INAMED__NAME: return AmaltheaPackage.CONNECTOR__NAME;
				case AmaltheaPackage.INAMED__QUALIFIED_NAME: return AmaltheaPackage.CONNECTOR__QUALIFIED_NAME;
				default: return -1;
			}
		}
		if (baseClass == ITaggable.class) {
			switch (baseFeatureID) {
				case AmaltheaPackage.ITAGGABLE__TAGS: return AmaltheaPackage.CONNECTOR__TAGS;
				default: return -1;
			}
		}
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedOperationID(int baseOperationID, Class<?> baseClass) {
		if (baseClass == INamed.class) {
			switch (baseOperationID) {
				case AmaltheaPackage.INAMED___GET_NAMED_CONTAINER: return AmaltheaPackage.CONNECTOR___GET_NAMED_CONTAINER;
				case AmaltheaPackage.INAMED___GET_NAME_PREFIX: return AmaltheaPackage.CONNECTOR___GET_NAME_PREFIX;
				case AmaltheaPackage.INAMED___GET_QUALIFIED_NAME_SEGMENTS: return AmaltheaPackage.CONNECTOR___GET_QUALIFIED_NAME_SEGMENTS;
				case AmaltheaPackage.INAMED___GET_DEFAULT_NAME_SEPARATOR: return AmaltheaPackage.CONNECTOR___GET_DEFAULT_NAME_SEPARATOR;
				case AmaltheaPackage.INAMED___GET_NAMESPACE: return AmaltheaPackage.CONNECTOR___GET_NAMESPACE;
				case AmaltheaPackage.INAMED___GET_NAME_PREFIX_SEGMENTS: return AmaltheaPackage.CONNECTOR___GET_NAME_PREFIX_SEGMENTS;
				default: return -1;
			}
		}
		if (baseClass == ITaggable.class) {
			switch (baseOperationID) {
				default: return -1;
			}
		}
		return super.eDerivedOperationID(baseOperationID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException {
		switch (operationID) {
			case AmaltheaPackage.CONNECTOR___GET_NAMED_CONTAINER:
				return getNamedContainer();
			case AmaltheaPackage.CONNECTOR___GET_NAME_PREFIX:
				return getNamePrefix();
			case AmaltheaPackage.CONNECTOR___GET_QUALIFIED_NAME_SEGMENTS:
				return getQualifiedNameSegments();
			case AmaltheaPackage.CONNECTOR___GET_DEFAULT_NAME_SEPARATOR:
				return getDefaultNameSeparator();
			case AmaltheaPackage.CONNECTOR___GET_NAMESPACE:
				return getNamespace();
			case AmaltheaPackage.CONNECTOR___GET_NAME_PREFIX_SEGMENTS:
				return getNamePrefixSegments();
		}
		return super.eInvoke(operationID, arguments);
	}

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

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

} //ConnectorImpl
