
<%
/**
 * Copyright (c) 2002-2019 IBM Corporation 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:
 *   IBM - Initial API and implementation
 *   Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 546714
 */
%>
<%final GenClass genClass = (GenClass)((Object[])argument)[0]; final GenPackage genPackage = genClass.getGenPackage(); final GenModel genModel=genPackage.getGenModel();%>
<%final boolean isJDK50 = genModel.getComplianceLevel().getValue() >= GenJDKLevel.JDK50;%>
<%final boolean isInterface = Boolean.TRUE.equals(((Object[])argument)[1]); final boolean isImplementation = Boolean.TRUE.equals(((Object[])argument)[2]); final boolean useInterfaceOverrideAnnotation = genModel.useInterfaceOverrideAnnotation() && !(isInterface && isImplementation);%>
<%final boolean isGWT = genModel.getRuntimePlatform() == GenRuntimePlatform.GWT;%>
<%final boolean forceDefaultCase = genModel.isSwitchMissingDefaultCase();final String indentDefaultCase = forceDefaultCase ? "\t\t" : "";%>
<%final String publicStaticFinalFlag = isImplementation ? "public static final " : "";%>
<%final String singleWildcard = isJDK50 ? "<?>" : "";%>
<%final String negativeOffsetCorrection = genClass.hasOffsetCorrection() ? " - " + genClass.getOffsetCorrectionField(null) : "";%>
<%final String positiveOffsetCorrection = genClass.hasOffsetCorrection() ? " + " + genClass.getOffsetCorrectionField(null) : "";%>
<%final String negativeOperationOffsetCorrection = genClass.hasOffsetCorrection() ? " - EOPERATION_OFFSET_CORRECTION" : "";%>
<%final String positiveOperationOffsetCorrection = genClass.hasOffsetCorrection() ? " + EOPERATION_OFFSET_CORRECTION" : "";%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern.base/egf/EMF_Pattern_Base.fcore#LogicalName=org.eclipse.egf.emf.pattern.base.HeaderJava" args="parameter:argument"%>
<%if (isInterface) {%>
package <%=genPackage.getInterfacePackageName()%>;
<%} else {%>
package <%=genPackage.getClassPackageName()%>;
<%}%>

<%genModel.markImportLocation(stringBuffer, genPackage);%>
<%if (isImplementation) { genClass.addClassPsuedoImports(); }%>

<%if (isInterface) {%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern/egf/EMF_Pattern.fcore#LogicalName=org.eclipse.egf.emf.pattern.model.call.Interface.Interface.interface.javadoc.override" args="genClass:genClass,genPackage:genPackage,genModel:genModel,isJDK50:isJDK50,isInterface:isInterface,isImplementation:isImplementation,useInterfaceOverrideAnnotation:useInterfaceOverrideAnnotation,isGWT:isGWT,forceDefaultCase:forceDefaultCase,indentDefaultCase:indentDefaultCase,publicStaticFinalFlag:publicStaticFinalFlag,singleWildcard:singleWildcard,negativeOffsetCorrection:negativeOffsetCorrection,positiveOffsetCorrection:positiveOffsetCorrection,negativeOperationOffsetCorrection:negativeOperationOffsetCorrection,positiveOperationOffsetCorrection:positiveOperationOffsetCorrection"%><%//Class/interface.javadoc.override.javajetinc%>
<%} else {%>
/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b><%=genClass.getFormattedName()%></b></em>'.
 * <!-- end-user-doc -->
<%if (!genClass.getImplementedGenFeatures().isEmpty()) {%>
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
<%for (GenFeature genFeature : genClass.getImplementedGenFeatures()) {%>
 *   <li>{@link <%=genClass.getQualifiedClassName()%>#<%=genFeature.getGetAccessor()%> <em><%=genFeature.getFormattedName()%></em>}</li>
<%}%>
 * </ul>
<%}%>
 *
<%if (genClass.hasImplicitAPITags()) {%>
 * <%=genClass.getImplicitAPITags(genModel.getIndentation(stringBuffer))%>
<%}%>
 * @generated
 */
<%}%>
<%if (isJDK50 && genClass.hasImplicitAPIDeprecatedTag()) {%>
@Deprecated
<%}%>
<%if (isImplementation) {%>
<%if (isJDK50 && !genClass.hasAPIDeprecatedTag() && GenModelUtil.hasImplicitAPIDeprecatedTag(genClass.getEGetGenFeatures(), genClass.getEIsSetGenFeatures(), genClass.getESetGenFeatures(), genClass.getEUnsetGenFeatures(), genClass.getEInverseAddGenFeatures(), genClass.getEInverseRemoveGenFeatures(), genClass.getEBasicRemoveFromContainerGenFeatures(), genClass.getToStringGenFeatures())) {%>
@SuppressWarnings("deprecation")
<%}%>
public<%if (genClass.isAbstract()) {%> abstract<%}%> class <%=genClass.getClassName()%><%=genClass.getTypeParameters().trim()%><%=genClass.getClassExtends()%><%=genClass.getClassImplements()%>
<%} else {%>
public interface <%=genClass.getInterfaceName()%><%=genClass.getTypeParameters().trim()%><%=genClass.getInterfaceExtends()%>
<%}%>
{
<%if (genModel.hasCopyrightField()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	<%=publicStaticFinalFlag%><%=genModel.getImportedName("java.lang.String")%> copyright = <%=genModel.getCopyrightFieldLiteral()%>;<%=genModel.getNonNLS()%>

<%}%>
<%if (isImplementation && genModel.getDriverNumber() != null) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public static final <%=genModel.getImportedName("java.lang.String")%> mofDriverNumber = "<%=genModel.getDriverNumber()%>";<%=genModel.getNonNLS()%>

<%}%>
<%if (isImplementation && genClass.isJavaIOSerializable()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	private static final long serialVersionUID = 1L;

<%}%>
<%if (isImplementation && genModel.isVirtualDelegation()) { String eVirtualValuesField = genClass.getEVirtualValuesField();%>
  <%if (eVirtualValuesField != null) {%>
	/**
	 * An array of objects representing the values of non-primitive features.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
      <%if (isGWT) {%>
	@<%=genModel.getImportedName("com.google.gwt.user.client.rpc.GwtTransient")%>
      <%}%>
	protected Object[] <%=eVirtualValuesField%>;

  <%}%>
  <%{ List<String> eVirtualIndexBitFields = genClass.getEVirtualIndexBitFields(new ArrayList<String>());%>
    <%if (!eVirtualIndexBitFields.isEmpty()) {%>
      <%for (String eVirtualIndexBitField : eVirtualIndexBitFields) {%>
	/**
	 * A bit field representing the indices of non-primitive feature values.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
      <%if (isGWT) {%>
	@<%=genModel.getImportedName("com.google.gwt.user.client.rpc.GwtTransient")%>
      <%}%>
	protected int <%=eVirtualIndexBitField%>;

      <%}%>
    <%}%>
  <%}%>
<%}%>
<%if (isImplementation && genClass.isModelRoot() && genModel.isBooleanFlagsEnabled() && genModel.getBooleanFlagsReservedBits() == -1) {%>
	/**
	 * A set of bit flags representing the values of boolean attributes and whether unsettable features have been set.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 * @ordered
	 */
      <%if (isGWT) {%>
	@<%=genModel.getImportedName("com.google.gwt.user.client.rpc.GwtTransient")%>
      <%}%>
	protected int <%=genModel.getBooleanFlagsField()%> = 0;

<%}%>
<%if (isImplementation && !genModel.isReflectiveDelegation()) {%>
  <%for (GenFeature genFeature : genClass.getReifiedGenFeatures()) {%>
      <%if (genModel.isArrayAccessors() && genFeature.isListType() && !genFeature.isFeatureMapType() && !genFeature.isMapType()) { String rawListItemType = genFeature.getRawListItemType(genClass); int index = rawListItemType.indexOf('['); String head = rawListItemType; String tail = ""; if (index != -1) { head = rawListItemType.substring(0, index); tail = rawListItemType.substring(index); } %>
	/**
	 * The empty value for the '{@link #<%=genFeature.getGetArrayAccessor()%>() <em><%=genFeature.getFormattedName()%></em>}' array accessor.
	 * This is specialized for the more specific element type known in this context.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #<%=genFeature.getGetArrayAccessor()%>()
       <%if (genFeature.hasAPITags()) {%>
	 * <%=genFeature.getAPITags(genModel.getIndentation(stringBuffer))%>
       <%}%>
	 * @generated
	 * @ordered
	 */
        <%if (isJDK50 && genFeature.hasAPIDeprecatedTag()) {%>
	@Deprecated
        <%}%>
        <%if (genFeature.getQualifiedListItemType(genClass).contains("<") || genFeature.getArrayItemType(genClass).contains("<")) {%>
	@SuppressWarnings("rawtypes")
        <%}%>
	protected static final <%=rawListItemType%>[] <%=genFeature.getUpperName()%>_EEMPTY_ARRAY = new <%=head%> [0]<%=tail%>;

      <%}%>
  <%}%>
  <%for (GenFeature genFeature : genClass.getDeclaredFieldGenFeatures()) {%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern/egf/EMF_Pattern.fcore#LogicalName=org.eclipse.egf.emf.pattern.model.call.Interface.Interface.declaredFieldGenFeature.override" args="genFeature:genFeature,genClass:genClass,genPackage:genPackage,genModel:genModel,isJDK50:isJDK50,isInterface:isInterface,isImplementation:isImplementation,useInterfaceOverrideAnnotation:useInterfaceOverrideAnnotation,isGWT:isGWT,forceDefaultCase:forceDefaultCase,indentDefaultCase:indentDefaultCase,publicStaticFinalFlag:publicStaticFinalFlag,singleWildcard:singleWildcard,negativeOffsetCorrection:negativeOffsetCorrection,positiveOffsetCorrection:positiveOffsetCorrection,negativeOperationOffsetCorrection:negativeOperationOffsetCorrection,positiveOperationOffsetCorrection:positiveOperationOffsetCorrection"%><%//Class/declaredFieldGenFeature.override.javajetinc%>
  <%}%>
<%}%>
<%if (isImplementation && genClass.hasOffsetCorrection() && !genClass.getImplementedGenFeatures().isEmpty()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	private static final int <%=genClass.getOffsetCorrectionField(null)%> = <%=genClass.getQualifiedClassifierAccessor()%>.getFeatureID(<%=genClass.getImplementedGenFeatures().get(0).getQualifiedFeatureAccessor()%>) - <%=genClass.getQualifiedFeatureID(genClass.getImplementedGenFeatures().get(0))%>;

<%}%>
<%if (isImplementation && !genModel.isReflectiveDelegation()) {%>
  <%for (GenFeature genFeature : genClass.getImplementedGenFeatures()) { GenFeature reverseFeature = genFeature.getReverse();%>
    <%if (reverseFeature != null && reverseFeature.getGenClass().hasOffsetCorrection()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
       <%if (genFeature.hasAPITags()) {%>
	 * <%=genFeature.getAPITags(genModel.getIndentation(stringBuffer))%>
       <%}%>
	 * @generated
	 */
        <%if (isJDK50 && genFeature.hasAPIDeprecatedTag()) {%>
	@Deprecated
        <%}%>
	private static final int <%=genClass.getOffsetCorrectionField(genFeature)%> = <%=reverseFeature.getGenClass().getQualifiedClassifierAccessor()%>.getFeatureID(<%=reverseFeature.getQualifiedFeatureAccessor()%>) - <%=reverseFeature.getGenClass().getQualifiedFeatureID(reverseFeature)%>;

    <%}%>
  <%}%>
<%}%>
<%if (genModel.isOperationReflection() && isImplementation && genClass.hasOffsetCorrection() && !genClass.getImplementedGenOperations().isEmpty()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	private static final int EOPERATION_OFFSET_CORRECTION = <%=genClass.getQualifiedClassifierAccessor()%>.getOperationID(<%=genClass.getImplementedGenOperations().get(0).getQualifiedOperationAccessor()%>) - <%=genClass.getQualifiedOperationID(genClass.getImplementedGenOperations().get(0))%>;

<%}%>
<%if (isImplementation) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	<%if (genModel.isPublicConstructors()) {%>public<%} else {%>protected<%}%> <%=genClass.getClassName()%>()
	{
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern/egf/EMF_Pattern.fcore#LogicalName=org.eclipse.egf.emf.pattern.model.call.Interface.Interface.egfCustom.constructor.override" args="genClass:genClass,genPackage:genPackage,genModel:genModel,isJDK50:isJDK50,isInterface:isInterface,isImplementation:isImplementation,useInterfaceOverrideAnnotation:useInterfaceOverrideAnnotation,isGWT:isGWT,forceDefaultCase:forceDefaultCase,indentDefaultCase:indentDefaultCase,publicStaticFinalFlag:publicStaticFinalFlag,singleWildcard:singleWildcard,negativeOffsetCorrection:negativeOffsetCorrection,positiveOffsetCorrection:positiveOffsetCorrection,negativeOperationOffsetCorrection:negativeOperationOffsetCorrection,positiveOperationOffsetCorrection:positiveOperationOffsetCorrection"%>
  <%for (GenFeature genFeature : genClass.getFlagGenFeaturesWithDefault()) {%>
		<%=genClass.getFlagsField(genFeature)%> |= <%=genFeature.getUpperName()%>_EFLAG<%if (!genFeature.isBooleanType()) {%>_DEFAULT<%}%>;
  <%}%>
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	protected <%=genModel.getImportedName("org.eclipse.emf.ecore.EClass")%> eStaticClass()
	{
		return <%=genClass.getQualifiedClassifierAccessor()%>;
	}

<%}%>
<%if (isImplementation && genModel.isDynamicDelegation()) {%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern/egf/EMF_Pattern.fcore#LogicalName=org.eclipse.egf.emf.pattern.model.call.Interface.Interface.dynamicDelegation" args="genClass:genClass,genPackage:genPackage,genModel:genModel,isJDK50:isJDK50,isInterface:isInterface,isImplementation:isImplementation,useInterfaceOverrideAnnotation:useInterfaceOverrideAnnotation,isGWT:isGWT,forceDefaultCase:forceDefaultCase,indentDefaultCase:indentDefaultCase,publicStaticFinalFlag:publicStaticFinalFlag,singleWildcard:singleWildcard,negativeOffsetCorrection:negativeOffsetCorrection,positiveOffsetCorrection:positiveOffsetCorrection,negativeOperationOffsetCorrection:negativeOperationOffsetCorrection,positiveOperationOffsetCorrection:positiveOperationOffsetCorrection"%>
<%}%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern/egf/EMF_Pattern.fcore#LogicalName=org.eclipse.egf.emf.pattern.model.call.Interface.Interface.reflectiveDelegation.override" args="genClass:genClass,genPackage:genPackage,genModel:genModel,isJDK50:isJDK50,isInterface:isInterface,isImplementation:isImplementation,useInterfaceOverrideAnnotation:useInterfaceOverrideAnnotation,isGWT:isGWT,forceDefaultCase:forceDefaultCase,indentDefaultCase:indentDefaultCase,publicStaticFinalFlag:publicStaticFinalFlag,singleWildcard:singleWildcard,negativeOffsetCorrection:negativeOffsetCorrection,positiveOffsetCorrection:positiveOffsetCorrection,negativeOperationOffsetCorrection:negativeOperationOffsetCorrection,positiveOperationOffsetCorrection:positiveOperationOffsetCorrection"%><%//Class/reflectiveDelegation.override.javajetinc%>
<%if (isImplementation) {%>
<%new Runnable() { public void run() { GenClass classExtendsGenClass = genClass.getClassExtendsGenClass(); List<GenFeature> classExtendsAllGenFeatures = classExtendsGenClass == null? Collections.<GenFeature>emptyList() : classExtendsGenClass.getAllGenFeatures();%>
  <%for (GenFeature genFeature : genClass.getReifiedGenFeatures()) {%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern/egf/EMF_Pattern.fcore#LogicalName=org.eclipse.egf.emf.pattern.model.call.Interface.Interface.genFeatureReified.override" args="genFeature:genFeature,classExtendsGenClass:classExtendsGenClass,classExtendsAllGenFeatures:classExtendsAllGenFeatures,genClass:genClass,genPackage:genPackage,genModel:genModel,isJDK50:isJDK50,isInterface:isInterface,isImplementation:isImplementation,useInterfaceOverrideAnnotation:useInterfaceOverrideAnnotation,isGWT:isGWT,forceDefaultCase:forceDefaultCase,indentDefaultCase:indentDefaultCase,publicStaticFinalFlag:publicStaticFinalFlag,singleWildcard:singleWildcard,negativeOffsetCorrection:negativeOffsetCorrection,positiveOffsetCorrection:positiveOffsetCorrection,negativeOperationOffsetCorrection:negativeOperationOffsetCorrection,positiveOperationOffsetCorrection:positiveOperationOffsetCorrection"%><%//Class/genFeatureReified.override.javajetinc%>
<%}}}.run();}%>
<%new Runnable() { public void run() {%>
<%for (GenFeature genFeature : (isImplementation ? genClass.getImplementedGenFeatures() : genClass.getDeclaredGenFeatures())) {%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern/egf/EMF_Pattern.fcore#LogicalName=org.eclipse.egf.emf.pattern.model.call.Interface.Interface.genFeature.override" args="genFeature:genFeature,genClass:genClass,genPackage:genPackage,genModel:genModel,isJDK50:isJDK50,isInterface:isInterface,isImplementation:isImplementation,useInterfaceOverrideAnnotation:useInterfaceOverrideAnnotation,isGWT:isGWT,forceDefaultCase:forceDefaultCase,indentDefaultCase:indentDefaultCase,publicStaticFinalFlag:publicStaticFinalFlag,singleWildcard:singleWildcard,negativeOffsetCorrection:negativeOffsetCorrection,positiveOffsetCorrection:positiveOffsetCorrection,negativeOperationOffsetCorrection:negativeOperationOffsetCorrection,positiveOperationOffsetCorrection:positiveOperationOffsetCorrection"%><%//Class/genFeature.override.javajetinc%>
<%}//for%>
<%}}.run();%>
<%for (GenOperation genOperation : (isImplementation ? genClass.getImplementedGenOperations() : genClass.getDeclaredGenOperations())) {%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern/egf/EMF_Pattern.fcore#LogicalName=org.eclipse.egf.emf.pattern.model.call.Interface.Interface.genOperation.override" args="genOperation:genOperation,genClass:genClass,genPackage:genPackage,genModel:genModel,isJDK50:isJDK50,isInterface:isInterface,isImplementation:isImplementation,useInterfaceOverrideAnnotation:useInterfaceOverrideAnnotation,isGWT:isGWT,forceDefaultCase:forceDefaultCase,indentDefaultCase:indentDefaultCase,publicStaticFinalFlag:publicStaticFinalFlag,singleWildcard:singleWildcard,negativeOffsetCorrection:negativeOffsetCorrection,positiveOffsetCorrection:positiveOffsetCorrection,negativeOperationOffsetCorrection:negativeOperationOffsetCorrection,positiveOperationOffsetCorrection:positiveOperationOffsetCorrection"%><%//Class/implementedGenOperation.override.javajetinc%>
<%}//for%>
<%if (isImplementation && !genModel.isReflectiveDelegation() && genClass.implementsAny(genClass.getEInverseAddGenFeatures())) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useGenerics()) {%>
    <%for (GenFeature genFeature : genClass.getEInverseAddGenFeatures()) {%>
      <%if (genFeature.isUncheckedCast(genClass)) {%>
	@SuppressWarnings("unchecked")
      <%break; }%>
    <%}%>
  <%}%>
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	public <%=genModel.getImportedName("org.eclipse.emf.common.notify.NotificationChain")%> eInverseAdd(<%=genModel.getImportedName("org.eclipse.emf.ecore.InternalEObject")%> otherEnd, int featureID, <%=genModel.getImportedName("org.eclipse.emf.common.notify.NotificationChain")%> msgs)
	{
		switch (featureID<%=negativeOffsetCorrection%>)
		{
<%for (GenFeature genFeature : genClass.getEInverseAddGenFeatures()) {%>
			case <%=genClass.getQualifiedFeatureID(genFeature)%>:
  <%if (genFeature.isListType()) { String cast = "("  + genModel.getImportedName("org.eclipse.emf.ecore.util.InternalEList") + (!genModel.useGenerics() ? ")" : "<" + genModel.getImportedName("org.eclipse.emf.ecore.InternalEObject") + ">)(" + genModel.getImportedName("org.eclipse.emf.ecore.util.InternalEList") + "<?>)");%>
    <%if (genFeature.isMapType() && genFeature.isEffectiveSuppressEMFTypes()) {%>
				return ((<%=cast%>(<%=genModel.getImportedName("org.eclipse.emf.common.util.EMap")%>.InternalMapView<%=genFeature.getImportedMapTemplateArguments(genClass)%>)<%=genFeature.getGetAccessor()%>()).eMap()).basicAdd(otherEnd, msgs);
    <%} else {%>
				return (<%=cast%><%=genFeature.getGetAccessor()%>()).basicAdd(otherEnd, msgs);
    <%}%>
  <%} else if (genFeature.isContainer()) {%>
				if (eInternalContainer() != null)
					msgs = eBasicRemoveFromContainer(msgs);
    <%if (genFeature.isBasicSet()) {%>
				return basicSet<%=genFeature.getAccessorName()%>((<%=genFeature.getImportedType(genClass)%>)otherEnd, msgs);
    <%} else {%>
				return eBasicSetContainer(otherEnd, <%=genClass.getQualifiedFeatureID(genFeature)%><%=positiveOffsetCorrection%>, msgs);
    <%}%>
  <%} else {%>
    <%if (genClass.getImplementingGenModel(genFeature).isVirtualDelegation()) {%>
				<%=genFeature.getImportedType(genClass)%> <%=genFeature.getSafeName()%> = (<%=genFeature.getImportedType(genClass)%>)eVirtualGet(<%=genClass.getQualifiedFeatureID(genFeature)%><%=positiveOffsetCorrection%>);
    <%} else if (genFeature.isVolatile() || genClass.getImplementingGenModel(genFeature).isDynamicDelegation()) {%>
				<%=genFeature.getImportedType(genClass)%> <%=genFeature.getSafeName()%> = <%if (genFeature.isResolveProxies()) {%>basicGet<%=genFeature.getAccessorName()%><%} else {%><%=genFeature.getGetAccessor()%><%}%>();
    <%}%>
				if (<%=genFeature.getSafeName()%> != null)
    <%if (genFeature.isEffectiveContains()) {%>
					msgs = <%=genFeature.getAsInternalEObject(genFeature.getSafeName(), true)%>.eInverseRemove(this, EOPPOSITE_FEATURE_BASE - <%=genClass.getQualifiedFeatureID(genFeature)%><%=negativeOffsetCorrection%>, null, msgs);
    <%} else { GenFeature reverseFeature = genFeature.getReverse(); GenClass targetClass = reverseFeature.getGenClass(); String reverseOffsetCorrection = targetClass.hasOffsetCorrection() ? " + " + genClass.getOffsetCorrectionField(genFeature) : "";%>
					msgs = <%=genFeature.getAsInternalEObject(genFeature.getSafeName(), true)%>.eInverseRemove(this, <%=targetClass.getQualifiedFeatureID(reverseFeature)%><%=reverseOffsetCorrection%>, <%=targetClass.getRawImportedInterfaceName()%>.class, msgs);
    <%}%>
				return basicSet<%=genFeature.getAccessorName()%>((<%=genFeature.getImportedType(genClass)%>)otherEnd, msgs);
  <%}%>
<%}%>
<%if (forceDefaultCase) {%>
			default:
<%} else {%>
		}
<%}%>
<%if (genModel.isMinimalReflectiveMethods()) {%>
<%=indentDefaultCase%>		return super.eInverseAdd(otherEnd, featureID, msgs);
<%} else {%>
<%=indentDefaultCase%>		return eDynamicInverseAdd(otherEnd, featureID, msgs);
<%}%>
<%if (forceDefaultCase) {%>
		}
<%}%>
	}

<%}%>
<%if (isImplementation && !genModel.isReflectiveDelegation() && genClass.implementsAny(genClass.getEInverseRemoveGenFeatures())) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	public <%=genModel.getImportedName("org.eclipse.emf.common.notify.NotificationChain")%> eInverseRemove(<%=genModel.getImportedName("org.eclipse.emf.ecore.InternalEObject")%> otherEnd, int featureID, <%=genModel.getImportedName("org.eclipse.emf.common.notify.NotificationChain")%> msgs)
	{
		switch (featureID<%=negativeOffsetCorrection%>)
		{
<%for (GenFeature genFeature : genClass.getEInverseRemoveGenFeatures()) {%>
			case <%=genClass.getQualifiedFeatureID(genFeature)%>:
  <%if (genFeature.isListType()) {%>
    <%if (genFeature.isMapType() && genFeature.isEffectiveSuppressEMFTypes()) {%>
				return ((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.InternalEList")%><%=singleWildcard%>)((<%=genModel.getImportedName("org.eclipse.emf.common.util.EMap")%>.InternalMapView<%=genFeature.getImportedMapTemplateArguments(genClass)%>)<%=genFeature.getGetAccessor()%>()).eMap()).basicRemove(otherEnd, msgs);
    <%} else if (genFeature.isWrappedFeatureMapType()) {%>
				return ((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.InternalEList")%><%=singleWildcard%>)((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.FeatureMap")%>.Internal.Wrapper)<%=genFeature.getGetAccessor()%>()).featureMap()).basicRemove(otherEnd, msgs);
    <%} else {%>
				return ((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.InternalEList")%><%=singleWildcard%>)<%=genFeature.getGetAccessor()%>()).basicRemove(otherEnd, msgs);
    <%}%>
  <%} else if (genFeature.isContainer() && !genFeature.isBasicSet()) {%>
				return eBasicSetContainer(null, <%=genClass.getQualifiedFeatureID(genFeature)%><%=positiveOffsetCorrection%>, msgs);
  <%} else if (genFeature.isUnsettable()) {%>
				return basicUnset<%=genFeature.getAccessorName()%>(msgs);
  <%} else {%>
				return basicSet<%=genFeature.getAccessorName()%>(null, msgs);
  <%}%>
<%}%>
<%if (forceDefaultCase) {%>
			default:
<%} else { // {%>
		}
<%}%>
<%if (genModel.isMinimalReflectiveMethods()) {%>
<%=indentDefaultCase%>		return super.eInverseRemove(otherEnd, featureID, msgs);
<%} else {%>
<%=indentDefaultCase%>		return eDynamicInverseRemove(otherEnd, featureID, msgs);
<%}%>
<%if (forceDefaultCase) { // {%>
		}
<%} // }%>
	}

<%}%>
<%if (isImplementation && !genModel.isReflectiveDelegation() && genClass.implementsAny(genClass.getEBasicRemoveFromContainerGenFeatures())) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	public <%=genModel.getImportedName("org.eclipse.emf.common.notify.NotificationChain")%> eBasicRemoveFromContainerFeature(<%=genModel.getImportedName("org.eclipse.emf.common.notify.NotificationChain")%> msgs)
	{
		switch (eContainerFeatureID()<%=negativeOffsetCorrection%>)
		{
<%for (GenFeature genFeature : genClass.getEBasicRemoveFromContainerGenFeatures()) {%>
  <%GenFeature reverseFeature = genFeature.getReverse(); GenClass targetClass = reverseFeature.getGenClass(); String reverseOffsetCorrection = targetClass.hasOffsetCorrection() ? " + " + genClass.getOffsetCorrectionField(genFeature) : "";%>
			case <%=genClass.getQualifiedFeatureID(genFeature)%>:
				return eInternalContainer().eInverseRemove(this, <%=targetClass.getQualifiedFeatureID(reverseFeature)%><%=reverseOffsetCorrection%>, <%=targetClass.getRawImportedInterfaceName()%>.class, msgs);
<%}%>
<%if (forceDefaultCase) {%>
			default:
<%} else { // {%>
		}
<%}%>
<%if (genModel.isMinimalReflectiveMethods()) {%>
<%=indentDefaultCase%>		return super.eBasicRemoveFromContainerFeature(msgs);
<%} else {%>
<%=indentDefaultCase%>		return eDynamicBasicRemoveFromContainer(msgs);
<%}%>
<%if (forceDefaultCase) { // {%>
		}
<%} // }%>
	}

<%}%>
<%if (isImplementation && !genModel.isReflectiveDelegation() && genClass.implementsAny(genClass.getEGetGenFeatures())) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	public Object eGet(int featureID, boolean resolve, boolean coreType)
	{
		switch (featureID<%=negativeOffsetCorrection%>)
		{
<%for (GenFeature genFeature : genClass.getEGetGenFeatures()) {%>
			case <%=genClass.getQualifiedFeatureID(genFeature)%>:
  <%if (genFeature.isPrimitiveType()) {%>
    <%if (isJDK50) {%>
				return <%=genFeature.getGetAccessor()%>();
    <%} else if (genFeature.isBooleanType()) {%>
				return <%=genFeature.getGetAccessor()%>() ? Boolean.TRUE : Boolean.FALSE;
    <%} else {%>
				return new <%=genFeature.getObjectType(genClass)%>(<%=genFeature.getGetAccessor()%>());
    <%}%>
  <%} else if (genFeature.isResolveProxies() && !genFeature.isListType()) {%>
				if (resolve) return <%=genFeature.getGetAccessor()%>();
				return basicGet<%=genFeature.getAccessorName()%>();
  <%} else if (genFeature.isMapType()) {%>
    <%if (genFeature.isEffectiveSuppressEMFTypes()) {%>
				if (coreType) return ((<%=genModel.getImportedName("org.eclipse.emf.common.util.EMap")%>.InternalMapView<%=genFeature.getImportedMapTemplateArguments(genClass)%>)<%=genFeature.getGetAccessor()%>()).eMap();
				else return <%=genFeature.getGetAccessor()%>();
    <%} else {%>
				if (coreType) return <%=genFeature.getGetAccessor()%>();
				else return <%=genFeature.getGetAccessor()%>().map();
    <%}%>
  <%} else if (genFeature.isWrappedFeatureMapType()) {%>
				if (coreType) return ((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.FeatureMap")%>.Internal.Wrapper)<%=genFeature.getGetAccessor()%>()).featureMap();
				return <%=genFeature.getGetAccessor()%>();
  <%} else if (genFeature.isFeatureMapType()) {%>
				if (coreType) return <%=genFeature.getGetAccessor()%>();
				return ((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.FeatureMap")%>.Internal)<%=genFeature.getGetAccessor()%>()).getWrapper();
  <%} else {%>
				return <%=genFeature.getGetAccessor()%>();
  <%}%>
<%}%>
<%if (forceDefaultCase) {%>
			default:
<%} else { // {%>
		}
<%}%>
<%if (genModel.isMinimalReflectiveMethods()) {%>
<%=indentDefaultCase%>		return super.eGet(featureID, resolve, coreType);
<%} else {%>
<%=indentDefaultCase%>		return eDynamicGet(featureID, resolve, coreType);
<%}%>
<%if (forceDefaultCase) { // {%>
		}
<%} // }%>
	}

<%}%>
<%if (isImplementation && !genModel.isReflectiveDelegation() && genClass.implementsAny(genClass.getESetGenFeatures())) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useGenerics()) {%>
    <%for (GenFeature genFeature : genClass.getESetGenFeatures()) {%>
      <%if (genFeature.isUncheckedCast(genClass) && !genFeature.isFeatureMapType() && !genFeature.isMapType()) {%>
	@SuppressWarnings("unchecked")
      <%break; }%>
    <%}%>
  <%}%>
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	public void eSet(int featureID, Object newValue)
	{
		switch (featureID<%=negativeOffsetCorrection%>)
		{
  <%for (GenFeature genFeature : genClass.getESetGenFeatures()) {%>
			case <%=genClass.getQualifiedFeatureID(genFeature)%>:
    <%if (genFeature.isListType()) {%>
      <%if (genFeature.isWrappedFeatureMapType()) {%>
				((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.FeatureMap")%>.Internal)((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.FeatureMap")%>.Internal.Wrapper)<%=genFeature.getGetAccessor()%>()).featureMap()).set(newValue);
      <%} else if (genFeature.isFeatureMapType()) {%>
				((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.FeatureMap")%>.Internal)<%=genFeature.getGetAccessor()%>()).set(newValue);
      <%} else if (genFeature.isMapType()) {%>
        <%if (genFeature.isEffectiveSuppressEMFTypes()) {%>
				((<%=genModel.getImportedName("org.eclipse.emf.ecore.EStructuralFeature")%>.Setting)((<%=genModel.getImportedName("org.eclipse.emf.common.util.EMap")%>.InternalMapView<%=genFeature.getImportedMapTemplateArguments(genClass)%>)<%=genFeature.getGetAccessor()%>()).eMap()).set(newValue);
        <%} else {%>
				((<%=genModel.getImportedName("org.eclipse.emf.ecore.EStructuralFeature")%>.Setting)<%=genFeature.getGetAccessor()%>()).set(newValue);
        <%}%>
      <%} else {%>
				<%=genFeature.getGetAccessor()%>().clear();
				<%=genFeature.getGetAccessor()%>().addAll((<%=genModel.getImportedName("java.util.Collection")%><%if (isJDK50) {%><? extends <%=genFeature.getListItemType(genClass)%>><%}%>)newValue);
      <%}%>
    <%} else if (!isJDK50 && genFeature.isPrimitiveType()) {%>
				set<%=genFeature.getAccessorName()%>(((<%=genFeature.getObjectType(genClass)%>)newValue).<%=genFeature.getPrimitiveValueFunction()%>());
    <%} else {%>
				set<%=genFeature.getAccessorName()%>(<%if (genFeature.getTypeGenDataType() == null || !genFeature.getTypeGenDataType().isObjectType() || !genFeature.getRawType().equals(genFeature.getType(genClass))) {%>(<%=genFeature.getObjectType(genClass)%>)<%}%>newValue);
    <%}%>
				return;
  <%}%>
<%if (forceDefaultCase) {%>
			default:
<%} else { // {%>
		}
<%}%>
  <%if (genModel.isMinimalReflectiveMethods()) {%>
<%=indentDefaultCase%>		super.eSet(featureID, newValue);
<%if (forceDefaultCase) {%>
				return;
<%}%>
  <%} else {%>
<%=indentDefaultCase%>		eDynamicSet(featureID, newValue);
<%if (forceDefaultCase) {%>
				return;
<%}%>
  <%}%>
<%if (forceDefaultCase) { // {%>
		}
<%} // }%>
	}

<%}%>
<%if (isImplementation && !genModel.isReflectiveDelegation() && genClass.implementsAny(genClass.getEUnsetGenFeatures())) {%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern/egf/EMF_Pattern.fcore#LogicalName=org.eclipse.egf.emf.pattern.model.call.Interface.Interface.eUnset.override" args="genClass:genClass,genPackage:genPackage,genModel:genModel,isJDK50:isJDK50,isInterface:isInterface,isImplementation:isImplementation,useInterfaceOverrideAnnotation:useInterfaceOverrideAnnotation,isGWT:isGWT,forceDefaultCase:forceDefaultCase,indentDefaultCase:indentDefaultCase,publicStaticFinalFlag:publicStaticFinalFlag,singleWildcard:singleWildcard,negativeOffsetCorrection:negativeOffsetCorrection,positiveOffsetCorrection:positiveOffsetCorrection,negativeOperationOffsetCorrection:negativeOperationOffsetCorrection,positiveOperationOffsetCorrection:positiveOperationOffsetCorrection"%><%//Class/eUnset.override.javajetinc%>
<%}%>
<%if (isImplementation && !genModel.isReflectiveDelegation() && genClass.implementsAny(genClass.getEIsSetGenFeatures())) {%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern/egf/EMF_Pattern.fcore#LogicalName=org.eclipse.egf.emf.pattern.model.call.Interface.Interface.eIsSet.override" args="genClass:genClass,genPackage:genPackage,genModel:genModel,isJDK50:isJDK50,isInterface:isInterface,isImplementation:isImplementation,useInterfaceOverrideAnnotation:useInterfaceOverrideAnnotation,isGWT:isGWT,forceDefaultCase:forceDefaultCase,indentDefaultCase:indentDefaultCase,publicStaticFinalFlag:publicStaticFinalFlag,singleWildcard:singleWildcard,negativeOffsetCorrection:negativeOffsetCorrection,positiveOffsetCorrection:positiveOffsetCorrection,negativeOperationOffsetCorrection:negativeOperationOffsetCorrection,positiveOperationOffsetCorrection:positiveOperationOffsetCorrection"%><%//Class/eIsSet.override.javajetinc%>
<%}%>
<%if (isImplementation && (!genClass.getMixinGenFeatures().isEmpty() || genClass.hasOffsetCorrection() && !genClass.getGenFeatures().isEmpty())) {%>
  <%if (!genClass.getMixinGenFeatures().isEmpty()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
    <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
    <%}%>
	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<%=singleWildcard%> baseClass)
	{
    <%for (GenClass mixinGenClass : genClass.getMixinGenClasses()) {%>
		if (baseClass == <%=mixinGenClass.getRawImportedInterfaceName()%>.class)
		{
			switch (derivedFeatureID<%=negativeOffsetCorrection%>)
			{
      <%for (GenFeature genFeature : mixinGenClass.getGenFeatures()) {%>
				case <%=genClass.getQualifiedFeatureID(genFeature)%>: return <%=mixinGenClass.getQualifiedFeatureID(genFeature)%>;
      <%}%>
				default: return -1;
			}
		}
    <%}%>
		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
	}
  <%}%>

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	public int eDerivedStructuralFeatureID(int baseFeatureID, Class<%=singleWildcard%> baseClass)
	{
  <%for (GenClass mixinGenClass : genClass.getMixinGenClasses()) {%>
		if (baseClass == <%=mixinGenClass.getRawImportedInterfaceName()%>.class)
		{
			switch (baseFeatureID)
			{
    <%for (GenFeature genFeature : mixinGenClass.getGenFeatures()) {%>
				case <%=mixinGenClass.getQualifiedFeatureID(genFeature)%>: return <%=genClass.getQualifiedFeatureID(genFeature)%><%=positiveOffsetCorrection%>;
    <%}%>
				default: return -1;
			}
		}
  <%}%>
  <%if (genClass.hasOffsetCorrection() && !genClass.getGenFeatures().isEmpty()) {%>
		if (baseClass == <%=genClass.getRawImportedInterfaceName()%>.class)
		{
			switch (baseFeatureID<%=negativeOffsetCorrection%>)
			{
    <%for (GenFeature genFeature : genClass.getGenFeatures()) {%>
				case <%=genClass.getQualifiedFeatureID(genFeature)%>: return <%=genClass.getQualifiedFeatureID(genFeature)%><%=positiveOffsetCorrection%>;
    <%}%>
				default: return -1;
			}
		}
  <%}%>
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

<%}%>
<%if (genModel.isOperationReflection() && isImplementation && (!genClass.getMixinGenOperations().isEmpty() || !genClass.getOverrideGenOperations(genClass.getExtendedGenOperations(), genClass.getImplementedGenOperations()).isEmpty() || genClass.hasOffsetCorrection() && !genClass.getGenOperations().isEmpty())) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	public int eDerivedOperationID(int baseOperationID, Class<%=singleWildcard%> baseClass)
	{
  <%for (GenClass extendedGenClass : genClass.getExtendedGenClasses()) { List<GenOperation> extendedImplementedGenOperations = extendedGenClass.getImplementedGenOperations(); List<GenOperation> implementedGenOperations = genClass.getImplementedGenOperations();%>
    <%if (!genClass.getOverrideGenOperations(extendedImplementedGenOperations, implementedGenOperations).isEmpty()) {%>
		if (baseClass == <%=extendedGenClass.getRawImportedInterfaceName()%>.class)
		{
			switch (baseOperationID)
			{
      <%for (GenOperation genOperation : extendedImplementedGenOperations) { GenOperation overrideGenOperation = genClass.getOverrideGenOperation(genOperation);%>
        <%if (implementedGenOperations.contains(overrideGenOperation)) {%>
				case <%=extendedGenClass.getQualifiedOperationID(genOperation)%>: return <%=genClass.getQualifiedOperationID(overrideGenOperation)%><%=positiveOperationOffsetCorrection%>;
        <%}%>
      <%}%>
				default: return super.eDerivedOperationID(baseOperationID, baseClass);
			}
		}
    <%}%>
  <%}%>
  <%for (GenClass mixinGenClass : genClass.getMixinGenClasses()) {%>
		if (baseClass == <%=mixinGenClass.getRawImportedInterfaceName()%>.class)
		{
			switch (baseOperationID)
			{
    <%for (GenOperation genOperation : mixinGenClass.getGenOperations()) { GenOperation overrideGenOperation = genClass.getOverrideGenOperation(genOperation);%>
				case <%=mixinGenClass.getQualifiedOperationID(genOperation)%>: return <%=genClass.getQualifiedOperationID(overrideGenOperation != null ? overrideGenOperation : genOperation)%><%=positiveOperationOffsetCorrection%>;
    <%}%>
				default: return -1;
			}
		}
  <%}%>
  <%if (genClass.hasOffsetCorrection() && !genClass.getGenOperations().isEmpty()) {%>
		if (baseClass == <%=genClass.getRawImportedInterfaceName()%>.class)
		{
			switch (baseOperationID<%=negativeOperationOffsetCorrection%>)
			{
    <%for (GenOperation genOperation : genClass.getGenOperations()) {%>
				case <%=genClass.getQualifiedOperationID(genOperation)%>: return <%=genClass.getQualifiedOperationID(genOperation)%><%=positiveOperationOffsetCorrection%>;
    <%}%>
				default: return -1;
			}
		}
  <%}%>
		return super.eDerivedOperationID(baseOperationID, baseClass);
	}

<%}%>
<%if (isImplementation && genModel.isVirtualDelegation()) { String eVirtualValuesField = genClass.getEVirtualValuesField();%>
  <%if (eVirtualValuesField != null) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	protected Object[] eVirtualValues()
	{
		return <%=eVirtualValuesField%>;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	protected void eSetVirtualValues(Object[] newValues)
	{
		<%=eVirtualValuesField%> = newValues;
	}

  <%}%>
  <%{ List<String> eVirtualIndexBitFields = genClass.getEVirtualIndexBitFields(new ArrayList<String>());%>
    <%if (!eVirtualIndexBitFields.isEmpty()) { List<String> allEVirtualIndexBitFields = genClass.getAllEVirtualIndexBitFields(new ArrayList<String>());%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	protected int eVirtualIndexBits(int offset)
	{
		switch (offset)
		{
      <%for (int i = 0; i < allEVirtualIndexBitFields.size(); i++) {%>
			case <%=i%> :
				return <%=allEVirtualIndexBitFields.get(i)%>;
      <%}%>
			default :
				throw new IndexOutOfBoundsException();
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	protected void eSetVirtualIndexBits(int offset, int newIndexBits)
	{
		switch (offset)
		{
      <%for (int i = 0; i < allEVirtualIndexBitFields.size(); i++) {%>
			case <%=i%> :
				<%=allEVirtualIndexBitFields.get(i)%> = newIndexBits;
				break;
      <%}%>
			default :
				throw new IndexOutOfBoundsException();
		}
	}

    <%}%>
  <%}%>
<%}%>
<%if (genModel.isOperationReflection() && isImplementation && !genClass.getImplementedGenOperations().isEmpty()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
  <%if (genModel.useGenerics()) {%>
    <%boolean isUnchecked = false; boolean isRaw = false; LOOP: for (GenOperation genOperation : (genModel.isMinimalReflectiveMethods() ? genClass.getImplementedGenOperations() : genClass.getAllGenOperations())) { for (GenParameter genParameter : genOperation.getGenParameters()) { if (genParameter.isUncheckedCast()) { if (genParameter.getTypeGenDataType() == null || !genParameter.getTypeGenDataType().isObjectType()) { isUnchecked = true; } if (genParameter.usesOperationTypeParameters() && !genParameter.getEcoreParameter().getEGenericType().getETypeArguments().isEmpty()) { isRaw = true; break LOOP; }}}}%>
    <%if (isUnchecked) {%>
	@SuppressWarnings(<%if (!isRaw) {%>"unchecked"<%} else {%>{"rawtypes", "unchecked" }<%}%>)
    <%}%>
  <%}%>
	public Object eInvoke(int operationID, <%=genModel.getImportedName("org.eclipse.emf.common.util.EList")%><%=singleWildcard%> arguments) throws <%=genModel.getImportedName(isGWT ? "org.eclipse.emf.common.util.InvocationTargetException" : "java.lang.reflect.InvocationTargetException")%>
	{
		switch (operationID<%=negativeOperationOffsetCorrection%>)
		{
<%for (GenOperation genOperation : (genModel.isMinimalReflectiveMethods() ? genClass.getImplementedGenOperations() : genClass.getAllGenOperations())) { List<GenParameter> genParameters = genOperation.getGenParameters(); int size = genParameters.size();  boolean hasCheckedException = genOperation.hasCheckedException(); String indent = hasCheckedException ? "\t" : ""; GenOperation overrideGenOperation = genClass.getOverrideGenOperation(genOperation);%>
			case <%=genClass.getQualifiedOperationID(overrideGenOperation != null ? overrideGenOperation : genOperation)%>:
  <%if (hasCheckedException) {%>
				try
				{
  <%/*}*/}%>
  <%if (genOperation.isVoid()) {%>
				<%=indent%><%=genOperation.getName()%>(<%for (int i = 0; i < size; i++) { GenParameter genParameter = genParameters.get(i);%><%if (!isJDK50 && genParameter.isPrimitiveType()) {%>(<%}%><%if (genParameter.getTypeGenDataType() == null || !genParameter.getTypeGenDataType().isObjectType() || !genParameter.usesOperationTypeParameters() && !genParameter.getRawType().equals(genParameter.getType(genClass))) {%>(<%=genParameter.usesOperationTypeParameters() ? genParameter.getRawImportedType() : genParameter.getObjectType(genClass)%>)<%}%>arguments.get(<%=i%>)<%if (!isJDK50 && genParameter.isPrimitiveType()) {%>).<%=genParameter.getPrimitiveValueFunction()%>()<%}%><%if (i < (size - 1)) {%>, <%}%><%}%>);
				<%=indent%>return null;
  <%} else {%>
				<%=indent%>return <%if (!isJDK50 && genOperation.isPrimitiveType()) {%>new <%=genOperation.getObjectType(genClass)%>(<%}%><%=genOperation.getName()%>(<%for (int i = 0; i < size; i++) { GenParameter genParameter = genParameters.get(i);%><%if (!isJDK50 && genParameter.isPrimitiveType()) {%>(<%}%><%if (genParameter.getTypeGenDataType() == null || !genParameter.getTypeGenDataType().isObjectType() || !genParameter.usesOperationTypeParameters() && !genParameter.getRawType().equals(genParameter.getType(genClass))) {%>(<%=genParameter.usesOperationTypeParameters() ? genParameter.getRawImportedType() : genParameter.getObjectType(genClass)%>)<%}%>arguments.get(<%=i%>)<%if (!isJDK50 && genParameter.isPrimitiveType()) {%>).<%=genParameter.getPrimitiveValueFunction()%>()<%}%><%if (i < (size - 1)) {%>, <%}%><%}%>)<%if (!isJDK50 && genOperation.isPrimitiveType()) {%>)<%}%>;
  <%}%>
  <%if (hasCheckedException) {/*{*/%>
				}
				catch (<%=genModel.getImportedName("java.lang.Throwable")%> throwable)
				{
					throw new <%=genModel.getImportedName(isGWT ? "org.eclipse.emf.common.util.InvocationTargetException" : "java.lang.reflect.InvocationTargetException")%>(throwable);
				}
  <%}%>
<%}%>
<%if (forceDefaultCase) {%>
			default:
<%} else { // {%>
		}
<%}%>
<%if (genModel.isMinimalReflectiveMethods()) {%>
<%=indentDefaultCase%>		return super.eInvoke(operationID, arguments);
<%} else {%>
<%=indentDefaultCase%>		return eDynamicInvoke(operationID, arguments);
<%}%>
<%if (forceDefaultCase) { // {%>
		}
<%} // }%>
	}

<%}%>
<%if (!genClass.hasImplementedToStringGenOperation() && isImplementation && !genModel.isReflectiveDelegation() && !genModel.isDynamicDelegation() && !genClass.getToStringGenFeatures().isEmpty()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	public String toString()
	{
		if (eIsProxy()) return super.toString();

		<%=genModel.useGenerics() ? "StringBuilder" : "StringBuffer"%> result = new <%=genModel.useGenerics() ? "StringBuilder" : "StringBuffer"%>(super.toString());
  <%{ boolean first = true;%>
    <%for (GenFeature genFeature : genClass.getToStringGenFeatures()) {%>
      <%if (first) { first = false;%>
		result.append(" (<%=genFeature.getName()%>: ");<%=genModel.getNonNLS()%>
      <%} else {%>
		result.append(", <%=genFeature.getName()%>: ");<%=genModel.getNonNLS()%>
      <%}%>
      <%if (genFeature.isUnsettable() && !genFeature.isListType()) {%>
        <%if (genModel.isVirtualDelegation() && !genFeature.isPrimitiveType()) {%>
		if (eVirtualIsSet(<%=genClass.getQualifiedFeatureID(genFeature)%><%=positiveOffsetCorrection%>)) result.append(eVirtualGet(<%=genClass.getQualifiedFeatureID(genFeature)%><%=positiveOffsetCorrection%>)); else result.append("<unset>");<%=genModel.getNonNLS()%>
        <%} else {%>
          <%if (genClass.isFlag(genFeature)) {%>
            <%if (genFeature.isBooleanType()) {%>
		if (<%if (genClass.isESetFlag(genFeature)) {%>(<%=genClass.getESetFlagsField(genFeature)%> & <%=genFeature.getUpperName()%>_ESETFLAG) != 0<%} else {%><%=genFeature.getUncapName()%>ESet<%}%>) result.append((<%=genClass.getFlagsField(genFeature)%> & <%=genFeature.getUpperName()%>_EFLAG) != 0); else result.append("<unset>");<%=genModel.getNonNLS()%>
            <%} else {%>
		if (<%if (genClass.isESetFlag(genFeature)) {%>(<%=genClass.getESetFlagsField(genFeature)%> & <%=genFeature.getUpperName()%>_ESETFLAG) != 0<%} else {%><%=genFeature.getUncapName()%>ESet<%}%>) result.append(<%=genFeature.getUpperName()%>_EFLAG_VALUES[(<%=genClass.getFlagsField(genFeature)%> & <%=genFeature.getUpperName()%>_EFLAG) >>> <%=genFeature.getUpperName()%>_EFLAG_OFFSET]); else result.append("<unset>");<%=genModel.getNonNLS()%>
            <%}%>
          <%} else {%>
		if (<%if (genClass.isESetFlag(genFeature)) {%>(<%=genClass.getESetFlagsField(genFeature)%> & <%=genFeature.getUpperName()%>_ESETFLAG) != 0<%} else {%><%=genFeature.getUncapName()%>ESet<%}%>) result.append(<%=genFeature.getSafeName()%>); else result.append("<unset>");<%=genModel.getNonNLS()%>
          <%}%>
        <%}%>
      <%} else {%>
        <%if (genModel.isVirtualDelegation() && !genFeature.isPrimitiveType()) {%>
		result.append(eVirtualGet(<%=genClass.getQualifiedFeatureID(genFeature)%><%=positiveOffsetCorrection%><%if (!genFeature.isListType() && !genFeature.isReferenceType()){%>, <%=genFeature.getEDefault()%><%}%>));
        <%} else {%>
          <%if (genClass.isFlag(genFeature)) {%>
          <%if (genFeature.isBooleanType()) {%>
		result.append((<%=genClass.getFlagsField(genFeature)%> & <%=genFeature.getUpperName()%>_EFLAG) != 0);
          <%} else {%>
		result.append(<%=genFeature.getUpperName()%>_EFLAG_VALUES[(<%=genClass.getFlagsField(genFeature)%> & <%=genFeature.getUpperName()%>_EFLAG) >>> <%=genFeature.getUpperName()%>_EFLAG_OFFSET]);
          <%}%>
          <%} else {%>
		result.append(<%=genFeature.getSafeName()%>);
          <%}%>
        <%}%>
      <%}%>
    <%}%>
  <%}%>
		result.append(')');
		return result.toString();
	}

<%}%>
<%if (isImplementation && genClass.isMapEntry()) { GenFeature keyFeature = genClass.getMapEntryKeyFeature(); GenFeature valueFeature = genClass.getMapEntryValueFeature();%>
<%String objectType = genModel.getImportedName("java.lang.Object");%>
<%String keyType = isJDK50 ? keyFeature.getObjectType(genClass) : objectType;%>
<%String valueType = isJDK50 ? valueFeature.getObjectType(genClass) : objectType;%>
<%String eMapType = genModel.getImportedName("org.eclipse.emf.common.util.EMap") + (isJDK50 ? "<" + keyType + ", " + valueType + ">" : "");%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
      <%if (isGWT) {%>
	@<%=genModel.getImportedName("com.google.gwt.user.client.rpc.GwtTransient")%>
      <%}%>
	protected int hash = -1;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (useInterfaceOverrideAnnotation) {%>
	@Override
  <%}%>
	public int getHash()
	{
		if (hash == -1)
		{
			<%=objectType%> theKey = getKey();
			hash = (theKey == null ? 0 : theKey.hashCode());
		}
		return hash;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (useInterfaceOverrideAnnotation) {%>
	@Override
  <%}%>
	public void setHash(int hash)
	{
		this.hash = hash;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (useInterfaceOverrideAnnotation) {%>
	@Override
  <%}%>
	public <%=keyType%> getKey()
	{
  <%if (!isJDK50 && keyFeature.isPrimitiveType()) {%>
		return new <%=keyFeature.getObjectType(genClass)%>(getTypedKey());
  <%} else {%>
		return getTypedKey();
  <%}%>
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (useInterfaceOverrideAnnotation) {%>
	@Override
  <%}%>
	public void setKey(<%=keyType%> key)
	{
  <%if (keyFeature.isListType()) {%>
		getTypedKey().addAll(<%if (!genModel.useGenerics()) {%>(<%=genModel.getImportedName("java.util.Collection")%>)<%}%>key);
  <%} else if (isJDK50) {%>
		setTypedKey(key);
  <%} else if (keyFeature.isPrimitiveType()) {%>
		setTypedKey(((<%=keyFeature.getObjectType(genClass)%>)key).<%=keyFeature.getPrimitiveValueFunction()%>());
  <%} else {%>
		setTypedKey((<%=keyFeature.getImportedType(genClass)%>)key);
  <%}%>
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (useInterfaceOverrideAnnotation) {%>
	@Override
  <%}%>
	public <%=valueType%> getValue()
	{
  <%if (!isJDK50 && valueFeature.isPrimitiveType()) {%>
		return new <%=valueFeature.getObjectType(genClass)%>(getTypedValue());
  <%} else {%>
		return getTypedValue();
  <%}%>
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (useInterfaceOverrideAnnotation) {%>
	@Override
  <%}%>
	public <%=valueType%> setValue(<%=valueType%> value)
	{
		<%=valueType%> oldValue = getValue();
  <%if (valueFeature.isListType()) {%>
		getTypedValue().clear();
		getTypedValue().addAll(<%if (!genModel.useGenerics()) {%>(<%=genModel.getImportedName("java.util.Collection")%>)<%}%>value);
  <%} else if (isJDK50) {%>
		setTypedValue(value);
  <%} else if (valueFeature.isPrimitiveType()) {%>
		setTypedValue(((<%=valueFeature.getObjectType(genClass)%>)value).<%=valueFeature.getPrimitiveValueFunction()%>());
  <%} else {%>
		setTypedValue((<%=valueFeature.getImportedType(genClass)%>)value);
  <%}%>
		return oldValue;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useGenerics()) {%>
	@SuppressWarnings("unchecked")
  <%}%>
	public <%=eMapType%> getEMap()
	{
		<%=genModel.getImportedName("org.eclipse.emf.ecore.EObject")%> container = eContainer();
		return container == null ? null : (<%=eMapType%>)container.eGet(eContainmentFeature());
	}

<%}%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern/egf/EMF_Pattern.fcore#LogicalName=org.eclipse.egf.emf.pattern.model.call.Interface.Interface.insert" args="genClass:genClass,genPackage:genPackage,genModel:genModel,isJDK50:isJDK50,isInterface:isInterface,isImplementation:isImplementation,useInterfaceOverrideAnnotation:useInterfaceOverrideAnnotation,isGWT:isGWT,forceDefaultCase:forceDefaultCase,indentDefaultCase:indentDefaultCase,publicStaticFinalFlag:publicStaticFinalFlag,singleWildcard:singleWildcard,negativeOffsetCorrection:negativeOffsetCorrection,positiveOffsetCorrection:positiveOffsetCorrection,negativeOperationOffsetCorrection:negativeOperationOffsetCorrection,positiveOperationOffsetCorrection:positiveOperationOffsetCorrection"%>
} //<%=isInterface ? " " + genClass.getInterfaceName() : genClass.getClassName()%>
<%// TODO fix the space above%>
<%genModel.emitSortedImports();%>
