Merge remote-tracking branch 'origin/master' into hhoyos/executors

diff --git a/examples/org.eclipse.epsilon.edl.engine/META-INF/MANIFEST.MF b/examples/org.eclipse.epsilon.edl.engine/META-INF/MANIFEST.MF
index 4ee5000..d826fa6 100644
--- a/examples/org.eclipse.epsilon.edl.engine/META-INF/MANIFEST.MF
+++ b/examples/org.eclipse.epsilon.edl.engine/META-INF/MANIFEST.MF
@@ -10,3 +10,4 @@
  org.eclipse.epsilon.edl.parse

 Bundle-ClassPath: org.eclipse.epsilon.ecl.engine.jar

 Bundle-RequiredExecutionEnvironment: JavaSE-1.8

+Automatic-Module-Name: org.eclipse.epsilon.edl.engine

diff --git a/examples/org.eclipse.epsilon.edl.engine/src/org/eclipse/epsilon/edl/EdlModule.java b/examples/org.eclipse.epsilon.edl.engine/src/org/eclipse/epsilon/edl/EdlModule.java
index c3434df..835469a 100644
--- a/examples/org.eclipse.epsilon.edl.engine/src/org/eclipse/epsilon/edl/EdlModule.java
+++ b/examples/org.eclipse.epsilon.edl.engine/src/org/eclipse/epsilon/edl/EdlModule.java
@@ -30,12 +30,11 @@
 import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;

 import org.eclipse.epsilon.eol.execute.context.IEolContext;

 

-

 public class EdlModule extends EolModule {

 	

-	protected List<ProcessRule> declaredProcessRules = new ArrayList<ProcessRule>();

+	protected List<ProcessRule> declaredProcessRules = new ArrayList<>();

 

-	public static void main(String[] args) throws Exception {

+	public static void main(String... args) throws Exception {

 		

 		EdlModule module = new EdlModule();

 		module.parse(new File("resources/test.edl"));

@@ -96,7 +95,7 @@
 	}

 	

 	public Object executeImpl() throws EolRuntimeException {

-

+		IEolContext context = getContext();

 		for (ProcessRule processRule : declaredProcessRules) {

 			processRule.execute(context);

 		}

@@ -105,13 +104,13 @@
 	}

 	

 	@Override

-	public IEolContext getContext(){

-		return context;

+	public IEolContext getContext() {

+		return super.getContext();

 	}

 

 	@Override

 	public void setContext(IEolContext context) {

-		this.context = context;

+		super.setContext(context);

 	}

 		

 	public List<ProcessRule> getDeclaredProcessRules() {

diff --git a/examples/org.eclipse.epsilon.eunit.examples.etl/META-INF/MANIFEST.MF b/examples/org.eclipse.epsilon.eunit.examples.etl/META-INF/MANIFEST.MF
index eb6e49a..cf7f806 100644
--- a/examples/org.eclipse.epsilon.eunit.examples.etl/META-INF/MANIFEST.MF
+++ b/examples/org.eclipse.epsilon.eunit.examples.etl/META-INF/MANIFEST.MF
@@ -10,10 +10,10 @@
  org.eclipse.epsilon.eol.engine,
  org.eclipse.epsilon.erl.engine,
  org.eclipse.epsilon.etl.engine,
- org.antlr.runtime_3.1.b1,
  org.eclipse.epsilon.eunit.dt.cmp.emf;bundle-version="1.2.0",
  org.eclipse.epsilon.eunit.dt.diff.emf;bundle-version="1.2.0",
  org.junit;bundle-version="4.0.0",
  com.google.guava;bundle-version="15.0.0",
  org.eclipse.epsilon.eunit.engine;bundle-version="1.1.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Automatic-Module-Name: org.eclipse.epsilon.eunit.examples.etl
diff --git a/examples/org.eclipse.epsilon.examples.testlang.engine/src/org/eclipse/epsilon/examples/testlang/engine/TestLangModule.java b/examples/org.eclipse.epsilon.examples.testlang.engine/src/org/eclipse/epsilon/examples/testlang/engine/TestLangModule.java
index 97748bc..6af89e0 100644
--- a/examples/org.eclipse.epsilon.examples.testlang.engine/src/org/eclipse/epsilon/examples/testlang/engine/TestLangModule.java
+++ b/examples/org.eclipse.epsilon.examples.testlang.engine/src/org/eclipse/epsilon/examples/testlang/engine/TestLangModule.java
@@ -40,7 +40,7 @@
 	@Override
 	protected void prepareContext() {
 		super.prepareContext();
-		context.getOperationContributorRegistry().add(new TestLangOperationContributor());
+		getContext().getOperationContributorRegistry().add(new TestLangOperationContributor());
 	}
 
 	@Override
diff --git a/plugins/org.eclipse.epsilon.common/src/org/eclipse/epsilon/common/launch/ProfilableRunConfiguration.java b/plugins/org.eclipse.epsilon.common/src/org/eclipse/epsilon/common/launch/ProfilableRunConfiguration.java
index e5a3296..ff2c27a 100644
--- a/plugins/org.eclipse.epsilon.common/src/org/eclipse/epsilon/common/launch/ProfilableRunConfiguration.java
+++ b/plugins/org.eclipse.epsilon.common/src/org/eclipse/epsilon/common/launch/ProfilableRunConfiguration.java
@@ -18,11 +18,13 @@
 import java.nio.file.StandardOpenOption;
 import java.time.Duration;
 import java.util.*;
+import java.util.concurrent.Callable;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import static org.eclipse.epsilon.common.util.OperatingSystem.*;
+import org.eclipse.epsilon.common.function.CheckedSupplier;
 import org.eclipse.epsilon.common.util.profiling.ProfileDiagnostic;
 import static org.eclipse.epsilon.common.util.profiling.BenchmarkUtils.*;
 import org.eclipse.epsilon.common.util.profiling.ProfileDiagnostic.MemoryUnit;
@@ -43,7 +45,7 @@
  * @author Sina Madani
  * @since 1.6
  */
-public abstract class ProfilableRunConfiguration implements Runnable {
+public abstract class ProfilableRunConfiguration implements Runnable, Callable<Object>, CheckedSupplier<Object, Exception> {
 	
 	protected String printMarker = "-----------------------------------------------------";
 	protected int id;
@@ -171,16 +173,27 @@
 	}
 	
 	@Override
+	public Object getThrows() throws Exception {
+		return call();
+	}
+	
+	@Override
+	public Object call() throws Exception {
+		preExecute();
+		result = execute();
+		hasRun = true;
+		postExecute();
+		return result;
+	}
+	
+	@Override
 	public final void run() {
 		try {
-			preExecute();
-			result = execute();
-			postExecute();
+			call();
 		}
 		catch (Exception ex) {
 			handleException(ex);
 		}
-		hasRun = true;
 	}
 	
 	protected void handleException(Exception ex) {
@@ -220,7 +233,7 @@
 			);
 		}
 		if (showResults) {
-			writeOut("Result: ", "", result, printMarker);
+			writeOut("Result: ", result, printMarker);
 		}
 	}
 	
diff --git a/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/EclModule.java b/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/EclModule.java
index 22cdd10..baab5c8 100644
--- a/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/EclModule.java
+++ b/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/EclModule.java
@@ -43,7 +43,7 @@
 	protected final NamedRuleList<MatchRule> declaredMatchRules = new NamedRuleList<>();

 	

 	public EclModule() {

-		this.context = new EclContext();

+		setContext(new EclContext());

 	}

 	

 	@Override

@@ -191,7 +191,7 @@
 	

 	@Override

 	public IEclContext getContext() {

-		return (IEclContext) context;

+		return (IEclContext) super.getContext();

 	}

 	

 	@Override

@@ -212,7 +212,7 @@
 	@Override

 	public void setContext(IEolContext context) {

 		if (context instanceof IEclContext) {

-			this.context = (IEclContext) context;

+			super.setContext(context);

 		}

 	}

 	

diff --git a/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/concurrent/EclModuleParallel.java b/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/concurrent/EclModuleParallel.java
index 99578ec..bc0ca1f 100644
--- a/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/concurrent/EclModuleParallel.java
+++ b/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/concurrent/EclModuleParallel.java
@@ -37,7 +37,7 @@
 	}
 	
 	public EclModuleParallel(int parallelism) {
-		this.context = new EclContextParallel(parallelism);
+		setContext(new EclContextParallel(parallelism));
 	}
 	
 	@Override
@@ -54,7 +54,7 @@
 	
 	@Override
 	public IEclContextParallel getContext() {
-		return (IEclContextParallel) context;
+		return (IEclContextParallel) super.getContext();
 	}
 	
 	@Override
@@ -76,6 +76,6 @@
 	@Override
 	public void configure(Map<String, ?> properties) throws IllegalArgumentException {
 		super.configure(properties);
-		context = IEolContextParallel.configureContext(properties, EclContextParallel::new, getContext());
+		setContext(IEolContextParallel.configureContext(properties, EclContextParallel::new, getContext()));
 	}
 }
diff --git a/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/execute/context/EclContext.java b/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/execute/context/EclContext.java
index 76932f8..3fa92de 100644
--- a/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/execute/context/EclContext.java
+++ b/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/execute/context/EclContext.java
@@ -9,6 +9,7 @@
  ******************************************************************************/

 package org.eclipse.epsilon.ecl.execute.context;

 

+import org.eclipse.epsilon.common.module.IModule;

 import org.eclipse.epsilon.ecl.IEclModule;

 import org.eclipse.epsilon.ecl.trace.MatchTrace;

 import org.eclipse.epsilon.erl.execute.context.ErlContext;

@@ -34,8 +35,15 @@
 	}

 

 	@Override

+	public void setModule(IModule module) {

+		if (module instanceof IEclModule) {

+			super.setModule(module);

+		}

+	}

+	

+	@Override

 	public IEclModule getModule() {

-		return (IEclModule) module;

+		return (IEclModule) super.getModule();

 	}

 	

 }

diff --git a/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/execute/context/concurrent/EclContextParallel.java b/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/execute/context/concurrent/EclContextParallel.java
index 27cd5f4..11b046f 100644
--- a/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/execute/context/concurrent/EclContextParallel.java
+++ b/plugins/org.eclipse.epsilon.ecl.engine/src/org/eclipse/epsilon/ecl/execute/context/concurrent/EclContextParallel.java
@@ -9,7 +9,8 @@
 **********************************************************************/
 package org.eclipse.epsilon.ecl.execute.context.concurrent;
 
-import org.eclipse.epsilon.ecl.IEclModule;
+import org.eclipse.epsilon.common.module.IModule;
+import org.eclipse.epsilon.ecl.concurrent.EclModuleParallel;
 import org.eclipse.epsilon.ecl.execute.context.IEclContext;
 import org.eclipse.epsilon.ecl.trace.MatchTrace;
 import org.eclipse.epsilon.eol.exceptions.concurrent.EolNestedParallelismException;
@@ -63,8 +64,15 @@
 	}
 
 	@Override
-	public IEclModule getModule() {
-		return (IEclModule) module;
+	public EclModuleParallel getModule() {
+		return (EclModuleParallel) super.getModule();
+	}
+	
+	@Override
+	public void setModule(IModule module) {
+		if (module instanceof EclModuleParallel) {
+			super.setModule(module);
+		}
 	}
 	
 	public static IEclContextParallel convertToParallel(IEclContext context) throws EolNestedParallelismException {
diff --git a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/EgxModule.java b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/EgxModule.java
index 80ff2b9..6605acd 100644
--- a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/EgxModule.java
+++ b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/EgxModule.java
@@ -78,7 +78,7 @@
 	}
 	
 	public EgxModule(IEgxContext egxContext) {
-		this.context = egxContext;
+		setContext(egxContext);
 	}
 	
 	@Override
@@ -179,7 +179,7 @@
 	@Override
 	protected void prepareContext() {
 		super.prepareContext();
-		getTemplateFactory().getContext().copyFrom(context, true);
+		getTemplateFactory().getContext().copyFrom(getContext(), true);
 	}
 	
 	@Override
@@ -197,6 +197,7 @@
 	 * @since 1.6
 	 */
 	protected void generateRules(EglTemplateFactory templateFactory) throws EolRuntimeException {
+		IEgxContext context = getContext();
 		for (GenerationRule rule : getGenerationRules()) {
 			rule.generateAll(context, templateFactory, this);
 		}
@@ -211,7 +212,7 @@
 
 	@Override
 	public IEgxContext getContext() {
-		return (IEgxContext) context;
+		return (IEgxContext) super.getContext();
 	}
 	
 	@Override
@@ -242,7 +243,7 @@
 	@Override
 	public void setContext(IEolContext context) {
 		if (context instanceof IEgxContext) {
-			this.context = (IEgxContext) context;
+			super.setContext(context);
 		}
 	}
 }
diff --git a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/concurrent/EgxModuleParallel.java b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/concurrent/EgxModuleParallel.java
index 7c147d8..2371855 100644
--- a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/concurrent/EgxModuleParallel.java
+++ b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/concurrent/EgxModuleParallel.java
@@ -47,7 +47,7 @@
 	}
 	
 	public EgxModuleParallel(IEgxContextParallel egxContext) {
-		this.context = egxContext;
+		setContext(egxContext);
 		this.invokedTemplates = new ConcurrentLinkedQueue<>();
 	}
 
@@ -78,7 +78,7 @@
 	
 	@Override
 	public IEgxContextParallel getContext() {
-		return (IEgxContextParallel) context;
+		return (IEgxContextParallel) super.getContext();
 	}
 	
 	@Override
@@ -95,11 +95,12 @@
 	@Override
 	public void configure(Map<String, ?> properties) throws IllegalArgumentException {
 		super.configure(properties);
-		context = IEolContextParallel.configureContext(
+		IEgxContextParallel context = getContext();
+		setContext(IEolContextParallel.configureContext(
 			properties,
-			threads -> new EgxContextParallel(getContext().getTemplateFactory(), threads),
-			getContext()
-		);
+			threads -> new EgxContextParallel(context.getTemplateFactory(), threads),
+			context
+		));
 	}
 	
 	@Override
diff --git a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/EglContext.java b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/EglContext.java
index 041d304..664dde7 100644
--- a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/EglContext.java
+++ b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/EglContext.java
@@ -149,4 +149,16 @@
 	public EglTemplate getCurrentTemplate() {

 		return executionManager.getCurrent().template;

 	}

+	

+	/*@Override

+	public IEglModule getModule() {

+		return (IEglModule) super.getModule();

+	}

+	

+	@Override

+	public void setModule(IModule module) {

+		if (module instanceof IEglModule) {

+			super.setModule(module);

+		}

+	}*/

 }

diff --git a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/EgxContext.java b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/EgxContext.java
index 07b76a5..96393e6 100644
--- a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/EgxContext.java
+++ b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/EgxContext.java
@@ -9,6 +9,7 @@
  ******************************************************************************/
 package org.eclipse.epsilon.egl.execute.context;
 
+import org.eclipse.epsilon.common.module.IModule;
 import org.eclipse.epsilon.egl.EglTemplateFactory;
 import org.eclipse.epsilon.egl.IEgxModule;
 import org.eclipse.epsilon.erl.execute.context.ErlContext;
@@ -44,8 +45,15 @@
 	}
 	
 	@Override
+	public void setModule(IModule module) {
+		if (module instanceof IEgxModule) {
+			super.setModule(module);
+		}
+	}
+	
+	@Override
 	public IEgxModule getModule() {
-		return (IEgxModule) module;
+		return (IEgxModule) super.getModule();
 	}
 
 	@Override
diff --git a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/concurrent/EgxContextParallel.java b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/concurrent/EgxContextParallel.java
index 0bd5ec8..cb75c78 100644
--- a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/concurrent/EgxContextParallel.java
+++ b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/execute/context/concurrent/EgxContextParallel.java
@@ -9,6 +9,7 @@
 **********************************************************************/
 package org.eclipse.epsilon.egl.execute.context.concurrent;
 
+import org.eclipse.epsilon.common.module.IModule;
 import org.eclipse.epsilon.egl.EglTemplateFactory;
 import org.eclipse.epsilon.egl.IEgxModule;
 import org.eclipse.epsilon.egl.execute.context.EgxModuleTemplateAdapter;
@@ -66,6 +67,13 @@
 	
 	@Override
 	public IEgxModule getModule() {
-		return (IEgxModule) module;
+		return (IEgxModule) super.getModule();
+	}
+	
+	@Override
+	public void setModule(IModule module) {
+		if (module instanceof IEgxModule) {
+			super.setModule(module);
+		}
 	}
 }
diff --git a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglModule.java b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglModule.java
index 68528df..76e33b6 100644
--- a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglModule.java
+++ b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglModule.java
@@ -60,7 +60,8 @@
 	}

 	

 	public EglModule(IEglContext context) {

-		preprocessorModule = new EglPreprocessorModule(this.context = /*new EglContext*/(context));

+		setContext/*new EglContext*/(context);

+		preprocessorModule = new EglPreprocessorModule(context);

 	}

 

 	@Override

@@ -194,7 +195,7 @@
 

 	@Override

 	public IEglContext getContext() {

-		return (IEglContext) context;

+		return (IEglContext) super.getContext();

 	}

 	

 	@Override

diff --git a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglPreprocessorContext.java b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglPreprocessorContext.java
index 1087fa3..9847325 100644
--- a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglPreprocessorContext.java
+++ b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglPreprocessorContext.java
@@ -34,6 +34,7 @@
 	
 	public EglPreprocessorContext(IEolContext delegate) {
 		this.delegate = delegate;
+		//this.setModule(delegate.getModule());
 	}
 	
 	public IEglContext getEglContext() {
diff --git a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglPreprocessorModule.java b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglPreprocessorModule.java
index f7d9777..a171cd6 100644
--- a/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglPreprocessorModule.java
+++ b/plugins/org.eclipse.epsilon.egl.engine/src/org/eclipse/epsilon/egl/internal/EglPreprocessorModule.java
@@ -49,7 +49,7 @@
 	 * @since 1.6
 	 */
 	public EglPreprocessorModule(IEolContext delegate) {
-		this.context = new EglPreprocessorContext(delegate != null ? delegate : super.context);
+		setContext(new EglPreprocessorContext(delegate != null ? delegate : context));
 		if (delegate instanceof IEglContext) {
 			getContext().setEglContext((IEglContext)delegate);
 		}
@@ -70,7 +70,7 @@
 	
 	@Override
 	public EglPreprocessorContext getContext() {
-		return (EglPreprocessorContext) context;
+		return (EglPreprocessorContext) super.getContext();
 	}
 	
 	@Override
diff --git a/plugins/org.eclipse.epsilon.emc.emf.decorator/src/org/eclipse/epsilon/emc/emf/decorator/DecoratorEmfModel.java b/plugins/org.eclipse.epsilon.emc.emf.decorator/src/org/eclipse/epsilon/emc/emf/decorator/DecoratorEmfModel.java
index ebc2535..eef3739 100644
--- a/plugins/org.eclipse.epsilon.emc.emf.decorator/src/org/eclipse/epsilon/emc/emf/decorator/DecoratorEmfModel.java
+++ b/plugins/org.eclipse.epsilon.emc.emf.decorator/src/org/eclipse/epsilon/emc/emf/decorator/DecoratorEmfModel.java
@@ -32,7 +32,7 @@
 	List<DecoratorDescriptor> decoratorDescriptors;

 	

 	protected List<EClass> getDecoratorEClasses(Collection<EPackage> ePackages) {

-		List<EClass> decoratorEClasses = new ArrayList<EClass>();

+		List<EClass> decoratorEClasses = new ArrayList<>();

 		for (EPackage ePackage :ePackages) {

 			for (EClassifier eClassifier : ePackage.getEClassifiers()) {

 				if (eClassifier instanceof EClass) {

@@ -50,7 +50,7 @@
 	protected List<DecoratorDescriptor> getDecoratorDescriptors() {

 		

 		if (decoratorDescriptors == null) {

-			decoratorDescriptors = new ArrayList<DecoratorDescriptor>();

+			decoratorDescriptors = new ArrayList<>();

 			

 			List<EClass> decoratorEClasses = getDecoratorEClasses(packages);

 			

@@ -98,7 +98,7 @@
 		// also cache the 

 		// actual decorator

 		

-		Collection<EObject> candidateDecorators = new ArrayList<EObject>();

+		Collection<EObject> candidateDecorators = new ArrayList<>();

 		try {

 			candidateDecorators = getAllOfKind(getFullyQualifiedName(decoratorDescriptor.getEClass()));

 		}

@@ -172,7 +172,7 @@
 				throws EolRuntimeException {

 			if (decorator == null) {

 				if (decoratorDescriptor.getLastValueFeature().isMany()) {

-					return new ArrayList<Object>();

+					return new ArrayList<>();

 				}

 				else {

 					return decoratorDescriptor.getLastValueFeature()

diff --git a/plugins/org.eclipse.epsilon.emc.emf/src/org/eclipse/epsilon/emc/emf/AbstractEmfModel.java b/plugins/org.eclipse.epsilon.emc.emf/src/org/eclipse/epsilon/emc/emf/AbstractEmfModel.java
index cdc803d..09ba3a6 100644
--- a/plugins/org.eclipse.epsilon.emc.emf/src/org/eclipse/epsilon/emc/emf/AbstractEmfModel.java
+++ b/plugins/org.eclipse.epsilon.emc.emf/src/org/eclipse/epsilon/emc/emf/AbstractEmfModel.java
@@ -244,7 +244,7 @@
 	}

 	

 	protected EClass classForName(String name, Registry registry) {	

-		boolean absolute = name.indexOf("::") > -1;

+		boolean absolute = name.contains("::");

 		

 		return registry.values()

 			.stream()

@@ -255,18 +255,13 @@
 			.orElse(null);

 	}

 

-	protected EClass classForName(String name, boolean absolute, Object pkg) {

-		for (EClassifier eClassifier : EmfUtil.getAllEClassifiers((EPackage)pkg)) {

+	protected EClass classForName(String name, boolean absolute, EPackage pkg) {

+		for (EClassifier eClassifier : EmfUtil.getAllEClassifiers(pkg)) {

 			if (eClassifier instanceof EClass) {

-				String eClassifierName = "";

-				if (absolute) {

-					eClassifierName = getFullyQualifiedName(eClassifier);

-				}

-				else {

-					eClassifierName = eClassifier.getName();

-				}

+				String eClassifierName = absolute ?

+					getFullyQualifiedName(eClassifier) : eClassifier.getName();

 				

-				if (eClassifierName.compareTo(name) == 0) {

+				if (eClassifierName.equals(name)) {

 					return (EClass) eClassifier;

 				}

 			}

@@ -313,10 +308,7 @@
 	

 	protected int instancesCount(Resource r) {

 		int i = 0;

-		Iterator<EObject> ite = r.getAllContents();

-		

-		while (ite.hasNext()) {

-			ite.next();

+		for (Iterator<EObject> ite = r.getAllContents(); ite.hasNext(); ite.next()) {

 			++i;

 		}

 		return i;

@@ -580,10 +572,8 @@
 	

 	protected String getFullyQualifiedName(EClassifier eClassifier) {

 		String fullyQualifiedName = eClassifier.getName();

-		EPackage parent = eClassifier.getEPackage();

-		while (parent != null) {

+		for (EPackage parent = eClassifier.getEPackage(); parent != null; parent = parent.getESuperPackage()) {

 			fullyQualifiedName = parent.getName() + "::" + fullyQualifiedName;

-			parent = parent.getESuperPackage();

 		}

 		return fullyQualifiedName;

 	}

diff --git a/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/EmlModule.java b/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/EmlModule.java
index c81039b..960b9b5 100644
--- a/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/EmlModule.java
+++ b/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/EmlModule.java
@@ -38,7 +38,7 @@
 	protected NamedRuleList<MergeRule> mergeRules;

 	

 	public EmlModule() {

-		this.context = new EmlContext();

+		setContext(new EmlContext());

 	}

 	

 	@Override

@@ -73,7 +73,8 @@
 	}

 	

 	@Override

-	public Object executeImpl() throws EolRuntimeException {

+	protected void prepareContext() {

+		super.prepareContext();

 		IEmlContext context = getContext();

 		

 		context.getFrameStack().put(

@@ -83,24 +84,37 @@
 			Variable.createReadOnlyVariable("context", context),

 			Variable.createReadOnlyVariable("thisModule", this)

 		);

-		

-		execute(getPre(), context);

-		context.getMergingStrategy().mergeModels(context);

-		execute(getPost(), context);

-		

+	}

+	

+	@Override

+	public Object executeImpl() throws EolRuntimeException {

+		prepareExecution();

+		merge();

+		postExecution();

 		return null;

 	}

 	

+	/**

+	 * Main execution logic.

+	 * 

+	 * @throws EolRuntimeException

+	 * @since 1.6

+	 */

+	protected void merge() throws EolRuntimeException {

+		IEmlContext context = getContext();

+		context.getMergingStrategy().mergeModels(context);

+	}

+	

 	@Override

 	public void setContext(IEolContext context) {

 		if (context instanceof IEmlContext) {

-			this.context = (IEmlContext) context;

+			this.context = context;//super.setContext(context);

 		}

 	}

 	

 	@Override

 	public IEmlContext getContext() {

-		return (IEmlContext) context;

+		return (IEmlContext) super.getContext();

 	}

 	

 	@Override

diff --git a/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/execute/context/EmlContext.java b/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/execute/context/EmlContext.java
index c8a5df0..df347bc 100644
--- a/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/execute/context/EmlContext.java
+++ b/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/execute/context/EmlContext.java
@@ -9,6 +9,7 @@
  ******************************************************************************/

 package org.eclipse.epsilon.eml.execute.context;

 

+import org.eclipse.epsilon.common.module.IModule;

 import org.eclipse.epsilon.ecl.trace.MatchTrace;

 import org.eclipse.epsilon.eml.EmlModule;

 import org.eclipse.epsilon.eml.execute.operations.EmlOperationFactory;

@@ -21,15 +22,12 @@
 

 	protected MatchTrace matchTrace = new MatchTrace();

 	protected MergeTrace mergeTrace = new MergeTrace();

-	//protected MatchTrace tempMatchTrace = new MatchTrace();

 	

 	private IMergingStrategy mergingStrategy = null;

-	//private MatchingStrategy matchingStrategy = null;

 	

 	public EmlContext() {

 		this.setOperationFactory(new EmlOperationFactory());

 		this.mergingStrategy = new DefaultMergingStrategy();

-		//this.matchingStrategy = new DefaultMatchingStrategy();

 	}

 	

 	@Override

@@ -41,37 +39,32 @@
 	public void setMergingStrategy(IMergingStrategy mergingStrategy) {

 		this.mergingStrategy = mergingStrategy;

 	}

-	

-	//public MatchingStrategy getMatchingStrategy() {

-	//	return matchingStrategy;

-	//}

-

-	//public void setMatchingStrategy(MatchingStrategy matchingStrategy) {

-	//	this.matchingStrategy = matchingStrategy;

-	//}

-

-	//public MatchTrace getTempMatchTrace() {

-	//	return tempMatchTrace;

-	//}

 

 	@Override

-	public MatchTrace getMatchTrace(){

+	public MatchTrace getMatchTrace() {

 		return matchTrace;

 	}

 

 	@Override

-	public MergeTrace getMergeTrace(){

+	public MergeTrace getMergeTrace() {

 		return mergeTrace;

 	}

 	

 	@Override

-	public EmlModule getModule(){

-		return (EmlModule) module;

+	public EmlModule getModule() {

+		return (EmlModule) super.getModule();

 	}

 	

 	@Override

-	public void setModule(EmlModule module){

-		this.module = module;

+	public void setModule(EmlModule module) {

+		super.setModule(module);

+	}

+	

+	@Override

+	public void setModule(IModule module) {

+		if (module instanceof EmlModule) {

+			this.module = module;//super.setModule(module);

+		}

 	}

 

 	@Override

@@ -83,20 +76,4 @@
 	public void setMergeTrace(MergeTrace mergeTrace) {

 		this.mergeTrace = mergeTrace;

 	}

-

-	//public void setTempMatchTrace(MatchTrace tempMatchTrace) {

-	//	this.tempMatchTrace = tempMatchTrace;

-	//}

-	

-	/*

-	@Override

-	public ITransformationStrategy getTransformationStrategy(Object source) {

-		if (mergingStrategy.getLeftModel().owns(source)){

-			return mergingStrategy.getLeftTransformationStrategy();

-		}

-		else {

-			return mergingStrategy.getRightTransformationStrategy();

-		}

-	}	

-	*/

 }

diff --git a/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/strategy/DefaultMergingStrategy.java b/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/strategy/DefaultMergingStrategy.java
index 090a191..d9669f9 100644
--- a/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/strategy/DefaultMergingStrategy.java
+++ b/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/strategy/DefaultMergingStrategy.java
@@ -46,10 +46,10 @@
 		List<MergeRule> rules = new ArrayList<>();

 		

 		// First we try to find rules that apply to instance of type only

-		for (MergeRule mergeRule : context.getModule().getMergeRules()){

+		for (MergeRule mergeRule : context.getModule().getMergeRules()) {

 			if (!mergeRule.isAbstract()){

-				if (mergeRule.appliesTo(match, context)){ 

-						rules.add(mergeRule);

+				if (mergeRule.appliesTo(match, context)) { 

+					rules.add(mergeRule);

 				}

 			}

 		}

@@ -106,8 +106,9 @@
 	@Override

 	public List<Object> getExcluded() {

 		if (excluded == null) {

-			excluded = new ArrayList<>();

-			for (Match match : context.getMatchTrace().getMatches()) {

+			Collection<Match> matches = context.getMatchTrace().getMatches();

+			excluded = new ArrayList<>(matches.size()*2);

+			for (Match match : matches) {

 				excluded.add(match.getLeft());

 				excluded.add(match.getRight());

 			}

diff --git a/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/trace/MergeTrace.java b/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/trace/MergeTrace.java
index 4dc8ee6..3ef3c8e 100644
--- a/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/trace/MergeTrace.java
+++ b/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/trace/MergeTrace.java
@@ -18,7 +18,7 @@
 

 public class MergeTrace extends ArrayList<Merge> {

 	

-	public void add(Match match, Collection<Object> targets, MergeRule rule){

+	public void add(Match match, Collection<Object> targets, MergeRule rule) {

 		Merge merge = new Merge();

 		merge.match = match;

 		merge.setTargets(targets);

@@ -26,7 +26,7 @@
 		add(merge);

 	}

 	

-	public Merges getMerges(Match match){

+	public Merges getMerges(Match match) {

 		ListIterator<Merge> li = listIterator();

 		Merges merges = new Merges();

 		while (li.hasNext()) {

@@ -38,10 +38,10 @@
 		return merges;

 	}

 

-	public Merges getMerges(Match match, MergeRule mergeRule){

+	public Merges getMerges(Match match, MergeRule mergeRule) {

 		ListIterator<Merge> li = listIterator();

 		Merges merges = new Merges();

-		while (li.hasNext()){

+		while (li.hasNext()) {

 			Merge merge = (Merge)li.next();

 			if (merge.getMatch() == match && merge.getRule() == mergeRule) {

 				merges.add(merge);

diff --git a/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/trace/Merges.java b/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/trace/Merges.java
index 69dd117..27a38ae 100644
--- a/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/trace/Merges.java
+++ b/plugins/org.eclipse.epsilon.eml.engine/src/org/eclipse/epsilon/eml/trace/Merges.java
@@ -17,10 +17,10 @@
 

 public class Merges extends ArrayList<Merge> {

 	

-	public Collection<Object> getTargets(){

+	public Collection<Object> getTargets() {

 		ListIterator<Merge> li = listIterator();

 		Collection<Object> targets = CollectionUtil.createDefaultList();

-		while (li.hasNext()){

+		while (li.hasNext()) {

 			Merge merge = li.next();

 			targets.addAll(merge.getTargets());

 		}

diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/EolModule.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/EolModule.java
index 4343317..8681f8f 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/EolModule.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/EolModule.java
@@ -35,7 +35,7 @@
 public class EolModule extends AbstractModule implements IEolModule {

 	

 	protected StatementBlock main;

-	protected IEolContext context = new EolContext();

+	protected IEolContext context;

 	protected List<Statement> postOperationStatements = new ArrayList<>();

 	protected OperationList declaredOperations = new OperationList();

 	protected List<Import> imports = new ArrayList<>();

@@ -44,7 +44,10 @@
 	protected Set<ModelDeclaration> modelDeclarations;

 	protected EolCompilationContext compilationContext;

 	private IEolModule parent;

-	private boolean prepareContextCalled = false;

+	

+	public EolModule() {

+		setContext(new EolContext());

+	}

 	

 	@Override

 	public void build(AST cst, IModule module) {

@@ -242,23 +245,15 @@
 

 	protected void prepareContext() {

 		IEolContext context = getContext();

-		if (prepareContextCalled) return;

 		

 		EolSystem system = new EolSystem();

 		system.setContext(context);

-

 		context.setModule(this);

 		

-		for (Import import_ : getImports()) {

-			import_.setContext(context);

-		}

-		

 		context.getFrameStack().putGlobal(

 			Variable.createReadOnlyVariable("null", null),

 			Variable.createReadOnlyVariable("System", system)

 		);

-		

-		prepareContextCalled = true;

 	}

 

 	@Override

@@ -425,7 +420,12 @@
 

 	@Override

 	public void setContext(IEolContext context) {

-		this.context = context;

+		if (this.context != context) {

+			this.context = context;

+			for (Import import_ : getImports()) {

+				import_.setContext(context);

+			}

+		}

 	}

 

 	/**

diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/IEolModule.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/IEolModule.java
index 76934ec..746c90e 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/IEolModule.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/IEolModule.java
@@ -14,7 +14,6 @@
 import java.util.List;

 import java.util.Map;

 import java.util.Set;

-

 import org.eclipse.epsilon.common.module.IModule;

 import org.eclipse.epsilon.common.parse.problem.ParseProblem;

 import org.eclipse.epsilon.eol.compile.context.EolCompilationContext;

@@ -59,7 +58,7 @@
 	

 	@Override

 	List<ParseProblem> getParseProblems();

-

+	

 	/**

 	 * Configure the IEolModule with the given properties

 	 * @param properties a map of property:value 

diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/concurrent/EolModuleParallel.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/concurrent/EolModuleParallel.java
index fb76b3e..01cbee5 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/concurrent/EolModuleParallel.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/concurrent/EolModuleParallel.java
@@ -31,11 +31,11 @@
 	}
 	
 	public EolModuleParallel() {
-		this.context = new EolContextParallel();
+		setContext(new EolContextParallel());
 	}
 	
 	public EolModuleParallel(int numThreads) {
-		this.context = new EolContextParallel(numThreads);
+		setContext(new EolContextParallel(numThreads));
 	}
 	
 	@Override
@@ -60,7 +60,7 @@
 	
 	@Override
 	public IEolContextParallel getContext() {
-		return (IEolContextParallel) context;
+		return (IEolContextParallel) super.getContext();
 	}
 	
 	/**
@@ -70,6 +70,6 @@
 	@Override
 	public void configure(Map<String, ?> properties) throws IllegalArgumentException {
 		super.configure(properties);
-		context = IEolContextParallel.configureContext(properties, EolContextParallel::new, getContext());
+		setContext(IEolContextParallel.configureContext(properties, EolContextParallel::new, getContext()));
 	}
 }
diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/Import.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/Import.java
index 6db81aa..8dc8ff9 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/Import.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/Import.java
@@ -27,8 +27,6 @@
 	private boolean found = false;

 	protected StringLiteral pathLiteral;

 	

-	public Import() {}

-	

 	public void setParentModule(IEolModule parentModule) {

 		this.parentModule = parentModule;

 	}

@@ -85,17 +83,16 @@
 			}

 			

 			found = true;

-			if (importedModule.getParseProblems().size() == 0) {

-				loaded = true;

-			}

-		} catch (Exception e) {

+			loaded = importedModule.getParseProblems().isEmpty();

+		}

+		catch (Exception ex) {

 			// Ignore the exception. The import's loaded flag is still false

 			// and it's up to the importing module to do something about it.

 		}

 	}

 	

 	@Override

-	public String toString(){

+	public String toString() {

 		return "import '" + getPath() + "'";

 	}

 	

@@ -107,6 +104,7 @@
 		return found;

 	}

 	

+	@Override

 	public IModule getModule() {

 		return importedModule;

 	}

diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/NameExpression.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/NameExpression.java
index e524ad2..2c1c0b8 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/NameExpression.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/NameExpression.java
@@ -51,7 +51,7 @@
 		// First look for a model element type
 		// if the name contains a !
 		if (variable == null) {
-			if (name.indexOf("!") > -1) {
+			if (name.contains("!")) {
 				variable = getModelElementType(name, context);
 			}
 		}
diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/TypeExpression.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/TypeExpression.java
index b4eebc9..6a5aaba 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/TypeExpression.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/dom/TypeExpression.java
@@ -69,7 +69,7 @@
 		}
 		
 		try {
-			return new EolModelElementType(name ,context);
+			return new EolModelElementType(name, context);
 		}
 		catch (EolModelNotFoundException | EolModelElementTypeNotFoundException ex) {
 			throw new EolTypeNotFoundException(getName(), this);
diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/exceptions/models/EolNotInstantiableModelElementTypeException.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/exceptions/models/EolNotInstantiableModelElementTypeException.java
index 2ba98d5..db9c588 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/exceptions/models/EolNotInstantiableModelElementTypeException.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/exceptions/models/EolNotInstantiableModelElementTypeException.java
@@ -22,7 +22,7 @@
 		this.typeName = typeName;

 	}

 	

-	public EolNotInstantiableModelElementTypeException(EolModelElementType type) {

+	public EolNotInstantiableModelElementTypeException(EolModelElementType type) throws EolModelElementTypeNotFoundException {

 		this.model = type.getModel().getName();

 		this.typeName = type.getTypeName();

 	}

diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/models/CachedModel.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/models/CachedModel.java
index 8142b47..c917984 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/models/CachedModel.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/models/CachedModel.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010 The University of York.
+ * Copyright (c) 2010-2019 The University of York.
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which is available at https://www.eclipse.org/legal/epl-2.0/
diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolCollectionType.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolCollectionType.java
index a828336..4900ceb 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolCollectionType.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolCollectionType.java
@@ -97,7 +97,7 @@
 	}

 	

 	@Override

-	public Object createInstance() {

+	public Collection<?> createInstance() {

 		try {

 			if (this.isCollection()) return null;

 			else if (this.isBag()) {

diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolMapType.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolMapType.java
index b29113a..ef3ce0b 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolMapType.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolMapType.java
@@ -42,12 +42,12 @@
 	}
 
 	@Override
-	public Object createInstance() throws EolRuntimeException {
+	public EolMap<?, ?> createInstance() throws EolRuntimeException {
 		return new EolMap<>();
 	}
 
 	@Override
-	public Object createInstance(List<Object> parameters) throws EolRuntimeException {
+	public EolMap<?, ?> createInstance(List<Object> parameters) throws EolRuntimeException {
 		return new EolMap<>();
 	}
 	
diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolModelElementType.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolModelElementType.java
index 7f81314..984d6f9 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolModelElementType.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolModelElementType.java
@@ -1,11 +1,12 @@
 /*******************************************************************************

- * Copyright (c) 2008 The University of York.

+ * Copyright (c) 2008-2019 The University of York.

  * This program and the accompanying materials

  * are made available under the terms of the Eclipse Public License 2.0

  * which is available at https://www.eclipse.org/legal/epl-2.0/

  * 

  * Contributors:

  *     Dimitrios Kolovos - initial API and implementation

+ *     Sina Madani - bug #538175

  ******************************************************************************/

 package org.eclipse.epsilon.eol.types;

 

@@ -15,6 +16,7 @@
 import java.util.Objects;

 import org.eclipse.epsilon.common.module.ModuleElement;

 import org.eclipse.epsilon.common.util.CollectionUtil;

+import org.eclipse.epsilon.eol.IEolModule;

 import org.eclipse.epsilon.eol.compile.m3.MetaClass;

 import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;

 import org.eclipse.epsilon.eol.exceptions.models.EolModelElementTypeNotFoundException;

@@ -22,13 +24,17 @@
 import org.eclipse.epsilon.eol.execute.context.IEolContext;

 import org.eclipse.epsilon.eol.execute.context.Variable;

 import org.eclipse.epsilon.eol.models.IModel;

+import org.eclipse.epsilon.eol.models.ModelRepository;

 import org.eclipse.epsilon.eol.models.ModelRepository.AmbiguityCheckResult;

 

 public class EolModelElementType extends EolType {

 	

-	protected String modelName = "", typeName = "";

-	protected IModel model;

-	protected MetaClass metaClass = null;

+	protected String modelName = "";

+	protected String typeName = "";

+	protected IEolModule module;

+	protected ModelRepository modelRepo;

+	protected MetaClass metaClass;

+	protected IModel cachedModelRef;

 	

 	public EolModelElementType(MetaClass metaClass) {

 		this.metaClass = metaClass;

@@ -36,7 +42,7 @@
 	}

 	

 	public EolModelElementType(String modelAndMetaClass) {

-		if (modelAndMetaClass.indexOf("!") > -1) {

+		if (modelAndMetaClass.contains("!")) {

 			String[] parts = modelAndMetaClass.split("!");

 			modelName = parts[0];

 			typeName = parts[1];

@@ -49,22 +55,10 @@
 	

 	public EolModelElementType(String modelAndMetaClass, IEolContext context) throws EolModelNotFoundException, EolModelElementTypeNotFoundException {

 		this(modelAndMetaClass);

+		this.module = (IEolModule) context.getModule();

 		

 		checkAmbiguityOfType(context);

-

-		try {

-			model = context.getModelRepository().getModelByName(modelName);

-		}

-		catch (EolModelNotFoundException ex) {

-			Variable modelVariable = context.getFrameStack().get(modelName);

-			if (modelVariable != null && modelVariable.getValue() instanceof IModel) {

-				model = (IModel) modelVariable.getValue();

-			}

-		}

-		

-		if (model == null || !model.hasType(typeName)) {

-			throw new EolModelElementTypeNotFoundException(modelName, typeName);

-		}

+		getModel(true);	// Eager caching, possibly prevents race conditions

 	}

 

 	private void checkAmbiguityOfType(IEolContext context) {

@@ -111,20 +105,20 @@
 	

 	public Collection<?> getAllOfKind() {

 		try {

-			return model.getAllOfKind(typeName);

+			return getModel().getAllOfKind(typeName);

 		}

-		catch (Exception e) {

-			e.printStackTrace();

+		catch (EolModelElementTypeNotFoundException ex) {

+			ex.printStackTrace();

 			return Collections.emptyList();

 		}

 	}

 	

 	public Collection<?> getAllOfType() {

 		try {

-			return model.getAllOfType(typeName);

+			return getModel().getAllOfType(typeName);

 		}

-		catch (Exception e) {

-			e.printStackTrace();

+		catch (EolModelElementTypeNotFoundException ex) {

+			ex.printStackTrace();

 			return Collections.emptyList();

 		}

 	}

@@ -145,16 +139,16 @@
 		return getAllOfKind();

 	}

 	

-	public boolean isInstantiable(){

-		return model.isInstantiable(typeName);

+	public boolean isInstantiable() throws EolModelElementTypeNotFoundException {

+		return getModel().isInstantiable(typeName);

 	}

 	

 	@Override

 	public boolean isType(Object o) {

 		try {

-			return model.isOfType(o,typeName);

+			return getModel().isOfType(o, typeName);

 		}

-		catch (Exception ex){

+		catch (EolModelElementTypeNotFoundException ex) {

 			ex.printStackTrace();

 			return false;

 		}

@@ -162,20 +156,20 @@
 	

 	@Override

 	public Object createInstance() throws EolRuntimeException {

-		return model.createInstance(typeName);

+		return getModel().createInstance(typeName);

 	}

 

 	@Override

 	public Object createInstance(List<Object> parameters) throws EolRuntimeException {

-		return model.createInstance(typeName, parameters);

+		return getModel().createInstance(typeName, parameters);

 	}

 	

 	@Override

 	public boolean isKind(Object o) {

 		try {

-			return model.isOfKind(o,typeName);

+			return getModel().isOfKind(o, typeName);

 		}

-		catch (Exception ex) {

+		catch (EolModelElementTypeNotFoundException ex) {

 			ex.printStackTrace();

 			return false;

 		}

@@ -184,14 +178,43 @@
 	@Override

 	public String getName() {

 		String name = "";

-		if (modelName.length() > 0) {

+		if (!modelName.isEmpty()) {

 			name = modelName + "!";

 		}

 		return name + typeName; 

 	}

 	

-	public IModel getModel() {

-		return model;

+	public IModel getModel() throws EolModelElementTypeNotFoundException {

+		return getModel(module.getContext().getModelRepository() != modelRepo);

+	}

+	

+	/**

+	 * Fetches the model from the module's context.

+	 * 

+	 * @param updateCached Whether to re-acquire reference to the model and model repository.

+	 * @return The model

+	 * @throws EolModelElementTypeNotFoundException

+	 * @since 1.6

+	 */

+	public IModel getModel(boolean updateCached) throws EolModelElementTypeNotFoundException {

+		if (cachedModelRef == null || updateCached) {

+			modelRepo = module.getContext().getModelRepository();

+			try {

+				cachedModelRef = modelRepo.getModelByName(modelName);

+			}

+			catch (EolModelNotFoundException ex) {

+				Variable modelVariable = module.getContext().getFrameStack().get(modelName);

+				if (modelVariable != null && modelVariable.getValue() instanceof IModel) {

+					cachedModelRef = (IModel) modelVariable.getValue();

+				}

+			}

+			

+			if (cachedModelRef == null || !cachedModelRef.hasType(typeName)) {

+				throw new EolModelElementTypeNotFoundException(modelName, typeName);

+			}

+		}

+		

+		return cachedModelRef;

 	}

 	

 	public MetaClass getMetaClass() {

@@ -209,7 +232,12 @@
 	

 	@Override

 	public int hashCode() {

-		return Objects.hash(super.hashCode(), model != null ? model.getName() : model, metaClass != null ? metaClass.getName() : metaClass);

+		return Objects.hash(

+			super.hashCode(),

+			getName(),

+			module,

+			metaClass != null ? metaClass.getName() : metaClass

+		);

 	}

 	

 	@Override

@@ -218,13 +246,7 @@
 		if (!eq) return false;

 		

 		EolModelElementType eme = (EolModelElementType) other;

-		

-		if (!(this.model == null && eme.model == null)) {

-			if (this.model == null || eme.model == null)

-				return false;

-			

-			eq = Objects.equals(this.model.getName(), eme.model.getName());

-		}

+		eq = Objects.equals(this.getName(), eme.getName());

 		

 		if (eq && !(this.metaClass == null && eme.metaClass == null)) {

 			if (this.metaClass == null || eme.metaClass == null)

@@ -232,6 +254,7 @@
 			

 			eq = Objects.equals(this.metaClass.getName(), eme.metaClass.getName());

 		}

+		eq = eq && Objects.equals(this.module, eme.module);

 		

 		return eq;

 	}

diff --git a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolNoType.java b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolNoType.java
index b91b100..4d73cd5 100644
--- a/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolNoType.java
+++ b/plugins/org.eclipse.epsilon.eol.engine/src/org/eclipse/epsilon/eol/types/EolNoType.java
@@ -20,13 +20,13 @@
 	public static EolNoTypeInstance NoInstance = new EolNoTypeInstance();

 	

 	@Override

-	public Object createInstance() throws EolRuntimeException {

+	public Void createInstance() throws EolRuntimeException {

 		return null;

 	}

 

 	@Override

-	public Object createInstance(List<Object> parameters)

-			throws EolRuntimeException {

+	public Void createInstance(List<Object> parameters)

+			throws EolIllegalOperationParametersException {

 		throw new EolIllegalOperationParametersException("createInstance");

 	}

 	

diff --git a/plugins/org.eclipse.epsilon.epl.engine/src/org/eclipse/epsilon/epl/EplModule.java b/plugins/org.eclipse.epsilon.epl.engine/src/org/eclipse/epsilon/epl/EplModule.java
index a4f0d09..e7ed4d0 100644
--- a/plugins/org.eclipse.epsilon.epl.engine/src/org/eclipse/epsilon/epl/EplModule.java
+++ b/plugins/org.eclipse.epsilon.epl.engine/src/org/eclipse/epsilon/epl/EplModule.java
@@ -128,7 +128,7 @@
 	
 	@Override
 	public Object executeImpl() throws EolRuntimeException {
-		execute(getPre(), context);
+		execute(getPre(), getContext());
 		
 		PatternMatcher patternMatcher = new PatternMatcher();
 		PatternMatchModel matchModel = null;
@@ -150,7 +150,7 @@
 			EolRuntimeException.propagate(ex);
 		}
 		
-		execute(getPost(), context);
+		execute(getPost(), getContext());
 		
 		return matchModel;
 	}
diff --git a/plugins/org.eclipse.epsilon.erl.engine/src/org/eclipse/epsilon/erl/ErlModule.java b/plugins/org.eclipse.epsilon.erl.engine/src/org/eclipse/epsilon/erl/ErlModule.java
index 5a17b9f..9ef1380 100644
--- a/plugins/org.eclipse.epsilon.erl.engine/src/org/eclipse/epsilon/erl/ErlModule.java
+++ b/plugins/org.eclipse.epsilon.erl.engine/src/org/eclipse/epsilon/erl/ErlModule.java
@@ -35,7 +35,7 @@
 	protected NamedRuleList<Post> declaredPost = new NamedRuleList<>();

 	

 	protected ErlModule() {

-		this.context = new ErlContext();

+		setContext(new ErlContext());

 	}

 	

 	@Override

@@ -112,11 +112,11 @@
 	

 	protected void prepareExecution() throws EolRuntimeException {

 		prepareContext();

-		execute(getPre(), context);

+		execute(getPre(), getContext());

 	}

 	

 	protected void postExecution() throws EolRuntimeException {

-		execute(getPost(), context);

+		execute(getPost(), getContext());

 	}

 	

 	protected void execute(List<? extends NamedStatementBlockRule> namedRules) throws EolRuntimeException {

@@ -152,12 +152,12 @@
 	@Override

 	public void setContext(IEolContext context) {

 		if (context instanceof IErlContext) {

-			this.context = context;

+			super.setContext(context);

 		}

 	}

 	

 	@Override

 	public IErlContext getContext() {

-		return (IErlContext) context;

+		return (IErlContext) super.getContext();

 	}

 }

diff --git a/plugins/org.eclipse.epsilon.erl.engine/src/org/eclipse/epsilon/erl/execute/context/ErlContext.java b/plugins/org.eclipse.epsilon.erl.engine/src/org/eclipse/epsilon/erl/execute/context/ErlContext.java
index d43ddcd..841fde9 100644
--- a/plugins/org.eclipse.epsilon.erl.engine/src/org/eclipse/epsilon/erl/execute/context/ErlContext.java
+++ b/plugins/org.eclipse.epsilon.erl.engine/src/org/eclipse/epsilon/erl/execute/context/ErlContext.java
@@ -9,6 +9,7 @@
 **********************************************************************/
 package org.eclipse.epsilon.erl.execute.context;
 
+import org.eclipse.epsilon.common.module.IModule;
 import org.eclipse.epsilon.eol.execute.ExecutorFactory;
 import org.eclipse.epsilon.eol.execute.context.EolContext;
 import org.eclipse.epsilon.erl.IErlModule;
@@ -41,8 +42,15 @@
 	}
 
 	@Override
+	public void setModule(IModule module) {
+		if (module instanceof IErlModule) {
+			super.setModule(module);
+		}
+	}
+	
+	@Override
 	public IErlModule getModule() {
-		return (IErlModule) module;
+		return (IErlModule) super.getModule();
 	}
 
 }
diff --git a/plugins/org.eclipse.epsilon.etl.engine/META-INF/MANIFEST.MF b/plugins/org.eclipse.epsilon.etl.engine/META-INF/MANIFEST.MF
index 22bd38b..1d8792c 100644
--- a/plugins/org.eclipse.epsilon.etl.engine/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.epsilon.etl.engine/META-INF/MANIFEST.MF
@@ -14,3 +14,4 @@
  org.eclipse.epsilon.etl.strategy,

  org.eclipse.epsilon.etl.trace

 Bundle-RequiredExecutionEnvironment: JavaSE-1.8

+Automatic-Module-Name: org.eclipse.epsilon.etl.engine

diff --git a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/EtlModule.java b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/EtlModule.java
index 52433ba..600c8de 100644
--- a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/EtlModule.java
+++ b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/EtlModule.java
@@ -41,7 +41,7 @@
 	protected NamedRuleList<TransformationRule> transformationRules;

 	

 	public EtlModule() {

-		this.context = new EtlContext();

+		setContext(new EtlContext());

 	}

 	

 	@Override

@@ -108,15 +108,23 @@
 	@Override

 	public Object executeImpl() throws EolRuntimeException {

 		prepareExecution();

+		transform();

+		postExecution();

+		return getContext().getTransformationTrace();

+	}

+	

+	/**

+	 * Main execution logic.

+	 * 

+	 * @throws EolRuntimeException

+	 * @since 1.6

+	 */

+	protected void transform() throws EolRuntimeException {

 		IEtlContext context = getContext();

-		

 		// Execute the transformModel() method of the strategy

 		if (context.getTransformationStrategy() != null) {

 			context.getTransformationStrategy().transformModels(context);

 		}

-		

-		postExecution();

-		return context.getTransformationTrace();

 	}

 	

 	@Override

@@ -155,13 +163,13 @@
 

 	@Override

 	public IEtlContext getContext() {

-		return (IEtlContext) context;

+		return (IEtlContext) super.getContext();

 	}

 	

 	@Override

 	public void setContext(IEolContext context) {

 		if (context instanceof IEtlContext) {

-			this.context = (IEtlContext) context;

+			super.setContext(context);

 		}

 	}

 	

diff --git a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/dom/TransformationRule.java b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/dom/TransformationRule.java
index 804b0ca..999f65d 100644
--- a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/dom/TransformationRule.java
+++ b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/dom/TransformationRule.java
@@ -35,11 +35,10 @@
 import org.eclipse.epsilon.etl.trace.TransformationList;

 import org.eclipse.epsilon.etl.trace.TransformationTrace;

 

-

 public class TransformationRule extends ExtensibleNamedRule {

 	

 	protected Parameter sourceParameter;

-	protected List<Parameter> targetParameters = new ArrayList<Parameter>();

+	protected List<Parameter> targetParameters = new ArrayList<>();

 	protected ExecutableBlock<Boolean> guard = null;

 	protected ExecutableBlock<Void> body = null;

 	protected IEtlContext context;

@@ -109,7 +108,7 @@
 		return transformedElements.contains(source);

 	}

 			

-	protected Collection<Object> rejected = new ArrayList<Object>();

+	protected Collection<Object> rejected = new ArrayList<>();

 	

 	public boolean appliesTo(Object source, IEtlContext context, boolean asSuperRule) throws EolRuntimeException {

 		return appliesTo(source, context, asSuperRule, true);

@@ -175,7 +174,7 @@
 		return targets;

 	}

 	

-	protected Set<Object> transformedElements = new HashSet<Object>();

+	protected Set<Object> transformedElements = new HashSet<>();

 	

 	public Collection<?> transform(Object source, IEtlContext context) throws EolRuntimeException{

 		

@@ -211,7 +210,7 @@
 			superRule.transform(source, targets, context);

 		}

 		

-		List<Variable> variables = new ArrayList<Variable>();

+		List<Variable> variables = new ArrayList<>();

 		variables.add(Variable.createReadOnlyVariable("self", this));

 		variables.add(Variable.createReadOnlyVariable(sourceParameter.getName(), source));

 		for (Parameter targetParameter : targetParameters) {

@@ -225,7 +224,7 @@
 	}

 	

 	@Override

-	public String toString(){

+	public String toString() {

 		

 		String targetTypes = "";

 		Iterator<Parameter> it = targetParameters.iterator();

diff --git a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/context/EtlContext.java b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/context/EtlContext.java
index fbb4486..17ee98d 100644
--- a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/context/EtlContext.java
+++ b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/context/EtlContext.java
@@ -9,6 +9,7 @@
  ******************************************************************************/

 package org.eclipse.epsilon.etl.execute.context;

 

+import org.eclipse.epsilon.common.module.IModule;

 import org.eclipse.epsilon.erl.execute.context.ErlContext;

 import org.eclipse.epsilon.etl.IEtlModule;

 import org.eclipse.epsilon.etl.execute.operations.EtlOperationFactory;

@@ -41,11 +42,18 @@
 	

 	@Override

 	public IEtlModule getModule() {

-		return (IEtlModule) module;

+		return (IEtlModule) super.getModule();

+	}

+	

+	@Override

+	public void setModule(IModule module) {

+		if (module instanceof IEtlModule) {

+			super.setModule(module);

+		}

 	}

 	

 	@Override

 	public void setModule(IEtlModule module) {

-		this.module = module;

-	}	

+		super.setModule(module);

+	}

 }

diff --git a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/operations/EquivalentOperation.java b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/operations/EquivalentOperation.java
index 9357700..fbc744c 100644
--- a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/operations/EquivalentOperation.java
+++ b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/operations/EquivalentOperation.java
@@ -32,7 +32,7 @@
 		

 		List<String> rules = null;

 		if (parameters.size() > 0) {

-			rules = new ArrayList<String>();

+			rules = new ArrayList<>();

 			for (Object parameter : parameters) {

 				rules.add(StringUtil.toString(parameter));

 			}

diff --git a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/operations/EquivalentsOperation.java b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/operations/EquivalentsOperation.java
index f3f35e7..28b71ba 100644
--- a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/operations/EquivalentsOperation.java
+++ b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/execute/operations/EquivalentsOperation.java
@@ -32,7 +32,7 @@
 		

 		List<String> rules = null;

 		if (parameters.size() > 0) {

-			rules = new ArrayList<String>();

+			rules = new ArrayList<>();

 			for (Object parameter : parameters) {

 				rules.add(StringUtil.toString(parameter));

 			}

diff --git a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/strategy/DefaultTransformationStrategy.java b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/strategy/DefaultTransformationStrategy.java
index a48270e..a2604ee 100644
--- a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/strategy/DefaultTransformationStrategy.java
+++ b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/strategy/DefaultTransformationStrategy.java
@@ -21,7 +21,7 @@
 import org.eclipse.epsilon.etl.dom.TransformationRule;

 import org.eclipse.epsilon.etl.execute.context.IEtlContext;

 

-public class DefaultTransformationStrategy implements ITransformationStrategy{

+public class DefaultTransformationStrategy implements ITransformationStrategy {

 	

 	protected IEquivalentProvider equivalentProvider;

 	//protected IModel sourceModel;

@@ -55,10 +55,12 @@
 		return Collections.emptyList();

 	}

 	

+	@Override

 	public boolean canTransform(Object source) {

 		return !getExcluded().contains(source);

 	}

 	

+	@Override

 	public Collection<?> transform(Object source, IEtlContext context, List<String> rules) throws EolRuntimeException{

 		

 		List<Object> targets = CollectionUtil.createDefaultList();

@@ -67,7 +69,7 @@
 		if (!canTransform(source)) return targets;

 		

 		for (TransformationRule rule : getRulesFor(source, context)) {

-			TransformationRule transformRule = (TransformationRule) rule;

+			TransformationRule transformRule = rule;

 			if (rules == null || rules.contains(rule.getName())) {

 				

 				Collection<?> transformed = transformRule.transform(source, context);

@@ -89,12 +91,12 @@
 		

 	}

 	

-	public List<TransformationRule> getRulesFor(Object source, IEtlContext context) throws EolRuntimeException{

-		List<TransformationRule> rules = new ArrayList<TransformationRule>();

+	public List<TransformationRule> getRulesFor(Object source, IEtlContext context) throws EolRuntimeException {

+		List<TransformationRule> rules = new ArrayList<>();

 		

 		for (TransformationRule rule : context.getModule().getTransformationRules()) {

-			if (!rule.isAbstract()){

-				if (rule.appliesTo(source, context, false)){

+			if (!rule.isAbstract()) {

+				if (rule.appliesTo(source, context, false)) {

 					rules.add(rule);

 				}

 			}

@@ -103,7 +105,8 @@
 		return rules;

 	}

 	

-	public Collection<?> getEquivalents(Object source, IEolContext context_, List<String> rules) throws EolRuntimeException{

+	@Override

+	public Collection<?> getEquivalents(Object source, IEolContext context_, List<String> rules) throws EolRuntimeException {

 

 		IEtlContext context = (IEtlContext) context_;

 		// First transform the source

@@ -113,6 +116,7 @@
 		//return context.getTransformationTrace().getTransformations(source).getTargets();

 	}

 	

+	@Override

 	public Object getEquivalent(Object source, IEolContext context_, List<String> rules) throws EolRuntimeException {

 		IEtlContext context = (IEtlContext) context_;

 		

@@ -127,11 +131,13 @@
 	

 	}

 	

+	@Override

 	public Collection<?> getEquivalent(Collection<?> collection, IEolContext context_, List<String> rules) throws EolRuntimeException{

 		IEtlContext context = (IEtlContext) context_;

 		return CollectionUtil.flatten(getEquivalents(collection, context, rules));

 	}

 	

+	@Override

 	public Collection<?> getEquivalents(Collection<?> collection, IEolContext context_, List<String> rules) throws EolRuntimeException{

 		IEtlContext context = (IEtlContext) context_;

 		Collection<Object> equivalents = CollectionUtil.createDefaultList();

@@ -144,6 +150,7 @@
 		return equivalents;

 	}

 	

+	@Override

 	public void transformModels(IEtlContext context) throws EolRuntimeException {

 		for (TransformationRule transformRule : context.getModule().getTransformationRules()) {			

 			if (!transformRule.isLazy(context) && !transformRule.isAbstract()) {

@@ -152,13 +159,14 @@
 		}

 	}

 

+	@Override

 	public void setEquivalentProvider(IEquivalentProvider equivalentProvider) {

 		this.equivalentProvider = equivalentProvider;

 	}

 

+	@Override

 	public IEquivalentProvider getEquivalentProvider() {

 		return equivalentProvider;

 	}

 	

-

 }

diff --git a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/strategy/FastTransformationStrategy.java b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/strategy/FastTransformationStrategy.java
index 46d9eb4..0291918 100644
--- a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/strategy/FastTransformationStrategy.java
+++ b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/strategy/FastTransformationStrategy.java
@@ -30,8 +30,8 @@
 public class FastTransformationStrategy implements ITransformationStrategy{

 	

 	protected IEquivalentProvider equivalentProvider;

-	protected HashMap<Object, Collection<Object>> flatTrace = new HashMap<Object, Collection<Object>>();

-	protected HashMap<Object, TransformationList> pendingTransformations = new HashMap<Object, TransformationList>();

+	protected HashMap<Object, Collection<Object>> flatTrace = new HashMap<>();

+	protected HashMap<Object, TransformationList> pendingTransformations = new HashMap<>();

 	

 	public FastTransformationStrategy(){

 		equivalentProvider = this;

@@ -41,10 +41,12 @@
 		return Collections.emptyList();

 	}

 	

+	@Override

 	public boolean canTransform(Object source) {

 		return !getExcluded().contains(source);

 	}

 	

+	@Override

 	public Collection<?> transform(Object source, IEtlContext context, List<String> rules) throws EolRuntimeException{

 		

 		throw new UnsupportedOperationException(

@@ -53,6 +55,7 @@
 		

 	}

 	

+	@Override

 	public Collection<?> getEquivalents(Object source, IEolContext context_, List<String> rules) throws EolRuntimeException{

 		IEtlContext context = (IEtlContext) context_;

 		

@@ -63,7 +66,7 @@
 		

 		if (rules == null || rules.isEmpty()) return flatTrace.get(source);

 		

-		Collection<Object> equivalents = new ArrayList<Object>();

+		Collection<Object> equivalents = new ArrayList<>();

 		for (Transformation transformation : context.getTransformationTrace().getTransformations(source)) {

 			if (rules.contains(transformation.getRule().getName())) {

 				equivalents.addAll(transformation.getTargets());

@@ -72,6 +75,7 @@
 		return equivalents;

 	}

 	

+	@Override

 	public Object getEquivalent(Object source, IEolContext context_, List<String> rules) throws EolRuntimeException {

 		IEtlContext context = (IEtlContext) context_;

 		

@@ -86,11 +90,13 @@
 		

 	}

 	

+	@Override

 	public Collection<?> getEquivalent(Collection<?> collection, IEolContext context_, List<String> rules) throws EolRuntimeException{

 		IEtlContext context = (IEtlContext) context_;

 		return CollectionUtil.flatten(getEquivalents(collection, context, rules));

 	}

 	

+	@Override

 	public Collection<?> getEquivalents(Collection<?> collection, IEolContext context_, List<String> rules) throws EolRuntimeException{

 		IEtlContext context = (IEtlContext) context_;

 		Collection<Object> equivalents = CollectionUtil.createDefaultList();

@@ -105,6 +111,7 @@
 	}

 	

 	

+	@Override

 	public void transformModels(IEtlContext context) throws EolRuntimeException {

 		

 		for (TransformationRule transformRule : context.getModule().getTransformationRules()) {			

@@ -166,13 +173,13 @@
 		} 		

 	}

 	

+	@Override

 	public void setEquivalentProvider(IEquivalentProvider equivalentProvider) {

 		this.equivalentProvider = equivalentProvider;

 	}

 

+	@Override

 	public IEquivalentProvider getEquivalentProvider() {

 		return equivalentProvider;

 	}

-	

-

 }

diff --git a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/trace/TransformationTrace.java b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/trace/TransformationTrace.java
index 5772d73..4df040d 100644
--- a/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/trace/TransformationTrace.java
+++ b/plugins/org.eclipse.epsilon.etl.engine/src/org/eclipse/epsilon/etl/trace/TransformationTrace.java
@@ -17,7 +17,7 @@
 public class TransformationTrace {

 	

 	//List storage = new ArrayList();

-	HashMap<Object, TransformationList> cache = new HashMap<Object, TransformationList>();

+	HashMap<Object, TransformationList> cache = new HashMap<>();

 	TransformationList transformations = new TransformationList();

 	

 	public void add(Object source, Collection<Object> targets, TransformationRule rule){

diff --git a/plugins/org.eclipse.epsilon.eunit.engine/META-INF/MANIFEST.MF b/plugins/org.eclipse.epsilon.eunit.engine/META-INF/MANIFEST.MF
index 086f60d..5d5d486 100644
--- a/plugins/org.eclipse.epsilon.eunit.engine/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.epsilon.eunit.engine/META-INF/MANIFEST.MF
@@ -13,3 +13,4 @@
  org.eclipse.epsilon.internal.eunit.xml
 Require-Bundle: org.eclipse.epsilon.eol.engine,
  org.eclipse.epsilon.common.dt;resolution:=optional
+Automatic-Module-Name: org.eclipse.epsilon.eunit.engine
diff --git a/plugins/org.eclipse.epsilon.eunit.engine/src/org/eclipse/epsilon/eunit/EUnitModule.java b/plugins/org.eclipse.epsilon.eunit.engine/src/org/eclipse/epsilon/eunit/EUnitModule.java
index 921e7da..9fafe04 100644
--- a/plugins/org.eclipse.epsilon.eunit.engine/src/org/eclipse/epsilon/eunit/EUnitModule.java
+++ b/plugins/org.eclipse.epsilon.eunit.engine/src/org/eclipse/epsilon/eunit/EUnitModule.java
@@ -100,7 +100,7 @@
 				if (!"data".equals(annName) && !"Data".equals(annName)) continue;
 
 				try {
-					results.add(new Pair<>(op, (String)ann.getValue(context)));
+					results.add(new Pair<>(op, (String)ann.getValue(getContext())));
 				} catch (EolRuntimeException e) {
 					// skip annotation and go on
 				}
@@ -112,7 +112,7 @@
 	public boolean isAnnotatedAs(Operation operation, String annotation) {
 		try {
 			return operation.hasAnnotation(annotation);
-			//return EolAnnotationsUtil.getBooleanAnnotationValue(operation, annotation, context, false, true);
+			//return EolAnnotationsUtil.getBooleanAnnotationValue(operation, annotation, getContext(), false, true);
 		}
 		catch (Exception ex) {
 			return false;
@@ -256,7 +256,7 @@
 
 		try {
 			final EolSequence<?> values
-				= (EolSequence<?>) entry.getLeft().execute(null, Collections.emptyList(), context, true);
+				= (EolSequence<?>) entry.getLeft().execute(null, Collections.emptyList(), getContext(), true);
 			final String variableName = entry.getRight();
 			for (Object value : values) {
 				EUnitTest child = new EUnitTest();
@@ -330,7 +330,7 @@
 
 			// Run the suite setup operations before all tests
 			for (Operation op : getSuiteSetups()) {
-				op.execute(null, Collections.emptyList(), context, false);
+				op.execute(null, Collections.emptyList(), getContext(), false);
 			}
 		}
 
@@ -351,7 +351,7 @@
 			if (node.isRootTest()) {
 				// Run the suite teardown operations after all tests
 				for (Operation op : getSuiteTeardowns()) {
-					op.execute(null, Collections.emptyList(), context, false);
+					op.execute(null, Collections.emptyList(), getContext(), false);
 				}
 			}
 		}
@@ -395,7 +395,7 @@
 		try {
 			// Load models from the inline model operations, if any
 			for (Operation inlineModelOp : getInlineModelOperations()) {
-				inlineModelOp.execute(null, Collections.emptyList(), context, false);
+				inlineModelOp.execute(null, Collections.emptyList(), getContext(), false);
 			}
 
 			// Apply the model bindings
@@ -405,12 +405,12 @@
 
 			// Call the @setup operations
 			for (Operation opSetup : this.getSetups()) {
-				opSetup.execute(null, Collections.emptyList(), context, false);
+				opSetup.execute(null, Collections.emptyList(), getContext(), false);
 			}
 
 			// Run the @test itself
 			if (opTest != null) {
-				opTest.execute(null, Collections.emptyList(), context, false);
+				opTest.execute(null, Collections.emptyList(), getContext(), false);
 				node.setResult(EUnitTestResultType.SUCCESS);
 			}
 			else {
@@ -421,7 +421,7 @@
 		finally {
 			// Call the @teardown operations
 			for (Operation opTeardown : this.getTeardowns()) {
-				opTeardown.execute(null, Collections.emptyList(), context, false);
+				opTeardown.execute(null, Collections.emptyList(), getContext(), false);
 			}
 		}
 	}
diff --git a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/EvlModule.java b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/EvlModule.java
index 4dceda1..23c4268 100644
--- a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/EvlModule.java
+++ b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/EvlModule.java
@@ -40,11 +40,11 @@
 	protected IEvlFixer fixer;

 	protected List<ConstraintContext> constraintContexts;

 	protected final ArrayList<ConstraintContext> declaredConstraintContexts = new ArrayList<>(0);

-	protected final Constraints constraints = new Constraints();

+	protected final ArrayList<Constraint> constraints = new ArrayList<>();

 	private boolean optimizeConstraints = false;

 	

 	public EvlModule() {

-		this.context = new EvlContext();

+		setContext(new EvlContext());

 	}

 

 	public static final String OPTIMIZE_CONSTRAINTS = "optimizeConstraints";

@@ -105,7 +105,7 @@
 		globalConstraintContext.setModule(this);

 		globalConstraintContext.setParent(this);

 		

-		Constraints globalConstraints = globalConstraintContext.getConstraints();

+		ArrayList<Constraint> globalConstraints = globalConstraintContext.getConstraints();

 		

 		List<AST>

 			constraintASTs = AstUtil.getChildren(cst, EvlParser.CONSTRAINT),

@@ -280,7 +280,7 @@
 	 * @since 1.6

 	 */

 	@Override

-	public Set<UnsatisfiedConstraint> executeImpl() throws EolRuntimeException {

+	public Collection<UnsatisfiedConstraint> executeImpl() throws EolRuntimeException {

 		prepareExecution();

 		checkConstraints();

 		postExecution();

@@ -292,17 +292,17 @@
 	 */

 	@SuppressWarnings("unchecked")

 	@Override

-	public final Set<UnsatisfiedConstraint> execute() throws EolRuntimeException {

-		return (Set<UnsatisfiedConstraint>) super.execute();

+	public final Collection<UnsatisfiedConstraint> execute() throws EolRuntimeException {

+		return (Collection<UnsatisfiedConstraint>) super.execute();

 	}

 	

 	@Override

 	public IEvlContext getContext() {

-		return (IEvlContext) context;

+		return (IEvlContext) super.getContext();

 	}

 	

 	@Override

-	public Constraints getConstraints() { 

+	public List<Constraint> getConstraints() { 

 		return constraints;

 	}

 	

diff --git a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/IEvlModule.java b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/IEvlModule.java
index 66d8cc7..842ff1f 100644
--- a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/IEvlModule.java
+++ b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/IEvlModule.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2008-2018 The University of York.

+ * Copyright (c) 2008-2019 The University of York.

  * This program and the accompanying materials

  * are made available under the terms of the Eclipse Public License 2.0

  * which is available at https://www.eclipse.org/legal/epl-2.0/

@@ -10,24 +10,45 @@
  ******************************************************************************/

 package org.eclipse.epsilon.evl;

 

+import java.util.Collection;

 import java.util.List;

-import java.util.Set;

+import java.util.Optional;

+import org.eclipse.epsilon.common.module.ModuleElement;

 import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;

 import org.eclipse.epsilon.erl.IErlModule;

+import org.eclipse.epsilon.evl.dom.Constraint;

 import org.eclipse.epsilon.evl.dom.ConstraintContext;

-import org.eclipse.epsilon.evl.dom.Constraints;

+import org.eclipse.epsilon.evl.dom.GlobalConstraintContext;

 import org.eclipse.epsilon.evl.execute.UnsatisfiedConstraint;

 import org.eclipse.epsilon.evl.execute.context.IEvlContext;

+import org.eclipse.epsilon.evl.execute.exceptions.EvlConstraintNotFoundException;

 

 public interface IEvlModule extends IErlModule {

 	

-	Constraints getConstraints();

+	List<Constraint> getConstraints();

 	

 	List<ConstraintContext> getDeclaredConstraintContexts();

 	

 	List<ConstraintContext> getConstraintContexts();

 	

 	/**

+	 * @since 1.6 returns Collection instead of List

+	 */

+	@Override

+	Collection<UnsatisfiedConstraint> execute() throws EolRuntimeException;

+	

+	void setUnsatisfiedConstraintFixer(IEvlFixer fixer);

+	

+	IEvlFixer getUnsatisfiedConstraintFixer();

+	

+	@Override

+	default IEvlContext getContext() {

+		return (IEvlContext) ((IErlModule)this).getContext();

+	}

+	

+	// UTILS

+	

+	/**

 	 * 

 	 * @param name

 	 * @return

@@ -41,19 +62,49 @@
 			.orElse(null);

 	}

 	

-	@Override

-	default IEvlContext getContext() {

-		return (IEvlContext) ((IErlModule)this).getContext();

+	/**

+	 * 

+	 * @param name

+	 * @param target

+	 * @param context

+	 * @param ast

+	 * @return

+	 * @throws EolRuntimeException

+	 * @since 1.6

+	 */

+	default Constraint getConstraint(String name, Object target, IEvlContext context, ModuleElement ast) throws EolRuntimeException {

+		Optional<Constraint> constraint = getConstraint(name, null, target, context, false);

+		if (!constraint.isPresent()) {

+			constraint = getConstraints().stream().filter(c -> c.getName().equals(name)).findFirst();

+		}

+		return constraint.orElseThrow(() -> new EvlConstraintNotFoundException(name, ast));

 	}

 	

 	/**

+	 * 

+	 * @param name

+	 * @param constraintContext

+	 * @param target

+	 * @param context

+	 * @param appliesTo

+	 * @return

+	 * @throws EolRuntimeException#

 	 * @since 1.6

 	 */

-	@Override

-	Set<UnsatisfiedConstraint> execute() throws EolRuntimeException;

-	

-	void setUnsatisfiedConstraintFixer(IEvlFixer fixer);

-	

-	IEvlFixer getUnsatisfiedConstraintFixer();

-	

+	default Optional<Constraint> getConstraint(String name, ConstraintContext constraintContext, Object target, IEvlContext context, boolean appliesTo) throws EolRuntimeException {

+		for (Constraint constraint : getConstraints()) {

+			ConstraintContext cc = constraintContext == null ? constraint.getConstraintContext() : constraintContext;

+			if (

+				constraint.getName().equals(name) && 

+				(

+					(cc instanceof GlobalConstraintContext) ||

+					cc.getAllOfSourceKind(context).contains(target)

+				) &&

+				(!appliesTo || constraint.appliesTo(target, context))

+			) {

+				return Optional.of(constraint);

+			}

+		}

+		return Optional.empty();

+	}

 }

diff --git a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/concurrent/EvlModuleParallel.java b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/concurrent/EvlModuleParallel.java
index 754e68c..7644ce9 100644
--- a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/concurrent/EvlModuleParallel.java
+++ b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/concurrent/EvlModuleParallel.java
@@ -32,15 +32,15 @@
 	protected abstract void checkConstraints() throws EolRuntimeException;
 	
 	public EvlModuleParallel() {
-		context = new EvlContextParallel();
+		setContext(new EvlContextParallel());
 	}
 	
 	public EvlModuleParallel(int parallelism) {
-		context = new EvlContextParallel(parallelism, true);
+		setContext(new EvlContextParallel(parallelism, true));
 	}
 	
 	protected EvlModuleParallel(int parallelism, boolean threadSafeBaseFrames) {
-		context = new EvlContextParallel(parallelism, threadSafeBaseFrames);
+		setContext(new EvlContextParallel(parallelism, threadSafeBaseFrames));
 	}
 	
 	@Override
@@ -57,7 +57,7 @@
 	
 	@Override
 	public IEvlContextParallel getContext() {
-		return (IEvlContextParallel) context;
+		return (IEvlContextParallel) super.getContext();
 	}
 	
 	@Override
@@ -74,10 +74,11 @@
 	@Override
 	public void configure(Map<String, ?> properties) throws IllegalArgumentException {
 		super.configure(properties);
-		context = IEolContextParallel.configureContext(
+		IEvlContextParallel context = getContext();
+		setContext(IEolContextParallel.configureContext(
 			properties,
 			threads -> new EvlContextParallel(threads, context.getFrameStack().isThreadSafe()),
-			getContext()
-		);
+			context
+		));
 	}
 }
diff --git a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/dom/Constraint.java b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/dom/Constraint.java
index a54bba5..ef2e2fa 100644
--- a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/dom/Constraint.java
+++ b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/dom/Constraint.java
@@ -189,8 +189,14 @@
 		return result;

 	}

 

+	/**

+	 * Checks whether this constraint's guard block has dependencies on other constraint(s).

+	 * 

+	 * @return <code>true</code> if the guard block exists and has a satisfies call.

+	 * @since 1.6

+	 */

 	public boolean guardBlockUsesSatisfies() {

-		return guardBlock.getText().contains("satisfies");

+		return guardBlock != null && guardBlock.getText().contains("satisfies");

 	}

 

 	public ConstraintContext getConstraintContext() {

diff --git a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/dom/ConstraintContext.java b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/dom/ConstraintContext.java
index cb220b0..9189f00 100644
--- a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/dom/ConstraintContext.java
+++ b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/dom/ConstraintContext.java
@@ -30,7 +30,7 @@
 
 public class ConstraintContext extends AnnotatableModuleElement implements IExecutableModuleElement {
 	
-	protected final Constraints constraints = new Constraints();
+	protected final ArrayList<Constraint> constraints = new ArrayList<>();
 	protected TypeExpression typeExpression;
 	protected ExecutableBlock<Boolean> guardBlock;
 	protected EolModelElementType type;
@@ -100,7 +100,7 @@
 		return typeExpression != null ? typeExpression.getName() : null;
 	}
 	
-	public Constraints getConstraints() {
+	public ArrayList<Constraint> getConstraints() {
 		return constraints;
 	}
 	
@@ -178,7 +178,7 @@
 	
 	/**
 	 * Checks all of this ConstraintContext's constraints for all applicable elements of this type.
-	 * @param context The execution context.
+	 * @param context_ The EVL execution context.
 	 * @throws EolRuntimeException
 	 * @return nothing.
 	 * @see {@link #execute(Collection, Object, IEvlContext)}
diff --git a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/dom/Constraints.java b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/dom/Constraints.java
deleted file mode 100644
index 4b87fad..0000000
--- a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/dom/Constraints.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*******************************************************************************

- * Copyright (c) 2008 The University of York.

- * This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License 2.0

- * which is available at https://www.eclipse.org/legal/epl-2.0/

- * 

- * Contributors:

- *     Dimitrios Kolovos - initial API and implementation

- ******************************************************************************/

-package org.eclipse.epsilon.evl.dom;

-

-import java.util.ArrayList;

-import java.util.Optional;

-import org.eclipse.epsilon.common.module.ModuleElement;

-import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;

-import org.eclipse.epsilon.evl.execute.context.IEvlContext;

-import org.eclipse.epsilon.evl.execute.exceptions.EvlConstraintNotFoundException;

-

-@SuppressWarnings("serial")

-public class Constraints extends ArrayList<Constraint> {

-	

-	/**

-	 * 

-	 * @param name

-	 * @param target

-	 * @param context

-	 * @param ast

-	 * @return

-	 * @throws EolRuntimeException

-	 * @since 1.6

-	 */

-	public Constraint getConstraint(String name, Object target, IEvlContext context, ModuleElement ast) throws EolRuntimeException {

-		Optional<Constraint> constraint = getConstraint(name, null, target, context, false);

-		if (!constraint.isPresent()) {

-			constraint = this.stream().filter(c -> c.getName().equals(name)).findFirst();

-		}

-		return constraint.orElseThrow(() -> new EvlConstraintNotFoundException(name, ast));

-	}

-	

-	public Optional<Constraint> getConstraint(String name, ConstraintContext constraintContext, Object target, IEvlContext context, boolean appliesTo) throws EolRuntimeException {

-		for (Constraint constraint : this) {

-			ConstraintContext cc = constraintContext == null ? constraint.getConstraintContext() : constraintContext;

-			if (

-				constraint.getName().equals(name) && 

-				(

-					(cc instanceof GlobalConstraintContext) ||

-					cc.getAllOfSourceKind(context).contains(target)

-				) &&

-				(!appliesTo || constraint.appliesTo(target, context))

-			) {

-				return Optional.of(constraint);

-			}

-		}

-		return Optional.empty();

-	}

-	

-}

diff --git a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/EvlOperationFactory.java b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/EvlOperationFactory.java
index 83e3557..76e97f9 100644
--- a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/EvlOperationFactory.java
+++ b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/EvlOperationFactory.java
@@ -15,7 +15,6 @@
 public class EvlOperationFactory extends EolOperationFactory {

 	

 	public EvlOperationFactory() {

-		super();

 		SatisfiesOperation satisfiesAll = new SatisfiesOperation(true);

 		operationCache.put("satisfies", satisfiesAll);

 		operationCache.put("satisfiesAll", satisfiesAll);

diff --git a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/context/EvlContext.java b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/context/EvlContext.java
index 77e155a..d793b2a 100644
--- a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/context/EvlContext.java
+++ b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/context/EvlContext.java
@@ -11,6 +11,7 @@
 

 import java.util.HashSet;

 import java.util.Set;

+import org.eclipse.epsilon.common.module.IModule;

 import org.eclipse.epsilon.erl.execute.context.ErlContext;

 import org.eclipse.epsilon.evl.IEvlModule;

 import org.eclipse.epsilon.evl.execute.UnsatisfiedConstraint;

@@ -33,8 +34,15 @@
 	}

 	

 	@Override

+	public void setModule(IModule module) {

+		if (module instanceof IEvlModule) {

+			super.setModule(module);

+		}

+	}

+	

+	@Override

 	public IEvlModule getModule() {

-		return (IEvlModule) module;

+		return (IEvlModule) super.getModule();

 	}

 

 	@Override

diff --git a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/context/concurrent/EvlContextParallel.java b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/context/concurrent/EvlContextParallel.java
index df60ae4..108c5f9 100644
--- a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/context/concurrent/EvlContextParallel.java
+++ b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/context/concurrent/EvlContextParallel.java
@@ -12,6 +12,7 @@
 import java.util.HashSet;
 import java.util.Set;
 import org.eclipse.epsilon.eol.execute.context.FrameStack;
+import org.eclipse.epsilon.common.module.IModule;
 import org.eclipse.epsilon.eol.exceptions.concurrent.EolNestedParallelismException;
 import org.eclipse.epsilon.eol.execute.concurrent.PersistentThreadLocal;
 import org.eclipse.epsilon.eol.execute.context.concurrent.IEolContextParallel;
@@ -82,8 +83,15 @@
 	}
 
 	@Override
+	public void setModule(IModule module) {
+		if (module instanceof EvlModuleParallel) {
+			super.setModule(module);
+		}
+	}
+	
+	@Override
 	public EvlModuleParallel getModule() {
-		return (EvlModuleParallel) module;
+		return (EvlModuleParallel) super.getModule();
 	}
 	
 	@Override
diff --git a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/operations/SatisfiesOperation.java b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/operations/SatisfiesOperation.java
index ad85e8a..5422cd5 100644
--- a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/operations/SatisfiesOperation.java
+++ b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/execute/operations/SatisfiesOperation.java
@@ -16,8 +16,8 @@
 import org.eclipse.epsilon.eol.execute.context.IEolContext;

 import org.eclipse.epsilon.eol.execute.operations.simple.SimpleOperation;

 import org.eclipse.epsilon.eol.types.EolNoType;

+import org.eclipse.epsilon.evl.IEvlModule;

 import org.eclipse.epsilon.evl.dom.Constraint;

-import org.eclipse.epsilon.evl.dom.Constraints;

 import org.eclipse.epsilon.evl.dom.GlobalConstraintContext;

 import org.eclipse.epsilon.evl.execute.context.IEvlContext;

 import org.eclipse.epsilon.evl.trace.ConstraintTrace;

@@ -49,15 +49,14 @@
 			return false;

 		

 		IEvlContext context = (IEvlContext) context_;

+		IEvlModule module = context.getModule();

 		ConstraintTrace constraintTrace = context.getConstraintTrace();

 		assert constraintTrace != null;

 		

-		Constraints constraints = context.getModule().getConstraints();

-		

 		for (Object parameter : parameters) {

 			String constraintName = context.getPrettyPrinterManager().toString(parameter);

 

-			Constraint constraint = constraints.getConstraint(constraintName, source, context, ast);

+			Constraint constraint = module.getConstraint(constraintName, source, context, ast);

 			

 			// This is to avoid duplication of global constraints

 			if (constraint.getConstraintContext() instanceof GlobalConstraintContext) {

@@ -71,12 +70,7 @@
 			}

 			else {

 				// Don't call execute() or shouldBeChecked because it might be a lazy constraint, so need to force appliesTo && check.

-				if (constraint.appliesTo(source, context)) {

-					valid = !constraint.check(source, context).isPresent();

-				}

-				else {

-					valid = false;

-				}

+				valid = constraint.appliesTo(source, context) && !constraint.check(source, context).isPresent();

 				

 				if (context.isOptimizeConstraintTrace()) {

 					constraintTrace.addChecked(constraint, source, valid);

diff --git a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/launch/EvlRunConfiguration.java b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/launch/EvlRunConfiguration.java
index f7e4ad7..7b76516 100644
--- a/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/launch/EvlRunConfiguration.java
+++ b/plugins/org.eclipse.epsilon.evl.engine/src/org/eclipse/epsilon/evl/launch/EvlRunConfiguration.java
@@ -9,7 +9,7 @@
 **********************************************************************/
 package org.eclipse.epsilon.evl.launch;
 
-import java.util.Set;
+import java.util.Collection;
 import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;
 import org.eclipse.epsilon.erl.launch.IErlRunConfiguration;
 import org.eclipse.epsilon.evl.EvlModule;
@@ -55,14 +55,14 @@
 	
 	@SuppressWarnings("unchecked")
 	@Override
-	public Set<UnsatisfiedConstraint> getResult() {
-		return (Set<UnsatisfiedConstraint>) super.getResult();
+	public Collection<UnsatisfiedConstraint> getResult() {
+		return (Collection<UnsatisfiedConstraint>) super.getResult();
 	}
 	
 	@SuppressWarnings("unchecked")
 	@Override
-	public Set<UnsatisfiedConstraint> execute() throws EolRuntimeException {
-		return (Set<UnsatisfiedConstraint>) super.execute();
+	public Collection<UnsatisfiedConstraint> execute() throws EolRuntimeException {
+		return (Collection<UnsatisfiedConstraint>) super.execute();
 	}
 	
 	@Override
diff --git a/plugins/org.eclipse.epsilon.ewl.engine/META-INF/MANIFEST.MF b/plugins/org.eclipse.epsilon.ewl.engine/META-INF/MANIFEST.MF
index 956c474..3db5486 100644
--- a/plugins/org.eclipse.epsilon.ewl.engine/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.epsilon.ewl.engine/META-INF/MANIFEST.MF
@@ -12,3 +12,4 @@
  org.eclipse.epsilon.ewl.execute.context,

  org.eclipse.epsilon.ewl.parse

 Bundle-RequiredExecutionEnvironment: JavaSE-1.8

+Automatic-Module-Name: org.eclipse.epsilon.ewl.engine

diff --git a/plugins/org.eclipse.epsilon.ewl.engine/src/org/eclipse/epsilon/ewl/EwlModule.java b/plugins/org.eclipse.epsilon.ewl.engine/src/org/eclipse/epsilon/ewl/EwlModule.java
index 30ac71a..3f68588 100644
--- a/plugins/org.eclipse.epsilon.ewl.engine/src/org/eclipse/epsilon/ewl/EwlModule.java
+++ b/plugins/org.eclipse.epsilon.ewl.engine/src/org/eclipse/epsilon/ewl/EwlModule.java
@@ -38,7 +38,7 @@
 	protected List<Wizard> wizards = new ArrayList<>();

 	

 	public EwlModule() {

-		this.context = new EwlContext();

+		setContext(new EwlContext());

 	}

 	

 	@Override

@@ -102,7 +102,7 @@
 

 	@Override

 	public IEwlContext getContext() {

-		return (IEwlContext) context;

+		return (IEwlContext) super.getContext();

 	}

 	

 	public List<Wizard> getWizards() {

@@ -110,6 +110,7 @@
 	}

 	

 	private boolean allApply(Wizard wizard, Collection<Object> self) throws EolRuntimeException {

+		IEwlContext context = getContext();

 		for (Object o : self) {

 			if (!wizard.appliesTo(o, context)) {

 				return false;

@@ -121,7 +122,7 @@
 	@Override

 	public void setContext(IEolContext context) {

 		if (context instanceof IEwlContext) {

-			this.context = context;

+			super.setContext(context);

 		}

 	}

 

diff --git a/plugins/org.eclipse.epsilon.ewl.engine/src/org/eclipse/epsilon/ewl/execute/context/EwlContext.java b/plugins/org.eclipse.epsilon.ewl.engine/src/org/eclipse/epsilon/ewl/execute/context/EwlContext.java
index 6d8628b..4af6d26 100644
--- a/plugins/org.eclipse.epsilon.ewl.engine/src/org/eclipse/epsilon/ewl/execute/context/EwlContext.java
+++ b/plugins/org.eclipse.epsilon.ewl.engine/src/org/eclipse/epsilon/ewl/execute/context/EwlContext.java
@@ -9,6 +9,7 @@
  ******************************************************************************/

 package org.eclipse.epsilon.ewl.execute.context;

 

+import org.eclipse.epsilon.common.module.IModule;

 import org.eclipse.epsilon.eol.execute.context.EolContext;

 import org.eclipse.epsilon.ewl.IEwlModule;

 

@@ -16,6 +17,13 @@
 	

 	@Override

 	public IEwlModule getModule() {

-		return (IEwlModule) module;

+		return (IEwlModule) super.getModule();

+	}

+	

+	@Override

+	public void setModule(IModule module) {

+		if (module instanceof IEwlModule) {

+			super.setModule(module);

+		}

 	}

 }

diff --git a/plugins/org.eclipse.epsilon.flock.engine/META-INF/MANIFEST.MF b/plugins/org.eclipse.epsilon.flock.engine/META-INF/MANIFEST.MF
index 9348969..fa8b867 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.epsilon.flock.engine/META-INF/MANIFEST.MF
@@ -20,3 +20,4 @@
  org.eclipse.epsilon.flock.model.domain.typemappings,
  org.eclipse.epsilon.flock.parse
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Automatic-Module-Name: org.eclipse.epsilon.flock.engine
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockContext.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockContext.java
index e86b5e0..7d60de9 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockContext.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockContext.java
@@ -12,6 +12,7 @@
  */
 package org.eclipse.epsilon.flock;
 
+import org.eclipse.epsilon.common.module.IModule;
 import org.eclipse.epsilon.eol.models.IModel;
 import org.eclipse.epsilon.eol.models.IReflectiveModel;
 import org.eclipse.epsilon.erl.execute.context.ErlContext;
@@ -58,7 +59,6 @@
 	private Model wrapModel(IModel model) throws FlockUnsupportedModelException {
 		if (model instanceof IReflectiveModel)
 			return new Model((IReflectiveModel)model, getPrettyPrinterManager());
-		
 		else
 			throw new FlockUnsupportedModelException("Flock can only be used with models that implement IReflectiveModel. " + model.getName() + " does not.");
 	}
@@ -107,4 +107,16 @@
 	public ConservativeCopyContext getConservativeCopyContext() {
 		return new ConservativeCopyContext(originalModel, migratedModel, execution);
 	}
+	
+	@Override
+	public void setModule(IModule module) {
+		if (module instanceof IFlockModule) {
+			super.setModule(module);
+		}
+	}
+	
+	@Override
+	public IFlockModule getModule() {
+		return (IFlockModule) super.getModule();
+	}
 }
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockModule.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockModule.java
index af6458e..8e1b38a 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockModule.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockModule.java
@@ -39,7 +39,7 @@
 	private MigrationStrategy strategy;
 	
 	public FlockModule() {
-		this.context = new FlockContext();
+		setContext(new FlockContext());
 	}
 	
 	@Override
@@ -130,7 +130,7 @@
 	
 	@Override
 	public IFlockContext getContext() {
-		return (IFlockContext) context;
+		return (IFlockContext) super.getContext();
 	}
 	
 	@Override
@@ -146,7 +146,7 @@
 	@Override
 	public void setContext(IEolContext context) {
 		if (context instanceof IFlockContext) {
-			this.context = context;
+			super.setContext(context);
 		}
 	}
 }
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockResult.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockResult.java
index de234da..5e6fbdb 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockResult.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/FlockResult.java
@@ -18,7 +18,7 @@
 
 public class FlockResult {
 
-	private final Collection<String> warnings = new LinkedList<String>();
+	private final Collection<String> warnings = new LinkedList<>();
 	
 	public void addWarning(String warning) {
 		warnings.add(warning);
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/IFlockModule.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/IFlockModule.java
index 20cefae..506ffb7 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/IFlockModule.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/IFlockModule.java
@@ -12,12 +12,12 @@
  */
 package org.eclipse.epsilon.flock;
 
-import org.eclipse.epsilon.eol.IEolModule;
 import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;
 import org.eclipse.epsilon.eol.models.IModel;
+import org.eclipse.epsilon.erl.IErlModule;
 import org.eclipse.epsilon.flock.execution.exceptions.FlockUnsupportedModelException;
 
-public interface IFlockModule extends IEolModule {
+public interface IFlockModule extends IErlModule {
 	
 	@Override
 	public IFlockContext getContext();
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/context/EquivalenceEstablishmentContext.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/context/EquivalenceEstablishmentContext.java
index 392827d..94244d8 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/context/EquivalenceEstablishmentContext.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/context/EquivalenceEstablishmentContext.java
@@ -37,7 +37,7 @@
 	}
 	
 	public Collection<TypeMappingContext> getTypeMappingContexts() {
-		final Collection<TypeMappingContext> contexts = new LinkedList<TypeMappingContext>();
+		final Collection<TypeMappingContext> contexts = new LinkedList<>();
 		
 		for (ModelElement original : originalModel.directContents()) {
 			contexts.add(new TypeMappingContext(original, context, execution, factory));
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/CollectionOfModelValues.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/CollectionOfModelValues.java
index 28b4930..51599b0 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/CollectionOfModelValues.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/CollectionOfModelValues.java
@@ -23,7 +23,7 @@
 
 class CollectionOfModelValues extends ModelValue<Collection<?>> implements Iterable<ModelValue<?>> {
 
-	private final Collection<ModelValue<?>> modelValues = new LinkedList<ModelValue<?>>();
+	private final Collection<ModelValue<?>> modelValues = new LinkedList<>();
 	
 	CollectionOfModelValues(Model model, Collection<ModelValue<?>> wrappedValues) {
 		modelValues.addAll(wrappedValues);
@@ -35,7 +35,7 @@
 	
 	@Override
 	public CollectionOfModelValues getEquivalentIn(Model model, ConservativeCopyContext context) throws ConservativeCopyException {
-		final Collection<ModelValue<?>> copiedModelValues = new LinkedList<ModelValue<?>>();
+		final Collection<ModelValue<?>> copiedModelValues = new LinkedList<>();
 		
 		for (ModelValue<?> modelValue : modelValues) {
 			final ModelValue<?> equivalent = modelValue.getEquivalentIn(model, context);
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/Model.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/Model.java
index 310b53f..55e8ce1 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/Model.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/Model.java
@@ -79,7 +79,7 @@
 	 * but contained in another model.
 	 */
 	public Iterable<ModelElement> directContents() {
-		final Collection<ModelElement> modelElements = new LinkedList<ModelElement>();
+		final Collection<ModelElement> modelElements = new LinkedList<>();
 		
 		for (Object unwrappedModelElement : underlyingModel.allContents()) {
 			if (underlyingModel.owns(unwrappedModelElement)) {
@@ -127,7 +127,7 @@
 		if (parts.size() > 1) {
 			// List#subList returns a "view" of the original list, which appears to be garbage collected
 			// when this method returns. Hence, we construct a new list to return to clients.
-			return new LinkedList<String>(parts.subList(0, parts.size() - 1));
+			return new LinkedList<>(parts.subList(0, parts.size() - 1));
 		} else {
 			return Collections.emptyList();
 		}
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/ModelType.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/ModelType.java
index 0082e49..b345e81 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/ModelType.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/ModelType.java
@@ -41,7 +41,7 @@
 	}
 		
 	Collection<String> getPropertiesSharedWith(ModelType other) throws EolModelElementTypeNotFoundException {
-		final Collection<String> sharedProperties = new LinkedList<String>(getProperties());
+		final Collection<String> sharedProperties = new LinkedList<>(getProperties());
 		
 		sharedProperties.retainAll(other.getProperties());
 		
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/ModelValueWrapper.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/ModelValueWrapper.java
index abd7c03..6056acf 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/ModelValueWrapper.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/emc/wrappers/ModelValueWrapper.java
@@ -46,7 +46,7 @@
 	}
 	
 	private Collection<ModelValue<?>> wrapValues(Collection<?> underlyingModelObjects) {
-		final Collection<ModelValue<?>> modelValues = new LinkedList<ModelValue<?>>();
+		final Collection<ModelValue<?>> modelValues = new LinkedList<>();
 		
 		for (Object underlyingModelObject : underlyingModelObjects) {
 			modelValues.add(model.wrap(underlyingModelObject));
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/equivalences/Equivalence.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/equivalences/Equivalence.java
index 88cc6a1..2965279 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/equivalences/Equivalence.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/equivalences/Equivalence.java
@@ -44,7 +44,7 @@
 	public abstract void ruleApplied(FlockExecution execution);
 	
 	public Collection<Variable> getVariables() {
-		final List<Variable> variables = new LinkedList<Variable>();
+		final List<Variable> variables = new LinkedList<>();
 		
 		variables.add(createVariable("original", getOriginal()));
 		variables.add(createVariable("migrated", getEquivalent()));
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/equivalences/Equivalences.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/equivalences/Equivalences.java
index 78a29da..ce0308e 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/equivalences/Equivalences.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/equivalences/Equivalences.java
@@ -24,7 +24,7 @@
 
 public class Equivalences {
 
-	private final List<Equivalence> equivalences = new LinkedList<Equivalence>();
+	private final List<Equivalence> equivalences = new LinkedList<>();
 	
 	/**
 	 * Factory method for establishing original to migrated model Equivalences from a MigrationStrategy and an IFlockContext.
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/execution/MigrateRuleContext.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/execution/MigrateRuleContext.java
index fa6c9d6..a9a01f7 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/execution/MigrateRuleContext.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/execution/MigrateRuleContext.java
@@ -25,7 +25,7 @@
 	private final Equivalence equivalence;
 	private final IEolContext context;
 	private final FlockExecution execution;
-	private final Map<ClassifierTypedConstruct, Boolean> applicabilityCache = new HashMap<ClassifierTypedConstruct, Boolean>();
+	private final Map<ClassifierTypedConstruct, Boolean> applicabilityCache = new HashMap<>();
 
 	public MigrateRuleContext(Equivalence equivalence, IEolContext context, FlockExecution execution) {
 		this.equivalence = equivalence;
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/MigrationStrategy.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/MigrationStrategy.java
index e38fc85..12d231d 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/MigrationStrategy.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/MigrationStrategy.java
@@ -31,7 +31,7 @@
 
 public class MigrationStrategy {
 	
-	private final List<ModuleElement> children = new LinkedList<ModuleElement>();
+	private final List<ModuleElement> children = new LinkedList<>();
 	private final TypeMappingConstructs typeMappingConstructs = new TypeMappingConstructs();
 	private final MigrateRules          migrateRules          = new MigrateRules();
 	
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/rules/IgnoredProperties.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/rules/IgnoredProperties.java
index 8e331fe..4397218 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/rules/IgnoredProperties.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/rules/IgnoredProperties.java
@@ -18,7 +18,7 @@
 
 public class IgnoredProperties {
 
-	private final Collection<String> ignoredProperties = new LinkedList<String>();
+	private final Collection<String> ignoredProperties = new LinkedList<>();
 	
 	public IgnoredProperties(String... ignoredProperties) {
 		this(Arrays.asList(ignoredProperties));
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/rules/MigrateRules.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/rules/MigrateRules.java
index 7590fda..943d2c6 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/rules/MigrateRules.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/rules/MigrateRules.java
@@ -21,7 +21,7 @@
 	private final List<MigrateRule> migrateRules;
 	
 	public MigrateRules(MigrateRule... rules) {
-		this.migrateRules = new LinkedList<MigrateRule>(Arrays.asList(rules));
+		this.migrateRules = new LinkedList<>(Arrays.asList(rules));
 	}
 
 	public void add(MigrateRule rule) {
diff --git a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/typemappings/TypeMappingConstructs.java b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/typemappings/TypeMappingConstructs.java
index 698ad35..3fa20e4 100644
--- a/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/typemappings/TypeMappingConstructs.java
+++ b/plugins/org.eclipse.epsilon.flock.engine/src/org/eclipse/epsilon/flock/model/domain/typemappings/TypeMappingConstructs.java
@@ -21,7 +21,7 @@
 import org.eclipse.epsilon.flock.execution.TypeMappingContext;
 
 public class TypeMappingConstructs {
-	private final List<TypeMappingConstruct> typeMappingConstructs = new LinkedList<TypeMappingConstruct>();
+	private final List<TypeMappingConstruct> typeMappingConstructs = new LinkedList<>();
 	private final EquivalenceFactory defaultEquivalenceFactory;
 	
 	public TypeMappingConstructs(TypeMappingConstruct... typeMappings) {
diff --git a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/HutnContext.java b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/HutnContext.java
index 770c18d..0888e8e 100644
--- a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/HutnContext.java
+++ b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/HutnContext.java
@@ -9,6 +9,7 @@
  ******************************************************************************/
 package org.eclipse.epsilon.hutn;
 
+import org.eclipse.epsilon.common.module.IModule;
 import org.eclipse.epsilon.eol.execute.context.EolContext;
 
 public class HutnContext extends EolContext implements IHutnContext {
@@ -19,6 +20,13 @@
 	
 	@Override
 	public IHutnModule getModule() {
-		return (IHutnModule) module;
+		return (IHutnModule) super.getModule();
+	}
+	
+	@Override
+	public void setModule(IModule module) {
+		if (module instanceof IHutnModule) {
+			super.setModule(module);
+		}
 	}
 }
diff --git a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/HutnModule.java b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/HutnModule.java
index 44a199c..76f1690 100644
--- a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/HutnModule.java
+++ b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/HutnModule.java
@@ -58,7 +58,7 @@
 	protected boolean hutnIsValid = false;
 	
 	public HutnModule() {
-		this.context = new HutnContext(this);
+		setContext(new HutnContext(this));
 	}
 	
 	@Override
@@ -89,7 +89,7 @@
 	
 	@Override
 	public IHutnContext getContext(){
-		return (IHutnContext) context;
+		return (IHutnContext) super.getContext();
 	}
 	
 	/*
@@ -284,12 +284,15 @@
 		
 		try {
 			final ModelGenerator modelGenerator = new ModelGenerator(spec);
-			if (generateCompleteTransformation) { modelGenerator.forceGenerationOfTransformationForWholeMetamodel(); }
+			if (generateCompleteTransformation) {
+				modelGenerator.forceGenerationOfTransformationForWholeMetamodel();
+			}
 			
-			final FileWriter writer = new FileWriter(destination);
-			writer.write(modelGenerator.generateTransformation());
-			writer.close();
-		} catch (IOException e) {
+			try (FileWriter writer = new FileWriter(destination)) {
+				writer.write(modelGenerator.generateTransformation());
+			}
+		}
+		catch (IOException e) {
 			throw new HutnGenerationException(e);
 		}
 	}
@@ -297,7 +300,7 @@
 	@Override
 	public void setContext(IEolContext context) {
 		if (context instanceof IHutnContext) {
-			this.context = (IHutnContext) context;
+			super.setContext(context);
 		}
 	}
 	
diff --git a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/util/EpsilonUtil.java b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/util/EpsilonUtil.java
index 4a476d2..2dfe014 100644
--- a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/util/EpsilonUtil.java
+++ b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/util/EpsilonUtil.java
@@ -22,6 +22,7 @@
 import org.eclipse.epsilon.evl.EvlModule;
 import org.eclipse.epsilon.evl.IEvlFixer;
 import org.eclipse.epsilon.evl.IEvlModule;
+import org.eclipse.epsilon.evl.execute.context.EvlContext;
 
 public abstract class EpsilonUtil {
 
@@ -34,8 +35,7 @@
 		target.setStoredOnDisposal(false);
 		target.setReadOnLoad(false);
 		
-		transformer.getContext().getModelRepository().addModel(source);
-		transformer.getContext().getModelRepository().addModel(target);
+		transformer.getContext().getModelRepository().addModels(source, target);
 		
 		addExtraModels(transformer.getContext(), extraModels);
 		
@@ -46,7 +46,10 @@
 	
 	public static IEvlModule initialseEvlModule(IEvlFixer fixer, IModel model, IModel... extraModels) throws EolModelLoadingException  {
 		final IEvlModule validator = new EvlModule();
-		
+		// Guarantee ordering of unsatisfied constraints for traceability tests
+		validator.setContext(new EvlContext() {{
+			unsatisfiedConstraints = new java.util.LinkedHashSet<>();
+		}});
 		validator.setUnsatisfiedConstraintFixer(fixer);
 		
 		model.setReadOnLoad(true);
@@ -64,9 +67,9 @@
 	private static void addExtraModels(IEolContext context, IModel... models) throws EolModelLoadingException {
 		for (IModel model : models) {
 			model.setStoredOnDisposal(false);
-			context.getModelRepository().addModel(model);
 			model.load();
 		}
+		context.getModelRepository().addModels(models);
 	}
 	
 	private static void addNativeTypeDelegate(IEolContext context) {
diff --git a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/AbstractValidator.java b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/AbstractValidator.java
index 4b3cedd..73bf951 100644
--- a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/AbstractValidator.java
+++ b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/AbstractValidator.java
@@ -31,7 +31,7 @@
 	}
 	
 	protected List<ParseProblem> validate(IModel model, List<IModel> extraModels) throws HutnValidationException {
-		return validate(model, extraModels.toArray(new IModel[]{}));
+		return validate(model, extraModels.toArray(new IModel[extraModels.size()]));
 	}
 	
 	protected List<ParseProblem> validate(IModel model, IModel... extraModels) throws HutnValidationException {
@@ -40,7 +40,8 @@
 		do {
 			fixer.reset();
 			problems = doValidate(model, extraModels);
-		} while (fixer.hasChangedModel());
+		}
+		while (fixer.hasChangedModel());
 		
 		return problems;
 	}
diff --git a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/model/HutnFixer.java b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/model/HutnFixer.java
index e1eebda..a50a11d 100644
--- a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/model/HutnFixer.java
+++ b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/model/HutnFixer.java
@@ -26,10 +26,10 @@
 	@Override
 	protected ParseProblem interpretUnsatisfiedConstraint(UnsatisfiedConstraint constraint) {
 		if (constraint.getInstance() instanceof ModelElement) {			
-			final ModelElement modelElement = (ModelElement)constraint.getInstance();
+			final ModelElement modelElement = (ModelElement) constraint.getInstance();
 			return new ParseProblem(modelElement.getLine(), modelElement.getCol(), constraint.getMessage());
-		
-		} else {
+		}
+		else {
 			throw new IllegalArgumentException("Constraint instance was not a ModelElement");
 		}
 	}
@@ -41,17 +41,16 @@
 	}
 	
 	private boolean applyFixForClassMustSpecifyRequiredReferences(UnsatisfiedConstraint constraint) throws EolRuntimeException {
-		final ClassObject object = (ClassObject)constraint.getInstance();
+		final ClassObject object = (ClassObject) constraint.getInstance();
 		
 		final List<Slot<?>> originalSlots = defensiveCopy(object.getSlots());
 		
-		((FixInstance)constraint.getFixes().getFirst()).perform();
+		((FixInstance)constraint.getFixes().iterator().next()).perform();
 		
 		// Return true only if fix caused a change.
 		return !originalSlots.equals(object.getSlots());
 	}
 	
-	
 	private static <T> List<T> defensiveCopy(List<T> original) {
 		return new LinkedList<>(original);
 	}
diff --git a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/model/HutnValidator.java b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/model/HutnValidator.java
index 585639c..23fd296 100644
--- a/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/model/HutnValidator.java
+++ b/plugins/org.eclipse.epsilon.hutn.engine/src/org/eclipse/epsilon/hutn/validation/model/HutnValidator.java
@@ -38,15 +38,16 @@
 	
 	public List<ParseProblem> getProblemsForIntermediateModel(Spec hutn) throws HutnValidationException {
 		final IModel model = new InMemoryEmfModel("Intermediate", resourceFor(hutn), HutnPackage.eINSTANCE);
-		final List<IModel> metamodels = new ArrayList<>();
+		final List<NsUri> hutnUris = hutn.getNsUris();
+		final List<IModel> metamodels = new ArrayList<>(hutnUris.size());
 		
-		for (NsUri uri : hutn.getNsUris()) {
+		for (NsUri uri : hutnUris) {
 			try {
 				final IModel metamodel = new EmfMetaModel("Metamodel", uri.getValue());
 				metamodel.load();
-				
 				metamodels.add(metamodel);
-			} catch (EolModelLoadingException e) {
+			}
+			catch (EolModelLoadingException e) {
 				throw new HutnUnrecognisedNsUriException(uri.getValue(), uri.getLine(), uri.getCol());
 			}
 		}
diff --git a/standalone/org.eclipse.epsilon.eol.cli/src/org/eclipse/epsilon/eol/cli/EolConfigParser.java b/standalone/org.eclipse.epsilon.eol.cli/src/org/eclipse/epsilon/eol/cli/EolConfigParser.java
index 24ef577..a971f52 100644
--- a/standalone/org.eclipse.epsilon.eol.cli/src/org/eclipse/epsilon/eol/cli/EolConfigParser.java
+++ b/standalone/org.eclipse.epsilon.eol.cli/src/org/eclipse/epsilon/eol/cli/EolConfigParser.java
@@ -48,12 +48,15 @@
 		if (args.length > 0) {
 			
 			if (args[0].toUpperCase().startsWith("CONFIG")) {
-				Class<?> configClass = Class.forName(args[0].substring(7));
+				Class<? extends IEolRunConfiguration> configClass = (Class<? extends IEolRunConfiguration>)
+					Class.forName(args[0].substring(7));
+				
 				String[] adjustedArgs = Arrays.copyOfRange(args, 1, args.length);
-				new EolConfigParser(configClass).apply(adjustedArgs).run();
+				new EolConfigParser(IEolRunConfiguration.Builder(configClass)).apply(adjustedArgs).run();
 			}
 			else {
-				new EolConfigParser(getRunConfigurationForScript(args[0])).apply(args).run();
+				new EolConfigParser(IEolRunConfiguration.Builder(getRunConfigurationForScript(args[0])))
+					.apply(args).run();
 			}
 			
 		}
@@ -65,9 +68,8 @@
 		scriptParamsOpt = "parameters";
 	
 	
-	@SuppressWarnings("unchecked")
-	public EolConfigParser(Class<C> configurationClass) {
-		super((B)IEolRunConfiguration.Builder(configurationClass));
+	public EolConfigParser(B builder) {
+		super(builder);
 		
 		requiredUsage += "-models [model class]#[model properties];"+nL;
 		optionalUsage += "  [module] [argtype=argvalue]s..."+nL;
diff --git a/tests/org.eclipse.epsilon.egl.engine.test.dependencies/dependencies.jar b/tests/org.eclipse.epsilon.egl.engine.test.dependencies/dependencies.jar
index 6e8e395..66e2735 100644
--- a/tests/org.eclipse.epsilon.egl.engine.test.dependencies/dependencies.jar
+++ b/tests/org.eclipse.epsilon.egl.engine.test.dependencies/dependencies.jar
Binary files differ
diff --git a/tests/org.eclipse.epsilon.eml.engine.test.acceptance/src/org/eclipse/epsilon/eml/engine/test/acceptance/trees/TestXmlTreeMerging.java b/tests/org.eclipse.epsilon.eml.engine.test.acceptance/src/org/eclipse/epsilon/eml/engine/test/acceptance/trees/TestXmlTreeMerging.java
index 441d137..b6253f3 100644
--- a/tests/org.eclipse.epsilon.eml.engine.test.acceptance/src/org/eclipse/epsilon/eml/engine/test/acceptance/trees/TestXmlTreeMerging.java
+++ b/tests/org.eclipse.epsilon.eml.engine.test.acceptance/src/org/eclipse/epsilon/eml/engine/test/acceptance/trees/TestXmlTreeMerging.java
@@ -39,20 +39,17 @@
 		
 		eclModule = new EclModule();
 		eclModule.parse(getClass().getResource("trees.ecl").toURI());
-		info = new HashMap<String, Object>();
+		info = new HashMap<>();
 		eclModule.getContext().getFrameStack().put(Variable.createReadOnlyVariable("info", info));
-		eclModule.getContext().getModelRepository().addModel(leftModel);
-		eclModule.getContext().getModelRepository().addModel(rightModel);
+		eclModule.getContext().getModelRepository().addModels(leftModel, rightModel);
 		eclModule.execute();
 		
 		mergedModel = loadXmlModel("Merged", "merged.xml", false);
 		emlModule = new EmlModule();
 		emlModule.parse(getClass().getResource("trees.eml").toURI());
 		emlModule.getContext().getFrameStack().put(Variable.createReadOnlyVariable("info", info));
-		emlModule.getContext().getModelRepository().addModel(leftModel);
-		emlModule.getContext().getModelRepository().addModel(rightModel);
+		emlModule.getContext().getModelRepository().addModels(leftModel, rightModel, mergedModel);
 		emlModule.getContext().setMatchTrace(eclModule.getContext().getMatchTrace().getReduced());
-		emlModule.getContext().getModelRepository().addModel(mergedModel);
 		emlModule.execute();
 	}
 	
diff --git a/tests/org.eclipse.epsilon.evl.engine.test.acceptance/src/org/eclipse/epsilon/evl/engine/test/acceptance/EvlAcceptanceTestSuite.java b/tests/org.eclipse.epsilon.evl.engine.test.acceptance/src/org/eclipse/epsilon/evl/engine/test/acceptance/EvlAcceptanceTestSuite.java
index db75e60..18e63cb 100644
--- a/tests/org.eclipse.epsilon.evl.engine.test.acceptance/src/org/eclipse/epsilon/evl/engine/test/acceptance/EvlAcceptanceTestSuite.java
+++ b/tests/org.eclipse.epsilon.evl.engine.test.acceptance/src/org/eclipse/epsilon/evl/engine/test/acceptance/EvlAcceptanceTestSuite.java
@@ -15,6 +15,7 @@
 
 import org.eclipse.epsilon.evl.engine.test.acceptance.builtins.EvlCanAccessBuiltinsTests;
 import org.eclipse.epsilon.evl.engine.test.acceptance.equivalence.*;
+import org.eclipse.epsilon.evl.engine.test.acceptance.reuse.EvlModuleReuseTests;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
@@ -25,6 +26,7 @@
 @SuiteClasses({
 		EvlCanAccessBuiltinsTests.class,
 		EvlTests.class,
+		EvlModuleReuseTests.class,
 		EvlModuleEquivalenceTests.class,
 		EvlParallelOperationsTests.class
 	}
diff --git a/tests/org.eclipse.epsilon.evl.engine.test.acceptance/src/org/eclipse/epsilon/evl/engine/test/acceptance/EvlTests.java b/tests/org.eclipse.epsilon.evl.engine.test.acceptance/src/org/eclipse/epsilon/evl/engine/test/acceptance/EvlTests.java
index 1c251be..24008e9 100644
--- a/tests/org.eclipse.epsilon.evl.engine.test.acceptance/src/org/eclipse/epsilon/evl/engine/test/acceptance/EvlTests.java
+++ b/tests/org.eclipse.epsilon.evl.engine.test.acceptance/src/org/eclipse/epsilon/evl/engine/test/acceptance/EvlTests.java
@@ -63,6 +63,10 @@
 		return EvlAcceptanceTestUtil.modules();
 	}
 	
+	public static IModel newTestModel() {
+		return setUpModel("test.xml");
+	}
+	
 	private static IModel setUpModel(String modelName) {
 		PlainXmlModel model = new PlainXmlModel();
 		model.setFile(new File(EvlAcceptanceTestUtil.modelsRoot+modelName));
@@ -102,6 +106,9 @@
 	private IEvlModule loadEVL(boolean optimised) throws Exception {
 		module = moduleGetter.get();
 		loadEVL(module, optimised);
+		if (optimised) {
+			module.getContext().setModule(module);
+		}
 		return module;
 	}
 	
@@ -112,8 +119,12 @@
 	}
 	
 	private void assertUnsatisfiedConstraints(int number, String contextName, String constraintName) {
+		assertUnsatisfiedConstraints(number, contextName, constraintName, module.getContext());
+	}
+	
+	public static void assertUnsatisfiedConstraints(int number, String contextName, String constraintName, IEvlContext context) {
 		int matches = 0;
-		for (UnsatisfiedConstraint uc : module.getContext().getUnsatisfiedConstraints()) {
+		for (UnsatisfiedConstraint uc : context.getUnsatisfiedConstraints()) {
 			Constraint ucConstraint = uc.getConstraint();
 			String contextTypeName = ucConstraint.getConstraintContext().getTypeName();
 			
@@ -126,40 +137,33 @@
 		assertEquals(number, matches);
 	}
 	
-	@SuppressWarnings("rawtypes")
-	@Test
-	public void testEvl() throws Exception {
-		module = loadEVL(false);
-
-		IEvlContext context = module.getContext();
-		module.execute();
-		
-		assertUnsatisfiedConstraints(0, null, "CanAccessPre");
-		assertUnsatisfiedConstraints(1, null, "EolTest");
-		assertUnsatisfiedConstraints(0, "t_a", "GuardVariableInvisibleInBlock");
-		assertUnsatisfiedConstraints(0, "t_a", "NeverChecked");
-		assertUnsatisfiedConstraints(2, "t_b", "EolTest2");
-		assertUnsatisfiedConstraints(2, "t_b", "AlwaysFalse");
-		assertUnsatisfiedConstraints(0, "t_b", "AlwaysTrue");
-		assertUnsatisfiedConstraints(2, "t_b", "ElementOperationInConstraint");
-		assertUnsatisfiedConstraints(0, "t_b", "NeverChecked");
-		assertUnsatisfiedConstraints(0, "t_b", "RequiresNonLazyConstraint");
-		assertUnsatisfiedConstraints(0, "t_b", "LazyWithGuard");
-		assertUnsatisfiedConstraints(2, "t_b", "RequiresLazyConstraint");
-		assertUnsatisfiedConstraints(2, "t_b", "RequiresContextlessLazy");
-		assertUnsatisfiedConstraints(2, "t_b", "InsaneLazyChain");
-		assertUnsatisfiedConstraints(2, "t_c", "WrongType");
-		assertUnsatisfiedConstraints(0, "t_c", "AlwaysTrueOperation");
-		assertUnsatisfiedConstraints(2, "t_c", "AlwaysFalseOperation");
-		assertUnsatisfiedConstraints(2, "t_c", "SatisfiesOneLazyAndNonLazy");
-		assertUnsatisfiedConstraints(2, "t_c", "SatisfiesAllLazyAndNonLazy");
-		assertUnsatisfiedConstraints(0, "t_c", "NeverCalledLazyGuard");
-		assertUnsatisfiedConstraints(2, "t_c", "LazyAlwaysFalseOperation");
-		assertUnsatisfiedConstraints(0, "t_c", "ExtendedPropertyCanBeAccessed");
-		assertUnsatisfiedConstraints(1, null, "LazyContextlessCallsLazy");
-		assertUnsatisfiedConstraints(1, null, "LazyContextlessDependedOn");
-		assertUnsatisfiedConstraints(0, null, "LazyContextlessNeverCalled");
-		assertUnsatisfiedConstraints(0, null, "ImportedOperationWithoutContext");
+	public static void testUnsatisfiedConstraintsForTestScriptAndModel(IEvlContext context) throws EolRuntimeException {
+		assertUnsatisfiedConstraints(0, null, "CanAccessPre", context);
+		assertUnsatisfiedConstraints(1, null, "EolTest", context);
+		assertUnsatisfiedConstraints(0, "t_a", "GuardVariableInvisibleInBlock", context);
+		assertUnsatisfiedConstraints(0, "t_a", "NeverChecked", context);
+		assertUnsatisfiedConstraints(2, "t_b", "EolTest2", context);
+		assertUnsatisfiedConstraints(2, "t_b", "AlwaysFalse", context);
+		assertUnsatisfiedConstraints(0, "t_b", "AlwaysTrue", context);
+		assertUnsatisfiedConstraints(2, "t_b", "ElementOperationInConstraint", context);
+		assertUnsatisfiedConstraints(0, "t_b", "NeverChecked", context);
+		assertUnsatisfiedConstraints(0, "t_b", "RequiresNonLazyConstraint", context);
+		assertUnsatisfiedConstraints(0, "t_b", "LazyWithGuard", context);
+		assertUnsatisfiedConstraints(2, "t_b", "RequiresLazyConstraint", context);
+		assertUnsatisfiedConstraints(2, "t_b", "RequiresContextlessLazy", context);
+		assertUnsatisfiedConstraints(2, "t_b", "InsaneLazyChain", context);
+		assertUnsatisfiedConstraints(2, "t_c", "WrongType", context);
+		assertUnsatisfiedConstraints(0, "t_c", "AlwaysTrueOperation", context);
+		assertUnsatisfiedConstraints(2, "t_c", "AlwaysFalseOperation", context);
+		assertUnsatisfiedConstraints(2, "t_c", "SatisfiesOneLazyAndNonLazy", context);
+		assertUnsatisfiedConstraints(2, "t_c", "SatisfiesAllLazyAndNonLazy", context);
+		assertUnsatisfiedConstraints(0, "t_c", "NeverCalledLazyGuard", context);
+		assertUnsatisfiedConstraints(2, "t_c", "LazyAlwaysFalseOperation", context);
+		assertUnsatisfiedConstraints(0, "t_c", "ExtendedPropertyCanBeAccessed", context);
+		assertUnsatisfiedConstraints(1, null, "LazyContextlessCallsLazy", context);
+		assertUnsatisfiedConstraints(1, null, "LazyContextlessDependedOn", context);
+		assertUnsatisfiedConstraints(0, null, "LazyContextlessNeverCalled", context);
+		assertUnsatisfiedConstraints(0, null, "ImportedOperationWithoutContext", context);
 		
 		for (UnsatisfiedConstraint uc : context.getUnsatisfiedConstraints()) {
 			uc.getMessage();
@@ -169,9 +173,15 @@
 			}
 		}
 		
-		assertEquals("true", ((Map)context.getFrameStack().get("blackboard").getValue()).get("fix-do-executed"));
+		assertEquals("true", ((Map<?,?>)context.getFrameStack().get("blackboard").getValue()).get("fix-do-executed"));
 	}
-
+	
+	@Test
+	public void testUnsatisfiedConstraints() throws Exception {
+		(module = loadEVL(false)).execute();
+		testUnsatisfiedConstraintsForTestScriptAndModel(module.getContext());
+	}
+	
 	@Test
 	public void testCanBeTransformedEVL() throws Exception {
 		module = loadEVL(true);
@@ -235,8 +245,7 @@
 	 */
 	@Test
 	public void testOptimizedExecution() throws Exception {
-		module = loadEVL(true);
-		module.execute();
+		(module = loadEVL(true)).execute();
 		
 		assertUnsatisfiedConstraints(0, "t_b", "NoGuardAlwaysTrue");
 		assertUnsatisfiedConstraints(4, "t_b", "NoGuardAlwaysFalse");
diff --git a/tests/org.eclipse.epsilon.evl.engine.test.acceptance/src/org/eclipse/epsilon/evl/engine/test/acceptance/reuse/EvlModuleReuseTests.java b/tests/org.eclipse.epsilon.evl.engine.test.acceptance/src/org/eclipse/epsilon/evl/engine/test/acceptance/reuse/EvlModuleReuseTests.java
new file mode 100644
index 0000000..68a0da3
--- /dev/null
+++ b/tests/org.eclipse.epsilon.evl.engine.test.acceptance/src/org/eclipse/epsilon/evl/engine/test/acceptance/reuse/EvlModuleReuseTests.java
@@ -0,0 +1,99 @@
+/*********************************************************************
+ * Copyright (c) 2019 The University of York.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+**********************************************************************/
+package org.eclipse.epsilon.evl.engine.test.acceptance.reuse;
+
+import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;
+import org.eclipse.epsilon.eol.exceptions.models.EolModelLoadingException;
+import org.eclipse.epsilon.eol.exceptions.models.EolModelNotFoundException;
+import org.eclipse.epsilon.eol.models.IModel;
+import org.eclipse.epsilon.eol.models.ModelRepository;
+import org.eclipse.epsilon.evl.*;
+import org.eclipse.epsilon.evl.engine.test.acceptance.EvlTests;
+import org.eclipse.epsilon.evl.execute.context.EvlContext;
+import org.eclipse.epsilon.evl.execute.context.IEvlContext;
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+/**
+ * Tests that the same module can be re-executed multiple times without re-parsing.
+ * 
+ * @author Sina Madani
+ * @since 1.6
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class EvlModuleReuseTests {
+
+	static IEvlModule module = new EvlModule();
+	
+	static IModel addAndLoadNewModel() throws EolModelLoadingException {
+		IModel model = EvlTests.newTestModel();
+		module.getContext().getModelRepository().addModel(model);
+		model.load();
+		return model;
+	}
+	
+	static IModel removeModel(String modelName) throws EolModelNotFoundException {
+		ModelRepository modelRepo = module.getContext().getModelRepository();
+		IModel model = modelRepo.getModelByName(modelName);
+		modelRepo.removeModel(model);
+		return model;
+	}
+	
+	@BeforeClass
+	public static void setUpBeforeClass() throws Exception {
+		module.parse(EvlTests.getTestScript(module));
+	}
+	
+	@After
+	public void testExecution() throws EolRuntimeException {
+		EvlTests.getTestScript(module);		// Setup variables
+		module.execute();
+		EvlTests.testUnsatisfiedConstraintsForTestScriptAndModel(module.getContext());
+	}
+	
+	@Test
+	public void test0_NormalExecution() throws EolModelLoadingException {
+		addAndLoadNewModel();
+	}
+	
+	@Test
+	public void test1_ReuseWithChangedContextSameModel() throws EolModelLoadingException {
+		module.setContext(new EvlContext());
+		addAndLoadNewModel();
+	}
+	
+	/**
+	 * This should work because UnsatisfiedConstraints is a Set
+	 * 
+	 * @throws EolModelNotFoundException
+	 */
+	@Test
+	public void test2_ReuseWithChangedModelRepositorySameModel() throws EolModelNotFoundException {
+		ModelRepository modelRepo = new ModelRepository();
+		modelRepo.addModel(module.getContext().getModelRepository().getModelByName("test"));
+		module.getContext().setModelRepository(modelRepo);
+	}
+	
+	@Test
+	public void test3_ReuseWithChangedContextDifferentModel() throws EolModelLoadingException {
+		module.setContext(new EvlContext());
+		addAndLoadNewModel();
+	}
+	
+	@Test
+	public void test4_ReuseWithChangedContextSameModelRepositorySameModel() {
+		IEvlContext context = new EvlContext();
+		context.setModelRepository(module.getContext().getModelRepository());
+		module.setContext(context);
+	}
+}
diff --git a/tests/org.eclipse.epsilon.hutn.test.unit/src/org/eclipse/epsilon/hutn/validation/model/Traceability.java b/tests/org.eclipse.epsilon.hutn.test.unit/src/org/eclipse/epsilon/hutn/validation/model/Traceability.java
index 859c74d..c2c159d 100644
--- a/tests/org.eclipse.epsilon.hutn.test.unit/src/org/eclipse/epsilon/hutn/validation/model/Traceability.java
+++ b/tests/org.eclipse.epsilon.hutn.test.unit/src/org/eclipse/epsilon/hutn/validation/model/Traceability.java
@@ -26,8 +26,12 @@
 	
 	@BeforeClass
 	public static void validateModel() throws HutnValidationException {
-		problems = modelValidationTest(createSpec("families", createPackageObject(createClassObject("Fido", "Pet",    10, 1),
-		                                                                    createClassObject("Fido", "Person", 20, 13))));
+		problems = modelValidationTest(createSpec(
+			"families", createPackageObject(
+				createClassObject("Fido", "Pet",    10, 1),
+		        createClassObject("Fido", "Person", 20, 13)
+		    )
+		));
 	}
 	
 	@Test
diff --git a/tests/org.eclipse.epsilon.hutn.test/META-INF/MANIFEST.MF b/tests/org.eclipse.epsilon.hutn.test/META-INF/MANIFEST.MF
index 9b3cb37..824ee35 100644
--- a/tests/org.eclipse.epsilon.hutn.test/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.epsilon.hutn.test/META-INF/MANIFEST.MF
@@ -10,3 +10,4 @@
 Bundle-Vendor: Eclipse.org
 Export-Package: org.eclipse.epsilon.hutn.test
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Automatic-Module-Name: org.eclipse.epsilon.hutn.test