[526558] Use a TestFileSystem for compile atl2qvtr
diff --git a/releng/org.eclipse.qvtd.build/.launches/Generate QVTd ATL2QVTr Transformation.launch b/releng/org.eclipse.qvtd.build/.launches/Generate QVTd ATL2QVTr Transformation.launch
index 1aef94d..1be64ff 100644
--- a/releng/org.eclipse.qvtd.build/.launches/Generate QVTd ATL2QVTr Transformation.launch
+++ b/releng/org.eclipse.qvtd.build/.launches/Generate QVTd ATL2QVTr Transformation.launch
@@ -8,7 +8,8 @@
 <listEntry value="4"/>

 </listAttribute>

 <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher"/>

-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="src/org/eclipse/qvtd/build/mwe2/GenerateQVTdATL2QVTrTransformation.mwe2"/>

+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="file:/${resource_loc:org.eclipse.qvtd.build}/src/org/eclipse/qvtd/build/mwe2/GenerateQVTdATL2QVTrTransformation.mwe2"/>

 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.qvtd.build"/>

 <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea"/>

+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>

 </launchConfiguration>

diff --git a/releng/org.eclipse.qvtd.build/META-INF/MANIFEST.MF b/releng/org.eclipse.qvtd.build/META-INF/MANIFEST.MF
index f60b307..cc1f4a4 100644
--- a/releng/org.eclipse.qvtd.build/META-INF/MANIFEST.MF
+++ b/releng/org.eclipse.qvtd.build/META-INF/MANIFEST.MF
@@ -21,7 +21,8 @@
  org.eclipse.qvtd.xtext.qvtcore.tests;bundle-version="[0.15.0,1.0.0)",
  org.eclipse.qvtd.umlx;bundle-version="[0.15.0,1.0.0)",
  org.eclipse.m2m.atl.common,
- org.eclipse.qvtd.atl
+ org.eclipse.qvtd.atl,
+ org.eclipse.qvtd.xtext.qvtrelation.tests
 Import-Package: org.apache.commons.logging,
  org.apache.log4j
 Bundle-Vendor: %providerName
diff --git a/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/mwe2/GenerateQVTdATL2QVTrTransformation.mwe2 b/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/mwe2/GenerateQVTdATL2QVTrTransformation.mwe2
index 0b62914..b40218d 100644
--- a/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/mwe2/GenerateQVTdATL2QVTrTransformation.mwe2
+++ b/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/mwe2/GenerateQVTdATL2QVTrTransformation.mwe2
@@ -27,17 +27,17 @@
 Workflow {
 	bean = ResourceSetImpl : resourceSet {}
     bean = StandaloneSetup { resourceSet = resourceSet
-    	platformUri = ".."
+    	platformUri = "."
     	scanClassPath = true
     }
     bean = EcoreGenModelSetup { resourceSet = resourceSet }
 
     component = CompileQVTrTransformation { /*resourceSet = resourceSet*/ skipOnErrors = true
-    	qvtrModel = "/org.eclipse.qvtd.atl/src/org/eclipse/qvtd/atl/atl2qvtr/ATL2QVTr.qvtr" 	
+    	qvtrModel = "/org.eclipse.qvtd.atl/model/ATL2QVTr.qvtr" 	
 		usedGenPackage = "org.eclipse.qvtd.pivot.qvtrelation/model/QVTrelation.genmodel#//qvtrelation"
-		usedGenPackage = "org.eclipse.m2m.atl.common/org/eclipse/m2m/atl/common/resources/ATL.genmodel#//ATL"
-		usedGenPackage = "org.eclipse.m2m.atl.common/org/eclipse/m2m/atl/common/resources/ATL.genmodel#//OCL"
-		usedGenPackage = "org.eclipse.m2m.atl.common/org/eclipse/m2m/atl/common/resources/ATL.genmodel#//PrimitiveTypes"
+		usedGenPackage = "org.eclipse.m2m.atl.common/model/ATL.genmodel#//ATL"
+		usedGenPackage = "org.eclipse.m2m.atl.common/model/ATL.genmodel#//OCL"
+		usedGenPackage = "org.eclipse.m2m.atl.common/model/ATL.genmodel#//PrimitiveTypes"
     }
     
 //	component = ConvertToUnixLineEndings {
diff --git a/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/utilities/AbstractTestQVT.java b/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/utilities/AbstractTestQVT.java
deleted file mode 100644
index 4c2d63e..0000000
--- a/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/utilities/AbstractTestQVT.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012, 2017 Willink Transformations and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     E.D.Willink - initial API and implementation
- *******************************************************************************/
-package org.eclipse.qvtd.build.utilities;
-
-import java.lang.reflect.Field;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.emf.common.EMFPlugin;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.ecore.xmi.XMLResource;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.ocl.pivot.internal.resource.ProjectMap;
-import org.eclipse.ocl.pivot.internal.resource.StandaloneProjectMap;
-import org.eclipse.ocl.pivot.resource.ASResource;
-import org.eclipse.ocl.pivot.utilities.ClassUtil;
-import org.eclipse.ocl.pivot.utilities.PivotUtil;
-import org.eclipse.qvtd.compiler.AbstractCompilerChain;
-import org.eclipse.qvtd.compiler.CompilerChain;
-import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTransformation;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluation.BasicQVTiExecutor;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiEnvironmentFactory;
-import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiTransformationExecutor;
-import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperative;
-import org.eclipse.qvtd.runtime.evaluation.Transformer;
-import org.eclipse.qvtd.xtext.qvtbase.tests.utilities.XtextCompilerUtil;
-
-public abstract class AbstractTestQVT extends QVTimperative
-{
-	public final static @NonNull Map<Object, Object> defaultSavingOptions;
-
-	// FIXME use a better default strategy for the saving options
-	static {
-		defaultSavingOptions = new HashMap<Object, Object>();
-		defaultSavingOptions.put(XMLResource.OPTION_ENCODING, "UTF-8");
-		defaultSavingOptions.put(XMLResource.OPTION_LINE_DELIMITER, "\n");
-		defaultSavingOptions.put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
-		defaultSavingOptions.put(XMLResource.OPTION_SCHEMA_LOCATION_IMPLEMENTATION, Boolean.TRUE);
-		defaultSavingOptions.put(XMLResource.OPTION_LINE_WIDTH, Integer.valueOf(132));
-		defaultSavingOptions.put(ASResource.OPTION_NORMALIZE_CONTENTS, Boolean.TRUE);
-	}
-
-	private static StandaloneProjectMap projectMap = null;
-
-	public static @NonNull StandaloneProjectMap getProjectMap() {
-		StandaloneProjectMap projectMap2 = projectMap;
-		if (projectMap2 == null) {
-			projectMap = projectMap2 = EMFPlugin.IS_ECLIPSE_RUNNING ? new ProjectMap(false) : new StandaloneProjectMap(false);
-		}
-		return projectMap2;
-	}
-
-	protected final @NonNull URI testsBaseURI;
-	protected final @NonNull String projectName;
-	protected final @NonNull String testFolderName;
-	protected final @NonNull URI testFolderURI;
-	protected final @NonNull URI samplesBaseUri;
-	protected AbstractCompilerChain compilerChain = null;
-	private BasicQVTiExecutor interpretedExecutor = null;
-	private QVTiTransformationExecutor generatedExecutor = null;
-	private Set<@NonNull String> nsURIs = new HashSet<@NonNull String>();
-
-	public AbstractTestQVT(@NonNull URI testsBaseURI, @NonNull String projectName, @NonNull String testFolderName) {
-		super(new QVTiEnvironmentFactory(getProjectMap(), null));
-		this.testsBaseURI = testsBaseURI;
-		this.projectName = projectName;
-		this.testFolderName = testFolderName;
-		this.testFolderURI = testsBaseURI.appendSegment(testFolderName);
-		this.samplesBaseUri = testFolderURI.appendSegment("samples");
-	}
-
-	protected abstract @NonNull AbstractCompilerChain createCompilerChain(@NonNull URI txURI, @NonNull URI prefixURI,
-			@NonNull Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> options);
-
-	public @Nullable Resource createModel(@NonNull String modelName, @NonNull String modelFile) {
-		URI modelURI = samplesBaseUri.appendSegment(modelFile);
-		return interpretedExecutor.createModel(modelName, modelURI, null);
-	}
-
-	@Override
-	public synchronized void dispose() {
-		super.dispose();
-		if (interpretedExecutor != null) {
-			interpretedExecutor.dispose();
-		}
-		if (compilerChain != null) {
-			compilerChain.dispose();
-		}
-		/**
-		 * Remove the eInstances from the EPackage.Registry.INSTANCE so that global registrations from the calling test
-		 * do not confuse subsequent tests that may want to use dynamic models.
-		 */
-		for (String nsURI : nsURIs) {
-			EPackage.Registry.INSTANCE.remove(nsURI);
-		}
-	}
-
-	protected @NonNull Class<? extends Transformer> doBuild(@NonNull String testFileName, @NonNull String outputName,
-			@NonNull Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> options,
-			@NonNull String @NonNull... genModelFiles) throws Exception {
-		URI prefixURI = testFolderURI.appendSegment(testFileName);
-		compilerChain = createCompilerChain(prefixURI, prefixURI, options);
-		ImperativeTransformation asTransformation = compilerChain.compile(outputName);
-		URI txURI = asTransformation.eResource().getURI();
-		if (txURI != null) {
-			URI inputURI = txURI;
-			URI serializedURI = txURI.trimFileExtension().appendFileExtension("serialized.qvti");
-			XtextCompilerUtil.doQVTiSerializeAndLoad(environmentFactory.getProjectManager(), inputURI, serializedURI);
-		}
-		Class<? extends Transformer> txClass = compilerChain.generate(asTransformation, genModelFiles);
-		return txClass;
-	}
-
-	public Transformer executeTransformation() throws Exception {
-		if (interpretedExecutor != null) {
-			interpretedExecutor.execute();
-			interpretedExecutor.saveModels(defaultSavingOptions);
-			return null;
-		}
-		else {
-			Transformer transformer = generatedExecutor.getTransformer();
-			transformer.run();						// FIXME BUG 511028
-			//			if (!transformer.run()) {
-			//				throw new Exception("Failed to execute");
-			//			}
-			return transformer;
-		}
-	}
-
-	@Override
-	public @NonNull QVTiEnvironmentFactory getEnvironmentFactory() {
-		return super.getEnvironmentFactory();
-	}
-
-	public @NonNull Collection<@NonNull ? extends Object> getRootObjects(@NonNull String modelName) {
-		if (interpretedExecutor != null) {
-			return interpretedExecutor.getRootObjects(modelName);
-		}
-		else {
-			return generatedExecutor.getTransformer().getRootObjects(modelName);
-		}
-	}
-
-	public @NonNull Map<Object, Object> getSaveOptions() {
-		Map<Object, Object> saveOptions = new HashMap<Object, Object>(defaultSavingOptions);
-		saveOptions.put(ASResource.OPTION_NORMALIZE_CONTENTS, Boolean.TRUE);
-		return saveOptions;
-	}
-
-	public @Nullable Resource loadInput(@NonNull String modelName, @NonNull String modelFile) {
-		URI modelURI = samplesBaseUri.appendSegment(modelFile);
-		if (interpretedExecutor != null) {
-			return interpretedExecutor.loadModel(modelName, modelURI);
-		}
-		else {
-			ResourceSet resourceSet = environmentFactory.getMetamodelManager().getASResourceSet();		// FIXME get package registrations in exteranl RespurcSet
-			PivotUtil.initializeLoadOptionsToSupportSelfReferences(resourceSet);
-			Resource inputResource = resourceSet.getResource(modelURI, true);
-			generatedExecutor.getTransformer().addRootObjects(modelName, ClassUtil.nonNullState(inputResource.getContents()));
-			return inputResource;
-		}
-	}
-
-	public void removeRegisteredPackage(@NonNull String ePackageClassName) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
-		Class<?> ePackageClass = Class.forName(ePackageClassName);
-		Field eNsURIField = ePackageClass.getField("eNS_URI");
-		String nsURI = String.valueOf(eNsURIField.get(null));
-		EPackage.Registry.INSTANCE.remove(nsURI);
-	}
-}
\ No newline at end of file
diff --git a/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/utilities/CompileQVTrTransformation.java b/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/utilities/CompileQVTrTransformation.java
index e071c44..718e694 100644
--- a/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/utilities/CompileQVTrTransformation.java
+++ b/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/utilities/CompileQVTrTransformation.java
@@ -12,11 +12,14 @@
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.log4j.Logger;
 import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
+import org.eclipse.emf.common.EMFPlugin;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EPackage;
 import org.eclipse.emf.ecore.EcorePackage;
@@ -27,15 +30,23 @@
 import org.eclipse.emf.mwe.core.monitor.ProgressMonitor;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.examples.codegen.dynamic.JavaFileUtil;
+import org.eclipse.ocl.examples.xtext.tests.TestFile;
+import org.eclipse.ocl.examples.xtext.tests.TestFileSystem;
+import org.eclipse.ocl.examples.xtext.tests.TestProject;
+import org.eclipse.ocl.pivot.internal.resource.ProjectMap;
 import org.eclipse.ocl.pivot.internal.resource.StandaloneProjectMap;
 import org.eclipse.ocl.pivot.model.OCLstdlib;
 import org.eclipse.ocl.pivot.resource.ProjectManager;
+import org.eclipse.ocl.pivot.utilities.ClassUtil;
 import org.eclipse.ocl.pivot.utilities.LabelUtil;
 import org.eclipse.qvtd.compiler.CompilerChain;
 import org.eclipse.qvtd.compiler.CompilerChain.Listener;
 import org.eclipse.qvtd.compiler.QVTrCompilerChain;
 import org.eclipse.qvtd.pivot.qvtcore.QVTcorePivotStandaloneSetup;
 import org.eclipse.qvtd.runtime.evaluation.Transformer;
+import org.eclipse.qvtd.xtext.qvtbase.tests.AbstractTestQVT;
+import org.eclipse.qvtd.xtext.qvtbase.tests.utilities.TestsXMLUtil;
 import org.eclipse.qvtd.xtext.qvtimperative.QVTimperativeStandaloneSetup;
 import org.eclipse.qvtd.xtext.qvtrelation.QVTrelationStandaloneSetup;
 
@@ -44,6 +55,128 @@
  */
 public class CompileQVTrTransformation extends AbstractWorkflowComponent
 {
+	protected class MyQVT extends AbstractTestQVT
+	{
+		protected final @NonNull String testProjectName;
+		private Collection<@NonNull GenPackage> usedGenPackages = null;
+		private Collection<@NonNull EPackage> loadedEPackages = null;
+
+		public MyQVT(@NonNull ProjectManager projectManager, @NonNull String testProjectName, @NonNull URI testBundleURI, @NonNull URI txURI, @NonNull URI prefixURI, @NonNull URI srcFileURI, @NonNull URI binFileURI) {
+			super(projectManager, testBundleURI, txURI, prefixURI, srcFileURI, binFileURI);
+			this.testProjectName = testProjectName;
+		}
+
+		public @NonNull GenPackage addUsedGenPackage(@NonNull String resourcePath, @Nullable String fragment) {
+			if (usedGenPackages == null) {
+				usedGenPackages = new ArrayList<>();
+			}
+			URI uri = URI.createPlatformResourceURI(resourcePath, false);
+			if (fragment != null) {
+				uri = uri.appendFragment(fragment);
+			}
+			GenPackage genPackage = ClassUtil.nonNullState((GenPackage)getResourceSet().getEObject(uri, true));
+			usedGenPackages.add(genPackage);
+			return genPackage;
+		}
+
+		@Override
+		protected @NonNull Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> createBuildCompilerChainOptions(boolean isIncremental) {
+			Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> options = super.createBuildCompilerChainOptions(isIncremental);
+			QVTrCompilerChain.setOption(options, CompilerChain.DEFAULT_STEP, CompilerChain.DEBUG_KEY, true);
+			QVTrCompilerChain.setOption(options, CompilerChain.DEFAULT_STEP, CompilerChain.SAVE_OPTIONS_KEY, TestsXMLUtil.defaultSavingOptions);
+			Map<@NonNull String, @Nullable String> genModelOptions = new HashMap<>();
+			genModelOptions.put(CompilerChain.GENMODEL_BASE_PREFIX, getBasePrefix());
+			QVTrCompilerChain.setOption(options, CompilerChain.GENMODEL_STEP, CompilerChain.GENMODEL_OPTIONS_KEY, genModelOptions);
+			//			genModelOptions.put(CompilerChain.GENMODEL_COPYRIGHT_TEXT, "Copyright (c) 2015, 2016 Willink Transformations and others.\n;All rights reserved. This program and the accompanying materials\n;are made available under the terms of the Eclipse Public License v1.0\n;which accompanies this distribution, and is available at\n;http://www.eclipse.org/legal/epl-v10.html\n;\n;Contributors:\n;  E.D.Willink - Initial API and implementation");
+			QVTrCompilerChain.setOption(options, CompilerChain.GENMODEL_STEP, CompilerChain.GENMODEL_USED_GENPACKAGES_KEY, usedGenPackages);
+			return options;
+		}
+
+		@Override
+		protected @NonNull List<@NonNull String> createClassProjectNames() {
+			List<@NonNull String> classProjectNames = super.createClassProjectNames();
+			classProjectNames.add(0, testProjectName);
+			return classProjectNames;
+		}
+
+		@Override
+		protected @NonNull QVTrCompilerChain createCompilerChain(@NonNull URI txURI, @NonNull URI prefixURI,
+				@NonNull Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> options) {
+			QVTrCompilerChain compilerChain = new QVTrCompilerChain(getEnvironmentFactory(), txURI, prefixURI, options);
+			compilerChain.addListener(new Listener()
+			{
+				@Override
+				public void compiled(@NonNull String step, @Nullable Object object) {
+					String label = LabelUtil.getLabel(object);
+					log.info("Compiled '" + step + "' : '" + label + "'");
+				}
+			});
+			return compilerChain;
+		}
+
+		@Override
+		protected @NonNull Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> createCompilerChainOptions() {
+			Map<@NonNull String, @Nullable String> genModelOptions = new HashMap<>();
+			genModelOptions.put(CompilerChain.GENMODEL_BASE_PREFIX, getBasePrefix());
+			//			genModelOptions.put(CompilerChain.GENMODEL_COPYRIGHT_TEXT, "Copyright (c) 2015, 2016 Willink Transformations and others.\n;All rights reserved. This program and the accompanying materials\n;are made available under the terms of the Eclipse Public License v1.0\n;which accompanies this distribution, and is available at\n;http://www.eclipse.org/legal/epl-v10.html\n;\n;Contributors:\n;  E.D.Willink - Initial API and implementation");
+			Map<@NonNull String, @Nullable String> traceOptions = new HashMap<@NonNull String, @Nullable String>();
+			//			traceOptions.put(CompilerChain.TRACE_NS_URI, middleNsURI);
+			Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> options = super.createCompilerChainOptions();
+			QVTrCompilerChain.setOption(options, CompilerChain.DEFAULT_STEP, CompilerChain.SAVE_OPTIONS_KEY, getSaveOptions());
+			QVTrCompilerChain.setOption(options, CompilerChain.JAVA_STEP, CompilerChain.URI_KEY, null);
+			QVTrCompilerChain.setOption(options, CompilerChain.CLASS_STEP, CompilerChain.URI_KEY, null);
+			QVTrCompilerChain.setOption(options, CompilerChain.TRACE_STEP, CompilerChain.TRACE_OPTIONS_KEY, traceOptions);
+			QVTrCompilerChain.setOption(options, CompilerChain.GENMODEL_STEP, CompilerChain.GENMODEL_USED_GENPACKAGES_KEY, usedGenPackages);
+			QVTrCompilerChain.setOption(options, CompilerChain.GENMODEL_STEP, CompilerChain.GENMODEL_OPTIONS_KEY, genModelOptions);
+			return options;
+		}
+
+		@Override
+		public synchronized void dispose() {
+			if (loadedEPackages != null) {
+				for (@NonNull EPackage ePackage : loadedEPackages) {
+					EPackage.Registry.INSTANCE.remove(ePackage.getNsURI());
+				}
+			}
+			super.dispose();
+		}
+
+		public @NonNull String getBasePrefix() {
+			return "org.eclipse.qvtd.xtext.qvtrelation.tests";
+		}
+
+		//		@Override
+		//		protected @NonNull ProjectManager getTestProjectManager() throws Exception {
+		// TODO Auto-generated method stub
+		//			return QVTrCompilerTests.this.getTestProjectManager();
+		//		}
+
+		@Override
+		protected @NonNull ProjectManager getTestProjectManager() throws Exception {
+			return EMFPlugin.IS_ECLIPSE_RUNNING ? new ProjectMap(true) : CompileQVTrTransformation.this.getTestProjectManager();
+		}
+
+		@Override
+		protected void loadGenModels(@NonNull String @NonNull... genModelFiles) {
+			URI primaryGenModelURI = compilerChain.getURI(CompilerChain.GENMODEL_STEP, CompilerChain.URI_KEY);
+			loadGenModel(primaryGenModelURI);
+			for (String genModelFile : genModelFiles) {
+				URI genModelURI = URI.createURI(genModelFile).resolve(testBundleURI);
+				loadGenModel(genModelURI);
+			}
+		}
+
+		public void loadEPackage(@NonNull Class<?> txClass, @NonNull String qualifiedClassName) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
+			Class<?> ePackageClass = txClass.getClassLoader().loadClass(getBasePrefix() + "." + qualifiedClassName);
+			EPackage ePackage = (EPackage)ePackageClass.getField("eINSTANCE").get(null);
+			assert ePackage != null;
+			if (loadedEPackages == null) {
+				loadedEPackages = new ArrayList<>();
+			}
+			loadedEPackages.add(ePackage);
+			//			}
+		}
+	}
 	private Logger log = Logger.getLogger(getClass());
 
 	private String qvtrModel = null;
@@ -90,6 +223,81 @@
 			}
 		}
 	}
+	public @Nullable TestFileSystem testFileSystem = null;
+	public @Nullable TestProject testProject = null;
+	public @Nullable ProjectManager testProjectManager = null;
+
+	/**
+	 * Return the name of the test bundle. The default implementation assumes that the package name is
+	 * the same as the bundle name. Override when this assumption is unjustified.
+	 */
+	protected @NonNull String getTestBundleName() {
+		return ClassUtil.nonNullState(getClass().getPackage().getName());
+	}
+	protected @NonNull URI getTestBundleURI() {
+		if (EMFPlugin.IS_ECLIPSE_RUNNING) {
+			return URI.createPlatformPluginURI("/" + getTestBundleName(), true);
+		}
+		else {
+			return URI.createPlatformResourceURI("/" + getTestBundleName(), true);
+		}
+	}
+
+	protected @NonNull TestFileSystem getTestFileSystem() {
+		TestFileSystem testFileSystem2 = testFileSystem;
+		if (testFileSystem2 == null) {
+			if (!EMFPlugin.IS_ECLIPSE_RUNNING) {
+				File testBundleFile = new File(".project");
+				String absolutePath = testBundleFile.getAbsolutePath();
+				assert !testBundleFile.exists() : "Default working directory should be the workspace rather than a project: " + absolutePath;
+			}
+			testFileSystem = testFileSystem2 = TestFileSystem.create();
+		}
+		return testFileSystem2;
+	}
+
+	/**
+	 * Return the URI of the file within the testProject.
+	 */
+	protected @NonNull URI getTestFileURI(@NonNull String filePath) {
+		TestProject testProject = getTestProject();
+		TestFile outFile = testProject.getOutputFile(filePath);
+		return URI.createFileURI(outFile.getFile().toString());
+	}
+
+	protected @NonNull TestProject getTestProject() {
+		TestProject testProject2 = testProject;
+		if (testProject2 == null) {
+			String testProjectName = getTestProjectName();
+			testProject = testProject2 = getTestFileSystem().getTestProject(testProjectName, true);
+		}
+		return testProject2;
+	}
+
+	protected @NonNull String getTestProjectName() {
+		return "QVTd_" + getClass().getSimpleName() + "__" + getTestName();
+	}
+
+	protected @NonNull String getTestName() {
+		return "atl2qvtr";
+	}
+
+	protected @NonNull ProjectManager getTestProjectManager() {
+		ProjectManager testProjectManager2 = testProjectManager;
+		if (testProjectManager2 == null) {
+			testProjectManager = testProjectManager2 = getTestProject().createTestProjectManager();
+		}
+		return testProjectManager2;
+	}
+
+	/**
+	 * Return the URI of the filePath within the testProject.
+	 */
+	protected @NonNull URI getTestURI(@NonNull String filePath) {
+		TestProject testProject = getTestProject();
+		TestFile outFile = testProject.getOutputFile(filePath);
+		return outFile.getURI();
+	}
 
 	@Override
 	public void invokeInternal(WorkflowContext ctx, ProgressMonitor arg1, Issues issues) {
@@ -101,27 +309,22 @@
 		QVTimperativeStandaloneSetup.doSetup();
 		log.info("Compiling '" + qvtrModel + "'");
 
-		MyQVT myQVT = new MyQVT("atl2qvtr") {
-
-			@Override
-			protected @NonNull QVTrCompilerChain createCompilerChain(@NonNull URI txURI, @NonNull URI prefixURI,
-					@NonNull Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> options) {
-				QVTrCompilerChain compilerChain = new QVTrCompilerChain(getEnvironmentFactory(), txURI, prefixURI, options);
-				compilerChain.addListener(new Listener()
-				{
-					@Override
-					public void compiled(@NonNull String step, @Nullable Object object) {
-						String label = LabelUtil.getLabel(object);
-						log.info("Compiled '" + step + "' : '" + label + "'");
-					}
-				});
-				return compilerChain;
-			}
-		};
+		String testProjectName = getTestProjectName();
+		URI testBundleURI = getTestBundleURI();
+		URI txURI = URI.createPlatformResourceURI("/org.eclipse.qvtd.atl/model/ATL2QVTr.qvtr", true);
+		ProjectManager testProjectManager = getTestProjectManager();
+		URI prefixURI = getTestURI("atl2qvtr");
+		URI srcFileURI = getTestFileURI(JavaFileUtil.TEST_SRC_FOLDER_NAME + "/");
+		URI binFileURI = getTestFileURI(JavaFileUtil.TEST_BIN_FOLDER_NAME + "/");
+		MyQVT myQVT = new MyQVT(testProjectManager, testProjectName, testBundleURI, txURI, prefixURI, srcFileURI, binFileURI);
+		myQVT.addClasspathProjectName("org.eclipse.m2m.atl.common");
+		myQVT.addClasspathProjectName("org.eclipse.qvtd.atl");
+		myQVT.addClasspathProjectName("org.eclipse.qvtd.pivot.qvtbase");
+		myQVT.addClasspathProjectName("org.eclipse.qvtd.pivot.qvtrelation");
+		myQVT.addClasspathProjectName("org.eclipse.qvtd.pivot.qvttemplate");
 		//
 		//	Install the GenPackages and ensure that their nsURIs redirect to their *.ecores.
 		//
-		ProjectManager projectManager = myQVT.getProjectManager();
 		for (@NonNull String usedGenPackage : usedGenPackages) {
 			int separator = usedGenPackage.indexOf("#");
 			String projectPath = usedGenPackage.substring(0, separator);
@@ -130,16 +333,14 @@
 			EPackage ePackage = genPackage.getEcorePackage();
 			String nsURI = ePackage.getNsURI();
 			URI uri = URI.createURI(nsURI);
-			projectManager.getPackageDescriptor(uri).configure(myQVT.getResourceSet(), StandaloneProjectMap.LoadFirstStrategy.INSTANCE,
+			testProjectManager.getPackageDescriptor(uri).configure(myQVT.getResourceSet(), StandaloneProjectMap.LoadFirstStrategy.INSTANCE,
 				StandaloneProjectMap.MapToFirstConflictHandler.INSTANCE);
-			projectManager.getPackageDescriptor(uri).configure(myQVT.getMetamodelManager().getASResourceSet(), StandaloneProjectMap.LoadFirstStrategy.INSTANCE,
+			testProjectManager.getPackageDescriptor(uri).configure(myQVT.getMetamodelManager().getASResourceSet(), StandaloneProjectMap.LoadFirstStrategy.INSTANCE,
 				StandaloneProjectMap.MapToFirstConflictHandler.INSTANCE);
 		}
 		try {
 			@SuppressWarnings("unused")
-			Class<? extends Transformer> txClass = myQVT.buildTransformation("atl2qvtr",
-				"ATL2QVTr.qvtr", "qvtr",
-				"http://www.eclipse.org/qvtd/xtext/qvtrelation/tests/atl2qvtr/ATL2QVTr", false); //,
+			Class<? extends Transformer> txClass = myQVT.buildTransformation("qvtr", false); //,
 		} catch (Exception e) {
 			issues.addError(this, "Failed to compile 'ATL2QVTr.qvtr'", null, e, null);
 		}
diff --git a/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/utilities/MyQVT.java b/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/utilities/MyQVT.java
deleted file mode 100644
index 4f6c5b3..0000000
--- a/releng/org.eclipse.qvtd.build/src/org/eclipse/qvtd/build/utilities/MyQVT.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2017 Willink Transformations and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     E.D.Willink - initial API and implementation
- *******************************************************************************/
-package org.eclipse.qvtd.build.utilities;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EcorePackage;
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.ocl.pivot.internal.resource.StandaloneProjectMap;
-import org.eclipse.ocl.pivot.utilities.ClassUtil;
-import org.eclipse.qvtd.compiler.AbstractCompilerChain;
-import org.eclipse.qvtd.compiler.CompilerChain;
-import org.eclipse.qvtd.compiler.CompilerChain.Key;
-import org.eclipse.qvtd.compiler.QVTrCompilerChain;
-import org.eclipse.qvtd.runtime.evaluation.Transformer;
-
-public class MyQVT extends AbstractTestQVT
-{
-	static final @NonNull String PROJECT_NAME = "org.eclipse.qvtd.atl";
-	static final @NonNull URI TESTS_BASE_URI = URI.createPlatformResourceURI("/" + PROJECT_NAME + "/bin/" + PROJECT_NAME.replace(".",  "/"), true);
-	static URI TESTS_JAVA_SRC_URI = URI.createPlatformResourceURI("/" + PROJECT_NAME +"/src-gen", true);
-	static URI TESTS_JAVA_BIN_URI = URI.createPlatformResourceURI("/" + PROJECT_NAME + "/bin", true);
-
-	private Collection<@NonNull GenPackage> usedGenPackages = null;
-
-	public MyQVT(@NonNull String testFolderName) {
-		super(MyQVT.TESTS_BASE_URI, MyQVT.PROJECT_NAME, testFolderName);
-		//
-		// http://www.eclipse.org/emf/2002/Ecore is referenced by just about any model load
-		// Ecore.core is referenced from Ecore.genmodel that is used by the CG to coordinate Ecore objects with their Java classes
-		// therefore suppress diagnostics about confusing usage.
-		//
-		URI ecoreURI = URI.createURI(EcorePackage.eNS_URI);
-		getProjectManager().getPackageDescriptor(ecoreURI).configure(getResourceSet(), StandaloneProjectMap.LoadFirstStrategy.INSTANCE,
-			StandaloneProjectMap.MapToFirstConflictHandler.INSTANCE);
-	}
-
-	public @NonNull GenPackage addUsedGenPackage(@NonNull String resourcePath, @Nullable String fragment) {
-		if (usedGenPackages == null) {
-			usedGenPackages = new ArrayList<>();
-		}
-		URI uri = URI.createPlatformResourceURI(resourcePath, false);
-		if (fragment != null) {
-			uri = uri.appendFragment(fragment);
-		}
-		EObject eObject = getResourceSet().getEObject(uri, true);
-		GenPackage genPackage = ClassUtil.nonNullState((GenPackage)eObject);
-		usedGenPackages.add(genPackage);
-		return genPackage;
-	}
-
-	public @NonNull Class<? extends Transformer> buildTransformation(@NonNull String testName, @NonNull String testFileName, @NonNull String outputName,
-			@NonNull String middleNsURI, boolean isIncremental, @NonNull String @NonNull... genModelFiles) throws Exception {
-		Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> options = createBuildCompilerChainOptions(testName, isIncremental);
-		return doBuild(testFileName, outputName, options, genModelFiles);
-	}
-
-	protected @NonNull Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> createBuildCompilerChainOptions(String testName, boolean isIncremental) {
-		Map<@NonNull String, @Nullable String> genModelOptions = new HashMap<>();
-		genModelOptions.put(CompilerChain.GENMODEL_BASE_PREFIX, MyQVT.PROJECT_NAME + "." + testName);
-		genModelOptions.put(CompilerChain.GENMODEL_COPYRIGHT_TEXT, "Copyright (c) 2015, 2016 Willink Transformations and others.\n;All rights reserved. This program and the accompanying materials\n;are made available under the terms of the Eclipse Public License v1.0\n;which accompanies this distribution, and is available at\n;http://www.eclipse.org/legal/epl-v10.html\n;\n;Contributors:\n;  E.D.Willink - Initial API and implementation");
-		Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> options = new HashMap<>();
-		QVTrCompilerChain.setOption(options, CompilerChain.DEFAULT_STEP, CompilerChain.DEBUG_KEY, true);
-		QVTrCompilerChain.setOption(options, CompilerChain.DEFAULT_STEP, CompilerChain.SAVE_OPTIONS_KEY, MyQVT.defaultSavingOptions);
-		QVTrCompilerChain.setOption(options, CompilerChain.JAVA_STEP, CompilerChain.URI_KEY, MyQVT.TESTS_JAVA_SRC_URI);
-		QVTrCompilerChain.setOption(options, CompilerChain.JAVA_STEP, CompilerChain.JAVA_INCREMENTAL_KEY, isIncremental);
-		QVTrCompilerChain.setOption(options, CompilerChain.JAVA_STEP, CompilerChain.JAVA_GENERATED_DEBUG_KEY, true);
-		QVTrCompilerChain.setOption(options, CompilerChain.CLASS_STEP, CompilerChain.URI_KEY, MyQVT.TESTS_JAVA_BIN_URI);
-		QVTrCompilerChain.setOption(options, CompilerChain.GENMODEL_STEP, CompilerChain.GENMODEL_USED_GENPACKAGES_KEY, usedGenPackages);
-		QVTrCompilerChain.setOption(options, CompilerChain.GENMODEL_STEP, CompilerChain.GENMODEL_OPTIONS_KEY, genModelOptions);
-		return options;
-	}
-
-	@Override
-	protected @NonNull QVTrCompilerChain createCompilerChain(@NonNull URI txURI, @NonNull URI prefixURI,
-			@NonNull Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> options) {
-		return new QVTrCompilerChain(getEnvironmentFactory(), txURI, prefixURI, options);
-	}
-
-	protected @NonNull Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> createCompilerChainOptions(String basePrefix) {
-		Map<@NonNull String, @Nullable String> genModelOptions = new HashMap<>();
-		genModelOptions.put(CompilerChain.GENMODEL_BASE_PREFIX, basePrefix);
-		genModelOptions.put(CompilerChain.GENMODEL_COPYRIGHT_TEXT, "Copyright (c) 2017 Willink Transformations and others.\n;All rights reserved. This program and the accompanying materials\n;are made available under the terms of the Eclipse Public License v1.0\n;which accompanies this distribution, and is available at\n;http://www.eclipse.org/legal/epl-v10.html\n;\n;Contributors:\n;  E.D.Willink - Initial API and implementation");
-		Map<@NonNull String, @Nullable String> traceOptions = new HashMap<@NonNull String, @Nullable String>();
-		//			traceOptions.put(CompilerChain.TRACE_NS_URI, middleNsURI);
-		Map<@NonNull String, @Nullable Map<CompilerChain.@NonNull Key<Object>, @Nullable Object>> options = new HashMap<>();
-		QVTrCompilerChain.setOption(options, CompilerChain.DEFAULT_STEP, CompilerChain.SAVE_OPTIONS_KEY, getSaveOptions());
-		QVTrCompilerChain.setOption(options, CompilerChain.JAVA_STEP, CompilerChain.URI_KEY, null);
-		QVTrCompilerChain.setOption(options, CompilerChain.CLASS_STEP, CompilerChain.URI_KEY, null);
-		QVTrCompilerChain.setOption(options, CompilerChain.TRACE_STEP, CompilerChain.TRACE_OPTIONS_KEY, traceOptions);
-		QVTrCompilerChain.setOption(options, CompilerChain.GENMODEL_STEP, CompilerChain.GENMODEL_USED_GENPACKAGES_KEY, usedGenPackages);
-		QVTrCompilerChain.setOption(options, CompilerChain.GENMODEL_STEP, CompilerChain.GENMODEL_OPTIONS_KEY, genModelOptions);
-		return options;
-	}
-
-	public @NonNull AbstractCompilerChain getCompilerChain() {
-		return ClassUtil.nonNullState(compilerChain);
-	}
-
-	public @NonNull URI getURI(@NonNull String genmodelStep, @NonNull Key<URI> uriKey) {
-		return compilerChain.getURI(CompilerChain.GENMODEL_STEP, CompilerChain.URI_KEY);
-	}
-}
\ No newline at end of file