gt: 		AMethodTypeCG methodType = new AMethodTypeCG();
context: /*
   * #%~
   * VDM Code Generator
   * %%
   * Copyright (C) 2008 - 2014 Overture
   * %%
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as
   * published by the Free Software Foundation, either version 3 of the
   * License, or (at your option) any later version.
   * 
   * This program 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 General Public License for more details.
   * 
   * You should have received a copy of the GNU General Public
   * License along with this program.  If not, see
   * <http://www.gnu.org/licenses/gpl-3.0.html>.
   * #~%
   */
  package org.overture.codegen.trans.assistants;
  
  import java.util.LinkedList;
  import java.util.List;
  
  import org.overture.ast.types.ASetType;
  import org.overture.ast.types.PType;
  import org.overture.ast.types.SSeqType;
  import org.overture.codegen.cgast.SExpCG;
  import org.overture.codegen.cgast.SPatternCG;
  import org.overture.codegen.cgast.SStmCG;
  import org.overture.codegen.cgast.STypeCG;
  import org.overture.codegen.cgast.analysis.AnalysisException;
  import org.overture.codegen.cgast.declarations.AFieldDeclCG;
  import org.overture.codegen.cgast.declarations.AFormalParamLocalParamCG;
  import org.overture.codegen.cgast.declarations.AMethodDeclCG;
  import org.overture.codegen.cgast.declarations.AModuleDeclCG;
  import org.overture.codegen.cgast.declarations.AStateDeclCG;
  import org.overture.codegen.cgast.declarations.AVarDeclCG;
  import org.overture.codegen.cgast.expressions.AAndBoolBinaryExpCG;
  import org.overture.codegen.cgast.expressions.AApplyExpCG;
  import org.overture.codegen.cgast.expressions.ACastUnaryExpCG;
  import org.overture.codegen.cgast.expressions.ACompSeqExpCG;
  import org.overture.codegen.cgast.expressions.AFieldExpCG;
  import org.overture.codegen.cgast.expressions.AIdentifierVarExpCG;
  import org.overture.codegen.cgast.expressions.AIntLiteralExpCG;
  import org.overture.codegen.cgast.expressions.ALessNumericBinaryExpCG;
  import org.overture.codegen.cgast.expressions.ANewExpCG;
  import org.overture.codegen.cgast.expressions.ANotUnaryExpCG;
  import org.overture.codegen.cgast.name.ATypeNameCG;
  import org.overture.codegen.cgast.patterns.AIdentifierPatternCG;
  import org.overture.codegen.cgast.patterns.ASetMultipleBindCG;
  import org.overture.codegen.cgast.statements.AAssignToExpStmCG;
  import org.overture.codegen.cgast.statements.ABlockStmCG;
  import org.overture.codegen.cgast.statements.ACallObjectExpStmCG;
  import org.overture.codegen.cgast.statements.AForLoopStmCG;
  import org.overture.codegen.cgast.statements.AIfStmCG;
  import org.overture.codegen.cgast.statements.AIncrementStmCG;
  import org.overture.codegen.cgast.statements.ALocalPatternAssignmentStmCG;
  import org.overture.codegen.cgast.types.ABoolBasicTypeCG;
  import org.overture.codegen.cgast.types.AClassTypeCG;
  import org.overture.codegen.cgast.types.AIntNumericBasicTypeCG;
  import org.overture.codegen.cgast.types.AMethodTypeCG;
  import org.overture.codegen.cgast.types.ARecordTypeCG;
  import org.overture.codegen.cgast.types.AVoidTypeCG;
  import org.overture.codegen.cgast.types.SSeqTypeCG;
  import org.overture.codegen.cgast.types.SSetTypeCG;
  import org.overture.codegen.ir.IRInfo;
  import org.overture.codegen.ir.ITempVarGen;
  import org.overture.codegen.ir.SourceNode;
  import org.overture.codegen.logging.Logger;
  import org.overture.codegen.trans.IIterationStrategy;
  import org.overture.codegen.trans.TempVarPrefixes;
  
  public class TransAssistantCG extends BaseTransformationAssistant
  {
  	protected IRInfo info;
  	protected TempVarPrefixes varPrefixes;
  
  	public TransAssistantCG(IRInfo info, TempVarPrefixes varPrefixes)
  	{
  		this.info = info;
  		this.varPrefixes = varPrefixes;
  	}
  
  	public IRInfo getInfo()
  	{
  		return info;
  	}
  
  	public TempVarPrefixes getVarPrefixes()
  	{
  		return varPrefixes;
  	}
  
  	public SSetTypeCG getSetTypeCloned(SExpCG set) throws AnalysisException
  	{
  		STypeCG typeCg = set.getType();
  
  		return getSetTypeCloned(typeCg);
  	}
  
  	public SSetTypeCG getSetTypeCloned(STypeCG typeCg) throws AnalysisException
  	{
  		if (typeCg instanceof SSetTypeCG)
  		{
  			SSetTypeCG setTypeCg = (SSetTypeCG) typeCg;
  
  			return setTypeCg.clone();
  		} else
  		{
  			SourceNode sourceNode = typeCg.getSourceNode();
  
  			if (sourceNode != null && sourceNode.getVdmNode() instanceof PType)
  			{
  				PType vdmType = (PType) sourceNode.getVdmNode();
  				ASetType setType = info.getTcFactory().createPTypeAssistant().getSet(vdmType);
  				try
  				{
  					typeCg = setType.apply(info.getTypeVisitor(), info);
  					return (SSetTypeCG) typeCg;
  
  				} catch (org.overture.ast.analysis.AnalysisException e)
  				{
  				}
  			}
  
  			throw new AnalysisException("Exptected set type. Got: " + typeCg);
  		}
  	}
  
  	public SSeqTypeCG getSeqTypeCloned(SExpCG seq) throws AnalysisException
  	{
  		STypeCG typeCg = seq.getType();
  
  		return getSeqTypeCloned(typeCg);
  	}
  
  	public SSeqTypeCG getSeqTypeCloned(STypeCG typeCg) throws AnalysisException
  	{
  		if (typeCg instanceof SSeqTypeCG)
  		{
  			SSeqTypeCG seqTypeCg = (SSeqTypeCG) typeCg;
  
  			return seqTypeCg.clone();
  		} else
  		{
  			SourceNode sourceNode = typeCg.getSourceNode();
  
  			if (sourceNode != null && sourceNode.getVdmNode() instanceof PType)
  			{
  				PType vdmType = (PType) sourceNode.getVdmNode();
  				SSeqType seqType = info.getTcFactory().createPTypeAssistant().getSeq(vdmType);
  				try
  				{
  					typeCg = seqType.apply(info.getTypeVisitor(), info);
  					return (SSeqTypeCG) typeCg;
  
  				} catch (org.overture.ast.analysis.AnalysisException e)
  				{
  				}
  			}
  
  			throw new AnalysisException("Exptected sequence type. Got: "
  					+ typeCg);
  		}
  	}
  
  	public AIdentifierVarExpCG consSuccessVar(String successVarName)
  	{
  		AIdentifierVarExpCG successVar = new AIdentifierVarExpCG();
  		successVar.setIsLambda(false);
  		successVar.setIsLocal(true);
  		successVar.setName(successVarName);
  		successVar.setType(new ABoolBasicTypeCG());
  
  		return successVar;
  	}
  
  	public AVarDeclCG consBoolVarDecl(String boolVarName, boolean initValue)
  	{
  		return info.getDeclAssistant().consLocalVarDecl(new ABoolBasicTypeCG(),
  				consIdPattern(boolVarName), info.getExpAssistant().consBoolLiteral(initValue));
  	}
  
  	public SExpCG consAndExp(SExpCG left, SExpCG right)
  	{
  		AAndBoolBinaryExpCG andExp = new AAndBoolBinaryExpCG();
  		andExp.setType(new ABoolBasicTypeCG());
  		andExp.setLeft(left);
  		andExp.setRight(right);
  
  		return andExp;
  	}
  
  	public SExpCG consLessThanCheck(String varName, long value)
  	{
  		AIdentifierVarExpCG left = new AIdentifierVarExpCG();
  		left.setType(new AIntNumericBasicTypeCG());
  		left.setIsLocal(true);
  		left.setName(varName);
  
  		AIntLiteralExpCG right = info.getExpAssistant().consIntLiteral(value);
  
  		ALessNumericBinaryExpCG less = new ALessNumericBinaryExpCG();
  		less.setType(new ABoolBasicTypeCG());
  		less.setLeft(left);
  		less.setRight(right);
  
  		return less;
  	}
  
  	public SExpCG consBoolCheck(String boolVarName, boolean negate)
  	{
  		AIdentifierVarExpCG boolVarExp = new AIdentifierVarExpCG();
  		boolVarExp.setType(new ABoolBasicTypeCG());
  		boolVarExp.setIsLocal(true);
  		boolVarExp.setName(boolVarName);
  
  		if (negate)
  		{
  			ANotUnaryExpCG negated = new ANotUnaryExpCG();
  			negated.setType(new ABoolBasicTypeCG());
  			negated.setExp(boolVarExp);
  
  			return negated;
  		} else
  		{
  			return boolVarExp;
  		}
  	}
  
  	public AAssignToExpStmCG consBoolVarAssignment(SExpCG predicate,
  			String boolVarName)
  	{
  		AAssignToExpStmCG boolVarAssignment = new AAssignToExpStmCG();
  		boolVarAssignment.setTarget(consBoolCheck(boolVarName, false));
  		boolVarAssignment.setExp(predicate != null ? predicate.clone()
  				: info.getExpAssistant().consBoolLiteral(true));
  
  		return boolVarAssignment;
  	}
  
  	public AVarDeclCG consSetBindDecl(String setBindName, SExpCG set)
  			throws AnalysisException
  	{
  		return info.getDeclAssistant().consLocalVarDecl(getSetTypeCloned(set),
  				consIdPattern(setBindName), set.clone());
  	}
  
  	public AVarDeclCG consDecl(String varName, STypeCG type, SExpCG exp)
  	{
  		return info.getDeclAssistant().consLocalVarDecl(type, consIdPattern(varName), exp);
  	}
  
  	public AClassTypeCG consClassType(String classTypeName)
  	{
  		AClassTypeCG classType = new AClassTypeCG();
  		classType.setName(classTypeName);
  
  		return classType;
  	}
  
  	public SExpCG consInstanceCall(STypeCG instanceType, String instanceName,
  			STypeCG returnType, String memberName, SExpCG... args)
  	{
  		AIdentifierVarExpCG instance = new AIdentifierVarExpCG();
  		instance.setType(instanceType.clone());
  		instance.setName(instanceName);
  		instance.setIsLocal(true);
  
  		AFieldExpCG fieldExp = new AFieldExpCG();
  		fieldExp.setMemberName(memberName);
  		fieldExp.setObject(instance);
  
  