[549655] QVTr...i works bidirectionally
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/AbstractCompilerChain.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/AbstractCompilerChain.java
index 45c3e13..0e66d9b 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/AbstractCompilerChain.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/AbstractCompilerChain.java
@@ -16,8 +16,10 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.tools.JavaFileObject;
 
@@ -35,10 +37,20 @@
 import org.eclipse.ocl.examples.codegen.dynamic.JavaClasspath;
 import org.eclipse.ocl.examples.codegen.dynamic.JavaFileUtil;
 import org.eclipse.ocl.examples.codegen.dynamic.JavaSourceFileObject;
-import org.eclipse.ocl.pivot.Model;
+import org.eclipse.ocl.pivot.Import;
+import org.eclipse.ocl.pivot.Iteration;
+import org.eclipse.ocl.pivot.LoopExp;
+import org.eclipse.ocl.pivot.Namespace;
+import org.eclipse.ocl.pivot.Operation;
+import org.eclipse.ocl.pivot.OperationCallExp;
+import org.eclipse.ocl.pivot.OppositePropertyCallExp;
+import org.eclipse.ocl.pivot.Property;
+import org.eclipse.ocl.pivot.PropertyCallExp;
 import org.eclipse.ocl.pivot.internal.manager.MetamodelManagerInternal;
 import org.eclipse.ocl.pivot.utilities.ClassUtil;
+import org.eclipse.ocl.pivot.utilities.NameUtil;
 import org.eclipse.ocl.pivot.utilities.PivotUtil;
+import org.eclipse.ocl.pivot.utilities.TreeIterable;
 import org.eclipse.qvtd.codegen.qvti.QVTiCodeGenOptions;
 import org.eclipse.qvtd.codegen.qvti.java.QVTiCodeGenerator;
 import org.eclipse.qvtd.compiler.internal.qvtb2qvts.ScheduleManager;
@@ -59,6 +71,7 @@
 import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreUtil;
 import org.eclipse.qvtd.pivot.qvtimperative.ImperativeModel;
 import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTransformation;
+import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTypedModel;
 import org.eclipse.qvtd.pivot.qvtimperative.QVTimperativePackage;
 import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiEnvironmentFactory;
 import org.eclipse.qvtd.pivot.qvtschedule.MappingRegion;
@@ -262,13 +275,15 @@
 			// Default QVTi strategy ok.
 			Resource iResource = createResource();
 			ScheduleModel scheduleModel = scheduleManager.getScheduleModel();
-			Model model = PivotUtil.createModel(ImperativeModel.class, QVTimperativePackage.Literals.IMPERATIVE_MODEL, null);
+			ImperativeModel model = PivotUtil.createModel(ImperativeModel.class, QVTimperativePackage.Literals.IMPERATIVE_MODEL, null);
+			iResource.getContents().add(model);
 			for (@NonNull RootRegion rootRegion : QVTscheduleUtil.getOwnedRootRegions(scheduleModel)) {
 				ScheduleManager directedScheduleManager = scheduleManager.getDirectedScheduleManager(rootRegion);
 				QVTs2QVTi tx = new QVTs2QVTi(directedScheduleManager, this, environmentFactory);
 				tx.transform(model, rootRegion);
 			}
-			iResource.getContents().add(model);
+			QVTs2QVTi tx = new QVTs2QVTi(scheduleManager, this, environmentFactory);
+			tx.resolveImports(model);
 			saveResource(iResource);
 			ImperativeTransformation transformation = (ImperativeTransformation) getTransformation(iResource);
 			throwCompilerChainExceptionForErrors();
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicPartition2Mapping.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicPartition2Mapping.java
index f1ecb0d..752bd6a 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicPartition2Mapping.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicPartition2Mapping.java
@@ -87,7 +87,6 @@
 import org.eclipse.qvtd.pivot.qvtimperative.ConnectionVariable;
 import org.eclipse.qvtd.pivot.qvtimperative.DeclareStatement;
 import org.eclipse.qvtd.pivot.qvtimperative.GuardParameter;
-import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTypedModel;
 import org.eclipse.qvtd.pivot.qvtimperative.LoopVariable;
 import org.eclipse.qvtd.pivot.qvtimperative.Mapping;
 import org.eclipse.qvtd.pivot.qvtimperative.MappingParameter;
@@ -1542,7 +1541,7 @@
 	private @NonNull GuardParameter createGuardParameter(@NonNull Node guardNode) {
 		ClassDatum classDatum = QVTscheduleUtil.getClassDatum(guardNode);
 		Type variableType = guardNode.getClassDatum().getPrimaryClass();
-		ImperativeTypedModel iTypedModel = ClassUtil.nonNullState(visitor.getQVTiTypedModel(classDatum.getReferredTypedModel()));
+		TypedModel iTypedModel = ClassUtil.nonNullState(visitor.getQVTiTypedModel(classDatum.getReferredTypedModel()));
 		GuardParameter guardParameter = helper.createGuardParameter(getSafeName(guardNode), iTypedModel, variableType, true);
 		Property successProperty = null;
 
@@ -1845,7 +1844,7 @@
 				}
 				ClassDatum classDatum = node.getClassDatum();
 				TypedModel pTypedModel = classDatum.getReferredTypedModel();
-				ImperativeTypedModel iTypedModel = ClassUtil.nonNullState(visitor.getQVTiTypedModel(pTypedModel));
+				TypedModel iTypedModel = ClassUtil.nonNullState(visitor.getQVTiTypedModel(pTypedModel));
 				NewStatement newStatement = helper.createNewStatement(getSafeName(node), iTypedModel, classDatum.getPrimaryClass());
 				newStatement.setOwnedExpression(constructor);
 				newStatement.setIsContained(node.isContained());
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/LoadingPartition2Mapping.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/LoadingPartition2Mapping.java
index ffe4566..f3f8981 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/LoadingPartition2Mapping.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/LoadingPartition2Mapping.java
@@ -35,7 +35,6 @@
 import org.eclipse.qvtd.pivot.qvtimperative.AppendParameter;
 import org.eclipse.qvtd.pivot.qvtimperative.BufferStatement;
 import org.eclipse.qvtd.pivot.qvtimperative.EntryPoint;
-import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTypedModel;
 import org.eclipse.qvtd.pivot.qvtimperative.MappingParameter;
 import org.eclipse.qvtd.pivot.qvtimperative.Statement;
 import org.eclipse.qvtd.pivot.qvtschedule.ClassDatum;
@@ -265,14 +264,14 @@
 		//
 		//	Create domains
 		//
-		Set<@NonNull ImperativeTypedModel> checkableTypedModels = new HashSet<>();
+		Set<@NonNull TypedModel> checkableTypedModels = new HashSet<>();
 		for (@NonNull Node node : partition.getPartialNodes()) {
 			ClassDatum classDatum = node.getClassDatum();
 			if (classDatum.isCheckable()) {
-				TypedModel qvtmTypedModel = classDatum.getReferredTypedModel();
-				ImperativeTypedModel qvtiTypedModel = visitor.getQVTiTypedModel(qvtmTypedModel);
-				if (qvtiTypedModel != null) {
-					checkableTypedModels.add(qvtiTypedModel);
+				TypedModel asTypedModel = classDatum.getReferredTypedModel();
+				TypedModel iTypedModel = visitor.getQVTiTypedModel(asTypedModel);
+				if (iTypedModel != null) {
+					checkableTypedModels.add(iTypedModel);
 				}
 			}
 		}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/QVTs2QVTi.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/QVTs2QVTi.java
index 1c50e91..ff2cde2 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/QVTs2QVTi.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/QVTs2QVTi.java
@@ -12,8 +12,10 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.eclipse.emf.ecore.EObject;
@@ -22,22 +24,28 @@
 import org.eclipse.ocl.pivot.Iteration;
 import org.eclipse.ocl.pivot.LoopExp;
 import org.eclipse.ocl.pivot.Model;
-import org.eclipse.ocl.pivot.NamedElement;
 import org.eclipse.ocl.pivot.Namespace;
 import org.eclipse.ocl.pivot.Operation;
 import org.eclipse.ocl.pivot.OperationCallExp;
 import org.eclipse.ocl.pivot.OppositePropertyCallExp;
+import org.eclipse.ocl.pivot.Package;
 import org.eclipse.ocl.pivot.Property;
 import org.eclipse.ocl.pivot.PropertyCallExp;
 import org.eclipse.ocl.pivot.utilities.ClassUtil;
 import org.eclipse.ocl.pivot.utilities.NameUtil;
+import org.eclipse.ocl.pivot.utilities.PivotUtil;
 import org.eclipse.ocl.pivot.utilities.TreeIterable;
 import org.eclipse.qvtd.compiler.ProblemHandler;
 import org.eclipse.qvtd.compiler.internal.qvtb2qvts.ScheduleManager;
 import org.eclipse.qvtd.pivot.qvtbase.Transformation;
+import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
 import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseEnvironmentFactory;
+import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil;
+import org.eclipse.qvtd.pivot.qvtimperative.ImperativeModel;
+import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTransformation;
 import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTypedModel;
 import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeHelper;
+import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeUtil;
 import org.eclipse.qvtd.pivot.qvtschedule.RootRegion;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.SymbolNameReservation;
@@ -57,7 +65,74 @@
 		assert scheduleManager.getEnvironmentFactory() == environmentFactory;
 	}
 
-	protected void resolveImports(@NonNull Model model) {
+	protected @NonNull Package getPackage(@NonNull ImperativeModel iModel, org.eclipse.ocl.pivot.@NonNull Package asPackage) {
+		List<org.eclipse.ocl.pivot.@NonNull Package> iPackages;
+		org.eclipse.ocl.pivot.Package asParentPackage = asPackage.getOwningPackage();
+		if (asParentPackage != null) {
+			org.eclipse.ocl.pivot.@NonNull Package iParentPackage = getPackage(iModel, asParentPackage);
+			iPackages = QVTimperativeUtil.Internal.getOwnedPackagesList(iParentPackage);
+		}
+		else {
+			iPackages = QVTimperativeUtil.Internal.getOwnedPackagesList(iModel);
+		}
+		String name = PivotUtil.getName(asPackage);
+		org.eclipse.ocl.pivot.Package iPackage = NameUtil.getNameable(iPackages, name);
+		if (iPackage == null) {
+			iPackage = createPackage(name, asPackage.getNsPrefix(), asPackage.getURI());
+			iPackages.add(iPackage);
+		}
+		return iPackage;
+	}
+
+	public @NonNull ProblemHandler getProblemHandler() {
+		return problemHandler;
+	}
+
+	public @NonNull ScheduleManager getScheduleManager() {
+		return scheduleManager;
+	}
+
+	protected @NonNull ImperativeTransformation getTransformation(@NonNull ImperativeModel iModel, @NonNull Transformation asTransformation) {
+		org.eclipse.ocl.pivot.Package asParentPackage = ClassUtil.nonNullState(asTransformation.getOwningPackage());
+		org.eclipse.ocl.pivot.@NonNull Package iParentPackage = getPackage(iModel, asParentPackage);
+		List<org.eclipse.ocl.pivot.@NonNull Class> iClasses = QVTimperativeUtil.Internal.getOwnedClassesList(iParentPackage);
+		String name = PivotUtil.getName(asTransformation);
+		org.eclipse.ocl.pivot.Class iTransformation = NameUtil.getNameable(iClasses, name);
+		if ((iTransformation == null) || !(iTransformation instanceof ImperativeTransformation)) {
+			iTransformation = createTransformation(name);
+			iClasses.add(iTransformation);
+			for (@NonNull TypedModel qvtmTypedModel : QVTbaseUtil.getModelParameters(asTransformation)) {
+				ImperativeTypedModel qvtiTypedModel = createTypedModel(PivotUtil.getName(qvtmTypedModel));
+				qvtiTypedModel.getUsedPackage().addAll(qvtmTypedModel.getUsedPackage());
+				qvtiTypedModel.setIsPrimitive(qvtmTypedModel.isIsPrimitive());
+				qvtiTypedModel.setIsTrace(qvtmTypedModel.isIsTrace());
+			}
+		}
+		return (ImperativeTransformation) iTransformation;
+	}
+
+	protected @NonNull TypedModel getTypedModel(@NonNull ImperativeTransformation iTransformation, @NonNull TypedModel asTypedModel) {
+		TypedModel iTypedModel = NameUtil.getNameable(QVTimperativeUtil.getModelParameters(iTransformation), PivotUtil.getName(asTypedModel));
+		if (iTypedModel == null) {
+			iTypedModel = createTypedModel(PivotUtil.getName(asTypedModel));
+			iTypedModel.getUsedPackage().addAll(asTypedModel.getUsedPackage());
+			iTypedModel.setIsPrimitive(asTypedModel.isIsPrimitive());
+			iTypedModel.setIsTrace(asTypedModel.isIsTrace());
+			iTransformation.getModelParameter().add(iTypedModel);
+		}
+		return iTypedModel;
+	}
+
+	protected @NonNull Map<@NonNull TypedModel, @NonNull TypedModel> getTypedModels(@NonNull ImperativeTransformation iTransformation, @NonNull Transformation asTransformation) {
+		@NonNull Map<@NonNull TypedModel, @NonNull TypedModel> asTypedModel2qvtiTypedModel = new HashMap<>();
+		for (@NonNull TypedModel asTypedModel : QVTbaseUtil.getModelParameters(asTransformation)) {
+			TypedModel iTypedModel = getTypedModel(iTransformation, asTypedModel);
+			asTypedModel2qvtiTypedModel.put(asTypedModel, iTypedModel);
+		}
+		return asTypedModel2qvtiTypedModel;
+	}
+
+	public void resolveImports(@NonNull ImperativeModel model) {
 		Set<@NonNull Namespace> importedNamespaces = new HashSet<@NonNull Namespace>();
 		for (EObject eObject : new TreeIterable(model, false)) {
 			if (eObject instanceof ImperativeTypedModel) {
@@ -131,28 +206,13 @@
 		}
 	}
 
-	protected void resolveTransformation(@NonNull Model model, @NonNull RootRegion rootRegion) {
+	public @NonNull Model transform(@NonNull ImperativeModel model, @NonNull RootRegion rootRegion) {
 		SymbolNameReservation symbolNameReservation = scheduleManager.getScheduleModel().getSymbolNameAdapter();
-		Transformation transformation = QVTscheduleUtil.getReferredTransformation(rootRegion);
-		QVTs2QVTiVisitor visitor = new QVTs2QVTiVisitor(scheduleManager, problemHandler, this, transformation, symbolNameReservation);
-		Transformation qvtiTransformation = (Transformation)rootRegion.accept(visitor);
-		NamedElement qvtiChild = qvtiTransformation;
-		for (org.eclipse.ocl.pivot.Package qvtmPackage = transformation.getOwningPackage(); qvtmPackage != null; qvtmPackage = qvtmPackage.getOwningPackage()) {
-			org.eclipse.ocl.pivot.@NonNull Package qvtiPackage = createPackage(ClassUtil.nonNull(qvtmPackage.getName()), qvtmPackage.getNsPrefix(), qvtmPackage.getURI());
-			if (qvtiChild instanceof Transformation) {
-				qvtiPackage.getOwnedClasses().add((Transformation)qvtiChild);
-			}
-			else {
-				qvtiPackage.getOwnedPackages().add((org.eclipse.ocl.pivot.Package)qvtiChild);
-			}
-			qvtiChild = qvtiPackage;
-		}
-		model.getOwnedPackages().add((org.eclipse.ocl.pivot.Package)qvtiChild);
-	}
-
-	public @NonNull Model transform(@NonNull Model model, @NonNull RootRegion rootRegion) {
-		resolveTransformation(model, rootRegion);
-		resolveImports(model);
+		Transformation asTransformation = QVTscheduleUtil.getReferredTransformation(rootRegion);
+		ImperativeTransformation iTransformation = getTransformation(model, asTransformation);
+		Map<@NonNull TypedModel, @NonNull TypedModel> asTypedModel2qvtiTypedModel = getTypedModels(iTransformation, asTransformation);
+		QVTs2QVTiVisitor visitor = new QVTs2QVTiVisitor(this, symbolNameReservation, asTypedModel2qvtiTypedModel);
+		rootRegion.accept(visitor);
 		return model;
 	}
 }
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/QVTs2QVTiVisitor.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/QVTs2QVTiVisitor.java
index c265d5f..f05b060 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/QVTs2QVTiVisitor.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/QVTs2QVTiVisitor.java
@@ -36,7 +36,6 @@
 import org.eclipse.ocl.pivot.utilities.EnvironmentFactory;
 import org.eclipse.ocl.pivot.utilities.MetamodelManager;
 import org.eclipse.ocl.pivot.utilities.NameUtil;
-import org.eclipse.qvtd.compiler.CompilerProblem;
 import org.eclipse.qvtd.compiler.ProblemHandler;
 import org.eclipse.qvtd.compiler.internal.qvtb2qvts.ScheduleManager;
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.ConnectionManager;
@@ -45,17 +44,15 @@
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.partitioner.PartitionsAnalysis;
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.partitioner.RootPartitionAnalysis;
 import org.eclipse.qvtd.compiler.internal.utilities.CompilerUtil;
-import org.eclipse.qvtd.pivot.qvtbase.Domain;
 import org.eclipse.qvtd.pivot.qvtbase.Function;
 import org.eclipse.qvtd.pivot.qvtbase.FunctionParameter;
-import org.eclipse.qvtd.pivot.qvtbase.Rule;
 import org.eclipse.qvtd.pivot.qvtbase.Transformation;
 import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
 import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil;
 import org.eclipse.qvtd.pivot.qvtimperative.EntryPoint;
-import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTypedModel;
+//import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTypedModel;
 import org.eclipse.qvtd.pivot.qvtimperative.Mapping;
-import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeHelper;
+import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeUtil;
 import org.eclipse.qvtd.pivot.qvtschedule.ClassDatum;
 import org.eclipse.qvtd.pivot.qvtschedule.Edge;
 import org.eclipse.qvtd.pivot.qvtschedule.EdgeConnection;
@@ -99,17 +96,16 @@
 	}
 
 	protected final @NonNull ScheduleManager scheduleManager;
-	protected final @NonNull QVTimperativeHelper helper;
+	protected final @NonNull QVTs2QVTi qvts2qvti;
 	protected final @NonNull EnvironmentFactory environmentFactory;
-	protected final @NonNull ProblemHandler problemHandler;
-	protected final @NonNull Transformation qvtmTransformation;
+	protected final @NonNull Transformation asTransformation;
 	protected final @NonNull SymbolNameReservation symbolNameReservation;
 
-	protected final @NonNull Transformation qvtiTransformation;
-	protected final @NonNull Map<@NonNull TypedModel, @NonNull ImperativeTypedModel> qvtmTypedModel2qvtiTypedModel = new HashMap<>();
-	protected final @NonNull List<@NonNull ImperativeTypedModel> checkableTypedModels = new ArrayList<>();
-	protected final @NonNull List<@NonNull ImperativeTypedModel> checkableAndEnforceableTypedModels = new ArrayList<>();
-	protected final @NonNull List<@NonNull ImperativeTypedModel> enforceableTypedModels = new ArrayList<>();
+	protected final @NonNull Transformation iTransformation;
+	protected final @NonNull Map<@NonNull TypedModel, @NonNull TypedModel> asTypedModel2iTypedModel;
+	protected final @NonNull List<@NonNull TypedModel> checkableTypedModels = new ArrayList<>();
+	protected final @NonNull List<@NonNull TypedModel> checkableAndEnforceableTypedModels = new ArrayList<>();
+	protected final @NonNull List<@NonNull TypedModel> enforceableTypedModels = new ArrayList<>();
 	protected final @NonNull Map<@NonNull Partition, @NonNull AbstractPartition2Mapping> partition2partition2mapping = new HashMap<>();
 	private @Nullable Set<@NonNull String> reservedNames = null;
 	private @NonNull Map<@NonNull Operation, @NonNull Operation> qvtmOperation2qvtiOperation = new HashMap<>();
@@ -117,21 +113,23 @@
 	private final @NonNull Set<@NonNull Transformation> otherTransformations = new HashSet<>();	// Workaround Bug 481658
 	private final @NonNull Map<@NonNull String, @NonNull Operation> name2operation = new HashMap<>();	// Workaround Bug 481658
 
-	private /*@LazyNonNull*/ ImperativeTypedModel qvtiMiddleTypedModel = null;
+	private /*@LazyNonNull*/ TypedModel iMiddleTypedModel = null;
 	private @NonNull Map<@NonNull ClassDatum, @NonNull Function> classDatum2keyFunction = new HashMap<>();
 
-	public QVTs2QVTiVisitor(@NonNull ScheduleManager scheduleManager, @NonNull ProblemHandler problemHandler, @NonNull QVTimperativeHelper helper, @NonNull Transformation qvtmTransformation, @NonNull SymbolNameReservation symbolNameReservation) {
+	public QVTs2QVTiVisitor(@NonNull QVTs2QVTi qvts2qvti, @NonNull SymbolNameReservation symbolNameReservation, @NonNull Map<@NonNull TypedModel, @NonNull TypedModel> asTypedModel2iTypedModel) {
 		super(null);
-		this.scheduleManager = scheduleManager;
-		this.helper = helper;
-		this.environmentFactory = helper.getEnvironmentFactory();
-		this.problemHandler = problemHandler;
-		this.qvtmTransformation = qvtmTransformation;
+		this.scheduleManager = qvts2qvti.getScheduleManager();
+		this.qvts2qvti = qvts2qvti;
+		this.environmentFactory = qvts2qvti.getEnvironmentFactory();
+		this.asTransformation = QVTbaseUtil.getContainingTransformation(asTypedModel2iTypedModel.keySet().iterator().next());
 		this.symbolNameReservation = symbolNameReservation;
-		String transformationName = qvtmTransformation.getName();
-		assert transformationName != null;
-		qvtiTransformation = helper.createTransformation(transformationName);
-		createTypedModels();
+		this.iTransformation = QVTimperativeUtil.getContainingTransformation(asTypedModel2iTypedModel.values().iterator().next());
+		this.asTypedModel2iTypedModel = asTypedModel2iTypedModel;
+		for (@NonNull TypedModel iTypedModel : asTypedModel2iTypedModel.values()) {
+			if (iTypedModel.isIsTrace()) {
+				iMiddleTypedModel = iTypedModel;
+			}
+		}
 		//		analyzeConnections();
 	}
 
@@ -181,10 +179,6 @@
 		}
 	} */
 
-	public void addProblem(@NonNull CompilerProblem problem) {
-		problemHandler.addProblem(problem);
-	}
-
 	public @Nullable Operation create(@Nullable Operation pOperation) {
 		if (pOperation == null) {
 			return null;
@@ -192,11 +186,11 @@
 		Operation iOperation = qvtmOperation2qvtiOperation.get(pOperation);
 		if (iOperation == null) {
 			Transformation containingTransformation = QVTbaseUtil.basicGetContainingTransformation(pOperation);
-			if (containingTransformation == qvtmTransformation) {
+			if (containingTransformation == asTransformation) {
 				iOperation = EcoreUtil.copy(pOperation);
 				assert iOperation != null;
 				qvtmOperation2qvtiOperation.put(pOperation, iOperation);
-				qvtiTransformation.getOwnedOperations().add(iOperation);
+				iTransformation.getOwnedOperations().add(iOperation);
 			}
 			else {					// FIXME Foreign queries ...
 				// FIXME working around Bug 481658
@@ -208,7 +202,7 @@
 					iOperation = EcoreUtil.copy(pOperation);
 					assert iOperation != null;
 					qvtmOperation2qvtiOperation.put(pOperation, iOperation);
-					qvtiTransformation.getOwnedOperations().add(iOperation);
+					iTransformation.getOwnedOperations().add(iOperation);
 				}
 				else {
 					iOperation = pOperation;
@@ -234,9 +228,9 @@
 			//
 			for (@NonNull PropertyDatum propertyDatum : propertyDatums) {
 				Property keyProperty = QVTscheduleUtil.getReferredProperty(propertyDatum);
-				FunctionParameter cParameter = helper.createFunctionParameter(keyProperty);
+				FunctionParameter cParameter = qvts2qvti.createFunctionParameter(keyProperty);
 				asParameters.add(cParameter);
-				ShadowPart asShadowPart = helper.createShadowPart(keyProperty, helper.createVariableExp(cParameter));
+				ShadowPart asShadowPart = qvts2qvti.createShadowPart(keyProperty, qvts2qvti.createVariableExp(cParameter));
 				asShadowParts.add(asShadowPart);
 			}
 			Collections.sort(asParameters, NameUtil.NAMEABLE_COMPARATOR);
@@ -258,10 +252,10 @@
 					}
 				}
 			} */
-			Function asFunction = helper.createFunction(functionName, primaryClass, true, asParameters);
-			OCLExpression asShadowExp = helper.createShadowExp(primaryClass, asShadowParts);
+			Function asFunction = qvts2qvti.createFunction(functionName, primaryClass, true, asParameters);
+			OCLExpression asShadowExp = qvts2qvti.createShadowExp(primaryClass, asShadowParts);
 			asFunction.setQueryExpression(asShadowExp);
-			qvtiTransformation.getOwnedOperations().add(asFunction);
+			iTransformation.getOwnedOperations().add(asFunction);
 			classDatum2keyFunction.put(classDatum, asFunction);
 		}
 	}
@@ -274,13 +268,13 @@
 		if (partition instanceof LoadingPartition) {
 			String mappingName = partition.getSymbolName();
 			assert mappingName != null;
-			EntryPoint entryPoint = helper.createEntryPoint(mappingName);
-			for (@NonNull TypedModel typedModel : QVTbaseUtil.getModelParameters(qvtmTransformation)) {
+			EntryPoint entryPoint = qvts2qvti.createEntryPoint(mappingName);
+			for (@NonNull TypedModel typedModel : QVTbaseUtil.getModelParameters(asTransformation)) {
 				if (scheduleManager.isInput(typedModel) && !typedModel.isIsPrimitive()) {
-					entryPoint.getCheckedTypedModels().add(qvtmTypedModel2qvtiTypedModel.get(typedModel));
+					entryPoint.getCheckedTypedModels().add(asTypedModel2iTypedModel.get(typedModel));
 				}
 				if (scheduleManager.isOutput(typedModel)) {
-					entryPoint.getEnforcedTypedModels().add(qvtmTypedModel2qvtiTypedModel.get(typedModel));
+					entryPoint.getEnforcedTypedModels().add(asTypedModel2iTypedModel.get(typedModel));
 				}
 			}
 			partition2mapping = new LoadingPartition2Mapping(this, entryPoint, (LoadingPartition)partition);
@@ -288,12 +282,12 @@
 		else {
 			String mappingName = partition.getSymbolName();
 			assert mappingName != null;
-			Mapping mapping = helper.createMapping(mappingName);
+			Mapping mapping = qvts2qvti.createMapping(mappingName);
 			partition2mapping = new BasicPartition2Mapping(this, mapping, (MappingPartitionAnalysis<?>) partitionAnalysis);
 		}
 		partition2mapping.synthesizeLocalStatements();
 		partition2partition2mapping.put(partition, partition2mapping);
-		qvtiTransformation.getRule().add(partition2mapping.getMapping());
+		iTransformation.getRule().add(partition2mapping.getMapping());
 		visitPartition(partition);
 		//		for (@SuppressWarnings("null")@NonNull Region childRegion : region.getCalledRegions()) {
 		//			if (region2region2mapping.get(childRegion) == null) {
@@ -302,58 +296,6 @@
 		//		}
 	}
 
-	protected void createTypedModels() {
-		for (TypedModel qvtmTypedModel : qvtmTransformation.getModelParameter()) {
-			String typedModelName = qvtmTypedModel.getName();
-			assert typedModelName != null;
-			ImperativeTypedModel qvtiTypedModel = helper.createTypedModel(typedModelName);
-			qvtiTypedModel.getUsedPackage().addAll(qvtmTypedModel.getUsedPackage());
-			boolean isPrimitive = qvtmTypedModel.isIsPrimitive();
-			boolean isTrace = qvtmTypedModel.isIsTrace();
-			qvtiTypedModel.setIsPrimitive(isPrimitive);
-			qvtiTypedModel.setIsTrace(isTrace);
-			if (isTrace) {
-				assert qvtiMiddleTypedModel == null;
-				qvtiMiddleTypedModel = qvtiTypedModel;
-			}
-			qvtmTypedModel2qvtiTypedModel.put(qvtmTypedModel, qvtiTypedModel);
-			qvtiTransformation.getModelParameter().add(qvtiTypedModel);
-		}
-		for (@NonNull Rule rule : QVTbaseUtil.getRule(qvtmTransformation)) {
-			for (@NonNull Domain domain : QVTbaseUtil.getOwnedDomains(rule)) {
-				TypedModel typedModel = domain.getTypedModel();
-				if (typedModel != null) {
-					/*	if (scheduleManager.isInput(domain)) {
-						ImperativeTypedModel checkableTypedModel = qvtmTypedModel2qvtiTypedModel.get(typedModel);
-						if ((checkableTypedModel != null) && !checkableAndEnforceableTypedModels.contains(checkableTypedModel)) {
-							checkableTypedModel.setIsChecked(true);
-							if (enforceableTypedModels.contains(checkableTypedModel)) {
-								checkableAndEnforceableTypedModels.add(checkableTypedModel);
-								enforceableTypedModels.remove(checkableTypedModel);
-							}
-							else if (!checkableTypedModels.contains(checkableTypedModel)) {
-								checkableTypedModels.add(checkableTypedModel);
-							}
-						}
-					}
-					if (scheduleManager.isOutput(domain)) {
-						ImperativeTypedModel enforceableTypedModel = qvtmTypedModel2qvtiTypedModel.get(typedModel);
-						if ((enforceableTypedModel != null) && !checkableAndEnforceableTypedModels.contains(enforceableTypedModel)) {
-							enforceableTypedModel.setIsEnforced(true);
-							if (checkableTypedModels.contains(enforceableTypedModel)) {
-								checkableAndEnforceableTypedModels.add(enforceableTypedModel);
-								checkableTypedModels.remove(enforceableTypedModel);
-							}
-							else if (!enforceableTypedModels.contains(enforceableTypedModel)) {
-								enforceableTypedModels.add(enforceableTypedModel);
-							}
-						}
-					} */
-				}
-			}
-		}
-	}
-
 	protected @NonNull Map<@NonNull ClassDatum, Set<@NonNull PropertyDatum>> gatherKeyCalls(List<@NonNull PartialRegionAnalysis<@NonNull PartitionsAnalysis>> sortedPartitionAnalyses) {
 		Map<@NonNull ClassDatum, Set<@NonNull PropertyDatum>> keyedClassDatum2propertyDatums = new HashMap<>();
 		for (@NonNull PartialRegionAnalysis<@NonNull PartitionsAnalysis> partitionAnalysis : sortedPartitionAnalyses) {
@@ -430,12 +372,12 @@
 		return environmentFactory.getIdResolver().getOperation(oclAnyEqualsId);
 	}
 
-	public @Nullable ImperativeTypedModel getQVTiTypedModel(@Nullable TypedModel qvtmTypedModel) {
-		if (qvtmTypedModel == null) {
-			assert qvtiMiddleTypedModel != null;
-			return qvtiMiddleTypedModel;
+	public @Nullable TypedModel getQVTiTypedModel(@Nullable TypedModel asTypedModel) {
+		if (asTypedModel == null) {
+			assert iMiddleTypedModel != null;
+			return iMiddleTypedModel;
 		}
-		return qvtmTypedModel2qvtiTypedModel.get(qvtmTypedModel);
+		return asTypedModel2iTypedModel.get(asTypedModel);
 	}
 
 	public @NonNull AbstractPartition2Mapping getPartition2Mapping(@NonNull Partition partition) {
@@ -446,7 +388,7 @@
 	}
 
 	public @NonNull ProblemHandler getProblemHandler() {
-		return problemHandler;
+		return qvts2qvti.getProblemHandler();
 	}
 
 	public @NonNull Set<@NonNull String> getReservedNames() {
@@ -455,15 +397,15 @@
 			reservedNames = reservedNames2 = new HashSet<>();
 			org.eclipse.ocl.pivot.Package standardLibraryPackage = getStandardLibrary().getPackage();
 			gatherReservedPackageNames(reservedNames2, Collections.singletonList(standardLibraryPackage));
-			reservedNames2.add(ClassUtil.nonNull(qvtmTransformation.getName()));
-			for (TypedModel typedModel : qvtmTransformation.getModelParameter()) {
+			reservedNames2.add(ClassUtil.nonNull(asTransformation.getName()));
+			for (TypedModel typedModel : asTransformation.getModelParameter()) {
 				reservedNames2.add(ClassUtil.nonNullState(typedModel.getName()));
 				gatherReservedPackageNames(reservedNames2, typedModel.getUsedPackage());
 			}
-			for (Operation operation : qvtmTransformation.getOwnedOperations()) {
+			for (Operation operation : asTransformation.getOwnedOperations()) {
 				reservedNames2.add(ClassUtil.nonNull(operation.getName()));
 			}
-			for (Property property : qvtmTransformation.getOwnedProperties()) {
+			for (Property property : asTransformation.getOwnedProperties()) {
 				reservedNames2.add(ClassUtil.nonNull(property.getName()));
 			}
 		}
@@ -479,7 +421,7 @@
 	}
 
 	public @NonNull Transformation getTransformation() {
-		return qvtiTransformation;
+		return iTransformation;
 	}
 
 	public @NonNull String reserveSymbolName(@NonNull SymbolNameBuilder symbolNameBuilder, @NonNull Object object) {
@@ -652,7 +594,7 @@
 		for (@NonNull Namespace importedNamespace : importedNamespaces) {
 			ownedImports.add(createImport(null, importedNamespace));
 		} */
-		return qvtiTransformation;
+		return null;
 	}
 
 	@Override
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeHelper.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeHelper.java
index 0ad27b8..029814a 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeHelper.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeHelper.java
@@ -108,10 +108,10 @@
 		return entryPoint;
 	}
 
-	public @NonNull GuardParameter createGuardParameter(@NonNull String name, @NonNull ImperativeTypedModel typedModel, @NonNull Type type, boolean isRequired) {
+	public @NonNull GuardParameter createGuardParameter(@NonNull String name, @NonNull TypedModel typedModel, @NonNull Type type, boolean isRequired) {
 		GuardParameter asVariable = QVTimperativeFactory.eINSTANCE.createGuardParameter();
 		asVariable.setName(name);
-		asVariable.setReferredTypedModel(typedModel);
+		asVariable.setReferredTypedModel((ImperativeTypedModel) typedModel);
 		setType(asVariable, type, isRequired);
 		return asVariable;
 	}
@@ -163,10 +163,10 @@
 		return ml;
 	}
 
-	public @NonNull NewStatement createNewStatement(@NonNull String name, @NonNull ImperativeTypedModel typedModel, @NonNull Type type) {
+	public @NonNull NewStatement createNewStatement(@NonNull String name, @NonNull TypedModel typedModel, @NonNull Type type) {
 		NewStatement newStatement = QVTimperativeFactory.eINSTANCE.createNewStatement();
 		newStatement.setName(name);
-		newStatement.setReferredTypedModel(typedModel);
+		newStatement.setReferredTypedModel((ImperativeTypedModel) typedModel);
 		newStatement.setType(type);
 		newStatement.setIsRequired(true);
 		return newStatement;