<%@ jet package="org.eclipse.emf.codegen.ecore.templates.model" imports="java.util.* org.eclipse.emf.codegen.ecore.genmodel.* org.eclipse.ocl.examples.codegen.genmodel.OCLGenModelUtil" class="FactoryClass"%>
<%
/**
 * 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
 */
%>
<%GenPackage genPackage = (GenPackage)((Object[])argument)[0]; GenModel genModel=genPackage.getGenModel(); /* Trick to import java.util.* without warnings */Iterator.class.getName();%>
<%final boolean isJDK50 = genModel.getComplianceLevel().getValue() >= GenJDKLevel.JDK50;%>
<%boolean isInterface = Boolean.TRUE.equals(((Object[])argument)[1]); boolean isImplementation = Boolean.TRUE.equals(((Object[])argument)[2]); boolean useInterfaceOverrideAnnotation = OCLGenModelUtil.INSTANCE.useInterfaceOverrideAnnotation(genModel) && !(isInterface && isImplementation);%>
<%String publicStaticFinalFlag = isImplementation ? "public static final " : "";%>
<%@ include file="../Header.javajetinc"%>
<%if (isInterface || genModel.isSuppressInterfaces()) {%>
package <%=genPackage.getReflectionPackageName()%>;
<%} else {%>
package <%=genPackage.getClassPackageName()%>;
<%}%>

<%if (isImplementation) {%>
<%genModel.addPseudoImport("org.eclipse.emf.ecore.impl.MinimalEObjectImpl.Container");%>
<%genModel.addPseudoImport("org.eclipse.emf.ecore.impl.MinimalEObjectImpl.Container.Dynamic");%>
<%genModel.addImport("org.eclipse.emf.ecore.EClass");%>
<%genModel.addImport("org.eclipse.emf.ecore.EObject");%>
<%if (!genPackage.hasJavaLangConflict() && !genPackage.hasInterfaceImplConflict() && !genPackage.getClassPackageName().equals(genPackage.getInterfacePackageName())) genModel.addImport(genPackage.getInterfacePackageName() + ".*");%>
<%}%>
<%genModel.markImportLocation(stringBuffer);%>

<%if (isInterface) {%>
/**
 * <!-- begin-user-doc -->
 * The <b>Factory</b> for the model.
 * It provides a create method for each non-abstract class of the model.
 * <!-- end-user-doc -->
<%if (!genModel.isSuppressEMFMetaData()) {%>
 * @see <%=genPackage.getQualifiedPackageInterfaceName()%>
<%}%>
<%if (OCLGenModelUtil.INSTANCE.hasAPITags(genPackage)) {%>
 * <%=OCLGenModelUtil.INSTANCE.getAPITags(genPackage, genModel.getIndentation(stringBuffer))%>
<%}%>
 * @generated
 */
<%} else {%>
/**
 * <!-- begin-user-doc -->
 * An implementation of the model <b>Factory</b>.
 * <!-- end-user-doc -->
<%if (OCLGenModelUtil.INSTANCE.hasAPITags(genPackage)) {%>
 * <%=OCLGenModelUtil.INSTANCE.getAPITags(genPackage, genModel.getIndentation(stringBuffer))%>
<%}%>
 * @generated
 */
<%}%>
<%if (isJDK50 && OCLGenModelUtil.INSTANCE.hasAPIDeprecatedTag(genPackage)) {%>
@Deprecated
<%}%>
<%if (isImplementation) {%>
  <%if (isJDK50 && !OCLGenModelUtil.INSTANCE.hasAPIDeprecatedTag(genPackage)) { List<GenClassifier> genClassifiers = new ArrayList<GenClassifier>(genPackage.getGenClassifiers()); for (Iterator<GenClassifier> i = genClassifiers.iterator(); i.hasNext(); ) { GenClassifier genClassifier = i.next(); if (genClassifier instanceof GenClass && ((GenClass)genClassifier).isAbstract()) i.remove(); } if (OCLGenModelUtil.INSTANCE.hasAPIDeprecatedTag(genClassifiers)) {%>
@SuppressWarnings("deprecation")
  <%}}%>
public class <%=genPackage.getFactoryClassName()%> extends <%=genModel.getImportedName("org.eclipse.emf.ecore.impl.EFactoryImpl")%><%if (!genModel.isSuppressInterfaces()) {%> implements <%=genPackage.getImportedFactoryInterfaceName()%><%}%>
<%} else {%>
public interface <%=genPackage.getFactoryInterfaceName()%><%if (!genModel.isSuppressEMFMetaData()) {%> extends <%=genModel.getImportedName("org.eclipse.emf.ecore.EFactory")%><%}%>
<%}%>
{
<%if (genModel.hasCopyrightField()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	<%=publicStaticFinalFlag%><%=genModel.getImportedName("java.lang.String")%> copyright = <%=genModel.getCopyrightFieldLiteral()%>;<%=genModel.getNonNLS()%>

<%}%>
<%if (isImplementation && (genModel.isSuppressEMFMetaData() || genModel.isSuppressInterfaces())) {%>
	/**
	 * The singleton instance of the factory.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	<%=publicStaticFinalFlag%><%=genPackage.getFactoryClassName()%> eINSTANCE = init();

<%}%>
<%if (isInterface && genModel.isSuppressEMFMetaData()) {%>
	/**
	 * The singleton instance of the factory.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	<%=publicStaticFinalFlag%><%=genPackage.getFactoryInterfaceName()%> INSTANCE = <%=genPackage.getQualifiedFactoryClassName()%>.eINSTANCE;

<%} else if (isInterface && !genModel.isSuppressInterfaces()) {%>
	/**
	 * The singleton instance of the factory.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	<%=publicStaticFinalFlag%><%=genPackage.getFactoryInterfaceName()%> eINSTANCE = <%=genPackage.getQualifiedFactoryClassName()%>.init();

<%}%>
<%if (isImplementation) {%>
	/**
	 * Creates the default factory implementation.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
<%String factoryType = genModel.isSuppressEMFMetaData() ? genPackage.getFactoryClassName() : genPackage.getImportedFactoryInterfaceName();%>
	public static <%=factoryType%> init()
	{
		try
		{
			<%=factoryType%> the<%=genPackage.getFactoryName()%> = (<%=factoryType%>)<%=genModel.getImportedName("org.eclipse.emf.ecore.EPackage")%>.Registry.INSTANCE.getEFactory(<%=genPackage.getPackageInterfaceName()%>.eNS_URI);
			if (the<%=genPackage.getFactoryName()%> != null)
			{
				return the<%=genPackage.getFactoryName()%>;
			}
		}
		catch (Exception exception)
		{
			<%=genModel.getImportedName("org.eclipse.emf.ecore.plugin.EcorePlugin")%>.INSTANCE.log(exception);
		}
		return new <%=genPackage.getImportedFactoryClassName()%>();
	}

	/**
	 * Creates an instance of the factory.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public <%=genPackage.getFactoryClassName()%>()
	{
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	public EObject create(EClass eClass)
	{
		switch (eClass.getClassifierID())
		{
<%for (GenClass genClass : genPackage.getGenClasses()) {%>
<%if (!genClass.isAbstract()) {%>
			case <%=genPackage.getClassifierValue(genClass)%>: return <%=!genClass.isEObjectExtension() ? "(EObject)" : "" %>create<%=genClass.getName()%>();
<%}%>
<%}%>
			default:
				throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier");<%=genModel.getNonNLS()%><%=genModel.getNonNLS(2)%>
		}
	}

<%if (!genPackage.getAllGenDataTypes().isEmpty()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	public Object createFromString(<%=genModel.getImportedName("org.eclipse.emf.ecore.EDataType")%> eDataType, String initialValue)
	{
		switch (eDataType.getClassifierID())
		{
<%for (GenDataType genDataType : genPackage.getAllGenDataTypes()) {%>
  <%if (genDataType.isSerializable()) {%>
			case <%=genPackage.getClassifierValue(genDataType)%>:
				return create<%=genDataType.getName()%>FromString(eDataType, initialValue);
  <%}%>
<%}%>
			default:
				throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");<%=genModel.getNonNLS()%><%=genModel.getNonNLS(2)%>
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Override
  <%}%>
	public String convertToString(<%=genModel.getImportedName("org.eclipse.emf.ecore.EDataType")%> eDataType, Object instanceValue)
	{
		switch (eDataType.getClassifierID())
		{
<%for (GenDataType genDataType : genPackage.getAllGenDataTypes()) {%>
  <%if (genDataType.isSerializable()) {%>
			case <%=genPackage.getClassifierValue(genDataType)%>:
				return convert<%=genDataType.getName()%>ToString(eDataType, instanceValue);
  <%}%>
<%}%>
			default:
				throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");<%=genModel.getNonNLS()%><%=genModel.getNonNLS(2)%>
		}
	}

<%}%>
<%for (GenClass genClass : genPackage.getGenClasses()) {%>
  <%if (!genClass.isAbstract()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
    <%if (OCLGenModelUtil.INSTANCE.hasAPITags(genClass)) {%>
	 * <%=OCLGenModelUtil.INSTANCE.getAPITags(genClass, genModel.getIndentation(stringBuffer))%>
    <%}%>
	 * @generated
	 */
<%if (isJDK50 && OCLGenModelUtil.INSTANCE.hasAPIDeprecatedTag(genClass)) {%>
	@Deprecated
<%}%>
<%if (useInterfaceOverrideAnnotation && !genClass.isMapEntry()) {%>
	@Override
<%}%>
	public <%=genClass.getTypeParameters()%><%=genClass.getImportedInterfaceName()%><%=genClass.getInterfaceTypeArguments()%> create<%=genClass.getName()%>()
	{
    <%if (genClass.isDynamic()) {%>
		<%=genClass.getImportedInterfaceName()%><%=genClass.getInterfaceTypeArguments()%> <%=genClass.getSafeUncapName()%> = <%=genClass.getCastFromEObject()%>super.create(<%=genClass.getQualifiedClassifierAccessor()%>);
    <%} else {%>
		<%=genClass.getImportedClassName()%><%=genClass.getClassTypeArguments()%> <%=genClass.getSafeUncapName()%> = new <%=genClass.getImportedClassName()%><%=genClass.getClassTypeArguments()%>()<%if (genModel.isSuppressInterfaces() && !genPackage.getReflectionPackageName().equals(genPackage.getInterfacePackageName())) {%>{}<%}%>;
    <%}%>
		return <%=genClass.getSafeUncapName()%>;
	}

  <%}%>
<%}%>
<%for (GenDataType genDataType : genPackage.getAllGenDataTypes()) {%>
  <%if (genDataType.isSerializable()) {%>
<%if (genPackage.isDataTypeConverters() || genDataType.hasCreatorBody()) { String eDataType = genDataType.getQualifiedClassifierAccessor();%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
  <%if (OCLGenModelUtil.INSTANCE.hasAPITags(genDataType)) {%>
	 * <%=OCLGenModelUtil.INSTANCE.getAPITags(genDataType, genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
    <%if (genModel.useGenerics() && genDataType.isUncheckedCast() && !genDataType.hasCreatorBody()) {%>
	@SuppressWarnings("unchecked")
    <%}%>
    <%if (isJDK50 && OCLGenModelUtil.INSTANCE.hasAPIDeprecatedTag(genDataType)) {%>
	@Deprecated
    <%}%>
  <%if (genPackage.isDataTypeConverters() && useInterfaceOverrideAnnotation) {%>
	@Override
  <%}%>
	public <%=genDataType.getImportedParameterizedInstanceClassName()%> create<%=genDataType.getName()%>(<%if (genDataType.hasCreatorBody()) {%>final <%}%>String <%if (genDataType.hasCreatorBody()) {%>it<%} else {%>literal<%}%>)
	{
    <%if (genDataType.hasCreatorBody()) {%>
		<%=genDataType.getCreatorBody(genModel.getIndentation(stringBuffer))%>
    <%} else if (genDataType instanceof GenEnum) {%>
		<%=genDataType.getImportedInstanceClassName()%> result = <%=genDataType.getImportedInstanceClassName()%>.get(literal);
		if (result == null) throw new IllegalArgumentException("The value '" + literal + "' is not a valid enumerator of '" + <%=eDataType%>.getName() + "'");<%=genModel.getNonNLS()%><%=genModel.getNonNLS(2)%><%=genModel.getNonNLS(3)%>
		return result;
    <%} else if (genDataType.getBaseType() != null) { GenDataType genBaseType = genDataType.getBaseType(); boolean isPrimitiveConversion = !genDataType.isPrimitiveType() && genBaseType.isPrimitiveType();%>
      <%if (genBaseType.getGenPackage() == genPackage) {%>
        <%if (isPrimitiveConversion && !isJDK50) {%>
		return new <%=genDataType.getObjectInstanceClassName()%>(create<%=genBaseType.getName()%>(literal));
        <%} else {%>
		return create<%=genBaseType.getName()%>(literal);
        <%}%>
      <%} else if (genBaseType.getGenPackage().isDataTypeConverters()) {%>
        <%if (isPrimitiveConversion && !isJDK50) {%>
		return new <%=genDataType.getObjectInstanceClassName()%>(<%=genBaseType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.create<%=genBaseType.getName()%>(literal));
        <%} else {%>
		return <%=genBaseType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.create<%=genBaseType.getName()%>(literal);
        <%}%>
      <%} else {%>
		return <%if (!genDataType.isObjectType()) {%>(<%=genDataType.getObjectInstanceClassName()%>)<%}%><%=genBaseType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.createFromString(<%=genBaseType.getQualifiedClassifierAccessor()%>, literal);
      <%}%>
    <%} else if (genDataType.getItemType() != null) { GenDataType genItemType = genDataType.getItemType(); %>
		if (literal == null) return null;
		<%=genDataType.getImportedParameterizedInstanceClassName()%> result = new <%=genModel.getImportedName("java.util.ArrayList")%><%if (genModel.useGenerics()) {%><<%=genItemType.getObjectType().getImportedParameterizedInstanceClassName()%>><%}%>();
      <%if (genModel.getRuntimeVersion().getValue() < GenRuntimeVersion.EMF26_VALUE) {%>
		for (<%=genModel.getImportedName("java.util.StringTokenizer")%> stringTokenizer = new <%=genModel.getImportedName("java.util.StringTokenizer")%>(literal); stringTokenizer.hasMoreTokens(); )
      <%} else {%>
		for (String item : split(literal))
      <%}%>
		{
      <%if (genModel.getRuntimeVersion().getValue() < GenRuntimeVersion.EMF26_VALUE) {%>
			String item = stringTokenizer.nextToken();
      <%}%>
      <%if (genItemType.getGenPackage() == genPackage) {%>
        <%if (genPackage.isDataTypeConverters()) { genItemType = genItemType.getObjectType();%>
			result.add(create<%=genItemType.getName()%>(item));
        <%} else {%>
			result.add(create<%=genItemType.getName()%>FromString(<%=genItemType.getQualifiedClassifierAccessor()%>, item));
        <%}%>
      <%} else {%>
        <%if (genItemType.getGenPackage().isDataTypeConverters()) { genItemType = genItemType.getObjectType();%>
			result.add(<%=genItemType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.create<%=genItemType.getName()%>(item));
        <%} else {%>
			result.add(<%=genItemType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.createFromString(<%=genItemType.getQualifiedClassifierAccessor()%>, item));
        <%}%>
      <%}%>
		}
		return result;
    <%} else if (!genDataType.getMemberTypes().isEmpty()) {%>
		if (literal == null) return <%=genDataType.getStaticValue(null)%>;
		<%=genDataType.getImportedInstanceClassName()%> result = <%=genDataType.getStaticValue(null)%>;
		RuntimeException exception = null;
      <%for (GenDataType genMemberType : genDataType.getMemberTypes()) {%>
		try
		{
      <%if (genMemberType.getGenPackage() == genPackage) {%>
        <%if (genPackage.isDataTypeConverters()) { if (!genDataType.isPrimitiveType()) genMemberType = genMemberType.getObjectType();%>
			result = create<%=genMemberType.getName()%>(literal);
        <%} else {%>
			result = (<%=genDataType.getObjectInstanceClassName()%>)create<%=genMemberType.getName()%>FromString(<%=genMemberType.getQualifiedClassifierAccessor()%>, literal);
        <%}%>
      <%} else {%>
        <%if (genPackage.isDataTypeConverters()) { if (!genDataType.isPrimitiveType()) genMemberType = genMemberType.getObjectType();%>
			result = <%=genMemberType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.create<%=genMemberType.getName()%>(literal);
        <%} else {%>
			result = (<%=genDataType.getObjectInstanceClassName()%>)<%=genMemberType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.createFromString(<%=genMemberType.getQualifiedClassifierAccessor()%>, literal);
        <%}%>
      <%}%>
			if (<%if (!genDataType.isPrimitiveType()) {%>result != null && <%}%><%=genModel.getImportedName("org.eclipse.emf.ecore.util.Diagnostician")%>.INSTANCE.validate(<%=eDataType%>, <%if (genDataType.isPrimitiveType() && !isJDK50) {%>new <%=genDataType.getObjectInstanceClassName()%>(result)<%} else {%>result<%}%>, null, null))
			{
				return result;
			}
		}
		catch (RuntimeException e)
		{
			exception = e;
		}
      <%}%>
		if (<%if (!genDataType.isPrimitiveType()) {%>result != null || <%}%>exception == null) return result;
    
		throw exception;
    <%} else if (!genDataType.hasConversionDelegate() && genModel.useGenerics() && (genDataType.isArrayType() || !genDataType.getEcoreDataType().getETypeParameters().isEmpty() || genDataType.getEcoreDataType().getInstanceTypeName().contains("<"))) {%>
		return (<%=genDataType.getImportedParameterizedObjectInstanceClassName()%>)super.createFromString(literal);
    <%} else if (!genDataType.hasConversionDelegate() && genDataType.isArrayType()) {%>
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new <%=genModel.getImportedName("java.lang.UnsupportedOperationException")%>();
    <%} else if (genDataType.isPrimitiveType() && !isJDK50) {%>
		return ((<%=genDataType.getObjectInstanceClassName()%>)super.createFromString(<%=eDataType%>, literal)).<%=genDataType.getPrimitiveValueFunction()%>();
    <%} else {%>
		return <%if (!genDataType.isObjectType()) {%>(<%=genDataType.getImportedParameterizedObjectInstanceClassName()%>)<%}%>super.createFromString(<%=eDataType%>, literal);
    <%}%>
	}

<%}%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
  <%if (OCLGenModelUtil.INSTANCE.hasAPITags(genDataType)) {%>
	 * <%=OCLGenModelUtil.INSTANCE.getAPITags(genDataType, genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
    <%if (!genPackage.isDataTypeConverters() && genModel.useGenerics() && genDataType.isUncheckedCast() && !genDataType.hasCreatorBody()) {%>
	@SuppressWarnings("unchecked")
    <%}%>
    <%if (isJDK50 && OCLGenModelUtil.INSTANCE.hasAPIDeprecatedTag(genDataType)) {%>
	@Deprecated
    <%}%>
	public <%=genDataType.getImportedParameterizedObjectInstanceClassName()%> create<%=genDataType.getName()%>FromString(<%=genModel.getImportedName("org.eclipse.emf.ecore.EDataType")%> eDataType, String initialValue)
	{
    <%if (genDataType instanceof GenEnum) {%>
      <%if (genPackage.isDataTypeConverters() || genDataType.hasCreatorBody()) {%>
		return create<%=genDataType.getName()%>(initialValue);
      <%} else {%>
		<%=((GenEnum)genDataType).getImportedInstanceClassName()%> result = <%=((GenEnum)genDataType).getImportedInstanceClassName()%>.get(initialValue);
		if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'");<%=genModel.getNonNLS()%><%=genModel.getNonNLS(2)%><%=genModel.getNonNLS(3)%>
		return result;
      <%}%>
    <%} else if (genDataType.getBaseType() != null) { GenDataType genBaseType = genDataType.getBaseType(); %>
      <%if (genBaseType.getGenPackage() == genPackage) {%>
		return <%if (!genDataType.getObjectInstanceClassName().equals(genBaseType.getObjectInstanceClassName())) {%>(<%=genDataType.getObjectInstanceClassName()%>)<%}%>create<%=genBaseType.getName()%>FromString(<%=genBaseType.getQualifiedClassifierAccessor()%>, initialValue);
      <%} else {%>
		return <%if (!genDataType.isObjectType()) {%>(<%=genDataType.getObjectInstanceClassName()%>)<%}%><%=genBaseType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.createFromString(<%=genBaseType.getQualifiedClassifierAccessor()%>, initialValue);
      <%}%>
    <%} else if (genDataType.getItemType() != null) { GenDataType genItemType = genDataType.getItemType(); %>
      <%if (genPackage.isDataTypeConverters()) {%>
		return create<%=genDataType.getName()%>(initialValue);
      <%} else {%>
		if (initialValue == null) return null;
		<%=genDataType.getImportedParameterizedObjectInstanceClassName()%> result = new <%=genModel.getImportedName("java.util.ArrayList")%><%if (genModel.useGenerics()) {%><<%=genItemType.getObjectType().getImportedParameterizedInstanceClassName()%>><%}%>();
        <%if (genModel.getRuntimeVersion().getValue() < GenRuntimeVersion.EMF26_VALUE) {%>
		for (<%=genModel.getImportedName("java.util.StringTokenizer")%> stringTokenizer = new <%=genModel.getImportedName("java.util.StringTokenizer")%>(initialValue); stringTokenizer.hasMoreTokens(); )
        <%} else {%>
		for (String item : split(initialValue))
        <%}%>
		{
        <%if (genModel.getRuntimeVersion().getValue() < GenRuntimeVersion.EMF26_VALUE) {%>
			String item = stringTokenizer.nextToken();
        <%}%>
      <%if (genItemType.getGenPackage() == genPackage) {%>
			result.add(create<%=genItemType.getName()%>FromString(<%=genItemType.getQualifiedClassifierAccessor()%>, item));
      <%} else {%>
			result.add(<%if (!genItemType.isObjectType()) {%>(<%=genItemType.getObjectInstanceClassName()%>)<%}%><%=genItemType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.createFromString(<%=genItemType.getQualifiedClassifierAccessor()%>, item));
      <%}%>
		}
		return result;
      <%}%>
    <%} else if (!genDataType.getMemberTypes().isEmpty()) {%>
      <%if (genPackage.isDataTypeConverters()) {%>
        <%if (genDataType.isPrimitiveType() && !isJDK50) {%>
		return new <%=genDataType.getObjectInstanceClassName()%>(create<%=genDataType.getName()%>(initialValue));
        <%} else {%>
		return create<%=genDataType.getName()%>(initialValue);
        <%}%>
      <%} else {%>
		if (initialValue == null) return null;
		<%=genDataType.getObjectInstanceClassName()%> result = null;
		RuntimeException exception = null;
      <%for (GenDataType genMemberType : genDataType.getMemberTypes()) {%>
		try
		{
      <%if (genMemberType.getGenPackage() == genPackage) {%>
			result = <%if (!genDataType.isObjectType() && !genDataType.getObjectInstanceClassName().equals(genMemberType.getObjectInstanceClassName())) {%>(<%=genDataType.getObjectInstanceClassName()%>)<%}%>create<%=genMemberType.getName()%>FromString(<%=genMemberType.getQualifiedClassifierAccessor()%>, initialValue);
      <%} else {%>
			result = <%if (!genDataType.isObjectType()) {%>(<%=genDataType.getObjectInstanceClassName()%>)<%}%><%=genMemberType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.createFromString(<%=genMemberType.getQualifiedClassifierAccessor()%>, initialValue);
      <%}%>
			if (result != null && <%=genModel.getImportedName("org.eclipse.emf.ecore.util.Diagnostician")%>.INSTANCE.validate(eDataType, result, null, null))
			{
				return result;
			}
		}
		catch (RuntimeException e)
		{
			exception = e;
		}
      <%}%>
		if (result != null || exception == null) return result;
    
		throw exception;
      <%}%>
    <%} else if (genPackage.isDataTypeConverters() || genDataType.hasCreatorBody()) {%>
		return create<%=genDataType.getName()%>(initialValue);
    <%} else if (!genDataType.hasConversionDelegate() && genModel.useGenerics() && (genDataType.isArrayType() || !genDataType.getEcoreDataType().getETypeParameters().isEmpty() || genDataType.getEcoreDataType().getInstanceTypeName().contains("<"))) {%>
		return <%if (!genDataType.isObjectType()) {%>(<%=genDataType.getImportedParameterizedObjectInstanceClassName()%>)<%}%>super.createFromString(initialValue);
    <%} else if (!genDataType.hasConversionDelegate() && genDataType.isArrayType()) {%>
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new <%=genModel.getImportedName("java.lang.UnsupportedOperationException")%>();
    <%} else {%>
		return <%if (!genDataType.isObjectType()) {%>(<%=genDataType.getImportedParameterizedObjectInstanceClassName()%>)<%}%>super.createFromString(eDataType, initialValue);
    <%}%>
	}

<%if (genPackage.isDataTypeConverters() || genDataType.hasConverterBody()) { String eDataType = genDataType.getQualifiedClassifierAccessor();%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
  <%if (OCLGenModelUtil.INSTANCE.hasAPITags(genDataType)) {%>
	 * <%=OCLGenModelUtil.INSTANCE.getAPITags(genDataType, genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
  <%if (isJDK50 && OCLGenModelUtil.INSTANCE.hasAPIDeprecatedTag(genDataType)) {%>
	@Deprecated
  <%}%>
  <%if (genPackage.isDataTypeConverters() && useInterfaceOverrideAnnotation) {%>
	@Override
  <%}%>
	public String convert<%=genDataType.getName()%>(<%if (genDataType.hasCreatorBody()) {%>final <%}%><%=genDataType.getImportedBoundedWildcardInstanceClassName()%> <%if (genDataType.hasConverterBody()) {%>it<%} else {%>instanceValue<%}%>)
	{
    <%if (genDataType.hasConverterBody()) {%>
		<%=genDataType.getConverterBody(genModel.getIndentation(stringBuffer))%>
    <%} else if (genDataType instanceof GenEnum) {%>
		return instanceValue == null ? null : instanceValue.toString();
    <%} else if (genDataType.getBaseType() != null) { GenDataType genBaseType = genDataType.getBaseType(); boolean isPrimitiveConversion = !genDataType.isPrimitiveType() && genBaseType.isPrimitiveType();%>
      <%if (genBaseType.getGenPackage() == genPackage) {%>
        <%if (isPrimitiveConversion) {%>
		return instanceValue == null ? null : convert<%=genBaseType.getName()%>(instanceValue<%if (!isJDK50) {%>.<%=genBaseType.getPrimitiveValueFunction()%>()<%}%>);
        <%} else {%>
		return convert<%=genBaseType.getName()%>(instanceValue);
        <%}%>
      <%} else if (genBaseType.getGenPackage().isDataTypeConverters()) {%>
		return <%=genBaseType.getGenPackage().getQualifiedFactoryInstanceAccessor()%>.convert<%=genBaseType.getName()%>(instanceValue);
      <%} else {%>
		return <%=genBaseType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.convertToString(<%=genBaseType.getQualifiedClassifierAccessor()%>, instanceValue);
      <%}%>
    <%} else if (genDataType.getItemType() != null) { GenDataType genItemType = genDataType.getItemType(); %>
		if (instanceValue == null) return null;
		if (instanceValue.isEmpty()) return "";
		<%=genModel.getImportedName(genModel.useGenerics() ? "java.lang.StringBuilder" : "java.lang.StringBuffer")%> result = new <%=genModel.getImportedName(genModel.useGenerics() ? "java.lang.StringBuilder" : "java.lang.StringBuffer")%>();
        <%String item; if (!genModel.useGenerics()) { item = "i.next()"; %>
		for (<%=genModel.getImportedName("java.util.Iterator")%> i = instanceValue.iterator(); i.hasNext(); )
        <%} else { item = "item";%>
		for (<%=genModel.getImportedName("java.lang.Object")%> item : instanceValue)
        <%}%>
		{
      <%if (genItemType.getGenPackage() == genPackage) {%>
        <%if (genPackage.isDataTypeConverters()) { genItemType = genItemType.getObjectType();%>
			result.append(convert<%=genItemType.getName()%>((<%=genItemType.getObjectInstanceClassName()%>)<%=item%>));
        <%} else {%>
			result.append(convert<%=genItemType.getName()%>ToString(<%=genItemType.getQualifiedClassifierAccessor()%>, <%=item%>));
        <%}%>
      <%} else {%>
        <%if (genItemType.getGenPackage().isDataTypeConverters()) { genItemType = genItemType.getObjectType();%>
			result.append(<%=genItemType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.convert<%=genItemType.getName()%>((<%=genItemType.getObjectInstanceClassName()%>)<%=item%>));
        <%} else {%>
			result.append(<%=genItemType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.convertToString(<%=genItemType.getQualifiedClassifierAccessor()%>, <%=item%>));
        <%}%>
      <%}%>
			result.append(' ');
		}
		return result.substring(0, result.length() - 1);
    <%} else if (!genDataType.getMemberTypes().isEmpty()) {%>
      <%if (!genDataType.isPrimitiveType()) {%>
		if (instanceValue == null) return null;
        <%for (GenDataType genMemberType : genDataType.getMemberTypes()) {%>
		if (<%=genMemberType.getQualifiedClassifierAccessor()%>.isInstance(instanceValue))
		{
			try
			{
          <%if (genMemberType.getGenPackage() == genPackage) {%>
            <%if (genPackage.isDataTypeConverters()) {%>
              <%if (genMemberType.getQualifiedInstanceClassName().equals(genDataType.getQualifiedInstanceClassName())) {%>
				String value = convert<%=genMemberType.getName()%>(instanceValue);
              <%} else if (genMemberType.isPrimitiveType() && !isJDK50) {%>
				String value = convert<%=genMemberType.getName()%>(((<%=genMemberType.getObjectType().getImportedInstanceClassName()%>)instanceValue).<%=genMemberType.getPrimitiveValueFunction()%>());
              <%} else {%>
				String value = convert<%=genMemberType.getName()%>((<%=genMemberType.getObjectType().getImportedBoundedWildcardInstanceClassName()%>)instanceValue);
              <%}%>
            <%} else {%>
				String value = convert<%=genMemberType.getName()%>ToString(<%=genMemberType.getQualifiedClassifierAccessor()%>, instanceValue);
            <%}%>
          <%} else {%>
            <%if (genMemberType.getGenPackage().isDataTypeConverters()) { genMemberType = genMemberType.getObjectType();%>
				String value = <%=genMemberType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.convert<%=genMemberType.getName()%>((<%=genMemberType.getObjectInstanceClassName()%>)instanceValue);
            <%} else {%>
				String value = <%=genMemberType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.convertToString(<%=genMemberType.getQualifiedClassifierAccessor()%>, instanceValue);
            <%}%>
          <%}%>
				if (value != null) return value;
			}
			catch (Exception e)
			{
				// Keep trying other member types until all have failed.
			}
		}
        <%}%>
      <%} else {%>
        <%for (GenDataType genMemberType : genDataType.getMemberTypes()) {%>
		try
		{
          <%if (genMemberType.getGenPackage() == genPackage) {%>
            <%if (genPackage.isDataTypeConverters()) {%>
			String value = convert<%=genMemberType.getName()%>(instanceValue);
            <%} else {%>
			String value = convert<%=genMemberType.getName()%>ToString(<%=genMemberType.getQualifiedClassifierAccessor()%>, <%if (!isJDK50) {%>new <%=genMemberType.getObjectInstanceClassName()%>(instanceValue)<%} else {%>instanceValue<%}%>);
            <%}%>
          <%} else {%>
            <%if (genMemberType.getGenPackage().isDataTypeConverters()) {%>
			String value = <%=genMemberType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.convert<%=genMemberType.getName()%>(instanceValue);
            <%} else {%>
			String value = <%=genMemberType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.convertToString(<%=genMemberType.getQualifiedClassifierAccessor()%>, <%if (!isJDK50) {%>new <%=genMemberType.getObjectInstanceClassName()%>(instanceValue)<%} else {%>instanceValue<%}%>);
            <%}%>
          <%}%>
			if (value != null) return value;
		}
		catch (Exception e)
		{
			// Keep trying other member types until all have failed.
		}
        <%}%>
      <%}%>
		throw new IllegalArgumentException("Invalid value: '"+instanceValue+"' for datatype :"+<%=eDataType%>.getName());
    <%} else if (!genDataType.hasConversionDelegate() && genModel.useGenerics() && (genDataType.isArrayType() || !genDataType.getEcoreDataType().getETypeParameters().isEmpty() || genDataType.getEcoreDataType().getInstanceTypeName().contains("<"))) {%>
		return super.convertToString(instanceValue);
    <%} else if (!genDataType.hasConversionDelegate() && genDataType.isArrayType()) {%>
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new <%=genModel.getImportedName("java.lang.UnsupportedOperationException")%>();
    <%} else if (genDataType.isPrimitiveType() && !isJDK50) {%>
		return super.convertToString(<%=eDataType%>, new <%=genDataType.getObjectInstanceClassName()%>(instanceValue));
    <%} else {%>
		return super.convertToString(<%=eDataType%>, instanceValue);
    <%}%>
	}

<%}%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
  <%if (OCLGenModelUtil.INSTANCE.hasAPITags(genDataType)) {%>
	 * <%=OCLGenModelUtil.INSTANCE.getAPITags(genDataType, genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
    <%if (genModel.useGenerics() && (genDataType.getItemType() != null || genDataType.isUncheckedCast()) && (genPackage.isDataTypeConverters() || genDataType.hasCreatorBody())) {%>
	@SuppressWarnings("unchecked")
    <%}%>
  <%if (isJDK50 && OCLGenModelUtil.INSTANCE.hasAPIDeprecatedTag(genDataType)) {%>
	@Deprecated
  <%}%>
	public String convert<%=genDataType.getName()%>ToString(<%=genModel.getImportedName("org.eclipse.emf.ecore.EDataType")%> eDataType, Object instanceValue)
	{
    <%if (genDataType instanceof GenEnum) {%>
      <%if (genPackage.isDataTypeConverters() || genDataType.hasConverterBody()) {%>
		return convert<%=genDataType.getName()%>((<%=genDataType.getImportedInstanceClassName()%>)instanceValue);
      <%} else {%>
		return instanceValue == null ? null : instanceValue.toString();
      <%}%>
    <%} else if (genDataType.getBaseType() != null) { GenDataType genBaseType = genDataType.getBaseType(); %>
      <%if (genBaseType.getGenPackage() == genPackage) {%>
		return convert<%=genBaseType.getName()%>ToString(<%=genBaseType.getQualifiedClassifierAccessor()%>, instanceValue);
      <%} else {%>
		return <%=genBaseType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.convertToString(<%=genBaseType.getQualifiedClassifierAccessor()%>, instanceValue);
      <%}%>
    <%} else if (genDataType.getItemType() != null) { GenDataType genItemType = genDataType.getItemType(); %>
      <%if (genPackage.isDataTypeConverters() || genDataType.hasCreatorBody()) {%>
		return convert<%=genDataType.getName()%>((<%=genDataType.getImportedBoundedWildcardInstanceClassName()%>)instanceValue);
      <%} else { final String singleWildcard = genModel.useGenerics() ? "<?>" : "";%>
		if (instanceValue == null) return null;
		<%=genModel.getImportedName("java.util.List")%><%=singleWildcard%> list = (<%=genModel.getImportedName("java.util.List")%><%=singleWildcard%>)instanceValue;
		if (list.isEmpty()) return "";
		<%=genModel.getImportedName("java.lang.StringBuffer")%> result = new <%=genModel.getImportedName("java.lang.StringBuffer")%>();
        <%String item; if (!genModel.useGenerics()) { item = "i.next()"; %>
		for (<%=genModel.getImportedName("java.util.Iterator")%> i = list.iterator(); i.hasNext(); )
        <%} else { item = "item";%>
		for (<%=genModel.getImportedName("java.lang.Object")%> item : list)
        <%}%>
		{
        <%if (genItemType.getGenPackage() == genPackage) {%>
			result.append(convert<%=genItemType.getName()%>ToString(<%=genItemType.getQualifiedClassifierAccessor()%>, <%=item%>));
        <%} else {%>
			result.append(<%=genItemType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.convertToString(<%=genItemType.getQualifiedClassifierAccessor()%>, <%=item%>));
        <%}%>
			result.append(' ');
		}
		return result.substring(0, result.length() - 1);
      <%}%>
    <%} else if (!genDataType.getMemberTypes().isEmpty()) {%>
      <%if (genPackage.isDataTypeConverters() || genDataType.hasConverterBody()) {%>
        <%if (genDataType.isPrimitiveType()) {%>
		return instanceValue == null ? null : convert<%=genDataType.getName()%>(((<%=genDataType.getObjectInstanceClassName()%>)instanceValue)<%if (!isJDK50) {%>.<%=genDataType.getPrimitiveValueFunction()%>()<%}%>);
        <%} else {%>
		return convert<%=genDataType.getName()%>(instanceValue);
        <%}%>
      <%} else {%>
		if (instanceValue == null) return null;
        <%for (GenDataType genMemberType : genDataType.getMemberTypes()) {%>
		if (<%=genMemberType.getQualifiedClassifierAccessor()%>.isInstance(instanceValue))
		{
			try
			{
        <%if (genMemberType.getGenPackage() == genPackage) {%>
				String value = convert<%=genMemberType.getName()%>ToString(<%=genMemberType.getQualifiedClassifierAccessor()%>, instanceValue);
        <%} else {%>
				String value = <%=genMemberType.getGenPackage().getQualifiedEFactoryInternalInstanceAccessor()%>.convertToString(<%=genMemberType.getQualifiedClassifierAccessor()%>, instanceValue);
        <%}%>
				if (value != null) return value;
			}
			catch (Exception e)
			{
				// Keep trying other member types until all have failed.
			}
		}
        <%}%>
		throw new IllegalArgumentException("Invalid value: '"+instanceValue+"' for datatype :"+eDataType.getName());
      <%}%>
    <%} else if (genPackage.isDataTypeConverters() || genDataType.hasConverterBody()) {%>
        <%if (genDataType.isPrimitiveType()) {%>
		return instanceValue == null ? null : convert<%=genDataType.getName()%>(<%if (!isJDK50) {%>(<%}%>(<%=genDataType.getObjectInstanceClassName()%>)instanceValue<%if (!isJDK50) {%>).<%=genDataType.getPrimitiveValueFunction()%>()<%}%>);
        <%} else {%>
		return convert<%=genDataType.getName()%>((<%=genDataType.getImportedBoundedWildcardInstanceClassName()%>)instanceValue);
        <%}%>
    <%} else if (!genDataType.hasConversionDelegate() && genModel.useGenerics() && (genDataType.isArrayType() || !genDataType.getEcoreDataType().getETypeParameters().isEmpty() || genDataType.getEcoreDataType().getInstanceTypeName().contains("<"))) {%>
		return super.convertToString(instanceValue);
    <%} else if (!genDataType.hasConversionDelegate() && genDataType.isArrayType()) {%>
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new <%=genModel.getImportedName("java.lang.UnsupportedOperationException")%>();
    <%} else {%>
		return super.convertToString(eDataType, instanceValue);
    <%}%>
	}

  <%}%>
<%}%>
<%} else {%>
  <%for (GenClass genClass : genPackage.getGenClasses()) {%>
    <%if (genClass.hasFactoryInterfaceCreateMethod()) {%>
	/**
	 * Returns a new object of class '<em><%=genClass.getFormattedName()%></em>'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @return a new object of class '<em><%=genClass.getFormattedName()%></em>'.
      <%if (OCLGenModelUtil.INSTANCE.hasAPITags(genClass)) {%>
	 * <%=OCLGenModelUtil.INSTANCE.getAPITags(genClass, genModel.getIndentation(stringBuffer))%>
      <%}%>
	 * @generated
	 */
<%if (isJDK50 && OCLGenModelUtil.INSTANCE.hasAPIDeprecatedTag(genClass)) {%>
	@Deprecated
<%}%>
	<%=genClass.getTypeParameters()%><%=genClass.getImportedInterfaceName()%><%=genClass.getInterfaceTypeArguments()%> create<%=genClass.getName()%>();

    <%}%>
  <%}%>
  <%if (genPackage.isDataTypeConverters()) {%>
    <%for (GenDataType genDataType : genPackage.getAllGenDataTypes()) {%>
      <%if (genDataType.isSerializable()) {%>
	/**
	 * Returns an instance of data type '<em><%=genDataType.getFormattedName()%></em>' corresponding the given literal.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param literal a literal of the data type.
	 * @return a new instance value of the data type.
  <%if (OCLGenModelUtil.INSTANCE.hasAPITags(genDataType)) {%>
	 * <%=OCLGenModelUtil.INSTANCE.getAPITags(genDataType, genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
  <%if (isJDK50 && OCLGenModelUtil.INSTANCE.hasAPIDeprecatedTag(genDataType)) {%>
	@Deprecated
  <%}%>
	<%=genDataType.getImportedParameterizedInstanceClassName()%> create<%=genDataType.getName()%>(String literal);

	/**
	 * Returns a literal representation of an instance of data type '<em><%=genDataType.getFormattedName()%></em>'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @param instanceValue an instance value of the data type.
	 * @return a literal representation of the instance value.
  <%if (OCLGenModelUtil.INSTANCE.hasAPITags(genDataType)) {%>
	 * <%=OCLGenModelUtil.INSTANCE.getAPITags(genDataType, genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
  <%if (isJDK50 && OCLGenModelUtil.INSTANCE.hasAPIDeprecatedTag(genDataType)) {%>
	@Deprecated
  <%}%>
	String convert<%=genDataType.getName()%>(<%=genDataType.getImportedBoundedWildcardInstanceClassName()%> instanceValue);

      <%}%>
    <%}%>
  <%}%>
<%}%>
<%if (!isImplementation && !genModel.isSuppressEMFMetaData()) {%>
	/**
	 * Returns the package supported by this factory.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @return the package supported by this factory.
	 * @generated
	 */
	<%=genPackage.getPackageInterfaceName()%> get<%=genPackage.getBasicPackageName()%>();

<%} else if (isImplementation) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
 <%if (useInterfaceOverrideAnnotation && !genModel.isSuppressEMFMetaData()) {%>
	@Override
 <%}%>
	public <%=genPackage.getImportedPackageInterfaceName()%> get<%=genPackage.getBasicPackageName()%>()
	{
		return (<%=genPackage.getImportedPackageInterfaceName()%>)getEPackage();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @deprecated
	 * @generated
	 */
  <%if (genModel.useClassOverrideAnnotation()) {%>
	@Deprecated
  <%}%>
	public static <%=genPackage.getImportedPackageInterfaceName()%> getPackage()
	{
		return <%=genPackage.getImportedPackageInterfaceName()%>.eINSTANCE;
	}

<%}%>
} //<%=isInterface ? genPackage.getFactoryInterfaceName() : genPackage.getFactoryClassName()%>
<%genModel.emitSortedImports();%>
