<%if (isImplementation) {%>
  <%if (!UML2GenModelUtil.isOperationsClasses(genPackage) && UML2GenModelUtil.hasOCLOperationBodies(genClass) && (!UML2GenModelUtil.hasOCLOperationBodies(genClass.getClassExtendsGenClass()) || !UML2GenModelUtil.isOperationsClasses(genClass.getClassExtendsGenClass().getGenPackage()))) {%>
	/**
	 * The cached environment for evaluating OCL expressions.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 * @ordered
	 */
	protected static final <%=genModel.getImportedName("org.eclipse.ocl.ecore.OCL")%> EOCL_ENV = <%=genModel.getImportedName("org.eclipse.ocl.ecore.OCL")%>.newInstance();

  <%}%>
  <%if (genClass.isModelRoot()) {%>
    <%if (UML2GenModelUtil.isFactoryMethods(genClass)) {%>
	/**
	 * Creates a new instance of the specified Ecore class.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param eClass The Ecore class of the instance to create.
	 * @return The new instance.
	 * @generated
	 */
	protected <%=genModel.getImportedName("org.eclipse.emf.ecore.EObject")%> create(<%=genModel.getImportedName("org.eclipse.emf.ecore.EClass")%> eClass)
	{
		return <%=genModel.getImportedName("org.eclipse.emf.ecore.util.EcoreUtil")%>.create(eClass);
	}

    <%}%>
    <%if (UML2GenModelUtil.isCacheAdapterSupport(genClass)) {%>
	/**
	 * Retrieves the cache adapter for this '<em><b><%=genClass.getFormattedName()%></b></em>'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @return The cache adapter for this '<em><b><%=genClass.getFormattedName()%></b></em>'.
	 * @generated
	 */
	protected <%=genModel.getImportedName("org.eclipse.uml2.common.util.CacheAdapter")%> getCacheAdapter()
	{
		return <%=genModel.getImportedName("org.eclipse.uml2.common.util.CacheAdapter")%>.getCacheAdapter(this);
	}

    <%}%>
  <%}%>
  <%for (GenFeature genFeature : UML2GenModelUtil.getImplementedUnionGenFeatures(genClass)) {%>
    <%if (genFeature.isGet()) {%>
      <%if (genFeature.isListType()) {%>
        <%if (!UML2GenModelUtil.isDerivedUnionListType(genClass, genFeature)) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
         <%if (genModel.useClassOverrideAnnotation() && genClass.getExtendedGenFeatures().contains(genFeature)) {%>
	@Override
         <%}%>
	protected <%=genFeature.getImportedType(genClass)%> <%=genFeature.getGetAccessor()%>Helper(<%=genFeature.getImportedType(genClass)%> <%=genFeature.getSafeName()%>)
	{
          <%if (genClass.getExtendedGenFeatures().contains(genFeature)) {%>
            <%if (UML2GenModelUtil.isDerivedUnionListType(genClass.getClassExtendsGenClass(), genFeature)) {%>
		<%=genFeature.getSafeName()%>.addAll(super.<%=genFeature.getGetAccessor()%>());
            <%} else {%>
		super.<%=genFeature.getGetAccessor()%>Helper(<%=genFeature.getSafeName()%>);
            <%}%>
          <%}%>
          <%for (GenFeature subsetGenFeature : UML2GenModelUtil.getSubsetGenFeatures(genClass, genFeature)) {%>
            <%if (!genClass.getExtendedGenFeatures().contains(subsetGenFeature)) {%>
              <%if (subsetGenFeature.isListType()) {%>
                <%if (subsetGenFeature.isResolveProxies() || UML2GenModelUtil.isUnion(subsetGenFeature)) {%>
                  <%if (subsetGenFeature.isIsSet() || UML2GenModelUtil.isUnion(subsetGenFeature) || UML2GenModelUtil.isRedefinition(subsetGenFeature) || UML2GenModelUtil.isRedefined(genClass, subsetGenFeature)) {%>
		if (isSet<%=subsetGenFeature.getAccessorName()%>())
		{
			for (<%=genModel.getImportedName("java.util.Iterator")%><%if (genModel.useGenerics()) {%><<%=genModel.getImportedName(subsetGenFeature.getQualifiedListItemType(genClass))%>><%}%> i = ((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.InternalEList")%>) <%=subsetGenFeature.getGetAccessor()%>()).basicIterator(); i.hasNext(); )
			{
				<%=genFeature.getSafeName()%>.add(i.next());
			}
		}
                  <%} else {%>
                    <%if (genClass.isField(subsetGenFeature)) {%>
		if (eIsSet(<%=genClass.getQualifiedFeatureID(subsetGenFeature)%>))
		{
			for (<%=genModel.getImportedName("java.util.Iterator")%><%if (genModel.useGenerics()) {%><<%=genModel.getImportedName(subsetGenFeature.getQualifiedListItemType(genClass))%>><%}%> i = ((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.InternalEList")%>) <%=subsetGenFeature.getGetAccessor()%>()).basicIterator(); i.hasNext(); )
			{
				<%=genFeature.getSafeName()%>.add(i.next());
			}
		}
                    <%} else {%>
		<%=subsetGenFeature.getImportedType(genClass)%> <%=subsetGenFeature.getSafeName()%> = <%=subsetGenFeature.getGetAccessor()%>();
		if (!<%=subsetGenFeature.getSafeName()%>.isEmpty())
		{
			for (<%=genModel.getImportedName("java.util.Iterator")%><%if (genModel.useGenerics()) {%><<%=genModel.getImportedName(subsetGenFeature.getQualifiedListItemType(genClass))%>><%}%> i = ((<%=genModel.getImportedName("org.eclipse.emf.ecore.util.InternalEList")%>) <%=subsetGenFeature.getSafeName()%>).basicIterator(); i.hasNext(); )
			{
				<%=genFeature.getSafeName()%>.add(i.next());
			}
		}
                    <%}%>
                  <%}%>
                <%} else {%>
                  <%if (subsetGenFeature.isIsSet() || UML2GenModelUtil.isUnion(subsetGenFeature) || UML2GenModelUtil.isRedefinition(subsetGenFeature) || UML2GenModelUtil.isRedefined(genClass, subsetGenFeature)) {%>
		if (isSet<%=subsetGenFeature.getAccessorName()%>())
		{
			<%=genFeature.getSafeName()%>.addAll(<%=subsetGenFeature.getGetAccessor()%>());
		}
                  <%} else {%>
                    <%if (genClass.isField(subsetGenFeature)) {%>
		if (eIsSet(<%=genClass.getQualifiedFeatureID(subsetGenFeature)%>))
		{
			<%=genFeature.getSafeName()%>.addAll(<%=subsetGenFeature.getGetAccessor()%>());
		}
                    <%} else {%>
		<%=subsetGenFeature.getImportedType(genClass)%> <%=subsetGenFeature.getSafeName()%> = <%=subsetGenFeature.getGetAccessor()%>();
		if (!<%=subsetGenFeature.getSafeName()%>.isEmpty())
		{
			<%=genFeature.getSafeName()%>.addAll(<%=subsetGenFeature.getSafeName()%>);
		}
                    <%}%>
                  <%}%>
                <%}%>
              <%} else {%>
                <%if (subsetGenFeature.isIsSet() || UML2GenModelUtil.isUnion(subsetGenFeature) || UML2GenModelUtil.isRedefinition(subsetGenFeature) || UML2GenModelUtil.isRedefined(genClass, subsetGenFeature)) {%>
		if (isSet<%=subsetGenFeature.getAccessorName()%>())
		{
			<%=genFeature.getSafeName()%>.add(<%if (subsetGenFeature.isBasicGet()) {%>basicGet<%=subsetGenFeature.getAccessorName()%><%} else {%><%=subsetGenFeature.getGetAccessor()%><%}%>());
		}
                <%} else {%>
		<%=subsetGenFeature.getImportedType(genClass)%> <%=subsetGenFeature.getSafeName()%> = <%if (subsetGenFeature.isBasicGet()) {%>basicGet<%=subsetGenFeature.getAccessorName()%><%} else {%><%=subsetGenFeature.getGetAccessor()%><%}%>();
		if (<%=subsetGenFeature.getSafeName()%> != null)
		{
			<%=genFeature.getSafeName()%>.add(<%=subsetGenFeature.getSafeName()%>);
		}
                <%}%>
              <%}%>
            <%}%>
          <%}%>
		return <%=genFeature.getSafeName()%>;
	}

        <%}%>
      <%}%>
    <%}%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
    <%if (isJDK50) { //isSetGenFeature.annotations.insert.javajetinc%>
<%@ include file="isSetGenFeature.annotations.insert.javajetinc" fail="silent" %>
    <%}%>
	public boolean isSet<%=genFeature.getAccessorName()%>()
	{
    <%if (!UML2GenModelUtil.getIsSetSubsetGenFeatures(genClass, genFeature).isEmpty()) { boolean first = true;%>
      <%if (first && genClass.getExtendedGenFeatures().contains(genFeature)) { first = false;%>
		return super.isSet<%=genFeature.getAccessorName()%>()
      <%}%>
      <%for (Iterator<GenFeature> isSetSubsetGenFeatures = UML2GenModelUtil.getIsSetSubsetGenFeatures(genClass, genFeature).iterator(); isSetSubsetGenFeatures.hasNext();) { GenFeature isSetSubsetGenFeature = isSetSubsetGenFeatures.next();%>
        <%if (first) { first = false;%>
          <%if (isSetSubsetGenFeature.isIsSet() || UML2GenModelUtil.isUnion(isSetSubsetGenFeature) || UML2GenModelUtil.isRedefinition(isSetSubsetGenFeature) || UML2GenModelUtil.isRedefined(genClass, isSetSubsetGenFeature)) {%>
		return isSet<%=isSetSubsetGenFeature.getAccessorName()%>()<%if (!isSetSubsetGenFeatures.hasNext()) {%>;<%}%>
          <%} else if (UML2GenModelUtil.isDuplicate(isSetSubsetGenFeature) && !UML2GenModelUtil.isRedefinition(isSetSubsetGenFeature)) {%>
            <%if (isSetSubsetGenFeature.isListType()) {%>
		return !<%=isSetSubsetGenFeature.getGetAccessor()%>().isEmpty()<%if (!isSetSubsetGenFeatures.hasNext()) {%>;<%}%>
            <%} else {%>
		return <%if (isSetSubsetGenFeature.isBasicGet()) {%>basicGet<%=isSetSubsetGenFeature.getAccessorName()%><%} else {%><%=isSetSubsetGenFeature.getGetAccessor()%><%}%>() != null<%if (!isSetSubsetGenFeatures.hasNext()) {%>;<%}%>
            <%}%>
          <%} else {%>
		return eIsSet(<%=genClass.getQualifiedFeatureID(isSetSubsetGenFeature)%>)<%if (!isSetSubsetGenFeatures.hasNext()) {%>;<%}%>
          <%}%>
        <%} else {%>
          <%if (isSetSubsetGenFeature.isIsSet() || UML2GenModelUtil.isUnion(isSetSubsetGenFeature) || UML2GenModelUtil.isRedefinition(isSetSubsetGenFeature) || UML2GenModelUtil.isRedefined(genClass, isSetSubsetGenFeature)) {%>
			|| isSet<%=isSetSubsetGenFeature.getAccessorName()%>()<%if (!isSetSubsetGenFeatures.hasNext()) {%>;<%}%>
          <%} else if (UML2GenModelUtil.isDuplicate(isSetSubsetGenFeature) && !UML2GenModelUtil.isRedefinition(isSetSubsetGenFeature)) {%>
            <%if (isSetSubsetGenFeature.isListType()) {%>
			|| !<%=isSetSubsetGenFeature.getGetAccessor()%>().isEmpty()<%if (!isSetSubsetGenFeatures.hasNext()) {%>;<%}%>
            <%} else {%>
			|| <%if (isSetSubsetGenFeature.isBasicGet()) {%>basicGet<%=isSetSubsetGenFeature.getAccessorName()%><%} else {%><%=isSetSubsetGenFeature.getGetAccessor()%><%}%>() != null<%if (!isSetSubsetGenFeatures.hasNext()) {%>;<%}%>
            <%}%>
          <%} else {%>
			|| eIsSet(<%=genClass.getQualifiedFeatureID(isSetSubsetGenFeature)%>)<%if (!isSetSubsetGenFeatures.hasNext()) {%>;<%}%>
          <%}%>
        <%}%>
      <%}%>
    <%} else {%>
      <%if (genClass.getExtendedGenFeatures().contains(genFeature)) {%>
		return super.isSet<%=genFeature.getAccessorName()%>();
      <%} else {%>
		return false;
      <%}%>
    <%}%>
	}

  <%}%>
  <%for (GenFeature genFeature : UML2GenModelUtil.getImplementedRedefinedGenFeatures(genClass)) { GenFeature redefinitionGenFeature = UML2GenModelUtil.getRedefinitionGenFeatures(genClass, genFeature).iterator().next();%>
    <%if (genFeature.isGet()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
      <%if (isJDK50) { //getGenFeature.annotations.insert.javajetinc%>
<%@ include file="getGenFeature.annotations.insert.javajetinc" fail="silent" %>
      <%}%>
	public <%=genFeature.getImportedType(genClass)%> <%=genFeature.getGetAccessor()%>()
	{
      <%if (genFeature.isListType()) {%>
        <%if (redefinitionGenFeature.isListType()) {%>
          <%if (genModel.useGenerics() && !redefinitionGenFeature.getListItemType(genClass).equals(genFeature.getListItemType(genClass))) {%>
		@SuppressWarnings("unchecked")
		<%=genFeature.getImportedType(genClass)%> <%=redefinitionGenFeature.getUncapName()%> = (<%=genFeature.getImportedType(genClass)%>)((<%=genModel.getImportedName("org.eclipse.emf.common.util.EList") + "<?>"%>)<%=redefinitionGenFeature.getGetAccessor()%>());
		return <%=redefinitionGenFeature.getUncapName()%>;
          <%} else {%>
		return <%=redefinitionGenFeature.getGetAccessor()%>();
          <%}%>
        <%} else {%>
		return new <%=genModel.getImportedName("org.eclipse.emf.ecore.util.EcoreEList")%>.UnmodifiableEList<%if (genModel.useGenerics()) {%><%="<" + genFeature.getListItemType(genClass) + ">"%><%}%>(this, <%if (UML2GenModelUtil.isDuplicate(genFeature) && !UML2GenModelUtil.isRedefinition(genFeature)) {%>null<%} else {%><%=genFeature.getQualifiedFeatureAccessor()%><%}%>, 0, <%=genModel.getImportedName("java.util.Collections")%>.EMPTY_LIST.toArray());
        <%}%>
      <%} else {%>
        <%if (redefinitionGenFeature.isListType()) {%>
		return null;
        <%} else {%>
		return <%=redefinitionGenFeature.getGetAccessor()%>();
        <%}%>
      <%}%>
	}

    <%}%>
    <%if (genFeature.isBasicGet()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
      <%if (isJDK50) { //basicGetGenFeature.annotations.insert.javajetinc%>
<%@ include file="basicGetGenFeature.annotations.insert.javajetinc" fail="silent" %>
      <%}%>
	public <%=genFeature.getImportedType(genClass)%> basicGet<%=genFeature.getAccessorName()%>()
	{
      <%if (redefinitionGenFeature.isListType()) {%>
		return null;
      <%} else {%>
		return <%if (redefinitionGenFeature.isBasicGet()) {%>basicGet<%=redefinitionGenFeature.getAccessorName()%><%} else {%><%=redefinitionGenFeature.getGetAccessor()%><%}%>();
      <%}%>
	}

    <%}%>
    <%if (genFeature.isBasicSet()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
      <%if (isJDK50) { //basicSetGenFeature.annotations.insert.javajetinc%>
<%@ include file="basicSetGenFeature.annotations.insert.javajetinc" fail="silent" %>
      <%}%>
	public <%=genModel.getImportedName("org.eclipse.emf.common.notify.NotificationChain")%> basicSet<%=genFeature.getAccessorName()%>(<%=genFeature.getImportedInternalType(genClass)%> new<%=genFeature.getCapName()%>, <%=genModel.getImportedName("org.eclipse.emf.common.notify.NotificationChain")%> msgs)
	{
      <%if (!redefinitionGenFeature.isSet() || redefinitionGenFeature.isListType()) {%>
		throw new UnsupportedOperationException();
      <%} else {%>
        <%if (!genFeature.getType(genClass).equals(redefinitionGenFeature.getType(genClass))) {%>
		if (new<%=genFeature.getCapName()%> != null && !(new<%=genFeature.getCapName()%> instanceof <%=redefinitionGenFeature.getImportedType(genClass)%>))
		{
			throw new IllegalArgumentException(String.valueOf(new<%=genFeature.getCapName()%>));
		}
        <%}%>
        <%if (redefinitionGenFeature.isBasicSet()) {%>
		return basicSet<%=redefinitionGenFeature.getAccessorName()%>(<%if (!genFeature.getType(genClass).equals(redefinitionGenFeature.getType(genClass))) {%>(<%=redefinitionGenFeature.getImportedType(genClass)%>) <%}%>new<%=genFeature.getCapName()%>, msgs);
        <%} else {%>
		set<%=redefinitionGenFeature.getAccessorName()%>(<%if (!genFeature.getType(genClass).equals(redefinitionGenFeature.getType(genClass))) {%>(<%=redefinitionGenFeature.getImportedType(genClass)%>) <%}%>new<%=genFeature.getCapName()%>);
		return msgs;
        <%}%>
      <%}%>
	}

    <%}%>
    <%if (genFeature.isSet()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
      <%if (isJDK50) { //setGenFeature.annotations.insert.javajetinc%>
<%@ include file="setGenFeature.annotations.insert.javajetinc" fail="silent" %>
      <%}%>
	public void set<%=genFeature.getAccessorName()%>(<%=genFeature.getImportedType(genClass)%> new<%=genFeature.getCapName()%>)
	{
      <%if (!redefinitionGenFeature.isSet() || redefinitionGenFeature.isListType()) {%>
		throw new UnsupportedOperationException();
      <%} else {%>
        <%if (!genFeature.getType(genClass).equals(redefinitionGenFeature.getType(genClass))) {%>
		if (new<%=genFeature.getCapName()%> != null && !(new<%=genFeature.getCapName()%> instanceof <%=redefinitionGenFeature.getImportedType(genClass)%>))
		{
			throw new IllegalArgumentException(String.valueOf(new<%=genFeature.getCapName()%>));
		}
        <%}%>
		set<%=redefinitionGenFeature.getAccessorName()%>(<%if (!genFeature.getType(genClass).equals(redefinitionGenFeature.getType(genClass))) {%>(<%=redefinitionGenFeature.getImportedType(genClass)%>) <%}%>new<%=genFeature.getCapName()%>);
      <%}%>
	}

    <%}%>
<%@ include file="genFeature.insert.javajetinc" fail="silent" %>
  <%}%>
  <%for (GenOperation genOperation : UML2GenModelUtil.getImplementedRedefinedGenOperations(genClass)) { GenOperation redefinitionGenOperation = UML2GenModelUtil.getRedefinitionGenOperations(genClass, genOperation).iterator().next();%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
    <%if (isJDK50) { //genOperation.annotations.insert.javajetinc%>
<%@ include file="genOperation.annotations.insert.javajetinc" fail="silent" %>
    <%}%>
	public <%=genOperation.getTypeParameters(genClass)%><%=genOperation.getImportedType(genClass)%> <%=genOperation.getName()%>(<%=genOperation.getParameters(genClass)%>)<%=genOperation.getThrows(genClass)%>
	{
    <%if (genOperation.isVoid()) {%>
		<%=redefinitionGenOperation.getName()%>(<%=genOperation.getParameterNames(", ")%>);
    <%} else {%>
      <%if (redefinitionGenOperation.isVoid()) {%>
		throw new UnsupportedOperationException();
      <%} else {%>
		return <%=redefinitionGenOperation.getName()%>(<%=genOperation.getParameterNames(", ")%>);
      <%}%>
    <%}%>
	}

  <%}%>
<%}%>