diff --git a/plugins/org.eclipse.qvtd.compiler/META-INF/MANIFEST.MF b/plugins/org.eclipse.qvtd.compiler/META-INF/MANIFEST.MF
index 397f303..3f3ed1f 100644
--- a/plugins/org.eclipse.qvtd.compiler/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.qvtd.compiler/META-INF/MANIFEST.MF
@@ -32,6 +32,7 @@
  org.eclipse.qvtd.compiler.internal.qvts2qvts.merger,
  org.eclipse.qvtd.compiler.internal.qvts2qvts.partitioner,
  org.eclipse.qvtd.compiler.internal.qvts2qvts.splitter,
+ org.eclipse.qvtd.compiler.internal.qvts2qvts.utilities,
  org.eclipse.qvtd.compiler.internal.qvtu2qvtm,
  org.eclipse.qvtd.compiler.internal.templates.model,
  org.eclipse.qvtd.compiler.internal.utilities
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/AbstractRegion2Mapping.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/AbstractRegion2Mapping.java
index 9773f2b..ed7ac3e 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/AbstractRegion2Mapping.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/AbstractRegion2Mapping.java
@@ -50,6 +50,7 @@
 import org.eclipse.qvtd.pivot.qvtimperative.MappingParameter;
 import org.eclipse.qvtd.pivot.qvtimperative.MappingParameterBinding;
 import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeHelper;
+import org.eclipse.qvtd.pivot.qvtschedule.BasicMappingRegion;
 import org.eclipse.qvtd.pivot.qvtschedule.Node;
 import org.eclipse.qvtd.pivot.qvtschedule.NodeConnection;
 import org.eclipse.qvtd.pivot.qvtschedule.Region;
@@ -60,7 +61,9 @@
 	protected final @NonNull QVTs2QVTiVisitor visitor;
 	protected final @NonNull QVTimperativeHelper helper;
 	protected final @NonNull Region region;
+	@SuppressWarnings("unused")private final @NonNull String regionName;
 	protected final @NonNull Mapping mapping;
+	@SuppressWarnings("unused")private final @NonNull String mappingName;
 
 	/**
 	 * Mapping from QVTm expression to Schedule Node.
@@ -86,9 +89,14 @@
 		this.visitor = visitor;
 		this.helper = new QVTimperativeHelper(visitor.getEnvironmentFactory());
 		this.region = region;
-		String name = region.getSymbolName();
-		assert name != null;
-		this.mapping = helper.createMapping(name);
+		this.regionName = RegionUtil.getName(region);
+		String mappingName = region.getSymbolName();
+		assert mappingName != null;
+		this.mapping = helper.createMapping(mappingName);
+		this.mappingName = mappingName;
+		if (region instanceof BasicMappingRegion) {
+			this.mapping.setIsAbstract(((BasicMappingRegion)region).getReferredMapping().isIsAbstract());
+		}
 		this.names = new HashSet<@NonNull String>(visitor.getReservedNames());
 		for (@NonNull Node node : RegionUtil.getOwnedNodes(region)) {
 			for (TypedElement typedElement : node.getTypedElements()) {
@@ -144,6 +152,10 @@
 		}
 	}
 
+	public @NonNull MappingCall createMappingCall(@NonNull List<@NonNull MappingParameterBinding> mappingParameterBindings) {
+		return helper.createMappingCall(getMapping(), mappingParameterBindings);
+	}
+
 	protected @NonNull CallExp createOclAsTypeCallExp(@NonNull OCLExpression asSource, @NonNull Type asType) {
 		ScheduleManager scheduleManager = RegionUtil.getScheduleManager(getRegion());
 		CompleteClass completeClass = scheduleManager.getEnvironmentFactory().getCompleteModel().getCompleteClass(asType);
@@ -151,8 +163,6 @@
 		return helper.createOperationCallExp(asSource, "oclAsType", asTypeExp);
 	}
 
-	public abstract void createSchedulingStatements();
-
 	protected int getCollectionDepth(@NonNull Type type) {
 		if (type instanceof CollectionType) {
 			Type elementType = ((CollectionType)type).getElementType();
@@ -279,12 +289,11 @@
 		return false;
 	}
 
+	public abstract void synthesizeCallStatements();
+	public abstract void synthesizeLocalStatements();
+
 	@Override
 	public String toString() {
 		return mapping.toString();
 	}
-
-	public @NonNull MappingCall createMappingCall(@NonNull List<@NonNull MappingParameterBinding> mappingParameterBindings) {
-		return helper.createMappingCall(getMapping(), mappingParameterBindings);
-	}
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java
index 9a465c5..0ad9f4b 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java
@@ -13,7 +13,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -30,6 +29,7 @@
 import org.eclipse.ocl.pivot.CollectionLiteralPart;
 import org.eclipse.ocl.pivot.CollectionRange;
 import org.eclipse.ocl.pivot.CollectionType;
+import org.eclipse.ocl.pivot.CompleteClass;
 import org.eclipse.ocl.pivot.EnumLiteralExp;
 import org.eclipse.ocl.pivot.IfExp;
 import org.eclipse.ocl.pivot.IterateExp;
@@ -71,6 +71,7 @@
 import org.eclipse.qvtd.compiler.internal.qvtm2qvts.ScheduleManager;
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.ClassDatumAnalysis;
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.RegionAnalysis;
+import org.eclipse.qvtd.compiler.internal.qvts2qvts.utilities.ReachabilityForest;
 import org.eclipse.qvtd.pivot.qvtbase.Function;
 import org.eclipse.qvtd.pivot.qvtbase.Transformation;
 import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
@@ -105,6 +106,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.Region;
 import org.eclipse.qvtd.pivot.qvtschedule.Role;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleConstants;
+import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
@@ -117,19 +119,8 @@
 	 * to build a linear edge traversal schedule in which unconditional checks that may fail appear
 	 * as early as possible.
 	 */
-	private class OldEdgeSchedule implements Comparator<@NonNull Edge>
+	private class OldEdgeSchedule
 	{
-		protected final @NonNull Region region;
-
-		private @NonNull Map<@NonNull Node, @NonNull Integer> node2depth;
-
-		private final @NonNull List<@NonNull Edge> oldUnconditionalEdges;
-
-		/**
-		 * All properties (and their opposites) that need to be checked for readiness before access.
-		 */
-		private final @Nullable Set<@NonNull Property> allCheckedProperties;
-
 		/**
 		 * The linear execution schedule for edges.
 		 */
@@ -141,16 +132,12 @@
 		private final @NonNull Set<@NonNull Edge> scheduledEdges = new HashSet<>();
 
 		/**
-		 * The edges (and their opposites) in edgeSchedule.
+		 * The nodes at the ends of the edges in edgeSchedule.
 		 */
 		private final @NonNull Set<@NonNull Node> scheduledNodes;
 
-		public OldEdgeSchedule(@NonNull Region region) {
-			this.region = region;
-			this.node2depth = computeDepths();
-			this.oldUnconditionalEdges = computeOldUnconditionalEdges();
-			this.allCheckedProperties = computeCheckedProperties();
-			this.scheduledNodes = Sets.newHashSet(RegionUtil.getHeadNodes(region));
+		public OldEdgeSchedule() {
+			this.scheduledNodes = Sets.newHashSet(RegionUtil.getHeadNodes(region));  // ?? leaf constants
 		}
 
 		private void addEdge(@NonNull Edge edge) {
@@ -176,21 +163,21 @@
 			if (scheduledNodes.add(targetNode)) {
 				Subexpression subexpression = node2subexpression.get(targetNode);
 				if (subexpression != null) {
-					for (@NonNull Node inputNode : subexpression.inputNodes) {
+					for (@NonNull Node inputNode : subexpression.unconditionalInputNodes) {
 						addNode(inputNode);
 					}
+					targetNode = subexpression.resultNode;
+					addNode(targetNode);
 				}
-				else {
-					Integer targetDepth = node2depth.get(targetNode);
-					assert targetDepth != null;
-					for (@NonNull Edge edge : RegionUtil.getIncomingEdges(targetNode)) {
-						if (edge.isOld()) {
-							Node sourceNode = RegionUtil.getSourceNode(edge);
-							Integer sourceDepth = node2depth.get(sourceNode);
-							assert sourceDepth != null;
-							if (sourceDepth < targetDepth) {
-								addEdge(edge);
-							}
+				Integer targetCost = reachabilityForest.getCost(targetNode);
+				assert targetCost != null;
+				for (@NonNull Edge edge : RegionUtil.getIncomingEdges(targetNode)) {
+					if (edge.isOld() && edge.isUnconditional()) {
+						Node sourceNode = RegionUtil.getSourceNode(edge);
+						Integer sourceCost = reachabilityForest.getCost(sourceNode);
+						assert sourceCost != null;
+						if (sourceCost < targetCost) {
+							addEdge(edge);
 						}
 					}
 				}
@@ -198,15 +185,17 @@
 		}
 
 		public void analyze() {
-			Set<@NonNull Edge> checkableEdges = computeCheckables();
-			int checkableSize = checkableEdges.size();
+			Set<@NonNull CheckedCondition> checkedConditions = computeCheckedConditions();
+			int checkableSize = checkedConditions.size();
 			if (checkableSize > 0) {
-				List<@NonNull Edge> sortedCheckableEdges = new ArrayList<>(checkableEdges);
+				List<@NonNull CheckedCondition> sortedCheckedConditions = new ArrayList<>(checkedConditions);
 				if (checkableSize > 1) {
-					Collections.sort(sortedCheckableEdges, this);
+					Collections.sort(sortedCheckedConditions);
 				}
-				for (@NonNull Edge checkableEdge : sortedCheckableEdges) {
-					addEdge(checkableEdge);
+				for (@NonNull CheckedCondition checkedCondition : sortedCheckedConditions) {
+					for (@NonNull Edge edge : checkedCondition.getEdges()) {
+						addEdge(edge);
+					}
 				}
 			}
 			for (@NonNull Edge edge : oldUnconditionalEdges) {
@@ -218,66 +207,84 @@
 			//			assert new HashSet<>(edgeSchedule).equals(new HashSet<>(oldEdges));
 		}
 
-		@Override
-		public int compare(@NonNull Edge e1, @NonNull Edge e2) {
-			Integer d1s = node2depth.get(RegionUtil.getSourceNode(e1));
-			Integer d1t = node2depth.get(RegionUtil.getTargetNode(e1));
-			Integer d2s = node2depth.get(RegionUtil.getSourceNode(e2));
-			Integer d2t = node2depth.get(RegionUtil.getTargetNode(e2));
-			assert (d1s != null) && (d1t != null) && (d2s != null) && (d2t != null);
-			int d1 = Math.max(d1s,  d1t);
-			int d2 = Math.max(d2s,  d2t);
-			if (d1 != d2) {
-				return d1 - d2;
-			}
-			if (d1s != d2s) {
-				return d1s - d2s;
-			}
-			return ClassUtil.safeCompareTo(e1.getDisplayName(), e2.getDisplayName());
-		}
-
 		/**
 		 * Return all old edges that require a check for readiness or consistency.
 		 */
-		private @NonNull Set<@NonNull Edge> computeCheckables() {
+		private @NonNull Set<@NonNull CheckedCondition> computeCheckedConditions() {
 			Set<@NonNull Property> allCheckedProperties2 = allCheckedProperties;
-			Set<@NonNull Edge> checkables = new HashSet<>();
+			Set<@NonNull CheckedCondition> checkedConditions = new HashSet<>();
+			Set<@NonNull NavigableEdge> checkedNavigableEdges = null;
 			for (@NonNull Edge edge : oldUnconditionalEdges) {
+				CheckedCondition checkedCondition = null;
 				if (edge instanceof CastEdge) {
-					checkables.add(edge);
+					checkedCondition = new CastEdgeCheckedCondition((CastEdge)edge);
 				}
 				else if (edge instanceof PredicateEdge) {
-					checkables.add(edge);
+					checkedCondition = new PredicateEdgeCheckedCondition((PredicateEdge)edge);
 				}
 				else if (edge instanceof NavigableEdge) {
+					NavigableEdge navigableEdge = (NavigableEdge)edge;
 					if (allCheckedProperties2 != null) {
-						Property property = ((NavigableEdge)edge).getProperty();
+						NavigableEdge primaryEdge = RegionUtil.getPrimaryEdge(navigableEdge);
+						Property property = primaryEdge.getProperty();
 						if (allCheckedProperties2.contains(property)) {
-							checkables.add(edge);
+							if (checkedNavigableEdges == null) {
+								checkedNavigableEdges = new HashSet<>();
+							}
+							if (checkedNavigableEdges.add(primaryEdge)) {
+								checkedCondition = new NavigableEdgeCheckedCondition(primaryEdge);
+							}
+						}
+					}
+					if (checkedCondition == null) {
+						Node targetNode = RegionUtil.getTargetNode(edge);
+						if (edge.isPredicated() && targetNode.isConstant()) {
+							checkedCondition = new ConstantTargetCheckedCondition((NavigableEdge)edge);
+						}
+						if ((checkedCondition == null) && edge.isOld()) {
+							Property property = QVTscheduleUtil.getProperty(navigableEdge);
+							CompleteClass edgeTargetCompleteClass = getMetamodelManager().getCompleteModel().getCompleteClass(QVTrelationUtil.getType(property));
+							Node sourceNode = RegionUtil.getSourceNode(edge);
+							Integer sourceCost = reachabilityForest.getCost(sourceNode);
+							Integer targetCost = reachabilityForest.getCost(targetNode);
+							assert (sourceCost != null) && (targetCost != null);
+							if (sourceCost < targetCost) {
+								CompleteClass targetNodeCompleteClass = targetNode.getCompleteClass();
+								if (!edgeTargetCompleteClass.conformsTo(targetNodeCompleteClass)) {
+									checkedCondition = new CastEdgeCheckedCondition(navigableEdge);
+								}
+							}
 						}
 					}
 				}
+				if (checkedCondition != null) {
+					checkedConditions.add(checkedCondition);
+				}
 			}
 			//
-			//	Double input nodes require a consistency check.
+			//	Multi-input nodes require a consistency check.
 			//
 			for (@NonNull Node node : RegionUtil.getOwnedNodes(region)) {
 				if (node.isOld() && node.isUnconditional()) {
-					Integer targetDepth = node2depth.get(node);
-					assert targetDepth != null;
+					Integer targetCost = reachabilityForest.getCost(node);
+					assert targetCost != null;
 					if (node.isOld()) {
 						Edge firstEdge = null;
+						MultipleEdgeCheckedCondition checkedCondition = null;
 						for (@NonNull Edge edge : RegionUtil.getIncomingEdges(node)) {
-							if (edge.isOld() && !edge.isExpression()) {
-								Integer sourceDepth = node2depth.get(RegionUtil.getSourceNode(edge));
-								assert sourceDepth != null;
-								if (sourceDepth <= targetDepth) {
+							if (edge.isOld() && !edge.isExpression()) {		// FIXME why exclude expression?
+								Integer sourceCost = reachabilityForest.getCost(RegionUtil.getSourceNode(edge));
+								assert sourceCost != null;
+								if (sourceCost <= targetCost) {
 									if (firstEdge == null) {
 										firstEdge = edge;
 									}
+									else if (checkedCondition == null){
+										checkedCondition = new MultipleEdgeCheckedCondition(firstEdge, edge);
+										checkedConditions.add(checkedCondition);
+									}
 									else {
-										checkables.add(firstEdge);
-										checkables.add(edge);
+										checkedCondition.addEdge(edge);
 									}
 								}
 							}
@@ -285,94 +292,7 @@
 					}
 				}
 			}
-			return checkables;
-		}
-
-		/**
-		 * Return all properties (and their opposites) that need checking for readiness prior to access.
-		 */
-		private @Nullable Set<@NonNull Property> computeCheckedProperties() {
-			//
-			// Better, we would not be pessimistic about input/output typedModel ambiguity in endogeneous
-			// mappings, but that incurs many typedModel accuracy issues.
-			//
-			Set<@NonNull Property> allCheckedProperties = null;
-			DomainUsage anyUsage = RegionUtil.getScheduleManager(region).getDomainAnalysis().getAnyUsage();
-			for (@NonNull TypedModel qvtmTypedModel : anyUsage.getTypedModels()) {
-				Iterable<@NonNull NavigableEdge> checkedEdges = RegionAnalysis.get(region).getCheckedEdges(qvtmTypedModel);
-				if (checkedEdges != null) {
-					for (NavigableEdge checkedEdge : checkedEdges) {
-						Property asProperty = RegionUtil.getProperty(checkedEdge);
-						if (allCheckedProperties == null) {
-							allCheckedProperties = new HashSet<>();
-						}
-						allCheckedProperties.add(asProperty);
-						Property asOppositeProperty = asProperty.getOpposite();
-						if (asOppositeProperty != null) {
-							allCheckedProperties.add(asOppositeProperty);
-						}
-					}
-				}
-			}
-			return allCheckedProperties;
-		}
-
-		/**
-		 * Return a map from each old node to the minimum edge distance from a head node.
-		 * @return
-		 */
-		private @NonNull Map<@NonNull Node, @NonNull Integer> computeDepths() {
-			// Successive depth candidate iteration works fine.
-			// A recursion has trouble with the forward/reverse edge pairs.
-			// A max-depth similarly has trouble with forward/reverse recursion.
-			Map<@NonNull Node, @NonNull Integer> node2minDepth = new HashMap<>();
-			Set<@NonNull Node> lowerDepthNodes = new HashSet<>();
-			Iterable<@NonNull Node> thisDepthNodes = RegionUtil.getHeadNodes(region);
-			for (int depth = 0; thisDepthNodes != null; depth++) {
-				Set<@NonNull Node> nextDepthNodes = null;
-				for (@NonNull Node node : thisDepthNodes) {
-					if (!node2minDepth.containsKey(node)) {
-						node2minDepth.put(node, depth);
-					}
-					for (@NonNull Edge edge : RegionUtil.getOutgoingEdges(node)) {
-						if (edge.isOld()) {
-							Node targetNode = RegionUtil.getTargetNode(edge);
-							if (!lowerDepthNodes.contains(targetNode)) {
-								if (nextDepthNodes == null) {
-									nextDepthNodes = new HashSet<>();
-								}
-								nextDepthNodes.add(targetNode);
-							}
-						}
-					}
-				}
-				for (@NonNull Node node : thisDepthNodes) {
-					lowerDepthNodes.add(node);
-				}
-				thisDepthNodes = nextDepthNodes;
-			}
-			for (@NonNull Node node : RegionUtil.getOwnedNodes(region)) {
-				if (node.isOld()) {
-					Integer depth = node2minDepth.get(node);
-					if (depth == null) {
-						assert node.isConstant();
-						node2minDepth.put(node, 0);
-					}
-				}
-			}
-			return node2minDepth;
-		}
-
-		private @NonNull List<@NonNull Edge> computeOldUnconditionalEdges() {
-			Set<@NonNull Edge> oldEdges = new HashSet<>();
-			for (@NonNull Edge edge : RegionUtil.getOwnedEdges(region)) {
-				if (edge.isOld() && edge.isUnconditional()) {
-					oldEdges.add(edge);
-				}
-			}
-			List<@NonNull Edge> sortedEdges = new ArrayList<>(oldEdges);
-			Collections.sort(sortedEdges, this);
-			return sortedEdges;
+			return checkedConditions;
 		}
 
 		private void createCastPredicates(@NonNull Node sourceNode, @NonNull VariableDeclaration sourceVariable) {
@@ -400,12 +320,7 @@
 			}
 		}
 
-		public @Nullable Set<@NonNull Property> getAllCheckedProperties() {
-			return allCheckedProperties;
-		}
-
 		public void synthesize() {
-			@SuppressWarnings("unused")String regionName = region.getName();
 			for (@NonNull Edge edge : edgeSchedule) {
 				assert edge.isUnconditional();
 				Node sourceNode = RegionUtil.getSourceNode(edge);
@@ -452,7 +367,7 @@
 					getSubexpressionDeclaration(targetNode);
 				}
 			}
-			List<@NonNull Subexpression> subexpressions = new ArrayList<>(node2subexpression.values());
+			List<@NonNull Subexpression> subexpressions = new ArrayList<>(resultNode2subexpression.values());
 			Collections.sort(subexpressions);
 			for (@NonNull Subexpression subexpression : subexpressions) {
 				if (!subexpression.resultNode.isNew() && subexpression.resultNode.isUnconditional()) {
@@ -921,16 +836,29 @@
 			}
 			TypedElement oldTypedElement = node.getTypedElements().iterator().next();
 			assert oldTypedElement != null;
-			if ((oldTypedElement instanceof Variable) && (((Variable)oldTypedElement).getOwnedInit() == null)) {
-				for (@NonNull Edge edge : RegionUtil.getIncomingEdges(node)) {
-					if (edge.isExpression() && QVTscheduleConstants.EQUALS_NAME.equals(edge.getName())) {
-						Node edgeSource = edge.getEdgeSource();
-						return create(edgeSource); //createBottomVariable(node, helper.createNullLiteralExp());		// FIXME is this possible?
+			if (oldTypedElement instanceof Variable) {
+				Variable variable = (Variable)oldTypedElement;
+				OCLExpression ownedInit = variable.getOwnedInit();
+				if (ownedInit == null) {
+					for (@NonNull Edge edge : RegionUtil.getIncomingEdges(node)) {
+						if (edge.isExpression() && QVTscheduleConstants.EQUALS_NAME.equals(edge.getName())) {
+							Node sourceNode = RegionUtil.getSourceNode(edge);
+							return create(sourceNode); //createBottomVariable(node, helper.createNullLiteralExp());		// FIXME is this possible?
+						}
+						else if (edge.isCast()) {
+							throw new UnsupportedOperationException();
+							//theVariable = createBottomVariable(node, helper.createNullLiteralExp());		// FIXME is this possible?
+						}
+						else if (edge.isNavigation()) {
+							Node sourceNode = RegionUtil.getSourceNode(edge);
+							OCLExpression sourceExpression = create(sourceNode);
+							Property referredProperty = RegionUtil.getProperty((NavigableEdge) edge);
+							return helper.createNavigationCallExp(sourceExpression, referredProperty);
+						}
 					}
-					else if (edge.isCast()) {
-						throw new UnsupportedOperationException();
-						//theVariable = createBottomVariable(node, helper.createNullLiteralExp());		// FIXME is this possible?
-					}
+				}
+				else {
+					return ownedInit.accept(this);
 				}
 			}
 			else {
@@ -948,16 +876,21 @@
 		private final @NonNull OperationNode resultNode;
 
 		/**
-		 * Externalnodes used within the subexpression
+		 * External nodes used within the subexpression
 		 */
 		private final @NonNull Set<@NonNull Node> inputNodes = new HashSet<>();
 
 		/**
+		 * External nodes used within the subexpression
+		 */
+		private final @NonNull Set<@NonNull Node> unconditionalInputNodes = new HashSet<>();
+
+		/**
 		 * Nodes within the subexpression
 		 */
 		private final @NonNull Set<@NonNull Node> contentNodes = new HashSet<>();
 
-		private @Nullable Integer depth = null;
+		private @Nullable Integer cost = null;
 
 		public Subexpression(@NonNull OperationNode resultNode) {
 			this.resultNode = resultNode;
@@ -971,8 +904,8 @@
 		@Override
 		public int compareTo(@NonNull Subexpression e2) {
 			Subexpression e1 = this;
-			int d1 = e1.getDepth();
-			int d2 = e2.getDepth();
+			int d1 = e1.getCost();
+			int d2 = e2.getCost();
 			if (d1 != d2) {
 				return d1 - d2;
 			}
@@ -981,26 +914,36 @@
 
 		private void computeSubexpressionContent(@NonNull Node node, @NonNull Set<@NonNull OperationNode> subexpressionResults) {
 			if (contentNodes.add(node)) {
+				node2subexpression.put(node, this);
 				for (@NonNull Edge edge : RegionUtil.getIncomingEdges(node)) {
 					//					if (edge.isUnconditional()) {
 					Node sourceNode = edge.getEdgeSource();
 					if (subexpressionResults.contains(sourceNode)) {
 						if (sourceNode.isOld() || (!edge.isSecondary() && resultNode.isNew())) {
 							inputNodes.add(sourceNode);
+							if (edge.isUnconditional() && sourceNode.isUnconditional()) {
+								unconditionalInputNodes.add(sourceNode);
+							}
+							//							edge2subexpression.put(edge, this);
 						}
 					}
 					else if (sourceNode.isExpression()) {
+						node2subexpression.put(sourceNode, this);
 						edge2subexpression.put(edge, this);
 						computeSubexpressionContent(sourceNode, subexpressionResults);
 					}
 					else if (!sourceNode.isUnconditional()) {
+						node2subexpression.put(sourceNode, this);
 						edge2subexpression.put(edge, this);
 						computeSubexpressionContent(sourceNode, subexpressionResults);
 					}
 					else {
 						if (sourceNode.isOld() || resultNode.isNew()) {
 							inputNodes.add(sourceNode);
-							edge2subexpression.put(edge, this);
+							if (edge.isUnconditional() && sourceNode.isUnconditional()) {
+								unconditionalInputNodes.add(sourceNode);
+							}
+							//							edge2subexpression.put(edge, this);
 						}
 					}
 					//					}
@@ -1008,19 +951,23 @@
 			}
 		}
 
-		public int getDepth() {
-			Integer depth2 = depth;
-			if (depth2 == null) {
-				int inputDepth = 0;
-				for (@NonNull Node inputNode : inputNodes) {
-					Subexpression inputSubexpression = node2subexpression.get(inputNode);
-					if (inputSubexpression != null) {
-						inputDepth = Math.max(inputDepth, inputSubexpression.getDepth()+1);
+		public int getCost() {
+			Integer cost2 = cost;
+			if (cost2 == null) {
+				cost2 = reachabilityForest.getCost(resultNode);
+				if (cost2 == null) {			// Can happen for REALIZED results
+					int inputCost = 0;
+					for (@NonNull Node inputNode : inputNodes) {
+						Subexpression inputSubexpression = resultNode2subexpression.get(inputNode);
+						if (inputSubexpression != null) {
+							inputCost = Math.max(inputCost, inputSubexpression.getCost()+1);
+						}
 					}
+					cost2 = inputCost;
 				}
-				depth = depth2 = inputDepth;
+				cost = cost2;
 			}
-			return depth2;
+			return cost2;
 		}
 		@Override
 		public @NonNull String toString() {
@@ -1029,9 +976,197 @@
 	}
 
 	/**
-	 * Map from each subexpression result to its contents.
+	 * A CheckedCondition identifies a possible micromapping failure mechanism. QVTi synthesis prioritises
+	 * easily computed CheckedConditions to minimize the wasted effort in computing failures.
 	 */
-	private final @NonNull Map<@NonNull OperationNode, @NonNull Subexpression> node2subexpression;
+	abstract class CheckedCondition implements Comparable<@NonNull CheckedCondition>
+	{
+		private int weight = -1;
+
+		protected void accumulateNodes(@NonNull Set<@NonNull Node> requiredNodes, @NonNull Edge edge) {
+			requiredNodes.addAll(getPrecedingNodes(RegionUtil.getSourceNode(edge)));
+			requiredNodes.addAll(getPrecedingNodes(RegionUtil.getTargetNode(edge)));
+		}
+
+		@Override
+		public int compareTo(@NonNull CheckedCondition that) {
+			int w1 = this.getWeight();
+			int w2 = that.getWeight();
+			return w1 - w2;
+		}
+
+		protected abstract int computeWeight();
+
+		public abstract @NonNull Iterable<@NonNull Edge> getEdges();
+
+		public int getWeight() {
+			if (weight < 0) {
+				weight = computeWeight();
+			}
+			return weight;
+		}
+
+		@Override
+		public @NonNull String toString() {
+			StringBuilder s = new StringBuilder();
+			s.append(getClass().getSimpleName());
+			s.append("(");
+			boolean isFirst = true;
+			for (@NonNull Edge edge : getEdges()) {
+				if (!isFirst) {
+					s.append(",");
+				}
+				s.append(edge.getDisplayName());
+				isFirst = false;
+			}
+			s.append(")");
+			return s.toString();
+		}
+
+	}
+
+	/**
+	 * A CastEdgeCheckedCondition identifies the failure when a source fails to compky with the required target type.
+	 */
+	class CastEdgeCheckedCondition extends CheckedCondition
+	{
+		private final @NonNull NavigableEdge castEdge;
+
+		public CastEdgeCheckedCondition(@NonNull NavigableEdge castEdge) {
+			this.castEdge = castEdge;
+		}
+
+		@Override
+		protected int computeWeight() {
+			Set<@NonNull Node> requiredNodes = new HashSet<>();
+			accumulateNodes(requiredNodes, castEdge);
+			return requiredNodes.size();
+		}
+
+		@Override
+		public @NonNull Iterable<@NonNull Edge> getEdges() {
+			return Collections.singletonList(castEdge);
+		}
+	}
+
+	/**
+	 * A ConstantTargetCheckedCondition identifies the failure when a computation fails to yield the required constant value.
+	 */
+	class ConstantTargetCheckedCondition extends CheckedCondition
+	{
+		private final @NonNull NavigableEdge predicateEdge;
+
+		public ConstantTargetCheckedCondition(@NonNull NavigableEdge predicateEdge) {
+			this.predicateEdge = predicateEdge;
+		}
+
+		@Override
+		protected int computeWeight() {
+			Set<@NonNull Node> requiredNodes = new HashSet<>();
+			requiredNodes.addAll(getPrecedingNodes(RegionUtil.getSourceNode(predicateEdge)));
+			return requiredNodes.size();
+		}
+
+		@Override
+		public @NonNull Iterable<@NonNull Edge> getEdges() {
+			return Collections.singletonList(predicateEdge);
+		}
+	}
+
+	/**
+	 * A MultipleEdgeCheckedCondition identifies the failure when two alternate navigation paths yield inconsistent results.
+	 */
+	class MultipleEdgeCheckedCondition extends CheckedCondition
+	{
+		private final @NonNull List<@NonNull Edge> edges = new ArrayList<>();
+
+		public MultipleEdgeCheckedCondition(@NonNull Edge firstEdge, @NonNull Edge secondEdge) {
+			addEdge(firstEdge);
+			addEdge(secondEdge);
+		}
+
+		public boolean addEdge(@NonNull Edge edge) {
+			return edges.add(edge);
+		}
+
+		@Override
+		protected int computeWeight() {
+			Set<@NonNull Node> requiredNodes = new HashSet<>();
+			for (@NonNull Edge edge : edges) {
+				accumulateNodes(requiredNodes, edge);
+			}
+			return requiredNodes.size();
+		}
+
+		@Override
+		public @NonNull Iterable<@NonNull Edge> getEdges() {
+			return edges;
+		}
+	}
+
+	/**
+	 * A NavigableEdgeCheckedCondition identifies the temporary failure that arises when
+	 * observing a property access to a not-yet assigned slot.
+	 */
+	class NavigableEdgeCheckedCondition extends CheckedCondition
+	{
+		private final @NonNull NavigableEdge navigableEdge;
+
+		public NavigableEdgeCheckedCondition(@NonNull NavigableEdge navigableEdge) {
+			this.navigableEdge = navigableEdge;
+		}
+
+		@Override
+		protected int computeWeight() {
+			Set<@NonNull Node> requiredNodes = new HashSet<>();
+			accumulateNodes(requiredNodes, navigableEdge);
+			return requiredNodes.size();
+		}
+
+		@Override
+		public @NonNull Iterable<@NonNull Edge> getEdges() {
+			return Collections.singletonList(navigableEdge);
+		}
+	}
+
+	/**
+	 * A PredicateEdgeCheckedCondition identifies the failure of a required consistent computation result.
+	 */
+	class PredicateEdgeCheckedCondition extends CheckedCondition
+	{
+		private final @NonNull PredicateEdge predicateEdge;
+
+		public PredicateEdgeCheckedCondition(@NonNull PredicateEdge predicateEdge) {
+			this.predicateEdge = predicateEdge;
+		}
+
+		@Override
+		protected int computeWeight() {
+			Set<@NonNull Node> requiredNodes = new HashSet<>();
+			accumulateNodes(requiredNodes, predicateEdge);
+			return requiredNodes.size();
+		}
+
+		@Override
+		public @NonNull Iterable<@NonNull Edge> getEdges() {
+			return Collections.singletonList(predicateEdge);
+		}
+	}
+
+	/**
+	 * Lazily computed closure of all preceding nodes, icluding the final node, of each node.
+	 */
+	private @Nullable Map<@NonNull Node, @NonNull Set<@NonNull Node>> node2precedingNodeClosure = null;
+
+	/**
+	 * Map from each subexpression result node to its contents.
+	 */
+	private final @NonNull Map<@NonNull OperationNode, @NonNull Subexpression> resultNode2subexpression;
+
+	/**
+	 * Map from each subexpression node to its contents.
+	 */
+	private final @NonNull Map<@NonNull Node, @NonNull Subexpression> node2subexpression = new HashMap<>();
 
 	/**
 	 * Map from each subexpression edge to its contents.
@@ -1039,6 +1174,18 @@
 	private final @NonNull Map<@NonNull Edge, @NonNull Subexpression> edge2subexpression = new HashMap<>();
 
 	/**
+	 * All properties (and their opposites) that need to be checked for readiness before access.
+	 */
+	private final @Nullable Set<@NonNull Property> allCheckedProperties;
+
+	/**
+	 * The unconditional old edges provide the pattern matching workload.
+	 * Once cost sorted the list is a sensible residual scheduling order after higher priority checked edges.
+	 * Conditional edges should be scheduled as a consequence of an invoking unconditional edge/node.
+	 */
+	private final @NonNull List<@NonNull Edge> oldUnconditionalEdges;
+
+	/**
 	 * The selected head from each head group that is actually passed. Other heads are computed.
 	 */
 	private final @NonNull List<@NonNull Node> headNodes = new ArrayList<>();
@@ -1053,27 +1200,70 @@
 	 */
 	private final @NonNull Map<@NonNull Node, @NonNull VariableDeclaration> node2variable = new HashMap<>();
 
+	/**
+	 * The mechanisms to reach required nodes.
+	 */
+	private final @NonNull ReachabilityForest reachabilityForest;
+
 	public BasicRegion2Mapping(@NonNull QVTs2QVTiVisitor visitor, @NonNull Region region) {
 		super(visitor, region);
-		@SuppressWarnings("unused")String name = region.getName();
-		this.node2subexpression = computeSubexpressions();
-
+		this.reachabilityForest = new ReachabilityForest(getReachabilityRootNodes(), getAvailableNavigableEdges());
+		this.resultNode2subexpression = computeSubexpressions();
 		//
-		//	Create the 'local' statements.
+		//	Gather the subexpression contents.
 		//
-		createHeadAndGuardNodeVariables();			// BLUE/CYAN guard/append nodes
-		OldEdgeSchedule oldSchedule = createNavigablePredicates();	// BLUE/CYAN navigable nodes and edges
-		createRealizedVariables();					// GREEN nodes
-		createPropertyAssignments();				// GREEN edges
-		createAddStatements();						// export to append nodes
-		createRealizedIncludesAssignments();
-		Set<@NonNull Property> allCheckedProperties = oldSchedule.getAllCheckedProperties();
-		if (allCheckedProperties != null) {
-			createObservedProperties(allCheckedProperties);					// wrap observable clauses around hazardous accesses
+		Set<@NonNull OperationNode> subexpressionResults = resultNode2subexpression.keySet();
+		for (@NonNull Subexpression subexpression : resultNode2subexpression.values()) {
+			subexpression.analyze(subexpressionResults);
 		}
+		this.allCheckedProperties = computeCheckedProperties();
+		this.oldUnconditionalEdges = computeOldUnconditionalEdges();
+	}
+	private @NonNull Iterable<@NonNull Node> getReachabilityRootNodes() {
 		//
-		//	The 'global' statements are created by createSchedulingStatements().
+		//	The zero-cost nodes are the head nodes ...
 		//
+		List<@NonNull Node> zeroCostNodes = Lists.newArrayList(RegionUtil.getHeadNodes(region));
+		//
+		//	... and the no-input constant nodes
+		//
+		for (@NonNull Node node : RegionUtil.getOwnedNodes(region)) {
+			if (node.isExplicitNull() || node.isOperation()) {
+				if (node.isConstant()) {
+					boolean hasNoComputationInputs = true;
+					for (@NonNull Edge edge : RegionUtil.getIncomingEdges(node)) {
+						if (edge.isComputation()) {
+							hasNoComputationInputs = false;
+							break;
+						}
+					}
+					if (hasNoComputationInputs) {
+						zeroCostNodes.add(node);
+					}
+				}
+			}
+		}
+		return zeroCostNodes;
+	}
+	/**
+	 * Return the navigable edges that may be used by to locate nodes by this partition.
+	 * The default implementation returns all old primary navigable edges
+	 * and all already realized navigable edges
+	 */
+	protected @NonNull Iterable<@NonNull NavigableEdge> getAvailableNavigableEdges() {
+		Set<@NonNull NavigableEdge> oldEdges = new HashSet<>();
+		for (@NonNull Edge edge : RegionUtil.getOwnedEdges(region)) {
+			if (edge.isOld() && edge.isNavigation() /*&& edge.isUnconditional()*/) {
+				Node sourceNode = RegionUtil.getSourceNode(edge);
+				Node targetNode = RegionUtil.getTargetNode(edge);
+				if (sourceNode.isOld() && targetNode.isOld()) {
+					oldEdges.add((NavigableEdge) edge);
+				}
+			}
+		}
+		//		List<@NonNull Edge> sortedEdges = new ArrayList<>(oldEdges);
+		//		Collections.sort(sortedEdges, reachabilityForest.getEdgeCostComparator());
+		return oldEdges;
 	}
 
 	public @Nullable VariableDeclaration basicGetVariable(@NonNull Node node) {
@@ -1081,55 +1271,103 @@
 	}
 
 	/**
+	 * Return all properties (and their opposites) that need checking for readiness prior to access.
+	 */
+	private @Nullable Set<@NonNull Property> computeCheckedProperties() {
+		//
+		// Better, we would not be pessimistic about input/output typedModel ambiguity in endogeneous
+		// mappings, but that incurs many typedModel accuracy issues.
+		//
+		Set<@NonNull Property> allCheckedProperties = null;
+		DomainUsage anyUsage = RegionUtil.getScheduleManager(region).getDomainAnalysis().getAnyUsage();
+		for (@NonNull TypedModel qvtmTypedModel : anyUsage.getTypedModels()) {
+			Iterable<@NonNull NavigableEdge> checkedEdges = RegionAnalysis.get(region).getCheckedEdges(qvtmTypedModel);
+			if (checkedEdges != null) {
+				for (@NonNull NavigableEdge checkedEdge : checkedEdges) {
+					Property asProperty = RegionUtil.getProperty(checkedEdge);
+					if (allCheckedProperties == null) {
+						allCheckedProperties = new HashSet<>();
+					}
+					allCheckedProperties.add(asProperty);
+					Property asOppositeProperty = asProperty.getOpposite();
+					if (asOppositeProperty != null) {
+						allCheckedProperties.add(asOppositeProperty);
+					}
+				}
+			}
+		}
+		return allCheckedProperties;
+	}
+
+	private @NonNull List<@NonNull Edge> computeOldUnconditionalEdges() {
+		Set<@NonNull Edge> oldEdges = new HashSet<>();
+		for (@NonNull Edge edge : RegionUtil.getOwnedEdges(region)) {
+			if (edge.isOld() && edge.isUnconditional()) {
+				Node sourceNode = RegionUtil.getSourceNode(edge);
+				Node targetNode = RegionUtil.getTargetNode(edge);
+				if (sourceNode.isOld() && targetNode.isOld()) {
+					oldEdges.add(edge);
+				}
+			}
+		}
+		List<@NonNull Edge> sortedEdges = new ArrayList<>(oldEdges);
+		Collections.sort(sortedEdges, reachabilityForest.getEdgeCostComparator());
+		return sortedEdges;
+	}
+
+	/**
 	 * Return all subexpressions and their content. A subexpression is an OperationNode whose value is consumed by
 	 * one (or more) PatternNodes or by two (or more) OperationNodes.
 	 */
 	private @NonNull Map<@NonNull OperationNode, @NonNull Subexpression> computeSubexpressions() {
-		Map<@NonNull OperationNode, @NonNull Subexpression> node2subexpression = new HashMap<>();
+		Map<@NonNull OperationNode, @NonNull Subexpression> resultNode2subexpression = new HashMap<>();
 		//
 		//	Identify the subexpression result nodes
 		//
 		for (@NonNull Node node : RegionUtil.getOwnedNodes(region)) {
 			if (node.isOperation() && node.isUnconditional()) {
 				OperationNode resultNode = (OperationNode) node;
-				Edge firstEdge = null;
-				boolean isSubexpression = false;
-				for (@NonNull Edge edge : RegionUtil.getIncomingEdges(node)) {
-					if (edge.isNew() && !edge.isSecondary()) {
-						Node edgeSource = edge.getSourceNode();
-						if (edgeSource.isPattern()) {
-							node2subexpression.put(resultNode, new Subexpression(resultNode));
-							isSubexpression = true;
-							break;
-						}
+				boolean isPrimitiveLiteralExp = false;
+				if (node.isConstant()) {
+					TypedElement oldTypedElement = node.getTypedElements().iterator().next();
+					assert oldTypedElement != null;
+					if (oldTypedElement instanceof PrimitiveLiteralExp) {
+						isPrimitiveLiteralExp = true;
 					}
 				}
-				if (!isSubexpression) {
-					for (@NonNull Edge edge : RegionUtil.getOutgoingEdges(node)) {
-						Node edgeTarget = edge.getTargetNode();
-						if (edgeTarget.isPattern() || edgeTarget.isTrue()) {
-							node2subexpression.put(resultNode, new Subexpression(resultNode));
-							break;
+				if (!isPrimitiveLiteralExp) {
+					Edge firstEdge = null;
+					boolean isSubexpression = false;
+					for (@NonNull Edge edge : RegionUtil.getIncomingEdges(node)) {
+						if (edge.isNew() && !edge.isSecondary()) {
+							Node edgeSource = edge.getSourceNode();
+							if (edgeSource.isPattern()) {
+								resultNode2subexpression.put(resultNode, new Subexpression(resultNode));
+								isSubexpression = true;
+								break;
+							}
 						}
-						if (firstEdge == null) {
-							firstEdge = edge;
-						}
-						else {
-							node2subexpression.put(resultNode, new Subexpression(resultNode));
-							break;
+					}
+					if (!isSubexpression) {
+						for (@NonNull Edge edge : RegionUtil.getOutgoingEdges(node)) {
+							Node edgeTarget = edge.getTargetNode();
+							if (edgeTarget.isPattern() || edgeTarget.isTrue()) {
+								resultNode2subexpression.put(resultNode, new Subexpression(resultNode));
+								break;
+							}
+							if (firstEdge == null) {
+								firstEdge = edge;
+							}
+							else {
+								resultNode2subexpression.put(resultNode, new Subexpression(resultNode));
+								break;
+							}
 						}
 					}
 				}
 			}
 		}
-		//
-		//	Gather the subexpression contents.
-		//
-		Set<@NonNull OperationNode> subexpressionResults = node2subexpression.keySet();
-		for (@NonNull Subexpression subexpression : node2subexpression.values()) {
-			subexpression.analyze(subexpressionResults);
-		}
-		return node2subexpression;
+		return resultNode2subexpression;
 	}
 
 	/**
@@ -1147,6 +1385,49 @@
 		}
 	}
 
+	private void createCallStatements(@NonNull Map<@NonNull Region, @NonNull Map<@NonNull Node, @NonNull Node>> calls) {
+		List<@NonNull MappingStatement> mappingStatements = new ArrayList<>();
+		Map<@NonNull LoopVariable, @NonNull OCLExpression> loopVariables = null;
+		for (Map.Entry<@NonNull Region, @NonNull Map<@NonNull Node, @NonNull Node>> entry : calls.entrySet()) {
+			@NonNull Region calledRegion = entry.getKey();
+			AbstractRegion2Mapping calledRegion2Mapping = visitor.getRegion2Mapping(calledRegion);
+			List<@NonNull MappingParameterBinding> mappingParameterBindings = new ArrayList<>();
+			for (Map.Entry<@NonNull Node, @NonNull Node> entry2 : entry.getValue().entrySet()) {
+				@NonNull Node sourceNode = entry2.getKey();
+				@NonNull Node targetNode = entry2.getValue();
+				OCLExpression sourceExpression = createVariableExp(sourceNode);
+				Type type = sourceExpression.getType();
+				if (type instanceof CollectionType) {
+					if (loopVariables == null) {
+						loopVariables = new HashMap<>();
+					}
+					Type elementType = ((CollectionType)type).getElementType();
+					assert elementType != null;
+					LoopVariable loopVariable = helper.createLoopVariable(getSafeName("loop" + loopVariables.size()), elementType);//, true, sourceExpression);
+					loopVariables.put(loopVariable, sourceExpression);
+					//					sourceExpression = PivotUtil.createVariableExp(loopVariable);
+					VariableDeclaration guardVariable = calledRegion2Mapping.getGuardVariable(targetNode);
+					mappingParameterBindings.add(helper.createLoopParameterBinding((GuardParameter) guardVariable, loopVariable));
+				}
+				else {
+					VariableDeclaration guardVariable = calledRegion2Mapping.getGuardVariable(targetNode);
+					mappingParameterBindings.add(helper.createSimpleParameterBinding((SimpleParameter) guardVariable, sourceExpression));
+				}
+			}
+			Collections.sort(mappingParameterBindings, QVTimperativeUtil.MappingParameterBindingComparator.INSTANCE);
+			MappingStatement mappingCallStatement = calledRegion2Mapping.createMappingCall(mappingParameterBindings);
+			if (loopVariables != null) {
+				for (Map.Entry<@NonNull LoopVariable, @NonNull OCLExpression> loopEntry : loopVariables.entrySet()) {
+					@NonNull LoopVariable loopVariable = loopEntry.getKey();
+					@NonNull OCLExpression loopSource = loopEntry.getValue();
+					mappingCallStatement = helper.createMappingLoop(loopSource, loopVariable, mappingCallStatement);
+				}
+			}
+			mappingStatements.add(mappingCallStatement);
+		}
+		mapping.getOwnedStatements().addAll(mappingStatements);
+	}
+
 	private @NonNull CheckStatement createCheckStatement(@NonNull OCLExpression booleanExpression) {
 		CheckStatement checkStatement = helper.createCheckStatement(booleanExpression);
 		mapping.getOwnedStatements().add(checkStatement);
@@ -1266,83 +1547,46 @@
 		createAppendParameters();
 	}
 
-	private void createMappingStatements(@NonNull Map<@NonNull Region, @NonNull Map<@NonNull Node, @NonNull Node>> calls) {
-		List<@NonNull MappingStatement> mappingStatements = new ArrayList<>();
-		Map<@NonNull LoopVariable, @NonNull OCLExpression> loopVariables = null;
-		for (Map.Entry<@NonNull Region, @NonNull Map<@NonNull Node, @NonNull Node>> entry : calls.entrySet()) {
-			@NonNull Region calledRegion = entry.getKey();
-			AbstractRegion2Mapping calledRegion2Mapping = visitor.getRegion2Mapping(calledRegion);
-			List<@NonNull MappingParameterBinding> mappingParameterBindings = new ArrayList<>();
-			for (Map.Entry<@NonNull Node, @NonNull Node> entry2 : entry.getValue().entrySet()) {
-				@NonNull Node sourceNode = entry2.getKey();
-				@NonNull Node targetNode = entry2.getValue();
-				OCLExpression sourceExpression = createVariableExp(sourceNode);
-				Type type = sourceExpression.getType();
-				if (type instanceof CollectionType) {
-					if (loopVariables == null) {
-						loopVariables = new HashMap<>();
+	private void createObservedProperties() {
+		Set<@NonNull Property> allCheckedProperties2 = allCheckedProperties;
+		if (allCheckedProperties2 != null) {
+			//
+			// Ideally we could install each observed property as it is actually used. But
+			// this needs to be coded in many places.
+			//
+			for (Statement asStatement : mapping.getOwnedStatements()) {
+				if (asStatement instanceof ObservableStatement) {
+					List<Property> observedProperties = ((ObservableStatement)asStatement).getObservedProperties();
+					for (EObject eObject : new TreeIterable(asStatement, false)) {
+						if (eObject instanceof PropertyCallExp) {
+							Property property = PivotUtil.getReferredProperty((PropertyCallExp) eObject);
+							if (allCheckedProperties2.contains(property) && !observedProperties.contains(property)) {
+								observedProperties.add(property);
+							}
+						}
+						else if (eObject instanceof OppositePropertyCallExp) {
+							Property property = PivotUtil.getReferredProperty((NavigationCallExp) eObject).getOpposite();
+							if (allCheckedProperties2.contains(property) && !observedProperties.contains(property)) {
+								observedProperties.add(property);
+							}
+						}
 					}
-					Type elementType = ((CollectionType)type).getElementType();
-					assert elementType != null;
-					LoopVariable loopVariable = helper.createLoopVariable(getSafeName("loop" + loopVariables.size()), elementType);//, true, sourceExpression);
-					loopVariables.put(loopVariable, sourceExpression);
-					//					sourceExpression = PivotUtil.createVariableExp(loopVariable);
-					VariableDeclaration guardVariable = calledRegion2Mapping.getGuardVariable(targetNode);
-					mappingParameterBindings.add(helper.createLoopParameterBinding((GuardParameter) guardVariable, loopVariable));
-				}
-				else {
-					VariableDeclaration guardVariable = calledRegion2Mapping.getGuardVariable(targetNode);
-					mappingParameterBindings.add(helper.createSimpleParameterBinding((SimpleParameter) guardVariable, sourceExpression));
 				}
 			}
-			Collections.sort(mappingParameterBindings, QVTimperativeUtil.MappingParameterBindingComparator.INSTANCE);
-			MappingStatement mappingCallStatement = calledRegion2Mapping.createMappingCall(mappingParameterBindings);
-			if (loopVariables != null) {
-				for (Map.Entry<@NonNull LoopVariable, @NonNull OCLExpression> loopEntry : loopVariables.entrySet()) {
-					@NonNull LoopVariable loopVariable = loopEntry.getKey();
-					@NonNull OCLExpression loopSource = loopEntry.getValue();
-					mappingCallStatement = helper.createMappingLoop(loopSource, loopVariable, mappingCallStatement);
-				}
-			}
-			mappingStatements.add(mappingCallStatement);
 		}
-		mapping.getOwnedStatements().addAll(mappingStatements);
 	}
 
 	/**
-	 * Recurse over the guard nodes and loaded/predicates region and convert the non-guard nodes to unrealized variables
-	 * and edges to predicates or initializations
+	 * Determine a traversal order for the old edges then synthesize the patttern matching statements.
 	 */
-	private @NonNull OldEdgeSchedule createNavigablePredicates() {
-		OldEdgeSchedule oldSchedule = new OldEdgeSchedule(region);
-		oldSchedule.analyze();
-		oldSchedule.synthesize();
-		return oldSchedule;
-	}
-
-	private void createObservedProperties(@NonNull Set<@NonNull Property> allCheckedProperties) {
-		//
-		// Ideally we could install each observed property as it is actually used. But
-		// this needs to be coded in many places.
-		//
-		for (Statement asStatement : mapping.getOwnedStatements()) {
-			if (asStatement instanceof ObservableStatement) {
-				List<Property> observedProperties = ((ObservableStatement)asStatement).getObservedProperties();
-				for (EObject eObject : new TreeIterable(asStatement, false)) {
-					if (eObject instanceof PropertyCallExp) {
-						Property property = PivotUtil.getReferredProperty((PropertyCallExp) eObject);
-						if (allCheckedProperties.contains(property) && !observedProperties.contains(property)) {
-							observedProperties.add(property);
-						}
-					}
-					else if (eObject instanceof OppositePropertyCallExp) {
-						Property property = PivotUtil.getReferredProperty((NavigationCallExp) eObject).getOpposite();
-						if (allCheckedProperties.contains(property) && !observedProperties.contains(property)) {
-							observedProperties.add(property);
-						}
-					}
-				}
-			}
+	private void createPatternMatch() {
+		if (mapping.isIsAbstract()) {
+			mapping.getOwnedStatements().add(createCheckStatement(helper.createBooleanLiteralExp(false)));	// FIXME add a message
+		}
+		else {
+			OldEdgeSchedule oldSchedule = new OldEdgeSchedule();
+			oldSchedule.analyze();
+			oldSchedule.synthesize();
 		}
 	}
 
@@ -1452,39 +1696,6 @@
 		}
 	}
 
-	@Override
-	public void createSchedulingStatements() {
-		Map<@NonNull Region, @NonNull Map<@NonNull Node, @NonNull Node>> calls = null;
-		for (@NonNull Region calledRegion : region.getCallableChildren()) {
-			if (calls == null) {
-				calls = new HashMap<>();
-			}
-			Map<@NonNull Node, @NonNull Node> source2target = calls.get(calledRegion);
-			if (source2target == null) {
-				source2target = new HashMap<>();
-				calls.put(calledRegion, source2target);
-			}
-			AbstractRegion2Mapping calledRegion2Mapping = visitor.getRegion2Mapping(calledRegion);
-			for (@NonNull Node calledGuardNode : calledRegion2Mapping.getGuardNodes()) {
-				for (@NonNull Node callingNode : calledGuardNode.getPassedBindingSources()) {
-					if (callingNode.getOwningRegion() == region) {
-						Node oldNode = source2target.put(callingNode, calledGuardNode);
-						assert oldNode == null;
-					}
-				}
-				for (@NonNull Node callingNode : calledGuardNode.getUsedBindingSources()) {
-					if (callingNode.getOwningRegion() == region) {
-						Node oldNode = source2target.put(callingNode, calledGuardNode);
-						assert oldNode == null;
-					}
-				}
-			}
-		}
-		if (calls != null) {
-			createMappingStatements(calls);
-		}
-	}
-
 	private @NonNull OCLExpression createVariableExp(@NonNull Node node) {
 		if (node.isExplicitNull()) {
 			return helper.createNullLiteralExp();
@@ -1507,6 +1718,24 @@
 		return (MappingParameter) variable;
 	}
 
+	public @NonNull Set<@NonNull Node> getPrecedingNodes(@NonNull Node targetNode) {
+		Map<@NonNull Node, @NonNull Set<@NonNull Node>> node2precedingNodeClosure2 = node2precedingNodeClosure;
+		if (node2precedingNodeClosure2 == null) {
+			node2precedingNodeClosure = node2precedingNodeClosure2 = new HashMap<>();
+		}
+		Set<@NonNull Node> precedingNodes = node2precedingNodeClosure2.get(targetNode);
+		if (precedingNodes == null) {
+			precedingNodes = new HashSet<>();
+			node2precedingNodeClosure2.put(targetNode, precedingNodes);
+			precedingNodes.add(targetNode);
+			for (@NonNull Node sourceNode : reachabilityForest.getPredecessors(targetNode)) {
+				precedingNodes.addAll(getPrecedingNodes(sourceNode));
+			}
+		}
+		assert precedingNodes.size() > 0;
+		return precedingNodes;
+	}
+
 	private @NonNull VariableDeclaration getSubexpressionDeclaration(@NonNull Node node) {
 		VariableDeclaration variable = node2variable.get(node);
 		if (variable == null) {
@@ -1535,6 +1764,15 @@
 		return variable; */
 	}
 
+	private boolean isHazardousWrite(@NonNull NavigableEdge edge) {
+		Node sourceNode = edge.getEdgeSource();
+		Property asProperty = edge.getProperty();
+		TypedModel typedModel = RegionUtil.getTypedModel(RegionUtil.getClassDatumAnalysis(sourceNode));
+		RegionAnalysis regionAnalysis = RegionAnalysis.get(region);
+		Iterable<@NonNull NavigableEdge> enforcedEdges = regionAnalysis.getEnforcedEdges(typedModel, asProperty);
+		return enforcedEdges != null;
+	}
+
 	private boolean isIfExp(@NonNull Node node) {
 		if (node.isExpression()) {
 			for (TypedElement typedElement : node.getTypedElements()) {
@@ -1545,24 +1783,6 @@
 		}
 		return false;
 	}
-
-	private boolean isHazardousWrite(@NonNull NavigableEdge edge) {
-		Node sourceNode = edge.getEdgeSource();
-		Property asProperty = edge.getProperty();
-		TypedModel typedModel = RegionUtil.getTypedModel(RegionUtil.getClassDatumAnalysis(sourceNode));
-		Iterable<@NonNull NavigableEdge> enforcedEdges = RegionAnalysis.get(region).getEnforcedEdges(typedModel);
-		if (enforcedEdges != null) {
-			Property asOppositeProperty = asProperty.getOpposite();
-			for (@NonNull NavigableEdge enforcedEdge : enforcedEdges) {
-				Property edgeProperty = enforcedEdge.getProperty();
-				if ((edgeProperty == asProperty) || (edgeProperty == asOppositeProperty)) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
 	@Override
 	public boolean isInfinite() {
 		if (region.getRecursionEdges().iterator().hasNext()) {		// FIXME unduly pessimistic
@@ -1613,6 +1833,53 @@
 	}
 
 	@Override
+	public void synthesizeCallStatements() {
+		Map<@NonNull Region, @NonNull Map<@NonNull Node, @NonNull Node>> calls = null;
+		for (@NonNull Region calledRegion : region.getCallableChildren()) {
+			if (calls == null) {
+				calls = new HashMap<>();
+			}
+			Map<@NonNull Node, @NonNull Node> source2target = calls.get(calledRegion);
+			if (source2target == null) {
+				source2target = new HashMap<>();
+				calls.put(calledRegion, source2target);
+			}
+			AbstractRegion2Mapping calledRegion2Mapping = visitor.getRegion2Mapping(calledRegion);
+			for (@NonNull Node calledGuardNode : calledRegion2Mapping.getGuardNodes()) {
+				for (@NonNull Node callingNode : calledGuardNode.getPassedBindingSources()) {
+					if (callingNode.getOwningRegion() == region) {
+						Node oldNode = source2target.put(callingNode, calledGuardNode);
+						assert oldNode == null;
+					}
+				}
+				for (@NonNull Node callingNode : calledGuardNode.getUsedBindingSources()) {
+					if (callingNode.getOwningRegion() == region) {
+						Node oldNode = source2target.put(callingNode, calledGuardNode);
+						assert oldNode == null;
+					}
+				}
+			}
+		}
+		if (calls != null) {
+			createCallStatements(calls);
+		}
+	}
+
+	/**
+	 * Create all the statements that support the local content of this micromapping.
+	 */
+	@Override
+	public void synthesizeLocalStatements() {
+		createHeadAndGuardNodeVariables();			// BLUE/CYAN guard/append nodes
+		createPatternMatch();						// BLUE/CYAN nodes and edges
+		createRealizedVariables();					// GREEN nodes
+		createPropertyAssignments();				// GREEN edges
+		createAddStatements();						// export to append nodes
+		createRealizedIncludesAssignments();
+		createObservedProperties();					// wrap observable clauses around hazardous accesses
+	}
+
+	@Override
 	public @NonNull String toString() {
 		return String.valueOf(region);
 	}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/NavigationEdgeSorter.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/NavigationEdgeSorter.java
index 6447df8..e03429a 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/NavigationEdgeSorter.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/NavigationEdgeSorter.java
@@ -29,8 +29,8 @@
 import com.google.common.collect.Lists;
 
 /**
- * NavigationEdgeSorter supports ordering of a list of NavigationEdges  into least-dependent first order thereby ensuring
- * that unrealized variables are created and initualized for accessed realized attribute nodes before they are used.
+ * NavigationEdgeSorter supports ordering of a list of NavigationEdges into least-dependent first order thereby ensuring
+ * that unrealized variables are created and initialized for accessed realized attribute nodes before they are used.
  */
 public class NavigationEdgeSorter
 {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/NavigationForestBuilder.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/NavigationForestBuilder.java
deleted file mode 100644
index 1db77cc..0000000
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/NavigationForestBuilder.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2015, 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.compiler.internal.qvts2qvti;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.ocl.pivot.utilities.NameUtil;
-import org.eclipse.qvtd.compiler.internal.qvtm2qvts.RegionUtil;
-import org.eclipse.qvtd.pivot.qvtschedule.Edge;
-import org.eclipse.qvtd.pivot.qvtschedule.NavigableEdge;
-import org.eclipse.qvtd.pivot.qvtschedule.Node;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-/**
- * A NavigationForestBuilder selects a forest of navigable edges to reach each navigable node from its heads.
- */
-class NavigationForestBuilder implements Comparator<@NonNull Edge>
-{
-	/**
-	 * The preferred non-secondary edges to be used in the tree.
-	 */
-	private final @NonNull Set<@NonNull Edge> forwardEdges = new HashSet<>();
-
-	/**
-	 * Edges that have no opposite.
-	 */
-	private final @NonNull Set<@NonNull NavigableEdge> manyToOneEdges = new HashSet<>();
-
-	/**
-	 * The edges that are traversed while locating each node and their depth in the traversal forest, 0 at edge sourced by root.
-	 */
-	private final @NonNull Map<@NonNull Edge, @NonNull Integer> traversedEdge2depth = new HashMap<>();
-
-	/**
-	 * The nodes that are traversed while locating each node and their depth in the traversal forest, 0 at root.
-	 */
-	//	private final @NonNull Map<@NonNull Node, @NonNull Integer> traversedNode2depth = new HashMap<>();
-
-	/**
-	 * The incoming edge for each node in the traversal forest, null at a root.
-	 */
-	private final @NonNull Map<@NonNull Node, @Nullable Edge> traversedNode2incomingEdge = new HashMap<>();
-
-	/**
-	 * The nodes that form the traversal forest.
-	 */
-	//	private final @NonNull Set<@NonNull Node> navigableNodes = new HashSet<>();
-
-	/**
-	 * The other edges that are traversed while traversing a primary operation input.
-	 */
-	private final @NonNull Set<@NonNull Edge> otherTraversedEdges = new HashSet<>();
-
-	/**
-	 * The edges that are not traversed while locating each node.
-	 */
-	private final @NonNull Set<@NonNull Edge> untraversedEdges = new HashSet<>();
-
-	public NavigationForestBuilder(@NonNull Iterable<@NonNull Node> rootNodes, @NonNull Iterable<@NonNull Edge> edges) {
-		for (@NonNull Node rootNode : rootNodes) {
-			traversedNode2incomingEdge.put(rootNode, null);
-		}
-		for (@NonNull Edge edge : edges) {
-			addEdge(edge);
-		}
-		//
-		//	Analyze the descendants of the roots to identify the most simply navigated forest.
-		//
-		analyze(traversedNode2incomingEdge.keySet());
-		//
-		//	Traverse the attributes too.
-		//
-		/*		for (@NonNull NavigationEdge edge : attributeEdges) {
-			Node targetNode = edge.getTarget();
-			if (!traversedNode2incomingEdge.containsKey(targetNode)) {
-				traversedNode2incomingEdge.put(targetNode, edge);
-			}
-			else {
-				untraversedEdges.add(edge);
-			}
-		} */
-		//
-		//	Identify the remaining untraversed edges that are not used to reach nodes and so must be reified as predicates to check nodes.
-		//
-		Set<@NonNull Edge> predicateEdges = Sets.newHashSet(forwardEdges);
-		for (@NonNull Edge traversedEdge : getTraversedEdges()) {
-			predicateEdges.remove(traversedEdge);
-			if (traversedEdge.isNavigation()) {
-				NavigableEdge oppositeEdge = ((NavigableEdge)traversedEdge).getOppositeEdge();
-				if (oppositeEdge != null) {
-					predicateEdges.remove(oppositeEdge);
-				}
-			}
-		}
-		predicateEdges.removeAll(otherTraversedEdges);
-		untraversedEdges.addAll(predicateEdges);
-	}
-
-	/**
-	 * Add a possible edge and end nodes categorizing a navigable edge as forward if it is a sole or primary edge,
-	 * reverse if it is a secondary edge.
-	 */
-	protected void addEdge(@NonNull Edge edge) {
-		if (edge.isRealized()) {}
-		else if (edge.isCast()) {}
-		else {
-			//			assert !edge.isExpression();
-			//			assert !edge.isComputation();
-			Node targetNode = edge.getEdgeTarget();
-			targetNode = RegionUtil.getCastTarget(targetNode);
-			if (!edge.isSecondary()) {
-				forwardEdges.add(edge);
-				if ((edge.getEdgeSource().isClass()) && (edge instanceof NavigableEdge)) {
-					NavigableEdge navigableEdge = (NavigableEdge)edge;
-					if (navigableEdge.getOppositeEdge() == null) {
-						manyToOneEdges.add((NavigableEdge)edge);
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * Identify the forest from the given roots.
-	 */
-	public void analyze(@NonNull Iterable<@NonNull Node> rootNodes) {
-		Set<@NonNull Node> moreNodes = Sets.newHashSet(rootNodes);
-		//
-		//	Advance breadth first, one depth at a time, accumulating all edges that make one stage of progress.
-		//
-		for (int depth = 0; moreNodes.size() > 0; depth++) {
-			//
-			//	Select the forward edges that make progress.
-			//
-			Set<@NonNull Node> moreMoreNodes = new HashSet<>();
-			for (@NonNull Node sourceNode : moreNodes) {
-				//				traversedNode2depth.put(sourceNode, depth);
-				for (@NonNull Edge forwardEdge : RegionUtil.getOutgoingEdges(sourceNode)) {
-					if (forwardEdges.contains(forwardEdge)) {
-						Node targetNode = RegionUtil.getCastTarget(forwardEdge.getEdgeTarget());
-						if (forwardEdge.isNavigation()) {
-							if (!traversedNode2incomingEdge.containsKey(targetNode)) {
-								traversedNode2incomingEdge.put(targetNode, forwardEdge);
-								moreMoreNodes.add(targetNode);
-								traversedEdge2depth.put(forwardEdge, depth);
-							}
-						}
-						else if (forwardEdge.isExpression()) {
-							boolean allReady = true;
-							for (@NonNull Edge incomingEdge : RegionUtil.getIncomingEdges(targetNode)) {
-								if (incomingEdge.isExpression()) {
-									Node expressionSourceNode = incomingEdge.getSourceNode();
-									if (!traversedNode2incomingEdge.containsKey(expressionSourceNode)) {
-										allReady = false;
-										break;
-									}
-								}
-							}
-							if (allReady) {
-								for (@NonNull Edge incomingEdge : RegionUtil.getIncomingEdges(targetNode)) {
-									if (incomingEdge.isExpression()) {
-										traversedEdge2depth.put(incomingEdge, depth);
-										if (incomingEdge != forwardEdge) {
-											otherTraversedEdges.add(incomingEdge);
-										}
-									}
-								}
-								traversedNode2incomingEdge.put(targetNode, forwardEdge);
-								if (!targetNode.getOutgoingEdges().isEmpty()) {
-									moreMoreNodes.add(targetNode);
-								}
-							}
-						}
-						else {
-							assert false;
-						}
-					}
-				}
-			}
-			if (moreMoreNodes.isEmpty()) {
-				//
-				//	If no forward edge makes progress, select just one backward edge instead.
-				//
-				for (@NonNull Edge forwardEdge : forwardEdges) {		// FIXME maintain reducing list of possibles
-					if (forwardEdge instanceof NavigableEdge) {
-						NavigableEdge navigableForwardEdge = (NavigableEdge)forwardEdge;
-						@Nullable NavigableEdge backwardEdge = navigableForwardEdge.getOppositeEdge();
-						if (backwardEdge != null) {
-							Node sourceNode = backwardEdge.getEdgeSource();
-							if (traversedNode2incomingEdge.containsKey(sourceNode)) {
-								Node targetNode = backwardEdge.getEdgeTarget();
-								if (!traversedNode2incomingEdge.containsKey(targetNode)) {
-									traversedNode2incomingEdge.put(targetNode, backwardEdge);
-									moreMoreNodes.add(targetNode);
-									traversedEdge2depth.put(backwardEdge, depth);
-									break;
-								}
-							}
-						}
-					}
-				}
-				if (moreMoreNodes.isEmpty()) {
-					//
-					//	If no backward edge makes progress, select just one inverse edge instead.
-					//
-					for (@NonNull NavigableEdge manyToOneEdge : manyToOneEdges) {		// FIXME maintain reducing list of possibles
-						Node sourceNode = manyToOneEdge.getEdgeTarget();
-						if (traversedNode2incomingEdge.containsKey(sourceNode)) {
-							Node targetNode = manyToOneEdge.getEdgeSource();
-							if (!traversedNode2incomingEdge.containsKey(targetNode)) {
-								traversedNode2incomingEdge.put(targetNode, manyToOneEdge);
-								moreMoreNodes.add(targetNode);
-								traversedEdge2depth.put(manyToOneEdge, depth);
-								break;
-							}
-						}
-					}
-				}
-			}
-			moreNodes = moreMoreNodes;
-		}
-	}
-
-	/**
-	 *	Select the shallowest first then alphabetical ordering of the traversal edges of the forest.
-	 *
-	 * FIXME prioritize fallible predicate paths
-	 */
-	@Override
-	public int compare(@NonNull Edge o1, @NonNull Edge o2) {
-		Integer d1 = traversedEdge2depth.get(o1);
-		Integer d2 = traversedEdge2depth.get(o2);
-		assert (d1 != null) && (d2 != null);
-		if (d1 != d2) {
-			return d1 - d2;
-		}
-		String n1 = o1.getDisplayName();
-		String n2 = o2.getDisplayName();
-		return n1.compareTo(n2);
-	}
-
-	/**
-	 *	Return a shallowest first then alphabetical ordering of the traversal edges of the forest.
-	 */
-	public @NonNull List<@NonNull Edge> getForestNavigations() {
-		List<@NonNull Edge> forestNavigations = Lists.newArrayList(getTraversedEdges());
-		forestNavigations.removeAll(otherTraversedEdges);
-		Collections.sort(forestNavigations, this);
-		return forestNavigations;
-	}
-
-	/**
-	 *	Return an alphabetical ordering of the residual edges to be checked as predicates.
-	 */
-	public @NonNull List<@NonNull Edge> getGraphPredicates() {
-		List<@NonNull Edge> graphPredicateEdges = new ArrayList<>();
-		for (@NonNull Edge untraversedEdge : untraversedEdges) {
-			graphPredicateEdges.add(untraversedEdge);
-		}
-		Collections.sort(graphPredicateEdges, NameUtil.NAMEABLE_COMPARATOR);
-		return graphPredicateEdges;
-	}
-
-	protected @NonNull Iterable<@NonNull Edge> getTraversedEdges() {
-		return traversedEdge2depth.keySet();
-	}
-}
\ No newline at end of file
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 79ada5e..0dbe92a 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
@@ -194,6 +194,7 @@
 		else {
 			region2mapping = new BasicRegion2Mapping(this, region);
 		}
+		region2mapping.synthesizeLocalStatements();
 		region2region2mapping.put(region, region2mapping);
 		qvtiTransformation.getRule().add(region2mapping.getMapping());
 		region.accept(this);
@@ -456,7 +457,7 @@
 		for (@NonNull Region region : sortedRegions) {
 			//			if (!region.isConnectionRegion()) {
 			AbstractRegion2Mapping region2Mapping = getRegion2Mapping(region);
-			region2Mapping.createSchedulingStatements();
+			region2Mapping.synthesizeCallStatements();
 			//			}
 		}
 		// Mappings are in schedule index order.
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/RootRegion2Mapping.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/RootRegion2Mapping.java
index 753adc7..57386b8 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/RootRegion2Mapping.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/RootRegion2Mapping.java
@@ -66,21 +66,6 @@
 
 	public RootRegion2Mapping(@NonNull QVTs2QVTiVisitor visitor, @NonNull LoadingRegion region) {
 		super(visitor, region);
-		//
-		//	Create domains
-		//
-		Set<@NonNull ImperativeTypedModel> checkableTypedModels = new HashSet<>();
-		for (@NonNull Node node : RegionUtil.getOwnedNodes(region)) {
-			ClassDatum classDatum = node.getClassDatum();
-			org.eclipse.ocl.pivot.Class type = classDatum.getCompleteClass().getPrimaryClass();
-			if (!(type instanceof DataType) && !(type instanceof AnyType) && !(type instanceof VoidType) && !(type instanceof InvalidType)) {
-				TypedModel qvtmTypedModel = classDatum.getReferredTypedModel();
-				ImperativeTypedModel qvtiTypedModel = visitor.getQVTiTypedModel(qvtmTypedModel);
-				if (qvtiTypedModel != null) {
-					checkableTypedModels.add(qvtiTypedModel);
-				}
-			}
-		}
 	}
 
 	private @NonNull ConnectionVariable createRootConnectionVariable(@NonNull String name, boolean isStrict, @NonNull Type type, @Nullable OCLExpression initExpression) {
@@ -123,78 +108,6 @@
 	}
 
 	@Override
-	public void createSchedulingStatements() {
-		//		BottomPattern bottomPattern = mapping.getBottomPattern();
-		createRootConnectionVariables();
-		/*		//
-		//	Cache the children in a middle bottom pattern variable.
-		//
-		OCLExpression parentExpression = createVariableExp(headNode);
-		OCLExpression initExpression = PivotUtil.createNavigationCallExp(parentExpression, property);
-		Type asType = initExpression.getType();
-		if (!(asType instanceof CollectionType)) {
-			initExpression = createOclAsSetCallExp(initExpression);
-			asType = initExpression.getType();
-		}
-		assert asType != null;
-		Variable childrenVariable = PivotUtil.createVariable(getSafeName("allChildren"), asType, true, initExpression);
-		mapping.getBottomPattern().getVariable().add(childrenVariable); */
-		//
-		//	Create union assignments for connections.
-		//
-		//		if (connection2variable != null) {
-		/*			Operation asOperation = NameUtil.getNameable(visitor.getStandardLibrary().getCollectionType().getOwnedOperations(), "union");
-			for (Node node : region.getNodes()) {
-				if (node.isComposed()) {
-					for (InterRegionEdge edge : node.getOutgoingPassedBindingEdges()) {
-						Node connectionNode = edge.getTarget();
-						Region connectionRegion = connectionNode.getRegion();
-						Variable connectionVariable = connection2variable.get(connectionRegion);
-						if (connectionVariable != null) {
-							OCLExpression collection1 = helper.createVariableExp(connectionVariable);
-							OCLExpression collection2 = createSelectByKind(node);
-							OCLExpression union = createOperationCallExp(collection1, asOperation, collection2);
-							VariableAssignment variableAssignment = QVTcoreBaseFactory.eINSTANCE.createVariableAssignment();
-							variableAssignment.setTargetVariable(connectionVariable);
-							variableAssignment.setValue(union);
-							bottomPattern.getAssignment().add(variableAssignment);
-						}
-					}
-				}
-			}
-			bottomPattern.getVariable().addAll(connection2variable.values());
-//		} */
-		/*		ChainNode chain = visitor.getChain(region);
-		for (ChainNode child : chain.getChildren()) {
-			Region calledRegion = child.getRegion();
-			if (!calledRegion.isConnectionRegion()) {
-				mappingStatement = createCalls(mappingStatement, calledRegion);
-			}
-			else if (Iterables.isEmpty(child.getChildren())) {
-//				mappingStatement = createCalls(mappingStatement, calledRegion);
-			}
-			else {
-				assert calledRegion.isConnectionRegion();
-				assert !Iterables.isEmpty(child.getChildren());
-				for (ChainNode connectionChild : child.getChildren()) {
-					Region connectionedRegion = connectionChild.getRegion();
-					assert !connectionedRegion.isConnectionRegion();
-					mappingStatement = createCalls(mappingStatement, connectionedRegion);
-				}
-			}
-		} */
-		List<Statement> ownedStatements = mapping.getOwnedStatements();
-		for (@NonNull Region callableRegion : region.getCallableChildren()) {
-			if (isInstall(callableRegion)) {
-				ownedStatements.add(createInstall(callableRegion));
-			}
-			else {
-				ownedStatements.add(createCall(callableRegion, null));
-			}
-		}
-	}
-
-	@Override
 	protected @NonNull OCLExpression createSelectByKind(@NonNull Node resultNode) {
 		throw new UnsupportedOperationException();
 		/*refactored code inlined at call point -- ?? ok, but needs usage analysis
@@ -267,4 +180,95 @@
 		}
 		return true;
 	}
+
+	@Override
+	public void synthesizeCallStatements() {
+		//		BottomPattern bottomPattern = mapping.getBottomPattern();
+		createRootConnectionVariables();
+		/*		//
+			//	Cache the children in a middle bottom pattern variable.
+			//
+			OCLExpression parentExpression = createVariableExp(headNode);
+			OCLExpression initExpression = PivotUtil.createNavigationCallExp(parentExpression, property);
+			Type asType = initExpression.getType();
+			if (!(asType instanceof CollectionType)) {
+				initExpression = createOclAsSetCallExp(initExpression);
+				asType = initExpression.getType();
+			}
+			assert asType != null;
+			Variable childrenVariable = PivotUtil.createVariable(getSafeName("allChildren"), asType, true, initExpression);
+			mapping.getBottomPattern().getVariable().add(childrenVariable); */
+		//
+		//	Create union assignments for connections.
+		//
+		//		if (connection2variable != null) {
+		/*			Operation asOperation = NameUtil.getNameable(visitor.getStandardLibrary().getCollectionType().getOwnedOperations(), "union");
+				for (Node node : region.getNodes()) {
+					if (node.isComposed()) {
+						for (InterRegionEdge edge : node.getOutgoingPassedBindingEdges()) {
+							Node connectionNode = edge.getTarget();
+							Region connectionRegion = connectionNode.getRegion();
+							Variable connectionVariable = connection2variable.get(connectionRegion);
+							if (connectionVariable != null) {
+								OCLExpression collection1 = helper.createVariableExp(connectionVariable);
+								OCLExpression collection2 = createSelectByKind(node);
+								OCLExpression union = createOperationCallExp(collection1, asOperation, collection2);
+								VariableAssignment variableAssignment = QVTcoreBaseFactory.eINSTANCE.createVariableAssignment();
+								variableAssignment.setTargetVariable(connectionVariable);
+								variableAssignment.setValue(union);
+								bottomPattern.getAssignment().add(variableAssignment);
+							}
+						}
+					}
+				}
+				bottomPattern.getVariable().addAll(connection2variable.values());
+	//		} */
+		/*		ChainNode chain = visitor.getChain(region);
+			for (ChainNode child : chain.getChildren()) {
+				Region calledRegion = child.getRegion();
+				if (!calledRegion.isConnectionRegion()) {
+					mappingStatement = createCalls(mappingStatement, calledRegion);
+				}
+				else if (Iterables.isEmpty(child.getChildren())) {
+	//				mappingStatement = createCalls(mappingStatement, calledRegion);
+				}
+				else {
+					assert calledRegion.isConnectionRegion();
+					assert !Iterables.isEmpty(child.getChildren());
+					for (ChainNode connectionChild : child.getChildren()) {
+						Region connectionedRegion = connectionChild.getRegion();
+						assert !connectionedRegion.isConnectionRegion();
+						mappingStatement = createCalls(mappingStatement, connectionedRegion);
+					}
+				}
+			} */
+		List<Statement> ownedStatements = mapping.getOwnedStatements();
+		for (@NonNull Region callableRegion : region.getCallableChildren()) {
+			if (isInstall(callableRegion)) {
+				ownedStatements.add(createInstall(callableRegion));
+			}
+			else {
+				ownedStatements.add(createCall(callableRegion, null));
+			}
+		}
+	}
+
+	@Override
+	public void synthesizeLocalStatements() {
+		//
+		//	Create domains
+		//
+		Set<@NonNull ImperativeTypedModel> checkableTypedModels = new HashSet<>();
+		for (@NonNull Node node : RegionUtil.getOwnedNodes(region)) {
+			ClassDatum classDatum = node.getClassDatum();
+			org.eclipse.ocl.pivot.Class type = classDatum.getCompleteClass().getPrimaryClass();
+			if (!(type instanceof DataType) && !(type instanceof AnyType) && !(type instanceof VoidType) && !(type instanceof InvalidType)) {
+				TypedModel qvtmTypedModel = classDatum.getReferredTypedModel();
+				ImperativeTypedModel qvtiTypedModel = visitor.getQVTiTypedModel(qvtmTypedModel);
+				if (qvtiTypedModel != null) {
+					checkableTypedModels.add(qvtiTypedModel);
+				}
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/utilities/ReachabilityForest.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/utilities/ReachabilityForest.java
new file mode 100644
index 0000000..fbaa3dc
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/utilities/ReachabilityForest.java
@@ -0,0 +1,320 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 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.compiler.internal.qvts2qvts.utilities;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.utilities.ClassUtil;
+import org.eclipse.qvtd.compiler.internal.qvtm2qvts.RegionUtil;
+import org.eclipse.qvtd.pivot.qvtschedule.Edge;
+import org.eclipse.qvtd.pivot.qvtschedule.NavigableEdge;
+import org.eclipse.qvtd.pivot.qvtschedule.Node;
+import com.google.common.collect.Lists;
+
+/**
+ * The ReachabilityForest comprises a tree of preferred edge paths from each head/leaf-constant root node to the
+ * nodes that can be reached from them. It answers the question: what preceding nodes are necessary to ensure
+ * that a given node is reachable.
+ */
+public class ReachabilityForest
+{
+	private static final int FORWARD_NAVIGATION_COST = 1;
+	private static final int INVERSE_MANY_NAVIGATION_COST = 5;
+	private static final int INVERSE_NAVIGATION_COST = 3;
+	private static final int ITERATOR_COST = 1;
+	private static final int OPERATION_COST = 10;
+	private static final int RESULT_COST = 1;
+
+	/**
+	 * The preferred non-secondary edges to be used in the tree.
+	 */
+	private final @NonNull Set<@NonNull NavigableEdge> forwardEdges = new HashSet<>();
+
+	/**
+	 * Edges that have no opposite.
+	 */
+	private final @NonNull Set<@NonNull Edge> manyToOneEdges = new HashSet<>();
+
+	/**
+	 * The incoming edge for each node in the traversal forest, null at a root.
+	 */
+	private final @NonNull Map<@NonNull Node, @Nullable Edge> node2reachingEdge = new HashMap<>();
+
+	/**
+	 * The cost for each node from the root in the traversal forest, 0 at a root. The cost is equal
+	 * to the sum of the costs of each edge on the lowest cost path from the root.
+	 */
+	private @NonNull Map<@NonNull Node, @NonNull Integer> node2cost = new HashMap<>();
+
+	/**
+	 * Lazily created compartor to order nodes lowest cost first.
+	 */
+	private @Nullable Comparator<@NonNull Edge> edgeCostComparator = null;
+
+	/**
+	 * Lazily created compartor to order nodes lowest cost first.
+	 */
+	private @Nullable Comparator<@NonNull Node> nodeCostComparator = null;
+
+
+	/**
+	 * Construct the Reachability forest for the specified rootNodes using the availableNavigableEdges to locate
+	 * paths to further nodes and also any old computation edges.
+	 */
+	public ReachabilityForest(@NonNull Iterable<@NonNull Node> rootNodes, @NonNull Iterable<@NonNull NavigableEdge> availableNavigableEdges) {
+		for (@NonNull Node rootNode : rootNodes) {
+			node2reachingEdge.put(rootNode, null);
+		}
+		for (@NonNull NavigableEdge edge : availableNavigableEdges) {
+			addEdge(edge);
+		}
+		//
+		//	Analyze the descendants of the roots to identify the most simply navigated forest.
+		//
+		analyze(node2reachingEdge.keySet());
+	}
+
+	protected void addEdge(@NonNull NavigableEdge edge) {
+		if (!edge.isSecondary()) {
+			forwardEdges.add(edge);
+			if ((edge.getEdgeSource().isClass()) && (edge.getOppositeEdge() == null)) {
+				manyToOneEdges.add(edge);
+			}
+		}
+	}
+
+	/**
+	 * Identify the forest from the given roots.
+	 */
+	protected void analyze(@NonNull Iterable<@NonNull Node> rootNodes) {
+		List<@Nullable List<@NonNull Node>> costs2nodes = new ArrayList<>();
+		for (@NonNull Node rootNode : rootNodes) {
+			node2cost.put(rootNode, 0);
+		}
+		costs2nodes.add(Lists.newArrayList(rootNodes));
+		//
+		//	Advance breadth first, one cost at a time, accumulating all edges that make one stage of progress.
+		//
+		for (int thisCost = 0; thisCost < costs2nodes.size(); thisCost++) {
+			List<@NonNull Node> thisCostNodes = costs2nodes.get(thisCost);
+			if (thisCostNodes != null) {
+				//
+				//	Add the forward edges that make progress to moreMoreNodes and remember the
+				//	backward and inverse edges in case forward egdes alone are inadequate.
+				//
+				for (@NonNull Node sourceNode : thisCostNodes) {
+					assert node2cost.get(sourceNode) == thisCost;
+					for (@NonNull Edge edge : RegionUtil.getOutgoingEdges(sourceNode)) {
+						Node targetNode = edge.getEdgeTarget();
+						if (!node2reachingEdge.containsKey(targetNode)) {
+							Integer targetCost = node2cost.get(targetNode);
+							assert (targetCost == null) || (thisCost < targetCost);
+							if (edge.isNavigation()) {
+								NavigableEdge navigableEdge = (NavigableEdge) edge;
+								if (forwardEdges.contains(navigableEdge)) {
+									int nextCost = thisCost + FORWARD_NAVIGATION_COST;
+									if ((targetCost == null) || (nextCost < targetCost)) {
+										node2cost.put(targetNode, nextCost);
+										node2reachingEdge.put(targetNode, edge);
+										putCosts(costs2nodes, nextCost, targetNode);
+									}
+								}
+								else {
+									NavigableEdge oppositeEdge = navigableEdge.getOppositeEdge();
+									if (forwardEdges.contains(oppositeEdge)) {
+										int nextCost = thisCost + INVERSE_NAVIGATION_COST;
+										if ((targetCost == null) || (nextCost < targetCost)) {
+											node2cost.put(targetNode, nextCost);
+											node2reachingEdge.put(targetNode, oppositeEdge);
+											putCosts(costs2nodes, nextCost, targetNode);
+										}
+									}
+									else if (manyToOneEdges.contains(oppositeEdge)) {
+										int nextCost = thisCost + INVERSE_MANY_NAVIGATION_COST;
+										if ((targetCost == null) || (nextCost < targetCost)) {
+											node2cost.put(targetNode, nextCost);
+											node2reachingEdge.put(targetNode, oppositeEdge);
+											putCosts(costs2nodes, nextCost, targetNode);
+										}
+									}
+								}
+							}
+							else if (edge.isComputation() /*&& edge.isUnconditional()*/) {
+								int nextCost = thisCost + OPERATION_COST;
+								if (targetNode.isOperation()) {
+									for (@NonNull Edge incomingEdge : RegionUtil.getIncomingEdges(targetNode)) {
+										if (incomingEdge.isOld() && incomingEdge.isComputation()) {
+											Node node = RegionUtil.getSourceNode(incomingEdge);
+											Integer cost = node2cost.get(node);
+											if ((cost == null) || (cost > thisCost)) {
+												nextCost = -1;
+												break;
+											}
+										}
+									}
+								}
+								else if (targetNode.isIterator()) {
+									nextCost = thisCost + ITERATOR_COST;
+								}
+								else {
+									nextCost = thisCost + RESULT_COST;
+								}
+								if (nextCost > 0) {
+									if ((targetCost == null) || (nextCost < targetCost)) {
+										node2cost.put(targetNode, nextCost);
+										node2reachingEdge.put(targetNode, edge);
+										putCosts(costs2nodes, nextCost, targetNode);
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	public @Nullable Integer getCost(@NonNull Node node) {
+		return node2cost.get(node);
+	}
+
+	/**
+	 * Return a comparator to sort edges source cost first then target cost then alphabetically.
+	 */
+	public @NonNull Comparator<@NonNull Edge> getEdgeCostComparator() {
+		Comparator<@NonNull Edge> edgeCostComparator2 = edgeCostComparator;
+		if (edgeCostComparator2 == null) {
+			edgeCostComparator = edgeCostComparator2 = new Comparator<@NonNull Edge>()
+			{
+				@Override
+				public int compare(@NonNull Edge e1, @NonNull Edge e2) {
+					Integer d1s = node2cost.get(RegionUtil.getSourceNode(e1));
+					Integer d1t = node2cost.get(RegionUtil.getTargetNode(e1));
+					Integer d2s = node2cost.get(RegionUtil.getSourceNode(e2));
+					Integer d2t = node2cost.get(RegionUtil.getTargetNode(e2));
+					assert (d1s != null) && (d1t != null) && (d2s != null) && (d2t != null);
+					int d1 = Math.max(d1s,  d1t);
+					int d2 = Math.max(d2s,  d2t);
+					if (d1 != d2) {
+						return d1 - d2;
+					}
+					if (d1s != d2s) {
+						return d1s - d2s;
+					}
+					return ClassUtil.safeCompareTo(e1.getDisplayName(), e2.getDisplayName());
+				}
+			};
+		}
+		return edgeCostComparator2;
+	}
+
+	/**
+	 * Return a comparator to sort nodes cost first then alphabetically.
+	 */
+	public @NonNull Comparator<@NonNull Node> getNodeCostComparator() {
+		Comparator<@NonNull Node> nodeCostComparator2 = nodeCostComparator;
+		if (nodeCostComparator2 == null) {
+			nodeCostComparator = nodeCostComparator2 = new Comparator<@NonNull Node>()
+			{
+				@Override
+				public int compare(@NonNull Node o1, @NonNull Node o2) {
+					Integer c1 = node2cost.get(o1);
+					Integer c2 = node2cost.get(o2);
+					assert (c1 != null) && (c2 != null);
+					int diff = c1 - c2;
+					if (diff != 0) {
+						return diff;
+					}
+					return ClassUtil.safeCompareTo(o1.getName(), o2.getName());
+				}
+			};
+		}
+		return nodeCostComparator2;
+	}
+
+	public @NonNull Iterable<@NonNull Node> getPredecessors(@NonNull Node targetNode) {
+		Set<@NonNull Node> precedingNodes = new HashSet<@NonNull Node>();
+		getPredecessors(precedingNodes, targetNode);
+		precedingNodes.remove(targetNode);
+		return precedingNodes;
+	}
+	private void getPredecessors(@NonNull Set<@NonNull Node> precedingNodes, @NonNull Node targetNode) {
+		if (precedingNodes.add(targetNode)) {
+			if (targetNode.isOperation()) {
+				for (@NonNull Edge edge : RegionUtil.getIncomingEdges(targetNode)) {
+					//					assert edge.isUnconditional();
+					if (edge.isComputation()) {
+						getPredecessors(precedingNodes, edge.getEdgeSource());
+					}
+				}
+			}
+			else {
+				Edge parentEdge = getReachingEdge(targetNode);
+				if (parentEdge != null) {
+					Node sourceNode = parentEdge.getEdgeSource();
+					if (sourceNode == targetNode) {		// invert a backward edge
+						sourceNode = parentEdge.getEdgeTarget();
+					}
+					getPredecessors(precedingNodes, sourceNode);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Return the edge from the preceding reachable node to the given reachable node. Null if none.
+	 */
+	public @Nullable Edge getReachingEdge(@NonNull Node node) {
+		return node2reachingEdge.get(node);
+	}
+
+	private void putCosts(@NonNull List<@Nullable List<@NonNull Node>> costs2nodes, int cost, @NonNull Node node) {
+		while (costs2nodes.size() <= cost) {
+			costs2nodes.add(null);
+		}
+		List<@NonNull Node> nodes = costs2nodes.get(cost);
+		if (nodes == null) {
+			nodes = new ArrayList<>();
+			costs2nodes.set(cost, nodes);
+		}
+		if (!nodes.contains(node)) {
+			nodes.add(node);
+		}
+	}
+
+	@Override
+	public @NonNull String toString() {
+		Comparator<@NonNull Node> nodeComparator = getNodeCostComparator();
+		StringBuilder s = new StringBuilder();
+		List<@NonNull Node> nodes = new ArrayList<>(node2cost.keySet());
+		Collections.sort(nodes, nodeComparator);
+		for (@NonNull Node node : nodes) {
+			if (s.length() > 0) {
+				s.append("\n");
+			}
+			s.append(node2cost.get(node));
+			s.append(": ");
+			s.append(node.getName());
+			s.append(" : ");
+			s.append(node2reachingEdge.get(node));
+		}
+		return s.toString();
+	}
+}
\ No newline at end of file
