
<%
/**
 * Copyright (c) 2002-2010 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 = genModel.useInterfaceOverrideAnnotation() && !(isInterface && isImplementation);%>
<%String publicStaticFinalFlag = isImplementation ? "public static final " : "";%>
<%@ 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 || 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 (genPackage.hasAPITags()) {%>
 * <%=genPackage.getAPITags(genModel.getIndentation(stringBuffer))%>
<%}%>
 * @generated
 */
<%} else {%>
/**
 * <!-- begin-user-doc -->
 * An implementation of the model <b>Factory</b>.
 * <!-- end-user-doc -->
<%if (genPackage.hasAPITags()) {%>
 * <%=genPackage.getAPITags(genModel.getIndentation(stringBuffer))%>
<%}%>
 * @generated
 */
<%}%>
<%if (isJDK50 && genPackage.hasAPIDeprecatedTag()) {%>
@Deprecated
<%}%>
<%if (isImplementation) {%>
  <%if (isJDK50 && !genPackage.hasAPIDeprecatedTag()) { 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 (GenModelUtil.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.getImportedPackageInterfaceName()%>.<%=genClass.getClassifierID()%>: 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.getImportedPackageInterfaceName()%>.<%=genDataType.getClassifierID()%>:
				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.getImportedPackageInterfaceName()%>.<%=genDataType.getClassifierID()%>:
				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 (genClass.hasAPITags()) {%>
	 * <%=genClass.getAPITags(genModel.getIndentation(stringBuffer))%>
    <%}%>
	 * @generated
	 */
<%if (isJDK50 && genClass.hasAPIDeprecatedTag()) {%>
	@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 (genDataType.hasAPITags()) {%>
	 * <%=genDataType.getAPITags(genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
    <%if (genModel.useGenerics() && genDataType.isUncheckedCast() && !genDataType.hasCreatorBody()) {%>
	@SuppressWarnings("unchecked")
    <%}%>
    <%if (isJDK50 && genDataType.hasAPIDeprecatedTag()) {%>
	@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 (genDataType.hasAPITags()) {%>
	 * <%=genDataType.getAPITags(genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
    <%if (!genPackage.isDataTypeConverters() && genModel.useGenerics() && genDataType.isUncheckedCast() && !genDataType.hasCreatorBody()) {%>
	@SuppressWarnings("unchecked")
    <%}%>
    <%if (isJDK50 && genDataType.hasAPIDeprecatedTag()) {%>
	@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 (genDataType.hasAPITags()) {%>
	 * <%=genDataType.getAPITags(genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
  <%if (isJDK50 && genDataType.hasAPIDeprecatedTag()) {%>
	@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 (genDataType.hasAPITags()) {%>
	 * <%=genDataType.getAPITags(genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
    <%if (genModel.useGenerics() && (genDataType.getItemType() != null || genDataType.isUncheckedCast()) && (genPackage.isDataTypeConverters() || genDataType.hasCreatorBody())) {%>
	@SuppressWarnings("unchecked")
    <%}%>
  <%if (isJDK50 && genDataType.hasAPIDeprecatedTag()) {%>
	@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 (genClass.hasAPITags()) {%>
	 * <%=genClass.getAPITags(genModel.getIndentation(stringBuffer))%>
      <%}%>
	 * @generated
	 */
<%if (isJDK50 && genClass.hasAPIDeprecatedTag()) {%>
	@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 (genDataType.hasAPITags()) {%>
	 * <%=genDataType.getAPITags(genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
  <%if (isJDK50 && genDataType.hasAPIDeprecatedTag()) {%>
	@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 (genDataType.hasAPITags()) {%>
	 * <%=genDataType.getAPITags(genModel.getIndentation(stringBuffer))%>
  <%}%>
	 * @generated
	 */
  <%if (isJDK50 && genDataType.hasAPIDeprecatedTag()) {%>
	@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();%>
