gt: 		typeName = typeName.trim();
context: /**
   * Optimus, framework for Model Transformation
   *
   * Copyright (C) 2013 Worldline or third-party contributors as
   * indicated by the @author tags or express copyright attribution
   * statements applied by the authors.
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License.
   *
   * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  package net.atos.optimus.m2m.javaxmi.operation.accesses;
  
  import java.util.Iterator;
  
  import net.atos.optimus.m2m.javaxmi.operation.annotations.builders.AnnotationTypeDeclarationBuilder;
  import net.atos.optimus.m2m.javaxmi.operation.annotations.builders.UnresolvedAnnotationDeclarationBuilder;
  import net.atos.optimus.m2m.javaxmi.operation.classes.UnresolvedClassDeclarationBuilder;
  import net.atos.optimus.m2m.javaxmi.operation.elements.Element;
  import net.atos.optimus.m2m.javaxmi.operation.interfaces.UnresolvedInterfaceDeclarationBuilder;
  import net.atos.optimus.m2m.javaxmi.operation.packages.JavaPackage;
  import net.atos.optimus.m2m.javaxmi.operation.packages.PackageHelper;
  import net.atos.optimus.m2m.javaxmi.operation.types.ArrayTypeBuilder;
  import net.atos.optimus.m2m.javaxmi.operation.types.PrimitiveTypeBuilder;
  import net.atos.optimus.m2m.javaxmi.operation.types.UnresolvedTypeBuilder;
  import net.atos.optimus.m2m.javaxmi.operation.types.WildCardTypeBuilder;
  import net.atos.optimus.m2m.javaxmi.operation.util.ASTElementFinder;
  
  import org.eclipse.emf.common.util.EList;
  import org.eclipse.gmt.modisco.java.AbstractTypeDeclaration;
  import org.eclipse.gmt.modisco.java.AnnotationTypeDeclaration;
  import org.eclipse.gmt.modisco.java.Model;
  import org.eclipse.gmt.modisco.java.ParameterizedType;
  import org.eclipse.gmt.modisco.java.Type;
  import org.eclipse.gmt.modisco.java.TypeAccess;
  import org.eclipse.gmt.modisco.java.UnresolvedAnnotationDeclaration;
  
  /**
   * The purpose of such class is to help with the creation of type accesses
   * 
   * @author tnachtergaele <nachtergaele.thomas@gmail.com>
   * 
   *
   */
  
  public class TypeAccessHelper {
  
  	/** String constant : entry character of an array */
  	public static final String ARRAY_ENTRY = "[";
  
  	/** String constant : exit character of an array */
  	public static final String ARRAY_EXIT = "]";
  
  	/** String constant : entry character of a parameterized type */
  	public static final String PARAMETRIZED_ENTRY = "<";
  
  	/** String constant : separator of a parameterized type */
  	public static final String PARAMETRIZED_SEPARATOR = ",";
  
  	/** String constant : the wild card character */
  	public static final String WILD_CARD = "?";
  
  	/** The Java keyword for class extension */
  	public static final String EXTENSION = "extends";
  
  	/** The Java keyword for generalization */
  	public static final String GENERALIZATION = "super";
  
  	/** String constant : separator of package chunks */
  	public static final String PACKAGE_SEPARATOR = ".";
  
  	/**
  	 * Private constructor
  	 * 
  	 */
  	private TypeAccessHelper() {
  	}
  
  	/**
  	 * Create a type access associated to a class
  	 * 
  	 * @param className
  	 *            the class name which we want a type access.
  	 * @return the created type access associated to the specified class name.
  	 */
  	public static TypeAccess createClassTypeAccess(String className) {
  		if (className.contains(TypeAccessHelper.PARAMETRIZED_ENTRY)) {
  			return TypeAccessHelper.createParameterizedType(
  					TypeAccessHelper.createClassTypeAccess(className.substring(0,
  							className.indexOf(TypeAccessHelper.PARAMETRIZED_ENTRY))), className);
  		}
  		return TypeAccessBuilder.builder()
  				.setType(UnresolvedClassDeclarationBuilder.builder().setName(className).build()).build();
  	}
  
  	/**
  	 * Create a type access associated to an interface
  	 * 
  	 * @param interfaceName
  	 *            the interface name which we want a type access.
  	 * @return the created type access associated to the specified interface
  	 *         name.
  	 */
  	public static TypeAccess createInterfaceTypeAccess(String interfaceName) {
  		if (interfaceName.contains(TypeAccessHelper.PARAMETRIZED_ENTRY)) {
  			return TypeAccessHelper.createParameterizedType(
  					TypeAccessHelper.createInterfaceTypeAccess(interfaceName.substring(0,
  							interfaceName.indexOf(TypeAccessHelper.PARAMETRIZED_ENTRY))), interfaceName);
  		}
  		return TypeAccessBuilder.builder()
  				.setType(UnresolvedInterfaceDeclarationBuilder.builder().setName(interfaceName).build()).build();
  	}
  
  	/**
  	 * Create a type access associated to an exception
  	 * 
  	 * @param exceptionName
  	 *            the exception name which we want a type access.
  	 * @return the created type access associated to the specified exception
  	 *         name.
  	 */
  	public static TypeAccess createExceptionTypeAccess(String exceptionName) {
  		if (exceptionName.contains(TypeAccessHelper.PARAMETRIZED_ENTRY)) {
  			return TypeAccessHelper.createParameterizedType(
  					TypeAccessHelper.createExceptionTypeAccess(exceptionName.substring(0,
  							exceptionName.indexOf(TypeAccessHelper.PARAMETRIZED_ENTRY))), exceptionName);
  		}
  		return TypeAccessBuilder.builder().setType(PrimitiveTypeBuilder.builder().setName(exceptionName).build())
  				.build();
  	}
  
  	/**
  	 * Create a type access associated to an annotation
  	 * 
  	 * @param element
  	 *            the element which we associate the annotation.
  	 * @param packageName
  	 *            the name of the package of the element.
  	 * @param annotationName
  	 *            the name of the annotation.
  	 * @return the created type access associated to the specified annotation
  	 *         name.
  	 */
  	public static TypeAccess createAnnotationTypeAccess(Element<?> element, String packageName, String annotationName) {
  		Model model = ASTElementFinder.findModel(element.getDelegate());
  		JavaPackage javaPackage = PackageHelper.createPackage(model, packageName);
  		AnnotationTypeDeclaration generatedAnnotation = null;
  		Iterator<AbstractTypeDeclaration> declarationIterator = javaPackage.getDelegate().getOwnedElements().iterator();
  
  		while (declarationIterator.hasNext() && generatedAnnotation == null) {
  			AbstractTypeDeclaration next = declarationIterator.next();
  			if (next instanceof AnnotationTypeDeclaration && annotationName.equals(next.getName())) {
  				generatedAnnotation = (AnnotationTypeDeclaration) next;
  			}
  		}
  
  		if (generatedAnnotation == null) {
  			return TypeAccessBuilder
  					.builder()
  					.setType(
  							AnnotationTypeDeclarationBuilder.builder().setName(annotationName)
  									.setPackage(javaPackage.getDelegate()).setProxy(true).build()).build();
  		}
  
  		return TypeAccessBuilder.builder().setType(generatedAnnotation).build();
  	}
  
  	/**
  	 * Create a type access associated to an orphan annotation
  	 * 
  	 * @param element
  	 *            the element which we associate the orphan annotation.
  	 * @param fullyQualifiedName
  	 *            the full qualified name of the orphan annotation.
  	 * @return the created type access associated to the specified orphan
  	 *         annotation name.
  	 */
  	public static TypeAccess createOrphanAnnotationTypeAccess(Element<?> element, String fullyQualifiedName) {
  		Model model = element == null ? null : ASTElementFinder.findModel(element.getDelegate());
  		UnresolvedAnnotationDeclaration annotation = null;
  		if (model != null) {
  			Iterator<Type> iterator = model.getOrphanTypes().iterator();
  			while (iterator.hasNext() && annotation == null) {
  				Type orphanType = iterator.next();
  				if (orphanType instanceof UnresolvedAnnotationDeclaration
  						&& fullyQualifiedName.equals(orphanType.getName())) {
  					annotation = (UnresolvedAnnotationDeclaration) orphanType;
  				}
  			}
  		}
  
  		if (annotation == null) {
  			annotation = UnresolvedAnnotationDeclarationBuilder.builder().setName(fullyQualifiedName).build();
  			if (model != null) {
  				model.getOrphanTypes().add(annotation);
  			}
  		}
  
  		return TypeAccessBuilder.builder().setType(annotation).build();
  	}
  
  	/**
  	 * Create a type associated to a class or an interface
  	 * 
  	 * @param typeName
  	 *            the type name which we want a type access.
  	 * @return the created type access associated to the specified type name.
  	 */
  	public static TypeAccess createTypeAccess(String typeName) {
  