Added support for recursive Template call.

Change-Id: Iaaae194f74a8f0e64da84789923db6d2c9c26c95
diff --git a/acceleo-aql/org.eclipse.acceleo.aql.ls.debug/src/org/eclipse/acceleo/aql/ls/debug/AcceleoDebugEvaluator.java b/acceleo-aql/org.eclipse.acceleo.aql.ls.debug/src/org/eclipse/acceleo/aql/ls/debug/AcceleoDebugEvaluator.java
index edef8bb..ba70ace 100644
--- a/acceleo-aql/org.eclipse.acceleo.aql.ls.debug/src/org/eclipse/acceleo/aql/ls/debug/AcceleoDebugEvaluator.java
+++ b/acceleo-aql/org.eclipse.acceleo.aql.ls.debug/src/org/eclipse/acceleo/aql/ls/debug/AcceleoDebugEvaluator.java
@@ -32,7 +32,7 @@
 
 	private class Debugger extends AbstractDSLDebugger {
 
-		public Debugger(IDSLDebugEventProcessor target) {
+		Debugger(IDSLDebugEventProcessor target) {
 			super(target);
 		}
 
@@ -112,10 +112,13 @@
 	/**
 	 * Constructor.
 	 * 
+	 * @param environment
+	 *            the {@link IllegalAccessError}
 	 * @param target
 	 *            the {@link IDSLDebugEventProcessor}
 	 */
-	public AcceleoDebugEvaluator(IDSLDebugEventProcessor target) {
+	public AcceleoDebugEvaluator(IAcceleoEnvironment environment, IDSLDebugEventProcessor target) {
+		super(environment);
 		this.debugger = new Debugger(target);
 	}
 
diff --git a/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/generated/recursive_template_invocation_is-expected.txt b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/generated/recursive_template_invocation_is-expected.txt
new file mode 100644
index 0000000..6166d2a
--- /dev/null
+++ b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/generated/recursive_template_invocation_is-expected.txt
@@ -0,0 +1,13 @@
+
+        
+    start
+    
+        continue 
+    start
+    
+        stop
+    
+
+    
+
+    
\ No newline at end of file
diff --git a/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall-expected-ast.txt b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall-expected-ast.txt
new file mode 100644
index 0000000..b2cc5fd
--- /dev/null
+++ b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall-expected-ast.txt
@@ -0,0 +1,37 @@
+
+header position 0..78
+module recursiveTemplateInvocation
+  metamodel http://www.eclipse.org/emf/2002/Ecore (37..75)
+  [comment @main (89..94) /] (80..96)
+  
+  public template recursive_source_is_argument(c : EClass (143..160))
+  @main
+    
+     (162..167)
+    [file url 'recursive_template_invocation_is' (174..208) mode overwrite
+      
+         (221..230)
+      [.recursive_is(c, true) (231..251)/] (230..253)
+      
+     (253..258) (221..258)
+    [/file] (167..265)
+    
+ (265..266) (162..266)[/template] (97..277)
+  
+  public template recursive_is(c : EClass (309..326), b : java.lang.Boolean (328..339))
+    
+    start
+     (341..356)
+    [if .not(b) (361..366)
+      
+        stop
+     (368..386) (368..386)
+    [else]
+      
+        continue  (392..410)
+      [.recursive_is(c, false) (411..432)/] (410..434)
+      
+     (434..439) (392..439)
+    [/if] (356..444)
+    
+ (444..445) (341..445)[/template] (279..456) (0..456)
\ No newline at end of file
diff --git a/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall-expected-runtimeMessages.txt b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall-expected-runtimeMessages.txt
new file mode 100644
index 0000000..0be6fd3
--- /dev/null
+++ b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall-expected-runtimeMessages.txt
@@ -0,0 +1 @@
+ (null 0 0) null[]
diff --git a/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall-expected-validation.txt b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall-expected-validation.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall-expected-validation.txt
diff --git a/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall.mtl b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall.mtl
new file mode 100644
index 0000000..324e948
--- /dev/null
+++ b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall.mtl
@@ -0,0 +1,17 @@
+[module recursiveTemplateInvocation('http://www.eclipse.org/emf/2002/Ecore')/]
+
+[comment @main/]
+[template public recursive_source_is_argument(c : ecore::EClass)]
+    [file ('recursive_template_invocation_is', overwrite)]
+        [c.recursive_is(true)/]
+    [/file]
+[/template]
+
+[template public recursive_is(c : ecore::EClass, b : Boolean)]
+    start
+    [if (not b)]
+        stop
+    [else]
+        continue [c.recursive_is(false)/]
+    [/if]
+[/template]
\ No newline at end of file
diff --git a/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall.xmi b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall.xmi
new file mode 100644
index 0000000..ad60384
--- /dev/null
+++ b/acceleo-aql/org.eclipse.acceleo.aql.tests/resources/evaluation/expressionStatement/templateRecusiveCall/templateRecusiveCall.xmi
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="anydsl" nsURI="http://www.eclipse.org/acceleo/anydsl" nsPrefix="anydsl">
+  <eClassifiers xsi:type="ecore:EClass" name="World">
+    <eAnnotations source="http://www.obeo.fr/dsl/dnc/archetype">
+      <details key="archetype" value="MomentInterval"/>
+    </eAnnotations>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="companies" upperBound="-1"
+        eType="#//Company" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="foods" upperBound="-1"
+        eType="#//Food" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="sources" upperBound="-1"
+        eType="#//Source" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="MultiNamedElement" abstract="true" interface="true">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" upperBound="-1" eType="#//SingleString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="NamedElement" abstract="true" interface="true">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="#//SingleString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Producer" eSuperTypes="#//NamedElement">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="adress" eType="#//Adress"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="company" eType="#//Company"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="foods" upperBound="-1"
+        eType="#//Food" eOpposite="#//Food/producers"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Adress">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="zipCode" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="city" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="country" eType="#//CountryData"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Company" abstract="true" interface="true"
+      eSuperTypes="#//NamedElement">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="adress" eType="#//Adress"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="world" eType="#//World"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="ProductionCompany" eSuperTypes="#//Company">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="producers" upperBound="-1"
+        eType="#//Producer" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Restaurant" eSuperTypes="#//Company">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="chefs" upperBound="-1"
+        eType="#//Chef" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="menu" upperBound="-1" eType="#//EStringToRecipeMap"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Chef" eSuperTypes="#//NamedElement">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="adress" eType="#//Adress"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="recipes" upperBound="-1"
+        eType="#//Recipe" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Recipe" eSuperTypes="#//NamedElement">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ingredients" upperBound="-1"
+        eType="#//Food"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Food" eSuperTypes="#//NamedElement">
+    <eOperations name="ripen" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean">
+      <eParameters name="color" eType="#//Color"/>
+    </eOperations>
+    <eOperations name="preferredColor" eType="#//Color"/>
+    <eOperations name="newFood" eType="#//Food"/>
+    <eOperations name="setColor">
+      <eParameters name="food" eType="#//Food"/>
+      <eParameters name="newColor" eType="#//Color"/>
+    </eOperations>
+    <eOperations name="setCaliber">
+      <eParameters name="food" eType="#//Food"/>
+      <eParameters name="newCaliber" upperBound="-1" eType="#//Caliber"/>
+    </eOperations>
+    <eOperations name="acceptedCaliber" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean">
+      <eParameters name="caliber" eType="#//Caliber"/>
+    </eOperations>
+    <eOperations name="label">
+      <eParameters name="text" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eOperations>
+    <eOperations name="preferredLabel" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString">
+      <eParameters name="text" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eOperations>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="color" upperBound="-1"
+        eType="#//Color"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="caliber" eType="#//Caliber"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="relatedFoods" upperBound="-1"
+        eType="#//Food"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="group" eType="#//Group"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="source" eType="#//Source"
+        eOpposite="#//Source/foods"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="producers" upperBound="-1"
+        eType="#//Producer" eOpposite="#//Producer/foods"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Source" abstract="true" interface="true"
+      eSuperTypes="#//MultiNamedElement">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="foods" upperBound="-1"
+        eType="#//Food" eOpposite="#//Food/source"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="origin" upperBound="-1"
+        eType="#//CountryData"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Plant" eSuperTypes="#//Source">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//Kind"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Animal" eSuperTypes="#//Source">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="part" upperBound="-1" eType="#//Part"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="Color">
+    <eLiterals name="black"/>
+    <eLiterals name="red" value="1"/>
+    <eLiterals name="green" value="2"/>
+    <eLiterals name="yellow" value="3"/>
+    <eLiterals name="orange" value="4"/>
+    <eLiterals name="brown" value="5"/>
+    <eLiterals name="pink" value="6"/>
+    <eLiterals name="palPink" value="7" literal="palPink"/>
+    <eLiterals name="veryYellow" value="8"/>
+    <eLiterals name="white" value="9"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="Caliber">
+    <eLiterals name="S"/>
+    <eLiterals name="M" value="1"/>
+    <eLiterals name="L" value="2"/>
+    <eLiterals name="XL" value="3"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="Group">
+    <eLiterals name="Water"/>
+    <eLiterals name="Dairy" value="1"/>
+    <eLiterals name="Fruit" value="2"/>
+    <eLiterals name="Grain" value="3"/>
+    <eLiterals name="Protein" value="4"/>
+    <eLiterals name="Sweet" value="5"/>
+    <eLiterals name="Vegetable" value="6"/>
+    <eLiterals name="Alcohol" value="7"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="Continent">
+    <eLiterals name="Europe"/>
+    <eLiterals name="Asia" value="1"/>
+    <eLiterals name="Africa" value="2"/>
+    <eLiterals name="America" value="3"/>
+    <eLiterals name="Australia" value="4"/>
+    <eLiterals name="Antarctica" value="5"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="Kind">
+    <eLiterals name="Other"/>
+    <eLiterals name="Seed" value="1"/>
+    <eLiterals name="Oilseed" value="2"/>
+    <eLiterals name="Tree" value="3"/>
+    <eLiterals name="Root" value="4"/>
+    <eLiterals name="Bulb" value="5"/>
+    <eLiterals name="Leaf" value="6"/>
+    <eLiterals name="Stem" value="7"/>
+    <eLiterals name="Flower" value="8"/>
+    <eLiterals name="Inflorescence" value="9"/>
+    <eLiterals name="Spice" value="10"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EEnum" name="Part">
+    <eLiterals name="Other"/>
+    <eLiterals name="Muscle" value="1"/>
+    <eLiterals name="Organ" value="2"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EDataType" name="CountryData" instanceClassName="anydsl.Country"/>
+  <eClassifiers xsi:type="ecore:EDataType" name="SingleString" instanceClassName="java.lang.String"/>
+  <eClassifiers xsi:type="ecore:EClass" name="EStringToRecipeMap" instanceClassName="java.util.Map$Entry">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="value" eType="#//Recipe"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/acceleo-aql/org.eclipse.acceleo.aql.tests/src/org/eclipse/acceleo/tests/evaluation/TemplateLookupTest.java b/acceleo-aql/org.eclipse.acceleo.aql.tests/src/org/eclipse/acceleo/tests/evaluation/TemplateLookupTest.java
index 4f28121..ecc8aff 100644
--- a/acceleo-aql/org.eclipse.acceleo.aql.tests/src/org/eclipse/acceleo/tests/evaluation/TemplateLookupTest.java
+++ b/acceleo-aql/org.eclipse.acceleo.aql.tests/src/org/eclipse/acceleo/tests/evaluation/TemplateLookupTest.java
@@ -83,12 +83,12 @@
 		final Map<String, Object> variables = new HashMap<String, Object>();
 		variables.put(PARAM1, EcoreFactory.eINSTANCE.createEPackage());
 
-		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator();
+		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator(acceleoEnvironment);
 		final ModuleElement start = module1.getModuleElements().get(0);
 		assertTrue(start instanceof Template && "t11".equals(((Template)start).getName()));
 		acceleoEnvironment.pushImport(acceleoEnvironment.getModuleQualifiedName(module1), start);
 
-		final String result = (String)evaluationEngine.generate(acceleoEnvironment, start, variables);
+		final String result = (String)evaluationEngine.generate(start, variables);
 
 		assertEquals("" + AbstractLanguageTestSuite.DEFAULT_END_OF_LINE_CHARACTER
 				+ "generated from m1.t11(EPackage)" + AbstractLanguageTestSuite.DEFAULT_END_OF_LINE_CHARACTER,
@@ -104,12 +104,12 @@
 		final Map<String, Object> variables = new HashMap<String, Object>();
 		variables.put(PARAM1, EcoreFactory.eINSTANCE.createEClass());
 
-		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator();
+		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator(acceleoEnvironment);
 		final ModuleElement start = module1.getModuleElements().get(1);
 		assertTrue(start instanceof Template && "t11".equals(((Template)start).getName()));
 		acceleoEnvironment.pushImport(acceleoEnvironment.getModuleQualifiedName(module1), start);
 
-		final String result = (String)evaluationEngine.generate(acceleoEnvironment, start, variables);
+		final String result = (String)evaluationEngine.generate(start, variables);
 
 		assertEquals("" + AbstractLanguageTestSuite.DEFAULT_END_OF_LINE_CHARACTER
 				+ AbstractLanguageTestSuite.DEFAULT_END_OF_LINE_CHARACTER
@@ -136,12 +136,12 @@
 		final Map<String, Object> variables = new HashMap<String, Object>();
 		variables.put(PARAM1, pack);
 
-		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator();
+		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator(acceleoEnvironment);
 		ModuleElement start = module2.getModuleElements().get(0);
 		assertTrue(start instanceof Template && "t21".equals(((Template)start).getName()));
 		acceleoEnvironment.pushImport(acceleoEnvironment.getModuleQualifiedName(module2), start);
 
-		final String result = (String)evaluationEngine.generate(acceleoEnvironment, start, variables);
+		final String result = (String)evaluationEngine.generate(start, variables);
 
 		assertEquals("" + AbstractLanguageTestSuite.DEFAULT_END_OF_LINE_CHARACTER
 				+ "generated from m2.t21(EPackage)" + AbstractLanguageTestSuite.DEFAULT_END_OF_LINE_CHARACTER
@@ -171,12 +171,12 @@
 		final Map<String, Object> variables = new HashMap<String, Object>();
 		variables.put(PARAM1, pack);
 
-		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator();
+		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator(acceleoEnvironment);
 		ModuleElement start = module2.getModuleElements().get(1);
 		assertTrue(start instanceof Template && "overrideMe".equals(((Template)start).getName()));
 		acceleoEnvironment.pushImport(acceleoEnvironment.getModuleQualifiedName(module2), start);
 
-		final String result = (String)evaluationEngine.generate(acceleoEnvironment, start, variables);
+		final String result = (String)evaluationEngine.generate(start, variables);
 
 		assertEquals("" + AbstractLanguageTestSuite.DEFAULT_END_OF_LINE_CHARACTER
 				+ "generated from m2.overrideMe(EClass)"
@@ -200,12 +200,12 @@
 		final Map<String, Object> variables = new HashMap<String, Object>();
 		variables.put(PARAM1, clazz);
 
-		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator();
+		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator(acceleoEnvironment);
 		ModuleElement start = module2.getModuleElements().get(3);
 		assertTrue(start instanceof Template && "toImportsAndBack".equals(((Template)start).getName()));
 		acceleoEnvironment.pushImport(acceleoEnvironment.getModuleQualifiedName(module2), start);
 
-		final String result = (String)evaluationEngine.generate(acceleoEnvironment, start, variables);
+		final String result = (String)evaluationEngine.generate(start, variables);
 
 		assertEquals("" + AbstractLanguageTestSuite.DEFAULT_END_OF_LINE_CHARACTER
 				+ AbstractLanguageTestSuite.DEFAULT_END_OF_LINE_CHARACTER + "generated from m4.t41(EClass)"
@@ -238,12 +238,12 @@
 		final Map<String, Object> variables = new HashMap<String, Object>();
 		variables.put(PARAM1, clazz);
 
-		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator();
+		final AcceleoEvaluator evaluationEngine = new AcceleoEvaluator(acceleoEnvironment);
 		ModuleElement start = module2.getModuleElements().get(4);
 		assertTrue(start instanceof Template && "toImportsExtends".equals(((Template)start).getName()));
 		acceleoEnvironment.pushImport(acceleoEnvironment.getModuleQualifiedName(module2), start);
 
-		final String result = (String)evaluationEngine.generate(acceleoEnvironment, start, variables);
+		final String result = (String)evaluationEngine.generate(start, variables);
 
 		assertEquals("" + AbstractLanguageTestSuite.DEFAULT_END_OF_LINE_CHARACTER
 				+ AbstractLanguageTestSuite.DEFAULT_END_OF_LINE_CHARACTER + "generated from m3.t31(EClass)"
diff --git a/acceleo-aql/org.eclipse.acceleo.aql.tests/src/org/eclipse/acceleo/tests/utils/AbstractEvaluationTestSuite.java b/acceleo-aql/org.eclipse.acceleo.aql.tests/src/org/eclipse/acceleo/tests/utils/AbstractEvaluationTestSuite.java
index 4bcdd79..953920d 100644
--- a/acceleo-aql/org.eclipse.acceleo.aql.tests/src/org/eclipse/acceleo/tests/utils/AbstractEvaluationTestSuite.java
+++ b/acceleo-aql/org.eclipse.acceleo.aql.tests/src/org/eclipse/acceleo/tests/utils/AbstractEvaluationTestSuite.java
@@ -78,7 +78,7 @@
 		final File modelFile = getModelFile(new File(getTestFolderPath()));
 		final ResourceSet rs = getResourceSet();
 		model = getModel(modelFile, rs);
-		evaluator = new AcceleoEvaluator();
+		evaluator = new AcceleoEvaluator(environment);
 	}
 
 	/**
@@ -145,7 +145,7 @@
 			for (EObject eObj : eObjects) {
 				final Map<String, Object> variables = new HashMap<String, Object>();
 				variables.put(parameterName, eObj);
-				evaluator.generate(environment, module, variables);
+				evaluator.generate(module, variables);
 			}
 
 			// assert generated content
diff --git a/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/AbstractModuleElementService.java b/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/AbstractModuleElementService.java
index c3e51b5..7150e37 100644
--- a/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/AbstractModuleElementService.java
+++ b/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/AbstractModuleElementService.java
@@ -15,6 +15,7 @@
 import org.eclipse.acceleo.Module;
 import org.eclipse.acceleo.ModuleElement;
 import org.eclipse.acceleo.VisibilityKind;
+import org.eclipse.acceleo.aql.AcceleoEnvironment;
 import org.eclipse.acceleo.query.runtime.impl.AbstractService;
 import org.eclipse.acceleo.query.validation.type.IType;
 import org.eclipse.emf.ecore.EObject;
@@ -26,6 +27,26 @@
  * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
  */
 public abstract class AbstractModuleElementService extends AbstractService {
+
+	/** The current evaluation environment. */
+	private final AcceleoEnvironment env;
+
+	/**
+	 * The {@link AcceleoEvaluator}.
+	 */
+	private final AcceleoEvaluator acceleoEvaluator;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param env
+	 *            The current evaluation environment.
+	 */
+	public AbstractModuleElementService(AcceleoEnvironment env) {
+		this.env = env;
+		this.acceleoEvaluator = new AcceleoEvaluator(env);
+	}
+
 	/**
 	 * Returns the wrapped module element.
 	 * 
@@ -33,11 +54,6 @@
 	 */
 	public abstract ModuleElement getModuleElement();
 
-	/**Gets the module qualified name.
-	 * @return the module qualified name
-	 */
-	public abstract String getModuleQualifiedName();
-
 	/**
 	 * Returns the underlying element's visibility if any.
 	 * 
@@ -46,13 +62,40 @@
 	public abstract VisibilityKind getVisibility();
 
 	/**
+	 * Gets the {@link AcceleoEnvironment}.
+	 * 
+	 * @return the {@link AcceleoEnvironment}
+	 */
+	protected AcceleoEnvironment getEnv() {
+		return env;
+	}
+
+	/**
+	 * Gets the {@link AcceleoEvaluator}.
+	 * 
+	 * @return the {@link AcceleoEvaluator}
+	 */
+	protected AcceleoEvaluator getAcceleoEvaluator() {
+		return acceleoEvaluator;
+	}
+
+	/**
+	 * Gets the module qualified name.
+	 * 
+	 * @return the module qualified name
+	 */
+	public String getModuleQualifiedName() {
+		return env.getModuleQualifiedName((Module)getModuleElement().eContainer());
+	}
+
+	/**
 	 * {@inheritDoc}
 	 *
 	 * @see org.eclipse.acceleo.query.runtime.IService#getShortSignature()
 	 */
 	@Override
 	public String getShortSignature() {
-		final List<IType> parameterTypes = getParameterTypes(null);
+		final List<IType> parameterTypes = getParameterTypes(getEnv().getQueryEnvironment());
 		final IType[] argumentTypes = parameterTypes.toArray(new IType[parameterTypes.size()]);
 
 		return serviceShortSignature(argumentTypes);
diff --git a/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/AcceleoEvaluator.java b/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/AcceleoEvaluator.java
index 7971c4f..a5e6af7 100644
--- a/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/AcceleoEvaluator.java
+++ b/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/AcceleoEvaluator.java
@@ -74,39 +74,43 @@
 	private static final String EMPTY_RESULT = "";
 
 	/** The current evaluation environment. */
-	private IAcceleoEnvironment environment;
+	private final IAcceleoEnvironment environment;
 
 	/**
 	 * The {@link IQueryEvaluationEngine} used to evaluate AQL expressions.
 	 */
-	private IQueryEvaluationEngine aqlEngine;
+	private final IQueryEvaluationEngine aqlEngine;
 
 	/**
 	 * The variables stack.
 	 */
-	private Deque<Map<String, Object>> variablesStack;
+	private final Deque<Map<String, Object>> variablesStack = new ArrayDeque<Map<String, Object>>();
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param environment
+	 *            the {@link IAcceleoEnvironment}
+	 */
+	public AcceleoEvaluator(IAcceleoEnvironment environment) {
+		this.environment = environment;
+		final IQueryEnvironment queryEnvironment = environment.getQueryEnvironment();
+		this.aqlEngine = QueryEvaluation.newEngine(queryEnvironment);
+	}
 
 	/**
 	 * Generates the given {@link ASTNode} with the given variables.
 	 * 
-	 * @param acceleoEnvironment
-	 *            the {@link IAcceleoEnvironment}
 	 * @param node
 	 *            the {@link ASTNode} to generate
 	 * @param variables
 	 *            the variables
 	 * @return the generated {@link Object}, can be <code>null</code>
 	 */
-	public Object generate(IAcceleoEnvironment acceleoEnvironment, ASTNode node,
-			Map<String, Object> variables) {
+	public Object generate(ASTNode node, Map<String, Object> variables) {
 
 		final Object res;
 
-		this.environment = acceleoEnvironment;
-		final IQueryEnvironment queryEnvironment = acceleoEnvironment.getQueryEnvironment();
-		this.aqlEngine = QueryEvaluation.newEngine(queryEnvironment);
-		this.variablesStack = new ArrayDeque<>();
-
 		pushVariables(variables);
 		try {
 			res = doSwitch(node);
diff --git a/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/QueryService.java b/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/QueryService.java
index cfeed75..10e2ae2 100644
--- a/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/QueryService.java
+++ b/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/QueryService.java
@@ -16,7 +16,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.eclipse.acceleo.Module;
 import org.eclipse.acceleo.Query;
 import org.eclipse.acceleo.Variable;
 import org.eclipse.acceleo.VisibilityKind;
@@ -35,14 +34,6 @@
  */
 public class QueryService extends AbstractModuleElementService {
 
-	/** The current evaluation environment. */
-	private final AcceleoEnvironment env;
-
-	/**
-	 * The {@link AcceleoEvaluator}.
-	 */
-	private final AcceleoEvaluator acceleoEvaluator;
-
 	/** The underlying query. */
 	private final Query query;
 
@@ -55,8 +46,7 @@
 	 *            The wrapped query.
 	 */
 	public QueryService(AcceleoEnvironment env, Query query) {
-		this.env = env;
-		this.acceleoEvaluator = new AcceleoEvaluator();
+		super(env);
 		this.query = query;
 	}
 
@@ -66,11 +56,6 @@
 	}
 
 	@Override
-	public String getModuleQualifiedName() {
-		return env.getModuleQualifiedName((Module)query.eContainer());
-	}
-
-	@Override
 	public VisibilityKind getVisibility() {
 		return query.getVisibility();
 	}
@@ -117,6 +102,6 @@
 			variables.put(var.getName(), arguments[i]);
 		}
 
-		return acceleoEvaluator.generate(env, query, variables);
+		return getAcceleoEvaluator().generate(query, variables);
 	}
 }
diff --git a/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/TemplateService.java b/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/TemplateService.java
index 07a901a..e8bb720 100644
--- a/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/TemplateService.java
+++ b/acceleo-aql/org.eclipse.acceleo.aql/src/org/eclipse/acceleo/aql/evaluation/TemplateService.java
@@ -17,7 +17,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.eclipse.acceleo.Module;
 import org.eclipse.acceleo.Template;
 import org.eclipse.acceleo.Variable;
 import org.eclipse.acceleo.VisibilityKind;
@@ -37,14 +36,6 @@
  */
 public class TemplateService extends AbstractModuleElementService {
 
-	/** The current evaluation environment. */
-	private final AcceleoEnvironment env;
-
-	/**
-	 * The {@link AcceleoEvaluator}.
-	 */
-	private final AcceleoEvaluator acceleoEvaluator;
-
 	/** The underlying template. */
 	private final Template template;
 
@@ -57,8 +48,7 @@
 	 *            The wrapped template.
 	 */
 	public TemplateService(AcceleoEnvironment env, Template template) {
-		this.env = env;
-		this.acceleoEvaluator = new AcceleoEvaluator();
+		super(env);
 		this.template = template;
 	}
 
@@ -68,11 +58,6 @@
 	}
 
 	@Override
-	public String getModuleQualifiedName() {
-		return env.getModuleQualifiedName((Module)template.eContainer());
-	}
-
-	@Override
 	public VisibilityKind getVisibility() {
 		return template.getVisibility();
 	}
@@ -116,6 +101,6 @@
 			variables.put(var.getName(), arguments[i]);
 		}
 
-		return acceleoEvaluator.generate(env, template, variables);
+		return getAcceleoEvaluator().generate(template, variables);
 	}
 }