[530054] Flattened residual SharedEdge / DataType relation experiment
diff --git a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java
index aade368..10d2e2a 100644
--- a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java
+++ b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java
@@ -453,6 +453,9 @@
 			else if (QVTimperativeUtil.isObserver(asMapping)) {
 				useClassMappings.add(asMapping);
 			}
+			else if (QVTimperativeUtil.isDataType(asMapping)) {
+				useClassMappings.add(asMapping);
+			}
 		}
 		if (useClassMappings.size() > 0) {
 			useClassMappings.add(QVTimperativeUtil.getRootMapping(asTransformation));
diff --git a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java
index 8ee38f8..0654409 100644
--- a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java
+++ b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCG2JavaVisitor.java
@@ -12,6 +12,7 @@
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -246,11 +247,18 @@
 			js.append("().");
 			js.append(isPartial ? "add" : "addAll");		// FIXME may need to loop addAll manually
 			js.append("(");
-			if (instanceClassName != null) {
+			if (instanceClassName == null) {
+				js.appendAtomicReferenceTo(cgInit);
+			}
+			else if (isPartial) {
 				js.appendEcoreValue(instanceClassName, cgInit);
 			}
 			else {
-				js.appendAtomicReferenceTo(cgInit);
+				//				js.appendEcoreValue("Collection<" + instanceClassName + ">", cgInit);
+				js.append("(");
+				js.appendClassReference(null, Collection.class, false, instanceClassName);
+				js.append(")");
+				js.appendValueName(cgInit);
 			}
 			js.append(");\n");
 		}
@@ -261,11 +269,11 @@
 			js.append(".");
 			js.append(setAccessor);
 			js.append("(");
-			if (instanceClassName != null) {
-				js.appendEcoreValue(instanceClassName, cgInit);
+			if (instanceClassName == null) {
+				js.appendAtomicReferenceTo(cgInit);
 			}
 			else {
-				js.appendAtomicReferenceTo(cgInit);
+				js.appendEcoreValue(instanceClassName, cgInit);
 			}
 			js.append(");\n");
 		}
@@ -859,6 +867,7 @@
 				js.append(", ");
 				js.appendValueName(cgParameter);
 			}
+			//	js.append(")");
 			js.append(");\n");
 			js.appendThis(functionName);
 			js.append("." + instanceName + " = ");
@@ -2277,9 +2286,6 @@
 		CGValuedElement value = cgMappingCallBinding.getOwnedValue();
 		TypeDescriptor argumentTypeDescriptor = context.getTypeDescriptor(cgMappingCallBinding);
 		TypeId pivotTypeId = value.getASTypeId();
-		if (pivotTypeId instanceof CollectionTypeId) {
-			pivotTypeId = ((CollectionTypeId)pivotTypeId).getElementTypeId();
-		}
 		TypeDescriptor iteratorTypeDescriptor = context.getBoxedDescriptor(ClassUtil.nonNullState(pivotTypeId));
 		if (argumentTypeDescriptor.isAssignableFrom(iteratorTypeDescriptor)) {
 			return null;
@@ -2329,22 +2335,24 @@
 		if (!js.appendLocalStatements(initValue)) {
 			return false;
 		}
-		final String iteratorName = getSymbolName(null, "iterator");
-		TypeId concreteElementTypeId = cgConnectionAssignment.getConnectionVariable().getASTypeId();
-		assert concreteElementTypeId != null;
-		BoxedDescriptor concreteBoxedDescriptor = context.getBoxedDescriptor(concreteElementTypeId);
-		BoxedDescriptor abstractBoxedDescriptor = concreteBoxedDescriptor;
-		if (!(initValue.getASTypeId() instanceof CollectionTypeId)) {
-			if (isIncremental) {
-				js.appendValueName(cgConnectionAssignment);
-				js.append(" = ");
-			}
-			js.appendReferenceTo(cgConnectionAssignment.getConnectionVariable());
-			js.append(".appendElement(");
-			js.appendValueName(initValue);
-			js.append(");\n");
+		//	TypeId concreteElementTypeId = cgConnectionAssignment.getConnectionVariable().getASTypeId();
+		//	assert concreteElementTypeId != null;
+		//	BoxedDescriptor concreteBoxedDescriptor = context.getBoxedDescriptor(concreteElementTypeId);
+		//	BoxedDescriptor abstractBoxedDescriptor = concreteBoxedDescriptor;
+		//	TypeId initTypeId = initValue.getASTypeId();
+		//	if ((initTypeId == concreteElementTypeId) || !(initTypeId instanceof CollectionTypeId)) {
+		if (isIncremental) {
+			js.appendValueName(cgConnectionAssignment);
+			js.append(" = ");
 		}
-		else {
+		js.appendReferenceTo(cgConnectionAssignment.getConnectionVariable());
+		js.append(".appendElement(");
+		js.appendValueName(initValue);
+		js.append(");\n");
+		//	}
+		//	The following is not used; it makes no sense to support a multi-addition to a connection.
+		/*	else {
+			final String iteratorName = getSymbolName(null, "iterator");		// FIXME use reserved iterator name
 			js.append("for (");
 			js.appendClassReference(Boolean.TRUE, abstractBoxedDescriptor);
 			js.append(" ");
@@ -2372,7 +2380,7 @@
 				js.pushIndentation(null);
 			}
 			js.appendReferenceTo(cgConnectionAssignment.getConnectionVariable());
-			js.append(".add(");
+			js.append(".add(");			// FIXME Is there ever used ?? there is no "add"
 			js.append(iteratorName);
 			js.append(");\n");
 			if (concreteBoxedDescriptor != abstractBoxedDescriptor) {
@@ -2381,7 +2389,7 @@
 			}
 			js.popIndentation();
 			js.append("}\n");
-		}
+		} */
 		return true;
 	}
 
@@ -2608,6 +2616,10 @@
 		//
 		js.appendDeclaration(cgFunctionCallExp);
 		js.append(" = ");
+		//	js.appendClassReference(null, ValueUtil.class);
+		//	js.append(".createSetValue(");
+		//	js.appendValueName(resultType);
+		//	js.append(", ");
 		boolean needComma = false;
 		if (isIdentifiedInstance) {
 			js.append("((");
diff --git a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCodeGenerator.java b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCodeGenerator.java
index 2f79a26..e93cd28 100644
--- a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCodeGenerator.java
+++ b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/java/QVTiCodeGenerator.java
@@ -178,7 +178,9 @@
 	@Override
 	public @NonNull ImportNameManager createImportNameManager() {
 		return new JavaImportNameManager() {
-			{		// Ensure re-used inherited names are not confused
+			@Override
+			protected void reserveImportNames() {	// Ensure re-used inherited names are not confused
+				super.reserveImportNames();
 				reserveImportName(org.eclipse.qvtd.runtime.evaluation.AbstractTransformer.class);
 				reserveImportName(org.eclipse.qvtd.runtime.evaluation.ExecutionVisitable.class);
 				reserveImportName(org.eclipse.qvtd.runtime.evaluation.Transformer.class);
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/AbstractScheduleManager.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/AbstractScheduleManager.java
index 98c626f..859e3f7 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/AbstractScheduleManager.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/AbstractScheduleManager.java
@@ -226,6 +226,7 @@
 	private final boolean doYedGraphs;
 
 	private @Nullable ConnectionManager connectionManager = null;
+	//	private @Nullable Set<@NonNull RelationAnalysis> sharedAggregateRelations = null;
 
 	//	private final @NonNull Map<@NonNull TransformationAnalysis, @NonNull TransformationAnalysis2TracePackage> transformationAnalysis2transformationAnalysis2tracePackage = new HashMap<>();
 
@@ -284,6 +285,15 @@
 		problemHandler.addProblem(CompilerUtil.createRegionWarning(region, messageTemplate, bindings));
 	}
 
+	/*	@Override
+	public void addSharedAggregateRelation(@NonNull RelationAnalysis relationAnalysis) {
+		Set<@NonNull RelationAnalysis> sharedAggregateRelations2 = sharedAggregateRelations;
+		if (sharedAggregateRelations2 == null) {
+			sharedAggregateRelations = sharedAggregateRelations2 = new HashSet<>();
+		}
+		sharedAggregateRelations2.add(relationAnalysis);
+	} */
+
 	@Override
 	public @NonNull AbstractTransformationAnalysis addTransformation(@NonNull Transformation asTransformation) {
 		AbstractTransformationAnalysis transformationAnalysis = createTransformationAnalysis(asTransformation);
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadNodeGroup.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadNodeGroup.java
index 2b0179e..2692b1c 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadNodeGroup.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/HeadNodeGroup.java
@@ -75,6 +75,11 @@
 						gotOne = true;
 					}
 				}
+				else if (source2targetEdge.isShared()) {
+					uniqueNodes.add(targetNode);
+					workList.add(targetNode);
+					gotOne = true;
+				}
 				else if (source2targetEdge.isComputation()) {
 					boolean allArgumentsReachable = true;
 					for (@NonNull Edge argumentEdge : QVTscheduleUtil.getIncomingEdges(targetNode)) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/OriginalContentsAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/OriginalContentsAnalysis.java
index b58b88f..ef597f4 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/OriginalContentsAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/OriginalContentsAnalysis.java
@@ -33,6 +33,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.Node;
 import org.eclipse.qvtd.pivot.qvtschedule.PropertyDatum;
 import org.eclipse.qvtd.pivot.qvtschedule.RuleRegion;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 
 import com.google.common.collect.Iterables;
@@ -62,7 +63,17 @@
 	/**
 	 * The Realized Edges that produce each base PropertyDatum (or its opposite).
 	 */
-	private final @NonNull Map<@NonNull PropertyDatum, @NonNull List<@NonNull NavigableEdge>> basePropertyDatum2newEdges = new HashMap<>();
+	private final @NonNull Map<@NonNull PropertyDatum, @NonNull List<@NonNull NavigationEdge>> basePropertyDatum2newEdges = new HashMap<>();
+
+	/**
+	 * The Shared Edge that produces each singleton ClassDatum.
+	 */
+	private final @NonNull Map<@NonNull ClassDatum, @NonNull SharedEdge> classDatum2newSharedEdge = new HashMap<>();
+
+	/**
+	 * The Shared Edge that produces each singleton ClassDatum.
+	 */
+	private final @NonNull Map<@NonNull ClassDatum, @NonNull List<@NonNull SharedEdge>> classDatum2oldSharedEdges = new HashMap<>();
 
 	/**
 	 * The regions that consume each ClassDatum, eagerly computed by addRegion().
@@ -100,17 +111,20 @@
 
 	private void addNewEdge(@NonNull RuleRegion region, @NonNull NavigableEdge newEdge) {
 		if (newEdge instanceof NavigationEdge) {
-			PropertyDatum propertyDatum = getPropertyDatum((NavigationEdge) newEdge);
-			addNewEdge(region, newEdge, propertyDatum);
+			PropertyDatum propertyDatum = getPropertyDatum((NavigationEdge)newEdge);
+			addNewEdge(region, (NavigationEdge)newEdge, propertyDatum);
 		}
 		else {
-			// FIXME SharedEdge
+			assert newEdge.isShared();
+			ClassDatum classDatum = QVTscheduleUtil.getClassDatum(QVTscheduleUtil.getTargetNode(newEdge));
+			SharedEdge oldEdge = classDatum2newSharedEdge.put(classDatum, (SharedEdge)newEdge);
+			assert oldEdge == null : "Duplicate new SharedEdge for " + classDatum;
 		}
 	}
-	private void addNewEdge(@NonNull RuleRegion region, @NonNull NavigableEdge newEdge, @NonNull PropertyDatum propertyDatum) {
+	private void addNewEdge(@NonNull RuleRegion region, @NonNull NavigationEdge newEdge, @NonNull PropertyDatum propertyDatum) {
 		@SuppressWarnings("unused") String name = propertyDatum.getName();
 		PropertyDatum basePropertyDatum = scheduleManager.getBasePropertyDatum(propertyDatum);
-		List<@NonNull NavigableEdge> edges = basePropertyDatum2newEdges.get(basePropertyDatum);
+		List<@NonNull NavigationEdge> edges = basePropertyDatum2newEdges.get(basePropertyDatum);
 		if (edges == null) {
 			edges = new ArrayList<>();
 			basePropertyDatum2newEdges.put(basePropertyDatum, edges);
@@ -142,6 +156,21 @@
 		}
 	}
 
+	private void addOldEdge(@NonNull RuleRegion region, @NonNull NavigableEdge oldEdge) {
+		if (oldEdge instanceof NavigationEdge) {
+		}
+		else {
+			assert oldEdge.isShared();
+			ClassDatum classDatum = QVTscheduleUtil.getClassDatum(QVTscheduleUtil.getTargetNode(oldEdge));
+			List<@NonNull SharedEdge> edges = classDatum2oldSharedEdges.get(classDatum);
+			if (edges == null) {
+				edges = new ArrayList<>();
+				classDatum2oldSharedEdges.put(classDatum, edges);
+			}
+			edges.add((SharedEdge)oldEdge);
+		}
+	}
+
 	private void addOldNode(@NonNull RuleRegion region, @NonNull Node oldNode) {
 		//		assert !"EObject".equals(headNode.getCompleteClass().getName());
 		//		Region region = oldNode.getRegion();
@@ -192,8 +221,13 @@
 			}
 		}
 		for (@NonNull Edge newEdge : QVTscheduleUtil.getOwnedEdges(region)) {
-			if (newEdge.isRealized() && newEdge.isNavigation()) {
-				addNewEdge(region, (NavigationEdge)newEdge);
+			if (newEdge.isNavigable()) {
+				if (newEdge.isRealized()) {
+					addNewEdge(region, (NavigableEdge)newEdge);
+				}
+				else {
+					addOldEdge(region, (NavigableEdge)newEdge);
+				}
 			}
 		}
 	}
@@ -247,9 +281,9 @@
 	 * FIXME In the event that the ends of the realized edges are realized variables, we do know the precise
 	 * type and could filter accordingly; a not-yet-exploited optimisation.
 	 */
-	private @Nullable Iterable<@NonNull NavigableEdge> getCompositeNewEdges(@NonNull NavigableEdge predicatedEdge) {
-		Set<@NonNull NavigableEdge> realizedEdges = null;
-		for (Map.Entry<@NonNull PropertyDatum, @NonNull List<@NonNull NavigableEdge>> entry : basePropertyDatum2newEdges.entrySet()) {
+	private @Nullable Iterable<@NonNull NavigationEdge> getCompositeNewEdges(@NonNull NavigableEdge predicatedEdge) {
+		Set<@NonNull NavigationEdge> realizedEdges = null;
+		for (Map.Entry<@NonNull PropertyDatum, @NonNull List<@NonNull NavigationEdge>> entry : basePropertyDatum2newEdges.entrySet()) {
 			Property property = entry.getKey().getReferredProperty();
 			if (property != null) {
 				@Nullable Property compositeProperty = null;
@@ -349,7 +383,7 @@
 		return newNodes;
 	}
 
-	public @Nullable Iterable<@NonNull NavigableEdge> getNewEdges(@NonNull NavigableEdge edge, @NonNull ClassDatum requiredClassDatum) {
+	public @Nullable Iterable<@NonNull NavigationEdge> getNewEdges(@NonNull NavigableEdge edge, @NonNull ClassDatum requiredClassDatum) {
 		if (edge instanceof NavigationEdge) {
 			Property property = QVTscheduleUtil.getReferredProperty((NavigationEdge)edge);
 			if (property.eContainer() == null) {			// Ignore pseudo-properties such as «iterate»
@@ -358,7 +392,7 @@
 			if (property == oclContainerProperty) {
 				return getCompositeNewEdges(edge);
 			}
-			Iterable<@NonNull NavigableEdge> realizedEdges = null;
+			Iterable<@NonNull NavigationEdge> realizedEdges = null;
 			PropertyDatum propertyDatum = getPropertyDatum((NavigationEdge) edge);
 			PropertyDatum basePropertyDatum = scheduleManager.getBasePropertyDatum(propertyDatum);
 			//		if (propertyDatum == null) {
@@ -371,29 +405,26 @@
 			if (realizedEdges == null) {
 				return null;
 			}
-			List<@NonNull NavigableEdge> conformantRealizedEdges = null;
-			for (@NonNull NavigableEdge realizedEdge : realizedEdges) {
+			List<@NonNull NavigationEdge> conformantRealizedEdges = null;
+			for (@NonNull NavigationEdge realizedEdge : realizedEdges) {
 				boolean matches = false;
-				if (realizedEdge.isNavigation()) {
-					NavigationEdge realizedNavigationEdge = (NavigationEdge)realizedEdge;
-					Property realizedProperty = QVTscheduleUtil.getReferredProperty(realizedNavigationEdge);
-					if (realizedProperty != property) {
-						assert realizedProperty.getOpposite() == property;
+				Property realizedProperty = QVTscheduleUtil.getReferredProperty(realizedEdge);
+				if (realizedProperty != property) {
+					assert realizedProperty.getOpposite() == property;
+					matches = true;
+				}
+				else {
+					Node targetNode = realizedEdge.getEdgeTarget();
+					ClassDatum realizedClassDatum = QVTscheduleUtil.getClassDatum(targetNode);
+					if (QVTscheduleUtil.conformsToClassOrBehavioralClass(realizedClassDatum, requiredClassDatum)) {
 						matches = true;
 					}
-					else {
-						Node targetNode = realizedEdge.getEdgeTarget();
-						ClassDatum realizedClassDatum = QVTscheduleUtil.getClassDatum(targetNode);
-						if (QVTscheduleUtil.conformsToClassOrBehavioralClass(realizedClassDatum, requiredClassDatum)) {
-							matches = true;
-						}
+				}
+				if (matches) {
+					if (conformantRealizedEdges == null) {
+						conformantRealizedEdges = new ArrayList<>();
 					}
-					if (matches) {
-						if (conformantRealizedEdges == null) {
-							conformantRealizedEdges = new ArrayList<>();
-						}
-						conformantRealizedEdges.add(realizedEdge);
-					}
+					conformantRealizedEdges.add(realizedEdge);
 				}
 			}
 			return conformantRealizedEdges;
@@ -456,6 +487,12 @@
 		return classDatum2oldNodes.get(classDatum);
 	}
 
+	public @Nullable Iterable<@NonNull SharedEdge> getOldSharedEdges(@NonNull SharedEdge edge) {
+		Node traceNode = QVTscheduleUtil.getTargetNode(edge);
+		ClassDatum classDatum = QVTscheduleUtil.getClassDatum(traceNode);
+		return classDatum2oldSharedEdges.get(classDatum);
+	}
+
 	private @NonNull PropertyDatum getPropertyDatum(@NonNull NavigationEdge producedEdge) {
 		assert !producedEdge.isCast();				// Handled by caller
 		Property forwardProperty = QVTscheduleUtil.getReferredProperty(producedEdge);
@@ -464,6 +501,12 @@
 		return scheduleManager.getPropertyDatum(forwardClassDatum, forwardProperty);
 	}
 
+	public @Nullable SharedEdge getNewSharedEdge(@NonNull SharedEdge edge) {
+		Node traceNode = QVTscheduleUtil.getTargetNode(edge);
+		ClassDatum classDatum = QVTscheduleUtil.getClassDatum(traceNode);
+		return classDatum2newSharedEdge.get(classDatum);
+	}
+
 	/**
 	 * Return true if this node is consumed solely by casts (or recursions) and so need not be considered as a true consumer.
 	 * The downstream usages will consume more accurately.
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RegionHelper.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RegionHelper.java
index 7a111b9..e803574 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RegionHelper.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/RegionHelper.java
@@ -93,6 +93,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.RootPartition;
 import org.eclipse.qvtd.pivot.qvtschedule.ShadowNode;
 import org.eclipse.qvtd.pivot.qvtschedule.ShadowPartEdge;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.StringLiteralNode;
 import org.eclipse.qvtd.pivot.qvtschedule.SuccessEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.SuccessNode;
@@ -696,6 +697,13 @@
 		return edge;
 	}
 
+	public @NonNull Edge createSharedEdge(@NonNull Role edgeRole, @NonNull Node sourceNode, @NonNull Property target2sourceProperty, @NonNull Node targetNode) {
+		SharedEdge edge = QVTscheduleFactory.eINSTANCE.createSharedEdge();
+		edge.initialize(edgeRole, sourceNode, "«shared»", targetNode);
+		edge.initializeProperty(target2sourceProperty);
+		return edge;
+	}
+
 	public @NonNull Node createStepNode(@NonNull String name, @NonNull CallExp callExp, @NonNull Node sourceNode, boolean isMatched) {
 		DomainUsage domainUsage = scheduleManager.getDomainUsage(callExp);
 		boolean isMiddleOrOutput = domainUsage.isOutput() || domainUsage.isMiddle();
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ScheduleManager.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ScheduleManager.java
index b967307..cb0e3e9 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ScheduleManager.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/ScheduleManager.java
@@ -61,6 +61,7 @@
 	void addProblem(@NonNull CompilerProblem problem);
 	void addRegionError(@NonNull Region region, @NonNull String messageTemplate, Object... bindings);
 	void addRegionWarning(@NonNull Region region, @NonNull String messageTemplate, Object... bindings);
+	//	void addSharedAggregateRelation(@NonNull RelationAnalysis relationAnalysis);
 
 	/**
 	 * Define an additional/only Transformation to be scheduled by the subsequent anayses and syntheses.
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/UtilityAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/UtilityAnalysis.java
index 8539c6e..27ea6c9 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/UtilityAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/UtilityAnalysis.java
@@ -301,6 +301,7 @@
 							moreMoreNodes.add(sourceNode);
 						}
 					}
+					else if (incomingEdge.isShared()) {}
 					else {
 						System.out.println("Unsupported incoming edge in " + this + " : " + incomingEdge);
 					}
@@ -323,7 +324,12 @@
 							}
 						}
 					}
-					else {		// SharedEdge
+					else if (outgoingEdge.isShared()) {
+						if (unconditionalNodes.add(targetNode)) {
+							moreMoreNodes.add(targetNode);
+						}
+					}
+					else {
 						System.out.println("Unsupported outgoing edge in " + this + " : " + outgoingEdge);
 					}
 				}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadAnalysis.java
index 63be326..d8f1a79 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtb2qvts/trace/TracedHeadAnalysis.java
@@ -25,13 +25,11 @@
 import org.eclipse.qvtd.compiler.internal.qvtb2qvts.HeadNodeGroup;
 import org.eclipse.qvtd.compiler.internal.qvtb2qvts.ScheduleManager;
 import org.eclipse.qvtd.compiler.internal.utilities.CompilerUtil;
-import org.eclipse.qvtd.pivot.qvtschedule.CastEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.Edge;
 import org.eclipse.qvtd.pivot.qvtschedule.KeyPartEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.MappingRegion;
 import org.eclipse.qvtd.pivot.qvtschedule.NavigationEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.Node;
-import org.eclipse.qvtd.pivot.qvtschedule.PredicateEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 
 import com.google.common.collect.Sets;
@@ -114,13 +112,16 @@
 								sources.add(sourceNode);
 							}
 						}
-						else if (edge instanceof CastEdge) {
+						else if (edge.isCast()) {
 							sources.add(sourceNode);
 						}
 						else if (edge instanceof KeyPartEdge) {
 							sources.add(sourceNode);
 						}
-						else if (edge instanceof PredicateEdge) {
+						else if (edge.isPredicate()) {
+							sources.add(sourceNode);
+						}
+						else if (edge.isShared()) {
 							sources.add(sourceNode);
 						}
 					}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhenOnlyInvocationAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhenOnlyClassInvocationAnalysis.java
similarity index 73%
rename from plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhenOnlyInvocationAnalysis.java
rename to plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhenOnlyClassInvocationAnalysis.java
index aef884f..330660c 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhenOnlyInvocationAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhenOnlyClassInvocationAnalysis.java
@@ -15,12 +15,12 @@
 import org.eclipse.qvtd.pivot.qvtschedule.Node;
 
 /**
- * A NonTopWhenOnlyInvocationAnalysis identifies the invocation of a non-top Relation by a when clause in another.
- * The Relation is is not invoked by a where clause anywhere else.
+ * A NonTopWhenOnlyClassInvocationAnalysis identifies the invocation of a non-top Relation by a when clause in another.
+ * The Relation has a non-DataType root varioable and is not invoked by a where clause anywhere else.
  */
-public class NonTopWhenOnlyInvocationAnalysis extends AbstractWhenInvocationAnalysis
+public class NonTopWhenOnlyClassInvocationAnalysis extends AbstractWhenInvocationAnalysis
 {
-	public NonTopWhenOnlyInvocationAnalysis(@NonNull RelationAnalysis invokingRelationAnalysis, @NonNull RelationAnalysis invokedRelationAnalysis) {
+	public NonTopWhenOnlyClassInvocationAnalysis(@NonNull RelationAnalysis invokingRelationAnalysis, @NonNull RelationAnalysis invokedRelationAnalysis) {
 		super(invokingRelationAnalysis, invokedRelationAnalysis);
 	}
 
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhenOnlyDataTypeInvocationAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhenOnlyDataTypeInvocationAnalysis.java
new file mode 100644
index 0000000..d1ea28d
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/NonTopWhenOnlyDataTypeInvocationAnalysis.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Willink Transformations and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ *   E.D.Willink - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.qvtd.compiler.internal.qvtr2qvts;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.ocl.pivot.Property;
+import org.eclipse.qvtd.pivot.qvtschedule.ClassDatum;
+import org.eclipse.qvtd.pivot.qvtschedule.NavigableEdge;
+import org.eclipse.qvtd.pivot.qvtschedule.Node;
+import org.eclipse.qvtd.pivot.qvtschedule.Role;
+
+/**
+ * A NonTopWhenOnlyDataTypeInvocationAnalysis identifies the invocation of a non-top Relation by a when clause in another.
+ * The Relation has only DataTyped root variables and is not invoked by a where clause anywhere else.
+ */
+public class NonTopWhenOnlyDataTypeInvocationAnalysis extends AbstractWhenInvocationAnalysis
+{
+	public NonTopWhenOnlyDataTypeInvocationAnalysis(@NonNull RelationAnalysis invokingRelationAnalysis, @NonNull RelationAnalysis invokedRelationAnalysis) {
+		super(invokingRelationAnalysis, invokedRelationAnalysis);
+	}
+
+	@Override
+	protected @NonNull NavigableEdge createInputEdge(@NonNull Node invokedNode, @NonNull Property invocationProperty, @NonNull Node argumentNode) {
+		if (invokedRelationAnalysis.isSharedAggregator()) {
+			invokedRelationAnalysis.createSharedEdge(Role.PREDICATED, argumentNode, invocationProperty, invokedNode);
+		}
+		return super.createInputEdge(invokedNode, invocationProperty, argumentNode);
+	}
+
+	@Override
+	protected @NonNull Node createInvocationNode(@NonNull String name, @NonNull ClassDatum classDatum, boolean isMatched) {
+		return invokingRelationAnalysis.createPredicatedNode(name, classDatum, isMatched);
+	}
+
+	@Override
+	public boolean isTop() {
+		return false;
+	}
+
+	@Override
+	public @NonNull String toString() {
+		return invokingRelationAnalysis.getRule().getName() + "==when-only==non-top==data==>" + invokedRelationAnalysis.getRule().getName();
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/QVTrelationScheduleManager.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/QVTrelationScheduleManager.java
index 604b9d7..96625f6 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/QVTrelationScheduleManager.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/QVTrelationScheduleManager.java
@@ -12,6 +12,9 @@
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.DataType;
+import org.eclipse.ocl.pivot.Type;
+import org.eclipse.ocl.pivot.VariableDeclaration;
 import org.eclipse.ocl.pivot.utilities.EnvironmentFactory;
 import org.eclipse.qvtd.compiler.CompilerOptions;
 import org.eclipse.qvtd.compiler.ProblemHandler;
@@ -32,6 +35,7 @@
 import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
 import org.eclipse.qvtd.pivot.qvtcore.analysis.RootDomainUsageAnalysis;
 import org.eclipse.qvtd.pivot.qvtrelation.Relation;
+import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain;
 import org.eclipse.qvtd.pivot.qvtrelation.RelationalTransformation;
 import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil;
 import org.eclipse.qvtd.pivot.qvtschedule.QVTscheduleFactory;
@@ -71,7 +75,13 @@
 		//		}
 		ruleRegion.setReferredRule(asRule);
 		ruleRegion.setName(getNameGenerator().createMappingName((Relation) asRule, null, qvtuConfiguration));
-		return new RelationAnalysis(transformationAnalysis, qvtuConfiguration, ruleRegion);
+		Relation relation = (Relation) asRule;
+		if (isSharedAggregator(relation)) {
+			return new SharedAggregatorRelationAnalysis(transformationAnalysis, qvtuConfiguration, ruleRegion);
+		}
+		else {
+			return new RelationAnalysis(transformationAnalysis, qvtuConfiguration, ruleRegion);
+		}
 	}
 
 	@Override
@@ -137,6 +147,28 @@
 		return qvtuConfiguration.isOutput(QVTrelationUtil.getTypedModel(domain));
 	}
 
+	protected boolean isSharedAggregator(@NonNull Relation relation) {
+		if (relation.isIsTopLevel()) {
+			return false;
+		}
+		for (@NonNull RelationDomain relationDomain : QVTrelationUtil.getOwnedDomains(relation)) {
+			if (relationDomain.isIsCheckable()) {
+				boolean allData = true;
+				for (@NonNull VariableDeclaration rootVariable : QVTrelationUtil.getRootVariables(relationDomain)) {
+					Type rootType = rootVariable.getType();
+					if (!(rootType instanceof DataType)) {
+						allData = false;
+						break;
+					}
+				}
+				if (allData) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
 	@Override
 	public boolean needsDiscrimination() {
 		return false;			// FIXME Bug 488647 discriminate cyclic QVTr output classes too
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/RelationAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/RelationAnalysis.java
index a6e0e8d..824c5d2 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/RelationAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/RelationAnalysis.java
@@ -20,11 +20,13 @@
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.DataType;
 import org.eclipse.ocl.pivot.NavigationCallExp;
 import org.eclipse.ocl.pivot.OCLExpression;
 import org.eclipse.ocl.pivot.Operation;
 import org.eclipse.ocl.pivot.OperationCallExp;
 import org.eclipse.ocl.pivot.Property;
+import org.eclipse.ocl.pivot.Type;
 import org.eclipse.ocl.pivot.Variable;
 import org.eclipse.ocl.pivot.VariableDeclaration;
 import org.eclipse.ocl.pivot.VariableExp;
@@ -86,7 +88,7 @@
 import com.google.common.collect.Lists;
 
 /**
- * A RelationAnalysis provides the analysis a QVTc mapping.
+ * A RelationAnalysis provides the analysis a QVTr mapping.
  */
 public class RelationAnalysis extends RuleAnalysis
 {
@@ -760,7 +762,24 @@
 					invocationAnalysis = new NonTopWhenAfterWhereInvocationAnalysis(this, invokedRelationAnalysis);
 				}
 				else {
-					invocationAnalysis = new NonTopWhenOnlyInvocationAnalysis(this, invokedRelationAnalysis);
+					boolean hasClassInput = false;
+					Relation rule2 = invokedRelationAnalysis.getRule();
+					for (@NonNull RelationDomain relationDomain : QVTrelationUtil.getOwnedDomains(rule2)) {
+						if (scheduleManager.isInput(relationDomain)) {
+							for (@NonNull VariableDeclaration rootVariable : QVTrelationUtil.getRootVariables(relationDomain)) {
+								Type type = QVTrelationUtil.getType(rootVariable);
+								if (!(type instanceof DataType)) {
+									hasClassInput = true;
+								}
+							}
+						}
+					}
+					if (hasClassInput) {
+						invocationAnalysis = new NonTopWhenOnlyClassInvocationAnalysis(this, invokedRelationAnalysis);
+					}
+					else {
+						invocationAnalysis = new NonTopWhenOnlyDataTypeInvocationAnalysis(this, invokedRelationAnalysis);
+					}
 				}
 			}
 			else {
@@ -1033,6 +1052,10 @@
 		return false;
 	}
 
+	public boolean isSharedAggregator() {
+		return false;
+	}
+
 	/*	public OCLExpression synthesizeKeyTemplate(@NonNull VariableDeclaration templateVariable, @NonNull Node @NonNull [] argNodes) {
 		Node keyNode = createOperationNode(true, QVTrelationUtil.getName(templateVariable), templateVariable, argNodes);
 		region.addVariableNode(templateVariable, keyNode);
@@ -1119,8 +1142,10 @@
 		if (isOutput) {
 			synthesizeOutputCollectionTemplate(collectionTemplateExp);
 		}
-		else if (!synthesizeSingleInputCollectionTemplate(collectionTemplateExp)) {
-			synthesizeMultipleInputCollectionTemplate(collectionTemplateExp);
+		else if (!synthesizeEmptyInputCollectionTemplate(collectionTemplateExp)) {
+			if (!synthesizeSingleInputCollectionTemplate(collectionTemplateExp)) {
+				synthesizeMultipleInputCollectionTemplate(collectionTemplateExp);
+			}
 		}
 	}
 
@@ -1178,6 +1203,23 @@
 	}
 
 	/**
+	 * Synthesize the simple CollectionTemplateExp pattern only match comprising no members and no rest.
+	 *
+	 * Returns false if a more complex match is needed.
+	 */
+	protected boolean synthesizeEmptyInputCollectionTemplate(@NonNull CollectionTemplateExp collectionTemplateExp) {
+		Variable rest = collectionTemplateExp.getRest();
+		if (rest != null) {
+			return false;
+		}
+		List<OCLExpression> members = collectionTemplateExp.getMember();
+		if (members.size() > 0) {
+			return false;
+		}
+		return true;
+	}
+
+	/**
 	 * Attempt to synthesize an x=y predicateExpression, returning true if successful.
 	 */
 	protected boolean synthesizeEqualsPredicate(@NonNull OCLExpression predicateExpression) {
@@ -1813,6 +1855,9 @@
 		if (hasOverrides) {
 			traceNode = createOldNode(traceVariable);
 		}
+		//	else if (isSharedAggregator()) {
+		//		traceNode = createRealizedStepNode(traceVariable);
+		//	}
 		else if (!relation.isIsTopLevel()) {
 			//			if (hasOverrides) {
 			traceNode = createOldNode(traceVariable);
@@ -1856,6 +1901,7 @@
 		return traceNode;
 	}
 
+	// FIXME Introduce derived RelationAnalysis strategies
 	public void synthesizeVariableDeclaration(@NonNull VariableDeclaration variableDeclaration) {	// FIXME move to derived visitVariableDeclaration
 		//		boolean isEnforced = false;
 		//		ClassDatum classDatum = scheduleManager.getClassDatum(variableDeclaration);
@@ -1887,6 +1933,9 @@
 		else if (getRealizedOutputVariables().contains(variableDeclaration)) {
 			createRealizedStepNode(variableDeclaration);
 		}
+		else if (hasIncomingWhenInvocationAnalyses() && Iterables.contains(QVTrelationUtil.getRootVariables(getRule()), variableDeclaration)) {
+			createOldNode(variableDeclaration);		// where 'output' is created by invoker
+		}
 		else {
 			if (variableDeclaration instanceof TemplateVariable) {
 				assert templateExp != null;
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/SharedAggregatorRelationAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/SharedAggregatorRelationAnalysis.java
new file mode 100644
index 0000000..e5d6676
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/SharedAggregatorRelationAnalysis.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2019 Willink Transformations and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ *   E.D.Willink - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.qvtd.compiler.internal.qvtr2qvts;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.Property;
+import org.eclipse.ocl.pivot.VariableDeclaration;
+import org.eclipse.qvtd.compiler.internal.qvtb2qvts.AbstractTransformationAnalysis;
+import org.eclipse.qvtd.compiler.internal.qvtc2qvtu.QVTuConfiguration;
+import org.eclipse.qvtd.compiler.internal.qvtr2qvts.trace.RelationAnalysis2TraceClass;
+import org.eclipse.qvtd.compiler.internal.qvtr2qvts.trace.VariableDeclaration2TraceProperty;
+import org.eclipse.qvtd.pivot.qvtrelation.Relation;
+import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil;
+import org.eclipse.qvtd.pivot.qvtschedule.Node;
+import org.eclipse.qvtd.pivot.qvtschedule.Role;
+import org.eclipse.qvtd.pivot.qvtschedule.RuleRegion;
+import org.eclipse.qvtd.pivot.qvtschedule.Node.Utility;
+
+/**
+ * A SharedAggregatorRelationAnalysis provides the analysis of a non-top QVTr mapping with a DataTY[pe roor variable.
+ */
+public class SharedAggregatorRelationAnalysis extends RelationAnalysis
+{
+	public SharedAggregatorRelationAnalysis(@NonNull AbstractTransformationAnalysis transformationAnalysis, @NonNull QVTuConfiguration qvtuConfiguration, @NonNull RuleRegion ruleRegion) {
+		super(transformationAnalysis, qvtuConfiguration, ruleRegion);
+	}
+
+	@Override
+	public boolean isSharedAggregator() {
+		return true;
+	}
+
+	@Override
+	protected void synthesizeTraceEdges(@NonNull Node traceNode, @Nullable Node dispatchNode) {
+		super.synthesizeTraceEdges(traceNode, dispatchNode);
+		RelationAnalysis2TraceClass ruleAnalysis2traceClass = getRuleAnalysis2TraceGroup().getRuleAnalysis2TraceClass();
+		for (@NonNull VariableDeclaration2TraceProperty variableDeclaration2traceProperty : ruleAnalysis2traceClass.getVariableDeclaration2TraceProperties()) {
+			VariableDeclaration tracedVariable = variableDeclaration2traceProperty.getOverridingVariable();
+			Node targetNode = region.getNode(tracedVariable);
+			assert targetNode != null;
+			if (targetNode.isOld()) {
+				Property traceProperty = variableDeclaration2traceProperty.getTraceProperty();
+				createSharedEdge(Role.REALIZED, targetNode, traceProperty, traceNode);
+			}
+		}
+	}
+
+	@Override
+	protected @NonNull Node synthesizeTraceNode() {
+		Relation relation = getRule();
+		VariableDeclaration traceVariable = QVTrelationUtil.getTraceVariable(relation);
+		Node traceNode = createRealizedStepNode(traceVariable);
+		traceNode.setUtility(Utility.TRACE);
+		return traceNode;
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/RelationAnalysis2TraceClass.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/RelationAnalysis2TraceClass.java
index e2cd839..dcb2fd3 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/RelationAnalysis2TraceClass.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/RelationAnalysis2TraceClass.java
@@ -259,39 +259,44 @@
 	//
 	protected void analyzeGlobalSuccessNode(@Nullable RelationAnalysis2TraceInterface baseRelationAnalysis2traceInterface) {
 		boolean hasTraceInterface = baseRelationAnalysis2traceInterface != null;
-		boolean hasWhenInvocation = getRuleAnalysis().hasIncomingWhenInvocationAnalyses();
 		if (hasTraceInterface) {		// FIXME Bug 540797 - this is used by e.g. mapBooleanExp in ATL2QVTr
 			return;
 		}
-		if (!hasWhenInvocation) {		// FIXME enforced guard needs globalSucess
-			return;
+		boolean hasWhenInvocation = getRuleAnalysis().hasIncomingWhenInvocationAnalyses();
+		boolean isDataTypeRelation = QVTrelationUtil.isDataTypeRelation(relation);
+		boolean needsGlobalSuccessProperty = false;
+		if (hasWhenInvocation && !isDataTypeRelation) {		// FIXME enforced guard needs globalSucess
+			needsGlobalSuccessProperty = true;
 		}
-		if (!QVTrelationUtil.hasOverrides(relation)) {
-			boolean hasPredicatedElement = false;
+		if (!needsGlobalSuccessProperty && !QVTrelationUtil.hasOverrides(relation) && !isDataTypeRelation) {
 			RuleRegion region = getRuleAnalysis().getRegion();
 			for (@NonNull Node node : QVTscheduleUtil.getOwnedNodes(region)) {
 				if (node.isPredicated()) {
-					hasPredicatedElement = true;
+					needsGlobalSuccessProperty = true;
 					break;
 				}
 			}
-			if (!hasPredicatedElement) {
+			if (!needsGlobalSuccessProperty) {
 				for (@NonNull Edge edge : QVTscheduleUtil.getOwnedEdges(region)) {
 					if (edge.isPredicated()) {
-						hasPredicatedElement = true;
+						needsGlobalSuccessProperty = true;
 						break;
 					}
 				}
-			}
-			if (!hasPredicatedElement) {
-				return;			// extStat is identical to trace class existence
-			}
+			}			// globalSuccess is identical to trace class existence
 		}
-		QVTrelationNameGenerator nameGenerator = relationAnalysis2traceGroup.getNameGenerator();
-		String globalSuccessPropertyName = nameGenerator.createTraceGlobalSuccessPropertyName();
-		createRelation2GlobalSuccessProperty(globalSuccessPropertyName);
+		if (!needsGlobalSuccessProperty && hasSharedEdge()) {
+			needsGlobalSuccessProperty = true;
+		}
+		if (needsGlobalSuccessProperty) {
+			QVTrelationNameGenerator nameGenerator = relationAnalysis2traceGroup.getNameGenerator();
+			String globalSuccessPropertyName = nameGenerator.createTraceGlobalSuccessPropertyName();
+			createRelation2GlobalSuccessProperty(globalSuccessPropertyName);
+		}
 	}
 
+
+
 	/*	@Override
 	public @Nullable RelationAnalysis2MiddleType getSuperRuleAnalysis2MiddleType() {
 		RelationAnalysis2TraceInterface ruleAnalysis2TraceInterface = relationAnalysis2traceGroup.basicGetRuleAnalysis2TraceInterface();
@@ -489,6 +494,10 @@
 		return false;
 	} */
 
+	private boolean hasSharedEdge() {
+		return false;
+	}
+
 	/**
 	 * Return true if there may be more than one trace instance for a given root variable.
 	 *
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 ab31c43..4939b55 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
@@ -101,6 +101,7 @@
 import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil;
 import org.eclipse.qvtd.pivot.qvtschedule.BooleanLiteralNode;
 import org.eclipse.qvtd.pivot.qvtschedule.ClassDatum;
+import org.eclipse.qvtd.pivot.qvtschedule.ConnectionEnd;
 import org.eclipse.qvtd.pivot.qvtschedule.Edge;
 import org.eclipse.qvtd.pivot.qvtschedule.ExpressionEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.IfNode;
@@ -121,6 +122,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.PropertyDatum;
 import org.eclipse.qvtd.pivot.qvtschedule.Region;
 import org.eclipse.qvtd.pivot.qvtschedule.Role;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.StringLiteralNode;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 import org.eclipse.qvtd.pivot.qvttemplate.CollectionTemplateExp;
@@ -1205,6 +1207,7 @@
 		}
 	}
 
+	protected final @NonNull MappingPartitionAnalysis<?> partitionAnalysis;
 	protected final @NonNull RegionAnalysis regionAnalysis;
 
 	/**
@@ -1254,6 +1257,7 @@
 
 	public BasicPartition2Mapping(@NonNull QVTs2QVTiVisitor visitor, @NonNull MappingPartitionAnalysis<?> partitionAnalysis) {
 		super(visitor, partitionAnalysis.getPartition());
+		this.partitionAnalysis = partitionAnalysis;
 		this.regionAnalysis = scheduleManager.getRegionAnalysis(QVTscheduleUtil.getRegion(partition));
 		this.reachabilityForest = partitionAnalysis.getReachabilityForest();
 		this.checkedConditionAnalysis = new CheckedConditionAnalysis(partitionAnalysis, scheduleManager);
@@ -1400,6 +1404,20 @@
 	private void createAddStatements() {
 		if (connection2variable != null) {
 			for (@NonNull NodeConnection connection : connection2variable.keySet()) {
+				ClassDatum classDatum = QVTscheduleUtil.getClassDatum(connection);
+				if (classDatum.isDataType()) {
+					boolean hasTargetEdges = false;
+					for (@NonNull ConnectionEnd connectionEnd : connection.getTargetConnectionEnds(partition)) {
+						Iterable<@NonNull Edge> edges = QVTscheduleUtil.getOutgoingEdges((Node) connectionEnd);
+						if (!Iterables.isEmpty(edges)) {
+							hasTargetEdges =  true;
+							break;
+						}
+					}
+					if (hasTargetEdges) {
+						continue;
+					}
+				}
 				Node sourceNode = connection.getSource(partition);
 				OCLExpression variableExpression = createVariableExp(sourceNode);
 				ConnectionVariable connectionVariable = connection2variable.get(connection);
@@ -1592,6 +1610,20 @@
 			}
 		}
 		guardNodes.addAll(headNodes);
+	/*	for (@NonNull SharedEdge sharedEdge : partitionAnalysis.getPredicatedSharedEdges()) {
+			Node targetNode = QVTscheduleUtil.getTargetNode(sharedEdge);
+			boolean hasOutgoingEdges = false;
+			for (@NonNull Edge outgoingEdge : QVTscheduleUtil.getOutgoingEdges(targetNode)) {
+				Role edgeRole = partition.getRole(outgoingEdge);
+				if (edgeRole != null) {
+					hasOutgoingEdges = true;
+				}
+			}
+			if (hasOutgoingEdges) {
+				assert !guardNodes.contains(targetNode);
+				guardNodes.add(targetNode);
+			}
+		} */
 		Collections.sort(guardNodes, NameUtil.NAMEABLE_COMPARATOR);
 		for (@NonNull Node guardNode : guardNodes) {
 			if (!guardNode.isDependency()) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/AbstractRegionAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/AbstractRegionAnalysis.java
index eb87393..0e2a81c 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/AbstractRegionAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/AbstractRegionAnalysis.java
@@ -19,16 +19,19 @@
 import org.eclipse.ocl.pivot.Property;
 import org.eclipse.ocl.pivot.utilities.ClassUtil;
 import org.eclipse.qvtd.compiler.internal.qvtb2qvts.AbstractTransformationAnalysis;
-import org.eclipse.qvtd.compiler.internal.qvtb2qvts.ScheduleManager;
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.analysis.AbstractPartialRegionAnalysis;
+import org.eclipse.qvtd.compiler.internal.qvts2qvts.analysis.PartialRegionAnalysis;
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.analysis.PartialRegionClassAnalysis;
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.analysis.PartialRegionPropertyAnalysis;
 import org.eclipse.qvtd.pivot.qvtschedule.ClassDatum;
 import org.eclipse.qvtd.pivot.qvtschedule.Edge;
 import org.eclipse.qvtd.pivot.qvtschedule.NavigationEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.Node;
+import org.eclipse.qvtd.pivot.qvtschedule.NodeConnection;
 import org.eclipse.qvtd.pivot.qvtschedule.PropertyDatum;
+import org.eclipse.qvtd.pivot.qvtschedule.Region;
 import org.eclipse.qvtd.pivot.qvtschedule.Role;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.SuccessEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 
@@ -207,8 +210,26 @@
 		return  node.getNodeRole();
 	}
 
-	public @NonNull ScheduleManager getScheduleManager() {
-		return scheduleManager;
+	@Override
+	public @Nullable Iterable<@NonNull PartialRegionAnalysis<@NonNull RegionsAnalysis>> getSharedPredecessors() {
+		List<@NonNull PartialRegionAnalysis<@NonNull RegionsAnalysis>> sharedPredecessors = null;
+		for (@NonNull SharedEdge sharedEdge : getRealizedSharedEdges()) {
+			Node thisNode = QVTscheduleUtil.getSourceNode(sharedEdge);
+			NodeConnection connection = thisNode.getIncomingConnection();
+			if (connection != null) {
+				for (@NonNull Node thatNode : QVTscheduleUtil.getSourceEnds(connection)) {
+					if (sharedPredecessors == null) {
+						sharedPredecessors = new ArrayList<>();
+					}
+					Region thatRegion = QVTscheduleUtil.getOwningRegion(thatNode);
+					RegionAnalysis regionAnalysis = transformationAnalysis.getRegionAnalysis(thatRegion);
+					if (!sharedPredecessors.contains(regionAnalysis)) {
+						sharedPredecessors.add(regionAnalysis);
+					}
+				}
+			}
+		}
+		return sharedPredecessors;
 	}
 
 	public @Nullable Edge getTraceEdge(@NonNull Node node) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/ConnectionManager.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/ConnectionManager.java
index 2e9f003..9aef8db 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/ConnectionManager.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/ConnectionManager.java
@@ -46,6 +46,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.Region;
 import org.eclipse.qvtd.pivot.qvtschedule.Role;
 import org.eclipse.qvtd.pivot.qvtschedule.RootRegion;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.DomainUsage;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.SymbolNameBuilder;
@@ -63,6 +64,7 @@
 	private static final @NonNull String JOIN_INPUT_PREFIX = "ji";
 	private static final @NonNull String JOIN_MIDDLE_PREFIX = "jm";
 	private static final @NonNull String JOIN_OUTPUT_PREFIX = "jo";
+	private static final @NonNull String JOIN_SHARED_PREFIX = "js";
 
 	public static final @NonNull List<@NonNull Partition> EMPTY_PARTITION_LIST = Collections.emptyList();
 
@@ -146,7 +148,7 @@
 				assert !predicatedProperty.isIsImplicit();
 				boolean isDataType = classDatum.isDataType();
 				assert isDataType;
-				Iterable<@NonNull NavigableEdge> realizedEdges = getNewEdges(predicatedEdge, classDatum);
+				Iterable<@NonNull NavigationEdge> realizedEdges = getNewEdges(predicatedEdge, classDatum);
 				if (realizedEdges != null) {
 					ClassDatum predicatedSourceClassDatum = QVTscheduleUtil.getClassDatum(QVTscheduleUtil.getSourceNode(predicatedEdge));
 					ClassDatum predicatedTargetClassDatum = QVTscheduleUtil.getClassDatum(QVTscheduleUtil.getTargetNode(predicatedEdge));
@@ -158,41 +160,36 @@
 						//	predicatedTargetClassDatum = scheduleManager.getEnvironmentFactory().getCompleteModel().getCompleteClass(elementType);
 						predicatedTargetClassDatum = QVTscheduleUtil.getElementalClassDatum((CollectionClassDatum)predicatedTargetClassDatum);
 					}
-					for (@NonNull NavigableEdge realizedEdge : realizedEdges) {
-						if (realizedEdge.isNavigation()) {
-							NavigationEdge predicatedRealizedEdge = (NavigationEdge)realizedEdge;
-							ClassDatum firstClassDatum = QVTscheduleUtil.getClassDatum(QVTscheduleUtil.getSourceNode(realizedEdge));
-							ClassDatum secondTargetClassDatum = QVTscheduleUtil.getClassDatum(QVTscheduleUtil.getTargetNode(realizedEdge));
-							ClassDatum realizedSourceClassDatum;
-							ClassDatum realizedTargetClassDatum;
-							Property realizedProperty = QVTscheduleUtil.getReferredProperty(predicatedRealizedEdge);
-							if (realizedProperty == predicatedProperty) {
-								realizedSourceClassDatum = firstClassDatum;
-								realizedTargetClassDatum = secondTargetClassDatum;
-							}
-							else {
-								assert realizedProperty == oppositeProperty;
-								realizedSourceClassDatum = secondTargetClassDatum;
-								realizedTargetClassDatum = firstClassDatum;
-							}
-							boolean conformingSources = QVTscheduleUtil.conformantWith(predicatedSourceClassDatum, realizedSourceClassDatum);
-							boolean conformingTargets;
-							//	if (isOneToMany) {
-							conformingTargets = QVTscheduleUtil.conformantWith(predicatedTargetClassDatum, realizedTargetClassDatum);
-							if (conformingSources && conformingTargets) {
-								if (attributeConnectionSourceEdges == null) {
-									attributeConnectionSourceEdges = new ArrayList<>();
-								}
-								attributeConnectionSourceEdges.add(realizedEdge);
-							}
-							else {
-								//	assert false;
-							}
+					for (@NonNull NavigationEdge realizedEdge : realizedEdges) {
+						ClassDatum firstClassDatum = QVTscheduleUtil.getClassDatum(QVTscheduleUtil.getSourceNode(realizedEdge));
+						ClassDatum secondTargetClassDatum = QVTscheduleUtil.getClassDatum(QVTscheduleUtil.getTargetNode(realizedEdge));
+						ClassDatum realizedSourceClassDatum;
+						ClassDatum realizedTargetClassDatum;
+						Property realizedProperty = QVTscheduleUtil.getReferredProperty(realizedEdge);
+						if (realizedProperty == predicatedProperty) {
+							realizedSourceClassDatum = firstClassDatum;
+							realizedTargetClassDatum = secondTargetClassDatum;
 						}
 						else {
-							// SharedEdge
+							assert realizedProperty == oppositeProperty;
+							realizedSourceClassDatum = secondTargetClassDatum;
+							realizedTargetClassDatum = firstClassDatum;
 						}
-						/*	}
+						boolean conformingSources = QVTscheduleUtil.conformantWith(predicatedSourceClassDatum, realizedSourceClassDatum);
+						boolean conformingTargets;
+						//	if (isOneToMany) {
+						conformingTargets = QVTscheduleUtil.conformantWith(predicatedTargetClassDatum, realizedTargetClassDatum);
+						if (conformingSources && conformingTargets) {
+							if (attributeConnectionSourceEdges == null) {
+								attributeConnectionSourceEdges = new ArrayList<>();
+							}
+							attributeConnectionSourceEdges.add(realizedEdge);
+						}
+						else {
+							//	assert false;
+						}
+					}
+					/*	}
 					else {
 						conformingTargets = areConforming(predicatedTargetCompleteClass, realizedTargetCompleteClass);
 						if (scheduleManager.isElementallyConformantSource(realizedEdge, predicatedEdge) && QVTscheduleUtil.isConformantTarget(realizedEdge, predicatedEdge)) {
@@ -206,7 +203,7 @@
 							assert !conformingSources || !conformingTargets;
 						}
 					} */
-					}
+					//	}
 					Node sourceNode = QVTscheduleUtil.getSourceNode(predicatedEdge);
 					ClassDatum sourceClassDatum = QVTscheduleUtil.getClassDatum(sourceNode);
 					partialNames.add(QVTscheduleUtil.getName(sourceClassDatum));
@@ -230,6 +227,24 @@
 						//					}
 					}
 				}
+				if (attributeConnectionSourceEdges != null) {
+					EdgeConnection edgeConnection = getAttributeConnection(invokingRegion2, attributeConnectionSourceEdges, partialNames, predicatedProperty);
+					edgeConnection.addUsedTargetEdge(predicatedEdge, false);
+					if (s != null) {
+						s.append("\n    Attribute EdgeConnection \"" + edgeConnection + "\" to " + castTarget);
+						for (@NonNull Edge sourceEdge : attributeConnectionSourceEdges) {
+							s.append("\n      from " + sourceEdge.getOwningRegion() + " : " + sourceEdge.getSourceNode());
+						}
+						//					Scheduler.CONNECTIONS.println("    classDatumAnalysis " + classDatumAnalysis);
+						//					for (@NonNull Node sourceNode : sourceNodes) {
+						//						Scheduler.CONNECTIONS.println("    from " + sourceNode.getRegion());
+						//						Scheduler.CONNECTIONS.println("       " + sourceNode);
+						//					}
+						//					for (@NonNull NavigationEdge realizedEdge : realizedEdges) {
+						//						Scheduler.CONNECTIONS.println("    edge " + realizedEdge);
+						//					}
+					}
+				}
 			}
 			else {
 				// Shared Edge
@@ -255,7 +270,7 @@
 			assert !isDataType;
 			Iterable<@NonNull Node> sourceNodes = getNewNodes(classDatum);
 			//			if (sourceNodes != null) {
-			Iterable<@NonNull NavigableEdge> realizedEdges = getNewEdges(predicatedEdge, classDatum);
+			Iterable<@NonNull NavigationEdge> realizedEdges = getNewEdges(predicatedEdge, classDatum);
 			if (realizedEdges != null) {
 				Set<@NonNull Region> edgeSourceRegions = new HashSet<>();
 				Set<@NonNull Region> nodeSourceRegions = new HashSet<>();
@@ -314,7 +329,7 @@
 						//			 && !rootRootRegion.isOnlyCastOrRecursed(predicatedNode)
 						//			 && !hasEdgeConnection(predicatedNode)
 						) {
-					NodeConnection predicatedConnection = getNodeConnection(invokingRegion2, sourceNodes, classDatum, scheduleManager.getDomainUsage(classDatum));
+					NodeConnection predicatedConnection = getNodeConnection(invokingRegion2, sourceNodes, classDatum);
 					predicatedConnection.addUsedTargetNode(castTarget, false);
 					if (s != null) {
 						s.append("\n    NodeConnection \"" + predicatedConnection + "\" to " + castTarget);
@@ -413,7 +428,7 @@
 		//
 		//	Connect up the head
 		//
-		NodeConnection headConnection = getNodeConnection(invokingRegion2, headSources, classDatum, scheduleManager.getDomainUsage(classDatum));
+		NodeConnection headConnection = getNodeConnection(invokingRegion2, headSources, classDatum);
 		if (headNode.isDependency()) {
 			headConnection.addUsedTargetNode(headNode, false);
 		}
@@ -437,29 +452,38 @@
 	private @Nullable Iterable<@NonNull NodeConnection> createHeadConnections(@Nullable StringBuilder s, @NonNull RootRegion rootRegion, @NonNull Region region) {
 		List<@NonNull NodeConnection> headConnections = null;
 		Iterable<@NonNull Node> headNodes = QVTscheduleUtil.getHeadNodes(region);
-		if (Iterables.isEmpty(region.getHeadNodes())) {
+		if (Iterables.isEmpty(headNodes)) {
 			scheduleManager.addRegionError(region, "No head nodes");
 		}
 		for (@NonNull Node headNode : headNodes) {
+			NodeConnection headConnection = null;
+			SharedEdge sharedEdge = isShared(headNode);
 			if (headNode.isDependency()) {
 				createHeadConnection(s, rootRegion, region, headNode);	/** Dependency nodes have extra not-head connections. */
 			}
+			else if (sharedEdge != null) {
+				headConnection = createSharedHeadConnection(s, rootRegion, region, sharedEdge);
+			}
 			else {
-				NodeConnection headConnection = createHeadConnection(s, rootRegion, region, headNode);
+				headConnection = createHeadConnection(s, rootRegion, region, headNode);
 				if (headConnection == null) {
 					scheduleManager.addRegionError(region, "No incoming connections for " + headNode.getName());
 					headConnection = createHeadConnection(s, rootRegion, region, headNode);	// FIXME debugging
 					return null;										//  so matching only fails for unmatchable real heads
 				}
-				else {
-					if (headConnections == null) {
-						headConnections = new ArrayList<>();
-					}
-					headConnections.add(headConnection);
-				}
-				// FIXME. If there are multiple heads and an internal node is reachable from more than one head, then the possible
-				// sources for the internal node are the intersection of the alternatives which may eliminate some call paths.
 			}
+			if (headConnection != null) {
+				if (headConnections == null) {
+					headConnections = new ArrayList<>();
+				}
+				headConnections.add(headConnection);
+			}
+			// FIXME. If there are multiple heads and an internal node is reachable from more than one head, then the possible
+			// sources for the internal node are the intersection of the alternatives which may eliminate some call paths.
+			//		}
+		}
+		if (headConnections == null) {
+			scheduleManager.addRegionError(region, "No incoming connections");
 		}
 		if (headConnections == null) {
 			scheduleManager.addRegionError(region, "No incoming connections");
@@ -506,32 +530,55 @@
 		//
 		//	Gather multiple edges sharing the same target to avoid multiple incoming connections -- FIXME no need to gather
 		//
-		Map<@NonNull Node, @NonNull List<@NonNull NavigableEdge>> castTargetNode2predicatedEdges = new HashMap<>();
+		Map<@NonNull Node, @NonNull List<@NonNull NavigableEdge>> targetNode2predicatedEdges = new HashMap<>();
 		for (@NonNull Edge edge : QVTscheduleUtil.getOwnedEdges(region)) {
 			assert !edge.isCast();
-			if (edge.isPredicated() && edge.isNavigation()) {
-				NavigationEdge predicatedEdge = (NavigationEdge)edge;
-				assert predicatedEdge.getIncomingConnection() == null;
-				Property predicatedProperty = predicatedEdge.getReferredProperty();
-				if (!predicatedProperty.isIsImplicit()) {		// unnavigable opposites are handled by the navigable property
-					Node castTargetNode = predicatedEdge.getEdgeTarget();
-					List<@NonNull NavigableEdge> predicatedEdges = castTargetNode2predicatedEdges.get(castTargetNode);
-					if (predicatedEdges == null) {
-						predicatedEdges = new ArrayList<>();
-						castTargetNode2predicatedEdges.put(castTargetNode, predicatedEdges);
+			if (edge.isPredicated()) {
+				if (edge.isNavigation()) {
+					NavigationEdge predicatedEdge = (NavigationEdge)edge;
+					assert predicatedEdge.getIncomingConnection() == null;
+					Property predicatedProperty = predicatedEdge.getReferredProperty();
+					if (!predicatedProperty.isIsImplicit()) {		// unnavigable opposites are handled by the navigable property
+						Node targetNode = predicatedEdge.getEdgeTarget();
+						List<@NonNull NavigableEdge> predicatedEdges = targetNode2predicatedEdges.get(targetNode);
+						if (predicatedEdges == null) {
+							predicatedEdges = new ArrayList<>();
+							targetNode2predicatedEdges.put(targetNode, predicatedEdges);
+						}
+						predicatedEdges.add(predicatedEdge);
 					}
-					predicatedEdges.add(predicatedEdge);
+				}
+				else if (edge.isShared()) {
+					SharedEdge callingSharedEdge = (SharedEdge)edge;
+					SharedEdge calledSharedEdge = originalContentsAnalysis.getNewSharedEdge((SharedEdge)edge);
+					if (calledSharedEdge == null) {
+						scheduleManager.addRegionError(region, "no source for " + callingSharedEdge);
+					}
+					//	else {
+					//		NodeConnection ec = getNodeConnection(rootRegion, Collections.singletonList(sourceNode), classDatum, scheduleManager.getDomainUsage(classDatum));
+					//	}
+					/*	assert predicatedEdge.getIncomingConnection() == null;
+					Property predicatedProperty = predicatedEdge.getReferredProperty();
+					if (!predicatedProperty.isIsImplicit()) {		// unnavigable opposites are handled by the navigable property
+						Node castTargetNode = predicatedEdge.getEdgeTarget();
+						List<@NonNull NavigableEdge> predicatedEdges = castTargetNode2predicatedEdges.get(castTargetNode);
+						if (predicatedEdges == null) {
+							predicatedEdges = new ArrayList<>();
+							castTargetNode2predicatedEdges.put(castTargetNode, predicatedEdges);
+						}
+						predicatedEdges.add(predicatedEdge);
+					} */
 				}
 			}
 		}
-		for (@NonNull Node castTargetNode : castTargetNode2predicatedEdges.keySet()) {
-			List<@NonNull NavigableEdge> predicatedEdges = castTargetNode2predicatedEdges.get(castTargetNode);
+		for (@NonNull Node targetNode : targetNode2predicatedEdges.keySet()) {
+			List<@NonNull NavigableEdge> predicatedEdges = targetNode2predicatedEdges.get(targetNode);
 			assert predicatedEdges != null;
-			if (castTargetNode.isClass()) {
-				createClassEdgeConnection(s, rootRegion, region, castTargetNode, predicatedEdges);
+			if (targetNode.isClass()) {
+				createClassEdgeConnection(s, rootRegion, region, targetNode, predicatedEdges);
 			}
 			else {
-				createAttributeEdgeConnection(s, rootRegion, region, castTargetNode, predicatedEdges);
+				createAttributeEdgeConnection(s, rootRegion, region, targetNode, predicatedEdges);
 			}
 		}
 	}
@@ -579,7 +626,7 @@
 			//
 			if (!sourceNodes.isEmpty()) {
 				ClassDatum classDatum = QVTscheduleUtil.getClassDatum(traceNode);
-				NodeConnection connection = getNodeConnection(rootRegion, sourceNodes, classDatum, scheduleManager.getDomainUsage(classDatum));
+				NodeConnection connection = getNodeConnection(rootRegion, sourceNodes, classDatum);
 				//
 				Set<@NonNull Node> targetNodes = new HashSet<>();
 				for (@NonNull Partition partition : partitions) {
@@ -621,6 +668,32 @@
 		}
 	}
 
+	private @Nullable NodeConnection createSharedHeadConnection(@Nullable StringBuilder s, @NonNull RootRegion rootRegion, @NonNull Region region, @NonNull SharedEdge sharedEdge) {
+		Node headNode = QVTscheduleUtil.getSourceNode(sharedEdge);
+		Node sharedNode = QVTscheduleUtil.getTargetNode(sharedEdge);
+		ClassDatum classDatum = QVTscheduleUtil.getClassDatum(sharedNode);
+		Iterable<@NonNull SharedEdge> oldSharedEdges = originalContentsAnalysis.getOldSharedEdges(sharedEdge);
+		if (oldSharedEdges != null) {
+			List<@NonNull Node> sourceNodes = new ArrayList<>();
+			for (@NonNull SharedEdge edge : oldSharedEdges) {
+				sourceNodes.add(QVTscheduleUtil.getSourceNode(edge));
+			}
+			NodeConnection connection = getNodeConnection(rootRegion, sourceNodes, classDatum);
+			connection.setDataType(true);
+			//	Set<@NonNull Node> targetNodes = new HashSet<>();
+			//	for (@NonNull Partition partition : partitions) {
+			//		Role nodeRole = QVTscheduleUtil.getRole(partition, traceNode);
+			//		if ((nodeRole != null) && nodeRole.isOld()) {
+			//			if (targetNodes.add(traceNode)) {
+			connection.addPassedTargetNode(headNode);
+			//			}
+			//		}
+			//	}
+			return connection;
+		}
+		return null;
+	}
+
 	private @NonNull EdgeConnection getAttributeConnection(@NonNull RootRegion rootRegion, @NonNull Iterable<@NonNull NavigableEdge> sourceEdges, @NonNull List<@NonNull String> partialNames, @NonNull Property property) {
 		Set<@NonNull NavigableEdge> sourceSet = Sets.newHashSet(sourceEdges);
 		EdgeConnection connection = edges2edgeConnection.get(sourceSet);
@@ -822,7 +895,7 @@
 		return loopingConnections;
 	}
 
-	private @Nullable Iterable<@NonNull NavigableEdge> getNewEdges(@NonNull NavigableEdge edge, @NonNull ClassDatum requiredClassDatum) {
+	private @Nullable Iterable<@NonNull NavigationEdge> getNewEdges(@NonNull NavigableEdge edge, @NonNull ClassDatum requiredClassDatum) {
 		return originalContentsAnalysis.getNewEdges(edge, requiredClassDatum);
 	}
 
@@ -842,7 +915,7 @@
 		return getOutgoingConnections(partition);
 	}
 
-	private @NonNull NodeConnection getNodeConnection(@NonNull RootRegion rootRegion, @NonNull Iterable<@NonNull Node> sourceNodes, @NonNull ClassDatum classDatum, @NonNull DomainUsage domainUsage) {
+	private @NonNull NodeConnection getNodeConnection(@NonNull RootRegion rootRegion, @NonNull Iterable<@NonNull Node> sourceNodes, @NonNull ClassDatum classDatum) {
 		Map<@NonNull Set<@NonNull Node>, @NonNull NodeConnection> nodes2connection = classDatum2nodes2nodeConnections.get(classDatum);
 		if (nodes2connection == null) {
 			nodes2connection = new HashMap<>();
@@ -851,8 +924,28 @@
 		Set<@NonNull Node> sourceSet = Sets.newHashSet(sourceNodes);
 		NodeConnection connection = nodes2connection.get(sourceSet);
 		if (connection == null) {
+			DomainUsage domainUsage = scheduleManager.getDomainUsage(classDatum);
 			SymbolNameBuilder s = new SymbolNameBuilder();
-			s.appendString(domainUsage.isInput() ? JOIN_INPUT_PREFIX : domainUsage.isOutput() ? JOIN_OUTPUT_PREFIX : JOIN_MIDDLE_PREFIX);
+			if (domainUsage.isInput()) {
+				s.appendString(JOIN_INPUT_PREFIX);
+			}
+			else if (domainUsage.isOutput()) {
+				s.appendString(JOIN_OUTPUT_PREFIX);
+			}
+			else {
+				boolean isShared = false;
+				for (@NonNull Node node : sourceNodes) {
+					if (isShared(node) != null) {
+						isShared = true;
+					}
+				}
+				if (isShared) {
+					s.appendString(JOIN_SHARED_PREFIX);
+				}
+				else {
+					s.appendString(JOIN_MIDDLE_PREFIX);
+				}
+			}
 			s.appendString("_");
 			s.appendName(classDatum.getName());
 			connection = createNodeConnection(rootRegion, sourceSet, classDatum, s);
@@ -1043,6 +1136,15 @@
 		return lastProduction >= firstConsumption;
 	}
 
+	private @Nullable SharedEdge isShared(@NonNull Node headNode) {
+		for (@NonNull Edge outgoingEdge : QVTscheduleUtil.getOutgoingEdges(headNode)) {
+			if (outgoingEdge.isShared()) {
+				return (SharedEdge) outgoingEdge;
+			}
+		}
+		return null;
+	}
+
 	public void removeCallToChild(@NonNull Partition parentPartition, @NonNull Partition childPartition) {
 		getCallableChildren(parentPartition).remove(childPartition);
 		getCallableParents(childPartition).remove(parentPartition);
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/analysis/AbstractPartialRegionAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/analysis/AbstractPartialRegionAnalysis.java
index c228376..9904b6c 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/analysis/AbstractPartialRegionAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/analysis/AbstractPartialRegionAnalysis.java
@@ -27,6 +27,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.Node;
 import org.eclipse.qvtd.pivot.qvtschedule.Partition;
 import org.eclipse.qvtd.pivot.qvtschedule.PropertyDatum;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.SuccessEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 
@@ -86,9 +87,11 @@
 	private final @NonNull List<@NonNull Node> predicatedMiddleNodes = new ArrayList<>();
 	private final @NonNull List<@NonNull NavigableEdge> predicatedOutputEdges = new ArrayList<>();
 	private final @NonNull List<@NonNull Node> predicatedOutputNodes = new ArrayList<>();
+	private final @NonNull List<@NonNull SharedEdge> predicatedSharedEdges = new ArrayList<>();
 	private final @NonNull List<@NonNull NavigableEdge> realizedMiddleEdges = new ArrayList<>();
 	private final @NonNull List<@NonNull Node> realizedMiddleNodes = new ArrayList<>();
 	private final @NonNull List<@NonNull NavigableEdge> realizedOutputEdges = new ArrayList<>();
+	private final @NonNull List<@NonNull SharedEdge> realizedSharedEdges = new ArrayList<>();
 	private final @NonNull List<@NonNull Node> realizedOutputNodes = new ArrayList<>();
 
 	/**
@@ -195,6 +198,13 @@
 		}
 	}
 
+	private void addConsumptionOfSharedEdge(@NonNull SharedEdge edge) {
+		if (!predicatedSharedEdges.contains(edge)) {
+			predicatedSharedEdges.add(edge);
+			//	addConsumptionOfEdge(sharedEdge);
+		}
+	}
+
 	private void addProductionOfEdge(@NonNull NavigableEdge edge) {
 		assert isNew(edge);
 		if (edge.isNavigation()) {
@@ -266,6 +276,13 @@
 		}
 	}
 
+	private void addProductionOfSharedEdge(@NonNull SharedEdge edge) {
+		if (!realizedSharedEdges.contains(edge)) {
+			realizedSharedEdges.add(edge);
+			//	addProductionOfEdge(sharedEdge);
+		}
+	}
+
 	protected void analyzeEdges() {
 		for (@NonNull Edge edge : getPartialEdges()) {
 			assert !edge.isCast();
@@ -314,6 +331,16 @@
 						}
 					}
 				}
+				else if (edge.isShared()) {
+					SharedEdge sharedEdge = (SharedEdge)edge;
+					if (sharedEdge.isPredicated()) {
+						addConsumptionOfSharedEdge(sharedEdge);
+						oldPrimaryNavigableEdges.add(sharedEdge);
+					}
+					else if (sharedEdge.isRealized()) {
+						addProductionOfSharedEdge(sharedEdge);
+					}
+				}
 				else if (edge.isExpression()) {}
 				else if (edge instanceof IteratedEdge) {}
 				else if (edge.isDependency()) {}
@@ -518,6 +545,10 @@
 		return predicatedOutputNodes;
 	}
 
+	public @NonNull Iterable<@NonNull SharedEdge> getPredicatedSharedEdges() {
+		return predicatedSharedEdges;
+	}
+
 	public @NonNull Iterable<@NonNull NavigableEdge> getRealizedEdges() {
 		return realizedEdges;
 	}
@@ -534,6 +565,10 @@
 		return realizedOutputNodes;
 	}
 
+	public @NonNull Iterable<@NonNull SharedEdge> getRealizedSharedEdges() {
+		return realizedSharedEdges;
+	}
+
 	public @NonNull ScheduleManager getScheduleManager() {
 		return scheduleManager;
 	}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/analysis/PartialRegionAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/analysis/PartialRegionAnalysis.java
index a12c77d..9a76b9e 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/analysis/PartialRegionAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/analysis/PartialRegionAnalysis.java
@@ -22,6 +22,7 @@
 	@Nullable Iterable<@NonNull PartialRegionClassAnalysis<@NonNull PRA>> getConsumedClassAnalyses();
 	@Nullable Iterable<@NonNull PartialRegionPropertyAnalysis<@NonNull PRA>> getConsumedPropertyAnalyses();
 	@Nullable Iterable<@NonNull PartialRegionAnalysis<@NonNull PRA>> getExplicitPredecessors();
+	@Nullable Iterable<@NonNull PartialRegionAnalysis<@NonNull PRA>> getSharedPredecessors();
 	@NonNull Partition getPartition();
 	@NonNull Region getRegion();
 	@NonNull Iterable<@NonNull Node> getTraceNodes();
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/AbstractPartitionAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/AbstractPartitionAnalysis.java
index 183f384..7be12a0 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/AbstractPartitionAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/AbstractPartitionAnalysis.java
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.eclipse.qvtd.compiler.internal.qvts2qvts.partitioner;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
@@ -21,9 +22,11 @@
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.analysis.PartialRegionPropertyAnalysis;
 import org.eclipse.qvtd.pivot.qvtschedule.Edge;
 import org.eclipse.qvtd.pivot.qvtschedule.Node;
+import org.eclipse.qvtd.pivot.qvtschedule.NodeConnection;
 import org.eclipse.qvtd.pivot.qvtschedule.Partition;
 import org.eclipse.qvtd.pivot.qvtschedule.Region;
 import org.eclipse.qvtd.pivot.qvtschedule.Role;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 
 /**
@@ -87,6 +90,27 @@
 	}
 
 	@Override
+	public @Nullable Iterable<@NonNull PartialRegionAnalysis<@NonNull PartitionsAnalysis>> getSharedPredecessors() {
+		List<@NonNull PartialRegionAnalysis<@NonNull PartitionsAnalysis>> sharedPredecessors = null;
+		for (@NonNull SharedEdge sharedEdge : getRealizedSharedEdges()) {
+			Node thisNode = QVTscheduleUtil.getSourceNode(sharedEdge);
+			NodeConnection connection = thisNode.getIncomingConnection();
+			if (connection != null) {
+				for (@NonNull Partition thatPartition : connection.getSourcePartitions()) {
+					if (sharedPredecessors == null) {
+						sharedPredecessors = new ArrayList<>();
+					}
+					PartitionAnalysis partitionAnalysis = partitionedTransformationAnalysis.getPartitionAnalysis(thatPartition);
+					if (!sharedPredecessors.contains(partitionAnalysis)) {
+						sharedPredecessors.add(partitionAnalysis);
+					}
+				}
+			}
+		}
+		return sharedPredecessors;
+	}
+
+	@Override
 	public @NonNull List<@NonNull Node> getTraceNodes() {
 		throw new UnsupportedOperationException();
 	}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/AbstractPartitioningStrategy.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/AbstractPartitioningStrategy.java
index aebee67..3a99063 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/AbstractPartitioningStrategy.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/AbstractPartitioningStrategy.java
@@ -73,7 +73,12 @@
 		if (useActivators) {
 			regionAnalysis.createLocalSuccess();
 		}
-		BasicPartitionAnalysis localPredicatePartition = new LocalPredicatePartitionFactory(mappingPartitioner, useActivators).createPartitionAnalysis(partitionedTransformationAnalysis);
+		LocalPredicatePartitionFactory localPredicatePartitionFactory = new LocalPredicatePartitionFactory(mappingPartitioner, useActivators);
+		if (localPredicatePartitionFactory.hasSharedEdges()) {
+			regionAnalysis.createLocalSuccess();
+			//			regionAnalysis.createGlobalSuccess();
+		}
+		BasicPartitionAnalysis localPredicatePartition = localPredicatePartitionFactory.createPartitionAnalysis(partitionedTransformationAnalysis);
 		BasicPartitionAnalysis globalPredicatePartition = new GlobalPredicatePartitionFactory(mappingPartitioner).createPartitionAnalysis(partitionedTransformationAnalysis);
 		BasicPartitionAnalysis speculatedPartition = new SpeculatedPartitionFactory(mappingPartitioner).createPartitionAnalysis(partitionedTransformationAnalysis);
 		newPartitionAnalyses.add(localPredicatePartition);
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/GlobalPredicatePartitionFactory.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/GlobalPredicatePartitionFactory.java
index 74faafe..c72c898 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/GlobalPredicatePartitionFactory.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/GlobalPredicatePartitionFactory.java
@@ -10,7 +10,9 @@
  *******************************************************************************/
 package org.eclipse.qvtd.compiler.internal.qvts2qvts.partitioner;
 
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNull;
@@ -21,6 +23,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.Edge;
 import org.eclipse.qvtd.pivot.qvtschedule.Node;
 import org.eclipse.qvtd.pivot.qvtschedule.Role;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.SuccessEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 
@@ -32,9 +35,20 @@
 public class GlobalPredicatePartitionFactory extends AbstractSimplePartitionFactory
 {
 	private final @NonNull Set<@NonNull Node> tracedInputNodes = new HashSet<>();
+	private final @Nullable Iterable<@NonNull SharedEdge> sharedEdges;
 
 	public GlobalPredicatePartitionFactory(@NonNull MappingPartitioner mappingPartitioner) {
 		super(mappingPartitioner);
+		List<@NonNull SharedEdge> sharedEdges = null;
+		for (@NonNull Edge edge : QVTscheduleUtil.getOwnedEdges(region)) {
+			if (edge.isShared()) {
+				if (sharedEdges == null) {
+					sharedEdges = new ArrayList<>();
+				}
+				sharedEdges.add((SharedEdge) edge);
+			}
+		}
+		this.sharedEdges = sharedEdges;
 	}
 
 	@Override
@@ -103,6 +117,16 @@
 		//
 		resolveSuccessNodes(partition, executionNodes);
 		//
+		//	Prime all shared edges
+		//
+		if (sharedEdges != null) {
+			for (@NonNull Edge edge : sharedEdges) {
+				addNode(partition, QVTscheduleUtil.getSourceNode(edge));
+				addNode(partition, QVTscheduleUtil.getTargetNode(edge));
+				addEdge(partition, edge, Role.PREDICATED);
+			}
+		}
+		//
 		//	Add the outstanding predicates that can be checked by this partition.
 		//
 		resolveConstantOutputNodes(partition/*isInfallible*/);
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/LocalPredicatePartitionFactory.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/LocalPredicatePartitionFactory.java
index a359b01..85877da 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/LocalPredicatePartitionFactory.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/LocalPredicatePartitionFactory.java
@@ -24,6 +24,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.Node;
 import org.eclipse.qvtd.pivot.qvtschedule.Node.Utility;
 import org.eclipse.qvtd.pivot.qvtschedule.Role;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 
 import com.google.common.collect.Iterables;
@@ -44,6 +45,8 @@
 	private final @NonNull Iterable<@NonNull Node> executionNodes;
 	private final @NonNull Iterable<@NonNull Node> realizedWhenNodes;
 	private final @Nullable Node dispatchNode;
+	private final @Nullable Iterable<@NonNull SharedEdge> sharedEdges;
+	private final @Nullable Iterable<@NonNull Node> sharedEdgeTargets;
 
 	public LocalPredicatePartitionFactory(@NonNull MappingPartitioner mappingPartitioner, boolean useActivators) {
 		super(mappingPartitioner);
@@ -51,6 +54,25 @@
 		this.useActivators = useActivators;
 		this.realizedWhenNodes = mappingPartitioner.getRealizedWhenNodes();
 		this.dispatchNode = mappingPartitioner.basicGetDispatchNode();
+		List<@NonNull SharedEdge> sharedEdges = null;
+		List<@NonNull Node> sharedEdgeTargets = null;
+		for (@NonNull Edge edge : QVTscheduleUtil.getOwnedEdges(region)) {
+			if (edge.isShared()) {
+				if (sharedEdges == null) {
+					sharedEdges = new ArrayList<>();
+				}
+				sharedEdges.add((SharedEdge) edge);
+				if (sharedEdgeTargets == null) {
+					sharedEdgeTargets = new ArrayList<>();
+				}
+				Node targetNode = QVTscheduleUtil.getTargetNode(edge);
+				if (!sharedEdgeTargets.contains(targetNode)) { 		// In practice two shared edges is an error
+					sharedEdgeTargets.add(targetNode);
+				}
+			}
+		}
+		this.sharedEdges = sharedEdges;
+		this.sharedEdgeTargets = sharedEdgeTargets;
 	}
 
 	@Override
@@ -108,6 +130,10 @@
 		return rootNodes;
 	}
 
+	public boolean hasSharedEdges() {
+		return sharedEdges != null;
+	}
+
 	protected void initializePartition(@NonNull BasicPartitionAnalysis partitionAnalysis) {
 		BasicPartition partition = partitionAnalysis.getPartition();
 		//	this.traceNode = mappingPartitioner.getTraceNode();
@@ -152,6 +178,16 @@
 			}
 		}
 		//
+		//	Prime all shared edges
+		//
+		if (sharedEdges != null) {
+			for (@NonNull Edge edge : sharedEdges) {
+				addNode(partition, QVTscheduleUtil.getSourceNode(edge));
+				addNode(partition, QVTscheduleUtil.getTargetNode(edge));
+				addEdge(partition, edge, Role.PREDICATED);
+			}
+		}
+		//
 		//	All old nodes reachable from heads that are not part of cycles are copied to the speculation guard.
 		//	NB. Unreachable loaded nodes are effectively predicates and so are deferred.
 		//
@@ -242,6 +278,13 @@
 
 	@Override
 	protected @Nullable Role resolveEdgeRole(@NonNull Role sourceNodeRole, @NonNull Edge edge, @NonNull Role targetNodeRole) {
+		if (sharedEdgeTargets != null) {		// No more edges to phantom shared edge target
+			Node sourceNode = QVTscheduleUtil.getSourceNode(edge);
+			Node targetNode = QVTscheduleUtil.getTargetNode(edge);
+			if (Iterables.contains(sharedEdgeTargets, sourceNode) || Iterables.contains(sharedEdgeTargets, targetNode)) {
+				return null;
+			}
+		}
 		Role edgeRole = QVTscheduleUtil.getEdgeRole(edge);
 		if (edgeRole == Role.REALIZED) {
 			if (mappingPartitioner.hasRealizedEdge(edge)) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/MappingPartitioner.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/MappingPartitioner.java
index e9e8d76..fa874ad 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/MappingPartitioner.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/MappingPartitioner.java
@@ -289,11 +289,16 @@
 	//	}
 
 	private @NonNull PartitioningStrategy createPartitioningStrategy(@NonNull PartitionedTransformationAnalysis partitionedTransformationAnalysis) {
+		for (@NonNull Edge edge : QVTscheduleUtil.getOwnedEdges(region)) {
+			if (edge.isShared() && edge.isRealized()) {
+				return new SharedPartitioningStrategy(partitionedTransformationAnalysis, this);
+			}
+		}
 		boolean useActivators = scheduleManager.useActivators();
-		if (useActivators) { 		// New QVTr-style spportg without activators
+		if (useActivators) { 		// New QVTr-style support with activators
 			return new DefaultPartitioningStrategy(partitionedTransformationAnalysis, this);
 		}
-		else {			// Obsolete QVTc-sty;e spportg without activators
+		else {			// Obsolete QVTc-style spportg without activators
 			return new LegacyPartitioningStrategy(partitionedTransformationAnalysis, this);
 		}
 	}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitionedTransformationAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitionedTransformationAnalysis.java
index 2dadb74..d3973a1 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitionedTransformationAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitionedTransformationAnalysis.java
@@ -15,6 +15,8 @@
 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.qvtb2qvts.AbstractTransformationAnalysis;
+import org.eclipse.qvtd.compiler.internal.qvts2qvts.RegionsAnalysis;
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.analysis.AbstractPartialRegionsAnalysis;
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.analysis.PartialRegionAnalysis;
 import org.eclipse.qvtd.compiler.internal.qvts2qvts.analysis.PartialRegionClassAnalysis;
@@ -113,7 +115,9 @@
 
 	@Override
 	protected @NonNull PartialRegionClassAnalysis<@NonNull PartitionsAnalysis> createClassAnalysis(@NonNull ClassDatum classDatum) {
-		return new TraceClassPartitionAnalysis(transformationPartitioner.getTransformationAnalysis().getClassAnalysis(classDatum));
+		AbstractTransformationAnalysis transformationAnalysis = transformationPartitioner.getTransformationAnalysis();
+		PartialRegionClassAnalysis<@NonNull RegionsAnalysis> classAnalysis = transformationAnalysis.getClassAnalysis(classDatum);	// This fails if ClassDatum instances are not created in a timely fashion
+		return new TraceClassPartitionAnalysis(classAnalysis);
 	}
 
 	public @NonNull AbstractFallibilityAnalysis getFallibilityAnalysis(@NonNull Partition partition) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SharedPartitioningStrategy.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SharedPartitioningStrategy.java
new file mode 100644
index 0000000..c5afb74
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SharedPartitioningStrategy.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Willink Transformations and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ *   E.D.Willink - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.qvtd.compiler.internal.qvts2qvts.partitioner;
+
+import org.eclipse.jdt.annotation.NonNull;
+
+/**
+ * SharedPartitioningStrategy inhibits partitioning and creates a SharedPartition.
+ */
+public class SharedPartitioningStrategy extends AbstractPartitioningStrategy
+{
+	public SharedPartitioningStrategy(@NonNull PartitionedTransformationAnalysis partitionedTransformationAnalysis, @NonNull MappingPartitioner mappingPartitioner) {
+		super(partitionedTransformationAnalysis, mappingPartitioner);
+	}
+
+	@Override
+	public @NonNull Iterable<@NonNull PartitionAnalysis> partition() {
+		createNonPartition();
+		check();
+		return newPartitionAnalyses;
+	}
+
+	protected void createNonPartition() {
+		newPartitionAnalyses.add(new NonPartitionFactory(mappingPartitioner).createPartitionAnalysis(partitionedTransformationAnalysis));
+	}
+
+	@Override
+	protected boolean useActivators() {
+		return false;
+	}
+}
\ 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
index da506a4..3edd0c2 100644
--- 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
@@ -26,6 +26,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.NavigableEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.NavigationEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.Node;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
 import com.google.common.collect.Lists;
 
@@ -42,11 +43,17 @@
 	private static final int ITERATOR_COST = 1;
 	private static final int OPERATION_COST = 10;
 	private static final int RESULT_COST = 1;
+	private static final int SHARED_NAVIGATION_COST = 10;
 
 	/**
 	 * The preferred non-secondary edges to be used in the tree.
 	 */
-	private final @NonNull Set<@NonNull NavigableEdge> forwardEdges = new HashSet<>();
+	private final @NonNull Set<@NonNull NavigationEdge> forwardEdges = new HashSet<>();
+
+	/**
+	 * The shared edges to be used in the tree.
+	 */
+	private @Nullable List<@NonNull SharedEdge> sharedEdges = null;
 
 	/**
 	 * Edges that have no opposite.
@@ -102,6 +109,13 @@
 				}
 			}
 		}
+		else if (edge instanceof SharedEdge) {
+			List<@NonNull SharedEdge> sharedEdges2 = sharedEdges;
+			if (sharedEdges2 == null) {
+				sharedEdges = sharedEdges2 = new ArrayList<>();
+			}
+			sharedEdges2.add((SharedEdge)edge);
+		}
 	}
 
 	/**
@@ -195,6 +209,22 @@
 				}
 			}
 		}
+		if (sharedEdges != null) {
+			for (@NonNull SharedEdge sharedEdge : sharedEdges) {
+				Node targetNode = sharedEdge.getEdgeTarget();
+				if (!node2reachingEdge.containsKey(targetNode)) {
+					Integer targetCost = node2cost.get(targetNode);
+					assert targetCost == null;
+					Node sourceNode = sharedEdge.getEdgeSource();
+					Integer sourceCost = node2cost.get(sourceNode);
+					if (sourceCost != null) {
+						int nextCost = sourceCost + SHARED_NAVIGATION_COST;
+						node2cost.put(targetNode, nextCost);
+						node2reachingEdge.put(targetNode, sharedEdge);
+					}
+				}
+			}
+		}
 	}
 
 	public @Nullable Integer getCost(@NonNull Node node) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/utilities/CompilerUtil.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/utilities/CompilerUtil.java
index 5973e06..fa3cb2a 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/utilities/CompilerUtil.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/utilities/CompilerUtil.java
@@ -269,6 +269,14 @@
 					producers.add(explicitPredecessor);
 				}
 			}
+			Iterable<@NonNull PartialRegionAnalysis<@NonNull PRA>> sharedPredecessors = consumer.getSharedPredecessors();		// Used by no-success QVTc trace
+			if (sharedPredecessors != null) {
+				for (@NonNull PartialRegionAnalysis<@NonNull PRA> sharedPredecessor : sharedPredecessors) {
+					Set<@NonNull PartialRegionAnalysis<@NonNull PRA>> producers = consumer2producers.get(consumer);
+					assert producers != null;
+					producers.add(sharedPredecessor);
+				}
+			}
 			Iterable<@NonNull PartialRegionClassAnalysis<@NonNull PRA>> consumedClassAnalyses = consumer.getConsumedClassAnalyses();
 			if (consumedClassAnalyses != null) {
 				for (@NonNull PartialRegionClassAnalysis<@NonNull PRA> consumedClassAnalysis : consumedClassAnalyses) {
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/graphs/DelegatingToGraphHelper.java b/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/graphs/DelegatingToGraphHelper.java
new file mode 100644
index 0000000..0bb00fc
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/graphs/DelegatingToGraphHelper.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Willink Transformations and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ *     E.D.Willink - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.qvtd.pivot.qvtbase.graphs;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder.GraphElement;
+import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder.GraphNode;
+
+public class DelegatingToGraphHelper implements ToGraphHelper
+{
+	protected final @NonNull ToGraphHelper delegate;
+
+	public DelegatingToGraphHelper(@NonNull ToGraphHelper delegate) {
+		this.delegate = delegate;
+	}
+
+	@Override
+	public @NonNull GraphStringBuilder getGraphStringBuilder() {
+		return delegate.getGraphStringBuilder();
+	}
+
+	@Override
+	public void setColor(@NonNull GraphElement element) {
+		delegate.setColor(element);
+	}
+
+	@Override
+	public void setHead(@NonNull GraphNode node) {
+		delegate.setHead(node);
+	}
+
+	@Override
+	public void setLabel(@NonNull GraphNode node) {
+		delegate.setLabel(node);
+	}
+
+	@Override
+	public void setPenwidth(@NonNull GraphNode node) {
+		delegate.setPenwidth(node);
+	}
+
+	@Override
+	public void setShapeAndStyle(@NonNull GraphNode node) {
+		delegate.setShapeAndStyle(node);
+	}
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/graphs/GraphMLStringBuilder.java b/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/graphs/GraphMLStringBuilder.java
index a3fc6e5..50245cf 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/graphs/GraphMLStringBuilder.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/graphs/GraphMLStringBuilder.java
@@ -208,6 +208,9 @@
 		else if ("vee".equals(arrowhead)) {
 			targetArrowType = ArrowType.standard;
 		}
+		else if ("odiamond".equals(arrowhead)) {
+			targetArrowType = ArrowType.white_diamond;
+		}
 	}
 
 	@Override
@@ -227,6 +230,9 @@
 		else if ("vee".equals(arrowtail)) {
 			sourceArrowType = ArrowType.standard;
 		}
+		else if ("odiamond".equals(arrowtail)) {
+			sourceArrowType = ArrowType.white_diamond;
+		}
 	}
 
 	@Override
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java
index 252f031..4189efd 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtimperative/src/org/eclipse/qvtd/pivot/qvtimperative/utilities/QVTimperativeUtil.java
@@ -23,8 +23,10 @@
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.ocl.pivot.CollectionType;
+import org.eclipse.ocl.pivot.DataType;
 import org.eclipse.ocl.pivot.OCLExpression;
 import org.eclipse.ocl.pivot.Property;
+import org.eclipse.ocl.pivot.Type;
 import org.eclipse.ocl.pivot.TypedElement;
 import org.eclipse.ocl.pivot.Variable;
 import org.eclipse.ocl.pivot.VariableDeclaration;
@@ -248,6 +250,22 @@
 		return ClassUtil.nonNullState(asSetStatement.getTargetVariable());
 	}
 
+	/**
+	 * Return true if one of the non-primitive domains has a DataType root variable. This will need a SharedEdge
+	 * to enforce the DataType-to-singleton mapping.
+	 */
+	public static boolean isDataType(@NonNull Mapping asMapping) {
+		for (@NonNull MappingParameter mappingParameter : getOwnedMappingParameters(asMapping)) {
+			if (mappingParameter instanceof GuardParameter) {
+				Type rootType = getType(mappingParameter);
+				if (rootType instanceof DataType) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
 	public static boolean isObserver(@NonNull Mapping asMapping) {
 		boolean isHazardous = false;
 		for (@NonNull Statement asStatement : ClassUtil.nullFree(asMapping.getOwnedStatements())) {
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtrelation/src/org/eclipse/qvtd/pivot/qvtrelation/utilities/QVTrelationUtil.java b/plugins/org.eclipse.qvtd.pivot.qvtrelation/src/org/eclipse/qvtd/pivot/qvtrelation/utilities/QVTrelationUtil.java
index 4416288..2d9fe97 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtrelation/src/org/eclipse/qvtd/pivot/qvtrelation/utilities/QVTrelationUtil.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtrelation/src/org/eclipse/qvtd/pivot/qvtrelation/utilities/QVTrelationUtil.java
@@ -23,8 +23,10 @@
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.DataType;
 import org.eclipse.ocl.pivot.OCLExpression;
 import org.eclipse.ocl.pivot.Property;
+import org.eclipse.ocl.pivot.Type;
 import org.eclipse.ocl.pivot.Variable;
 import org.eclipse.ocl.pivot.resource.ASResource;
 import org.eclipse.ocl.pivot.VariableDeclaration;
@@ -376,6 +378,24 @@
 	//		return ClassUtil.nonNullState(rRelation.getWhere());
 	//	}
 
+	/**
+	 * Return true if one of the non-primitive domains has a DataType root variable. This will need a SharedEdge
+	 * to enforce the DataType-to-singleton mapping.
+	 */
+	public static boolean isDataTypeRelation(@NonNull Relation relation) {
+		for (@NonNull RelationDomain relationDomain : QVTrelationUtil.getOwnedDomains(relation)) {
+			if (!getTypedModel(relationDomain).isIsPrimitive()) {
+				for (@NonNull VariableDeclaration rootVariable : getRootVariables(relationDomain)) {
+					Type rootType = QVTrelationUtil.getType(rootVariable);
+					if (rootType instanceof DataType) {
+						return true;
+					}
+				}
+			}
+		}
+		return false;
+	}
+
 	public static boolean isTraceClassVariable(@NonNull VariableDeclaration variable) {
 		return TRACE_CLASS_NAME.equals(variable.getName()) && (variable instanceof SharedVariable) && ((SharedVariable)variable).isIsImplicit();
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/Edge.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/Edge.java
index e2c1341..6e25535 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/Edge.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/Edge.java
@@ -365,6 +365,11 @@
 	boolean isSecondary();
 
 	/**
+	 * Return true if this edge is to a shared singleton.
+	 */
+	boolean isShared();
+
+	/**
 	 * Return true if this edge is for a multi-region speculated predicate.
 	 */
 	boolean isSpeculated();
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/NodeConnection.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/NodeConnection.java
index b7592b5..78e40fa 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/NodeConnection.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/NodeConnection.java
@@ -28,7 +28,7 @@
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
 	 * <!-- begin-model-doc -->
-	 * Non-null if this edge is part of a bidirectional pair.
+	 * The type and typed model of the passed connection element.
 	 * <!-- end-model-doc -->
 	 * @return the value of the '<em>Class Datum</em>' reference.
 	 * @see #setClassDatum(ClassDatum)
@@ -49,6 +49,31 @@
 	void setClassDatum(ClassDatum value);
 
 	/**
+	 * Returns the value of the '<em><b>Data Type</b></em>' attribute.
+	 * The default value is <code>"false"</code>.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * <!-- begin-model-doc -->
+	 * True if the connection input is a DataType for which the output is the  singletone trace element.
+	 * <!-- end-model-doc -->
+	 * @return the value of the '<em>Data Type</em>' attribute.
+	 * @see #setDataType(boolean)
+	 * @see org.eclipse.qvtd.pivot.qvtschedule.QVTschedulePackage#getNodeConnection_DataType()
+	 * @model default="false" required="true"
+	 *        annotation="http://www.eclipse.org/emf/2002/GenModel get='throw new UnsupportedOperationException();  // FIXME Unimplemented http://www.eclipse.org/qvt/2017/QVTschedule!NodeConnection!dataType'"
+	 * @generated
+	 */
+	boolean isDataType();
+	/**
+	 * Sets the value of the '{@link org.eclipse.qvtd.pivot.qvtschedule.NodeConnection#isDataType <em>Data Type</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Data Type</em>' attribute.
+	 * @see #isDataType()
+	 * @generated
+	 */
+	void setDataType(boolean value);
+	/**
 	 * Returns the value of the '<em><b>Mandatory Target Nodes</b></em>' reference list.
 	 * The list contents are of type {@link org.eclipse.qvtd.pivot.qvtschedule.Node}.
 	 * <!-- begin-user-doc -->
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTscheduleFactory.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTscheduleFactory.java
index 784f358..5e88550 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTscheduleFactory.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTscheduleFactory.java
@@ -494,6 +494,15 @@
 	@NonNull ShadowPartEdge createShadowPartEdge();
 
 	/**
+	 * Returns a new object of class '<em>Shared Edge</em>'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return a new object of class '<em>Shared Edge</em>'.
+	 * @generated
+	 */
+	@NonNull SharedEdge createSharedEdge();
+
+	/**
 	 * Returns a new object of class '<em>String Literal Node</em>'.
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTschedulePackage.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTschedulePackage.java
index 3f17938..8edb36d 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTschedulePackage.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTschedulePackage.java
@@ -981,6 +981,27 @@
 	EReference getShadowPartEdge_ReferredPart();
 
 	/**
+	 * Returns the meta object for class '{@link org.eclipse.qvtd.pivot.qvtschedule.SharedEdge <em>Shared Edge</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for class '<em>Shared Edge</em>'.
+	 * @see org.eclipse.qvtd.pivot.qvtschedule.SharedEdge
+	 * @generated
+	 */
+	EClass getSharedEdge();
+
+	/**
+	 * Returns the meta object for the reference '{@link org.eclipse.qvtd.pivot.qvtschedule.SharedEdge#getReferredOppositeProperty <em>Referred Opposite Property</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the reference '<em>Referred Opposite Property</em>'.
+	 * @see org.eclipse.qvtd.pivot.qvtschedule.SharedEdge#getReferredOppositeProperty()
+	 * @see #getSharedEdge()
+	 * @generated
+	 */
+	EReference getSharedEdge_ReferredOppositeProperty();
+
+	/**
 	 * Returns the meta object for class '{@link org.eclipse.qvtd.pivot.qvtschedule.StringLiteralNode <em>String Literal Node</em>}'.
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -1729,6 +1750,17 @@
 	EReference getNodeConnection_ClassDatum();
 
 	/**
+	 * Returns the meta object for the attribute '{@link org.eclipse.qvtd.pivot.qvtschedule.NodeConnection#isDataType <em>Data Type</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>Data Type</em>'.
+	 * @see org.eclipse.qvtd.pivot.qvtschedule.NodeConnection#isDataType()
+	 * @see #getNodeConnection()
+	 * @generated
+	 */
+	EAttribute getNodeConnection_DataType();
+
+	/**
 	 * Returns the meta object for the reference list '{@link org.eclipse.qvtd.pivot.qvtschedule.NodeConnection#getMandatoryTargetNodes <em>Mandatory Target Nodes</em>}'.
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -3045,6 +3077,24 @@
 		EReference SHADOW_PART_EDGE__REFERRED_PART = eINSTANCE.getShadowPartEdge_ReferredPart();
 
 		/**
+		 * The meta object literal for the '{@link org.eclipse.qvtd.pivot.qvtschedule.impl.SharedEdgeImpl <em>Shared Edge</em>}' class.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @see org.eclipse.qvtd.pivot.qvtschedule.impl.SharedEdgeImpl
+		 * @see org.eclipse.qvtd.pivot.qvtschedule.impl.QVTschedulePackageImpl#getSharedEdge()
+		 * @generated
+		 */
+		EClass SHARED_EDGE = eINSTANCE.getSharedEdge();
+
+		/**
+		 * The meta object literal for the '<em><b>Referred Opposite Property</b></em>' reference feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		EReference SHARED_EDGE__REFERRED_OPPOSITE_PROPERTY = eINSTANCE.getSharedEdge_ReferredOppositeProperty();
+
+		/**
 		 * The meta object literal for the '{@link org.eclipse.qvtd.pivot.qvtschedule.impl.StringLiteralNodeImpl <em>String Literal Node</em>}' class.
 		 * <!-- begin-user-doc -->
 		 * <!-- end-user-doc -->
@@ -3679,6 +3729,14 @@
 		EReference NODE_CONNECTION__CLASS_DATUM = eINSTANCE.getNodeConnection_ClassDatum();
 
 		/**
+		 * The meta object literal for the '<em><b>Data Type</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		EAttribute NODE_CONNECTION__DATA_TYPE = eINSTANCE.getNodeConnection_DataType();
+
+		/**
 		 * The meta object literal for the '<em><b>Mandatory Target Nodes</b></em>' reference list feature.
 		 * <!-- begin-user-doc -->
 		 * <!-- end-user-doc -->
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTscheduleTables.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTscheduleTables.java
index ea94c9b..ee0b491 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTscheduleTables.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/QVTscheduleTables.java
@@ -275,6 +275,7 @@
 		public static final @NonNull EcoreExecutorType _ScheduleModel = new EcoreExecutorType(QVTschedulePackage.Literals.SCHEDULE_MODEL, PACKAGE, 0);
 		public static final @NonNull EcoreExecutorType _ShadowNode = new EcoreExecutorType(QVTschedulePackage.Literals.SHADOW_NODE, PACKAGE, 0);
 		public static final @NonNull EcoreExecutorType _ShadowPartEdge = new EcoreExecutorType(QVTschedulePackage.Literals.SHADOW_PART_EDGE, PACKAGE, 0);
+		public static final @NonNull EcoreExecutorType _SharedEdge = new EcoreExecutorType(QVTschedulePackage.Literals.SHARED_EDGE, PACKAGE, 0);
 		public static final @NonNull EcoreExecutorType _StringLiteralNode = new EcoreExecutorType(QVTschedulePackage.Literals.STRING_LITERAL_NODE, PACKAGE, 0);
 		public static final @NonNull EcoreExecutorType _SuccessEdge = new EcoreExecutorType(QVTschedulePackage.Literals.SUCCESS_EDGE, PACKAGE, 0);
 		public static final @NonNull EcoreExecutorType _SuccessNode = new EcoreExecutorType(QVTschedulePackage.Literals.SUCCESS_NODE, PACKAGE, 0);
@@ -356,6 +357,7 @@
 			_ScheduleModel,
 			_ShadowNode,
 			_ShadowPartEdge,
+			_SharedEdge,
 			_StringLiteralNode,
 			_SuccessEdge,
 			_SuccessNode,
@@ -912,6 +914,14 @@
 		private static final @NonNull ExecutorFragment _ShadowPartEdge__OclElement = new ExecutorFragment(Types._ShadowPartEdge, OCLstdlibTables.Types._OclElement);
 		private static final @NonNull ExecutorFragment _ShadowPartEdge__ShadowPartEdge = new ExecutorFragment(Types._ShadowPartEdge, QVTscheduleTables.Types._ShadowPartEdge);
 
+		private static final @NonNull ExecutorFragment _SharedEdge__ConnectionEnd = new ExecutorFragment(Types._SharedEdge, QVTscheduleTables.Types._ConnectionEnd);
+		private static final @NonNull ExecutorFragment _SharedEdge__Edge = new ExecutorFragment(Types._SharedEdge, QVTscheduleTables.Types._Edge);
+		private static final @NonNull ExecutorFragment _SharedEdge__Element = new ExecutorFragment(Types._SharedEdge, PivotTables.Types._Element);
+		private static final @NonNull ExecutorFragment _SharedEdge__NavigableEdge = new ExecutorFragment(Types._SharedEdge, QVTscheduleTables.Types._NavigableEdge);
+		private static final @NonNull ExecutorFragment _SharedEdge__OclAny = new ExecutorFragment(Types._SharedEdge, OCLstdlibTables.Types._OclAny);
+		private static final @NonNull ExecutorFragment _SharedEdge__OclElement = new ExecutorFragment(Types._SharedEdge, OCLstdlibTables.Types._OclElement);
+		private static final @NonNull ExecutorFragment _SharedEdge__SharedEdge = new ExecutorFragment(Types._SharedEdge, QVTscheduleTables.Types._SharedEdge);
+
 		private static final @NonNull ExecutorFragment _StringLiteralNode__ConnectionEnd = new ExecutorFragment(Types._StringLiteralNode, QVTscheduleTables.Types._ConnectionEnd);
 		private static final @NonNull ExecutorFragment _StringLiteralNode__Element = new ExecutorFragment(Types._StringLiteralNode, PivotTables.Types._Element);
 		private static final @NonNull ExecutorFragment _StringLiteralNode__MappingNode = new ExecutorFragment(Types._StringLiteralNode, QVTscheduleTables.Types._MappingNode);
@@ -1210,13 +1220,14 @@
 		public static final @NonNull ExecutorProperty _Node__OperationRegion__resultNode = new ExecutorPropertyWithImplementation("OperationRegion", Types._Node, 24, new EcoreLibraryOppositeProperty(QVTschedulePackage.Literals.OPERATION_REGION__RESULT_NODE));
 
 		public static final @NonNull ExecutorProperty _NodeConnection__classDatum = new EcoreExecutorProperty(QVTschedulePackage.Literals.NODE_CONNECTION__CLASS_DATUM, Types._NodeConnection, 0);
-		public static final @NonNull ExecutorProperty _NodeConnection__mandatoryTargetNodes = new EcoreExecutorProperty(QVTschedulePackage.Literals.NODE_CONNECTION__MANDATORY_TARGET_NODES, Types._NodeConnection, 1);
-		public static final @NonNull ExecutorProperty _NodeConnection__passedTargetNodes = new EcoreExecutorProperty(QVTschedulePackage.Literals.NODE_CONNECTION__PASSED_TARGET_NODES, Types._NodeConnection, 2);
-		public static final @NonNull ExecutorProperty _NodeConnection__preferredTargetNodes = new EcoreExecutorProperty(QVTschedulePackage.Literals.NODE_CONNECTION__PREFERRED_TARGET_NODES, Types._NodeConnection, 3);
-		public static final @NonNull ExecutorProperty _NodeConnection__Node__incomingConnection = new ExecutorPropertyWithImplementation("Node", Types._NodeConnection, 4, new EcoreLibraryOppositeProperty(QVTschedulePackage.Literals.NODE__INCOMING_CONNECTION));
-		public static final @NonNull ExecutorProperty _NodeConnection__Node__outgoingConnections = new ExecutorPropertyWithImplementation("Node", Types._NodeConnection, 5, new EcoreLibraryOppositeProperty(QVTschedulePackage.Literals.NODE__OUTGOING_CONNECTIONS));
-		public static final @NonNull ExecutorProperty _NodeConnection__Partition__intermediateConnections = new ExecutorPropertyWithImplementation("Partition", Types._NodeConnection, 6, new EcoreLibraryOppositeProperty(QVTschedulePackage.Literals.PARTITION__INTERMEDIATE_CONNECTIONS));
-		public static final @NonNull ExecutorProperty _NodeConnection__Partition__rootConnections = new ExecutorPropertyWithImplementation("Partition", Types._NodeConnection, 7, new EcoreLibraryOppositeProperty(QVTschedulePackage.Literals.PARTITION__ROOT_CONNECTIONS));
+		public static final @NonNull ExecutorProperty _NodeConnection__dataType = new EcoreExecutorProperty(QVTschedulePackage.Literals.NODE_CONNECTION__DATA_TYPE, Types._NodeConnection, 1);
+		public static final @NonNull ExecutorProperty _NodeConnection__mandatoryTargetNodes = new EcoreExecutorProperty(QVTschedulePackage.Literals.NODE_CONNECTION__MANDATORY_TARGET_NODES, Types._NodeConnection, 2);
+		public static final @NonNull ExecutorProperty _NodeConnection__passedTargetNodes = new EcoreExecutorProperty(QVTschedulePackage.Literals.NODE_CONNECTION__PASSED_TARGET_NODES, Types._NodeConnection, 3);
+		public static final @NonNull ExecutorProperty _NodeConnection__preferredTargetNodes = new EcoreExecutorProperty(QVTschedulePackage.Literals.NODE_CONNECTION__PREFERRED_TARGET_NODES, Types._NodeConnection, 4);
+		public static final @NonNull ExecutorProperty _NodeConnection__Node__incomingConnection = new ExecutorPropertyWithImplementation("Node", Types._NodeConnection, 5, new EcoreLibraryOppositeProperty(QVTschedulePackage.Literals.NODE__INCOMING_CONNECTION));
+		public static final @NonNull ExecutorProperty _NodeConnection__Node__outgoingConnections = new ExecutorPropertyWithImplementation("Node", Types._NodeConnection, 6, new EcoreLibraryOppositeProperty(QVTschedulePackage.Literals.NODE__OUTGOING_CONNECTIONS));
+		public static final @NonNull ExecutorProperty _NodeConnection__Partition__intermediateConnections = new ExecutorPropertyWithImplementation("Partition", Types._NodeConnection, 7, new EcoreLibraryOppositeProperty(QVTschedulePackage.Literals.PARTITION__INTERMEDIATE_CONNECTIONS));
+		public static final @NonNull ExecutorProperty _NodeConnection__Partition__rootConnections = new ExecutorPropertyWithImplementation("Partition", Types._NodeConnection, 8, new EcoreLibraryOppositeProperty(QVTschedulePackage.Literals.PARTITION__ROOT_CONNECTIONS));
 
 		public static final @NonNull ExecutorProperty _NumericLiteralNode__numericValue = new EcoreExecutorProperty(QVTschedulePackage.Literals.NUMERIC_LITERAL_NODE__NUMERIC_VALUE, Types._NumericLiteralNode, 0);
 
@@ -1278,6 +1289,8 @@
 
 		public static final @NonNull ExecutorProperty _ShadowPartEdge__referredPart = new EcoreExecutorProperty(QVTschedulePackage.Literals.SHADOW_PART_EDGE__REFERRED_PART, Types._ShadowPartEdge, 0);
 
+		public static final @NonNull ExecutorProperty _SharedEdge__referredOppositeProperty = new EcoreExecutorProperty(QVTschedulePackage.Literals.SHARED_EDGE__REFERRED_OPPOSITE_PROPERTY, Types._SharedEdge, 0);
+
 		public static final @NonNull ExecutorProperty _StringLiteralNode__stringValue = new EcoreExecutorProperty(QVTschedulePackage.Literals.STRING_LITERAL_NODE__STRING_VALUE, Types._StringLiteralNode, 0);
 
 		public static final @NonNull ExecutorProperty _Symbolable__symbolName = new EcoreExecutorProperty(QVTschedulePackage.Literals.SYMBOLABLE__SYMBOL_NAME, Types._Symbolable, 0);
@@ -2105,6 +2118,18 @@
 			};
 		private static final int @NonNull [] __ShadowPartEdge = { 1,1,1,1,1,1,1 };
 
+		private static final @NonNull ExecutorFragment @NonNull [] _SharedEdge =
+			{
+				Fragments._SharedEdge__OclAny /* 0 */,
+				Fragments._SharedEdge__OclElement /* 1 */,
+				Fragments._SharedEdge__ConnectionEnd /* 2 */,
+				Fragments._SharedEdge__Element /* 2 */,
+				Fragments._SharedEdge__Edge /* 3 */,
+				Fragments._SharedEdge__NavigableEdge /* 4 */,
+				Fragments._SharedEdge__SharedEdge /* 5 */
+			};
+		private static final int @NonNull [] __SharedEdge = { 1,1,2,1,1,1 };
+
 		private static final @NonNull ExecutorFragment @NonNull [] _StringLiteralNode =
 			{
 				Fragments._StringLiteralNode__OclAny /* 0 */,
@@ -2300,6 +2325,7 @@
 			Types._ScheduleModel.initFragments(_ScheduleModel, __ScheduleModel);
 			Types._ShadowNode.initFragments(_ShadowNode, __ShadowNode);
 			Types._ShadowPartEdge.initFragments(_ShadowPartEdge, __ShadowPartEdge);
+			Types._SharedEdge.initFragments(_SharedEdge, __SharedEdge);
 			Types._StringLiteralNode.initFragments(_StringLiteralNode, __StringLiteralNode);
 			Types._SuccessEdge.initFragments(_SuccessEdge, __SuccessEdge);
 			Types._SuccessNode.initFragments(_SuccessNode, __SuccessNode);
@@ -4701,6 +4727,41 @@
 			OCLstdlibTables.Operations._OclElement__oclModelTypes /* oclModelTypes() */
 		};
 
+		private static final @NonNull ExecutorOperation @NonNull [] _SharedEdge__SharedEdge = {};
+		private static final @NonNull ExecutorOperation @NonNull [] _SharedEdge__ConnectionEnd = {};
+		private static final @NonNull ExecutorOperation @NonNull [] _SharedEdge__Edge = {};
+		private static final @NonNull ExecutorOperation @NonNull [] _SharedEdge__Element = {
+			PivotTables.Operations._Element__allOwnedElements /* allOwnedElements() */,
+			PivotTables.Operations._Element__getValue /* getValue(Type[1],String[1]) */
+		};
+		private static final @NonNull ExecutorOperation @NonNull [] _SharedEdge__NavigableEdge = {};
+		private static final @NonNull ExecutorOperation @NonNull [] _SharedEdge__OclAny = {
+			OCLstdlibTables.Operations._OclAny___lt__gt_ /* _'<>'(OclSelf[1]) */,
+			OCLstdlibTables.Operations._OclAny___eq_ /* _'='(OclSelf[1]) */,
+			OCLstdlibTables.Operations._OclAny__oclAsSet /* oclAsSet() */,
+			OCLstdlibTables.Operations._OclAny__oclAsType /* oclAsType(TT)(TT[1]) */,
+			OCLstdlibTables.Operations._OclAny__oclIsInState /* oclIsInState(OclState[?]) */,
+			OCLstdlibTables.Operations._OclAny__oclIsInvalid /* oclIsInvalid() */,
+			OCLstdlibTables.Operations._OclAny__oclIsKindOf /* oclIsKindOf(OclType[1]) */,
+			OCLstdlibTables.Operations._OclAny__oclIsNew /* oclIsNew() */,
+			OCLstdlibTables.Operations._OclAny__oclIsTypeOf /* oclIsTypeOf(OclType[1]) */,
+			OCLstdlibTables.Operations._OclAny__oclIsUndefined /* oclIsUndefined() */,
+			OCLstdlibTables.Operations._OclAny__0_oclLog /* oclLog() */,
+			OCLstdlibTables.Operations._OclAny__1_oclLog /* oclLog(String[?]) */,
+			OCLstdlibTables.Operations._OclAny__oclType /* oclType() */,
+			OCLstdlibTables.Operations._OclAny__oclTypes /* oclTypes() */,
+			OCLstdlibTables.Operations._OclAny__toString /* toString() */
+		};
+		private static final @NonNull ExecutorOperation @NonNull [] _SharedEdge__OclElement = {
+			OCLstdlibTables.Operations._OclElement__allInstances /* allInstances() */,
+			OCLstdlibTables.Operations._OclElement__oclAsModelType /* oclAsModelType(TT)(TT[1]) */,
+			OCLstdlibTables.Operations._OclElement__oclContainer /* oclContainer() */,
+			OCLstdlibTables.Operations._OclElement__oclContents /* oclContents() */,
+			OCLstdlibTables.Operations._OclElement__oclIsModelKindOf /* oclIsModelKindOf(OclType[1]) */,
+			OCLstdlibTables.Operations._OclElement__oclModelType /* oclModelType() */,
+			OCLstdlibTables.Operations._OclElement__oclModelTypes /* oclModelTypes() */
+		};
+
 		private static final @NonNull ExecutorOperation @NonNull [] _StringLiteralNode__StringLiteralNode = {};
 		private static final @NonNull ExecutorOperation @NonNull [] _StringLiteralNode__ConnectionEnd = {};
 		private static final @NonNull ExecutorOperation @NonNull [] _StringLiteralNode__Element = {
@@ -5575,6 +5636,14 @@
 			Fragments._ShadowPartEdge__OclElement.initOperations(_ShadowPartEdge__OclElement);
 			Fragments._ShadowPartEdge__ShadowPartEdge.initOperations(_ShadowPartEdge__ShadowPartEdge);
 
+			Fragments._SharedEdge__ConnectionEnd.initOperations(_SharedEdge__ConnectionEnd);
+			Fragments._SharedEdge__Edge.initOperations(_SharedEdge__Edge);
+			Fragments._SharedEdge__Element.initOperations(_SharedEdge__Element);
+			Fragments._SharedEdge__NavigableEdge.initOperations(_SharedEdge__NavigableEdge);
+			Fragments._SharedEdge__OclAny.initOperations(_SharedEdge__OclAny);
+			Fragments._SharedEdge__OclElement.initOperations(_SharedEdge__OclElement);
+			Fragments._SharedEdge__SharedEdge.initOperations(_SharedEdge__SharedEdge);
+
 			Fragments._StringLiteralNode__ConnectionEnd.initOperations(_StringLiteralNode__ConnectionEnd);
 			Fragments._StringLiteralNode__Element.initOperations(_StringLiteralNode__Element);
 			Fragments._StringLiteralNode__MappingNode.initOperations(_StringLiteralNode__MappingNode);
@@ -6197,6 +6266,7 @@
 			QVTscheduleTables.Properties._NodeConnection__classDatum,
 			QVTscheduleTables.Properties._Connection__commonPartition,
 			QVTscheduleTables.Properties._Connection__connectionRole,
+			QVTscheduleTables.Properties._NodeConnection__dataType,
 			QVTscheduleTables.Properties._Connection__intermediatePartitions,
 			QVTscheduleTables.Properties._NodeConnection__mandatoryTargetNodes,
 			QVTscheduleTables.Properties._Connection__name,
@@ -6444,6 +6514,18 @@
 			QVTscheduleTables.Properties._Edge__targetNode
 		};
 
+		private static final @NonNull ExecutorProperty @NonNull [] _SharedEdge = {
+			QVTscheduleTables.Properties._Edge__cluster,
+			QVTscheduleTables.Properties._Edge__edgeRole,
+			QVTscheduleTables.Properties._NavigableEdge__incomingConnection,
+			QVTscheduleTables.Properties._Edge__name,
+			QVTscheduleTables.Properties._NavigableEdge__outgoingConnections,
+			QVTscheduleTables.Properties._Edge__owningRegion,
+			QVTscheduleTables.Properties._SharedEdge__referredOppositeProperty,
+			QVTscheduleTables.Properties._Edge__sourceNode,
+			QVTscheduleTables.Properties._Edge__targetNode
+		};
+
 		private static final @NonNull ExecutorProperty @NonNull [] _StringLiteralNode = {
 			QVTscheduleTables.Properties._Node__classDatum,
 			QVTscheduleTables.Properties._Node__cluster,
@@ -6640,6 +6722,7 @@
 			Fragments._ScheduleModel__ScheduleModel.initProperties(_ScheduleModel);
 			Fragments._ShadowNode__ShadowNode.initProperties(_ShadowNode);
 			Fragments._ShadowPartEdge__ShadowPartEdge.initProperties(_ShadowPartEdge);
+			Fragments._SharedEdge__SharedEdge.initProperties(_SharedEdge);
 			Fragments._StringLiteralNode__StringLiteralNode.initProperties(_StringLiteralNode);
 			Fragments._SuccessEdge__SuccessEdge.initProperties(_SuccessEdge);
 			Fragments._SuccessNode__SuccessNode.initProperties(_SuccessNode);
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/SharedEdge.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/SharedEdge.java
new file mode 100644
index 0000000..f71e891
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/SharedEdge.java
@@ -0,0 +1,69 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2013, 2018 Willink Transformations and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ *   E.D.Willink - Initial API and implementation
+ *
+ * </copyright>
+ */
+package org.eclipse.qvtd.pivot.qvtschedule;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.ocl.pivot.Property;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Shared Edge</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <!-- begin-model-doc -->
+ * A SharedEdge supports the directed shared aggregation from a DataType node to its aggregator node within a Region.
+ * <!-- end-model-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * </p>
+ * <ul>
+ *   <li>{@link org.eclipse.qvtd.pivot.qvtschedule.SharedEdge#getReferredOppositeProperty <em>Referred Opposite Property</em>}</li>
+ * </ul>
+ *
+ * @see org.eclipse.qvtd.pivot.qvtschedule.QVTschedulePackage#getSharedEdge()
+ * @model
+ * @generated
+ */
+public interface SharedEdge extends NavigableEdge {
+	/**
+	 * Returns the value of the '<em><b>Referred Opposite Property</b></em>' reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * <!-- begin-model-doc -->
+	 * The property to navigate from source to target.
+	 * <!-- end-model-doc -->
+	 * @return the value of the '<em>Referred Opposite Property</em>' reference.
+	 * @see #setReferredOppositeProperty(Property)
+	 * @see org.eclipse.qvtd.pivot.qvtschedule.QVTschedulePackage#getSharedEdge_ReferredOppositeProperty()
+	 * @model required="true"
+	 *        annotation="http://www.eclipse.org/emf/2002/GenModel get='throw new UnsupportedOperationException();  // FIXME Unimplemented http://www.eclipse.org/qvt/2017/QVTschedule!SharedEdge!referredOppositeProperty'"
+	 * @generated
+	 */
+	Property getReferredOppositeProperty();
+
+	/**
+	 * Sets the value of the '{@link org.eclipse.qvtd.pivot.qvtschedule.SharedEdge#getReferredOppositeProperty <em>Referred Opposite Property</em>}' reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Referred Opposite Property</em>' reference.
+	 * @see #getReferredOppositeProperty()
+	 * @generated
+	 */
+	void setReferredOppositeProperty(Property value);
+
+	void initializeProperty(@NonNull Property target2sourceProperty);
+
+} // SharedEdge
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/EdgeImpl.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/EdgeImpl.java
index 4746fb5..7802375 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/EdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/EdgeImpl.java
@@ -853,6 +853,11 @@
 	}
 
 	@Override
+	public boolean isShared() {
+		return false;
+	}
+
+	@Override
 	public boolean isSpeculated() {
 		assert edgeRole != null;
 		return edgeRole == Role.SPECULATED;
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/NodeConnectionImpl.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/NodeConnectionImpl.java
index 838c9f9..d416d02 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/NodeConnectionImpl.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/NodeConnectionImpl.java
@@ -59,6 +59,7 @@
  * </p>
  * <ul>
  *   <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.NodeConnectionImpl#getClassDatum <em>Class Datum</em>}</li>
+ *   <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.NodeConnectionImpl#isDataType <em>Data Type</em>}</li>
  *   <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.NodeConnectionImpl#getMandatoryTargetNodes <em>Mandatory Target Nodes</em>}</li>
  *   <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.NodeConnectionImpl#getPassedTargetNodes <em>Passed Target Nodes</em>}</li>
  *   <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.NodeConnectionImpl#getPreferredTargetNodes <em>Preferred Target Nodes</em>}</li>
@@ -75,7 +76,7 @@
 	 * @generated
 	 * @ordered
 	 */
-	public static final int NODE_CONNECTION_FEATURE_COUNT = ConnectionImpl.CONNECTION_FEATURE_COUNT + 4;
+	public static final int NODE_CONNECTION_FEATURE_COUNT = ConnectionImpl.CONNECTION_FEATURE_COUNT + 5;
 
 	/**
 	 * The number of operations of the '<em>Node Connection</em>' class.
@@ -123,6 +124,26 @@
 	protected ClassDatum classDatum;
 
 	/**
+	 * The default value of the '{@link #isDataType() <em>Data Type</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #isDataType()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final boolean DATA_TYPE_EDEFAULT = false;
+
+	/**
+	 * The cached value of the '{@link #isDataType() <em>Data Type</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #isDataType()
+	 * @generated
+	 * @ordered
+	 */
+	protected boolean dataType = DATA_TYPE_EDEFAULT;
+
+	/**
 	 * The cached value of the '{@link #getMandatoryTargetNodes() <em>Mandatory Target Nodes</em>}' reference list.
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -212,6 +233,29 @@
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public boolean isDataType() {
+		return dataType;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void setDataType(boolean newDataType) {
+		boolean oldDataType = dataType;
+		dataType = newDataType;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, ElementImpl.ELEMENT_FEATURE_COUNT + 8, oldDataType, dataType));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
 	 * @generated NOT
 	 */
 	@Override
@@ -258,12 +302,14 @@
 		switch (featureID) {
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 7:
 				if (resolve) return getClassDatum();
-				return basicGetClassDatum();
+			return basicGetClassDatum();
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 8:
-				return getMandatoryTargetNodes();
+				return isDataType();
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 9:
-				return getPassedTargetNodes();
+				return getMandatoryTargetNodes();
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 10:
+				return getPassedTargetNodes();
+			case ElementImpl.ELEMENT_FEATURE_COUNT + 11:
 				return getPreferredTargetNodes();
 		}
 		return super.eGet(featureID, resolve, coreType);
@@ -280,19 +326,22 @@
 		switch (featureID) {
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 7:
 				setClassDatum((ClassDatum)newValue);
-				return;
+			return;
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 8:
-				getMandatoryTargetNodes().clear();
-				getMandatoryTargetNodes().addAll((Collection<? extends Node>)newValue);
-				return;
+				setDataType((Boolean)newValue);
+			return;
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 9:
-				getPassedTargetNodes().clear();
-				getPassedTargetNodes().addAll((Collection<? extends Node>)newValue);
-				return;
+				getMandatoryTargetNodes().clear();
+			getMandatoryTargetNodes().addAll((Collection<? extends Node>)newValue);
+			return;
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 10:
+				getPassedTargetNodes().clear();
+			getPassedTargetNodes().addAll((Collection<? extends Node>)newValue);
+			return;
+			case ElementImpl.ELEMENT_FEATURE_COUNT + 11:
 				getPreferredTargetNodes().clear();
-				getPreferredTargetNodes().addAll((Collection<? extends Node>)newValue);
-				return;
+			getPreferredTargetNodes().addAll((Collection<? extends Node>)newValue);
+			return;
 		}
 		super.eSet(featureID, newValue);
 	}
@@ -307,16 +356,19 @@
 		switch (featureID) {
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 7:
 				setClassDatum((ClassDatum)null);
-				return;
+			return;
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 8:
-				getMandatoryTargetNodes().clear();
-				return;
+				setDataType(DATA_TYPE_EDEFAULT);
+			return;
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 9:
-				getPassedTargetNodes().clear();
-				return;
+				getMandatoryTargetNodes().clear();
+			return;
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 10:
+				getPassedTargetNodes().clear();
+			return;
+			case ElementImpl.ELEMENT_FEATURE_COUNT + 11:
 				getPreferredTargetNodes().clear();
-				return;
+			return;
 		}
 		super.eUnset(featureID);
 	}
@@ -332,15 +384,22 @@
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 7:
 				return classDatum != null;
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 8:
-				return mandatoryTargetNodes != null && !mandatoryTargetNodes.isEmpty();
+				return dataType != DATA_TYPE_EDEFAULT;
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 9:
-				return passedTargetNodes != null && !passedTargetNodes.isEmpty();
+				return mandatoryTargetNodes != null && !mandatoryTargetNodes.isEmpty();
 			case ElementImpl.ELEMENT_FEATURE_COUNT + 10:
+				return passedTargetNodes != null && !passedTargetNodes.isEmpty();
+			case ElementImpl.ELEMENT_FEATURE_COUNT + 11:
 				return preferredTargetNodes != null && !preferredTargetNodes.isEmpty();
 		}
 		return super.eIsSet(featureID);
 	}
 
+	@Override
+	public String toString() {
+		return super.toString();
+	}
+
 	/**
 	 * {@inheritDoc}
 	 * @generated
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/QVTscheduleFactoryImpl.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/QVTscheduleFactoryImpl.java
index 901cd95..cfa69e4 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/QVTscheduleFactoryImpl.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/QVTscheduleFactoryImpl.java
@@ -120,14 +120,15 @@
 			case 63: return createScheduleModel();
 			case 64: return createShadowNode();
 			case 65: return createShadowPartEdge();
-			case 66: return createStringLiteralNode();
-			case 67: return createSuccessEdge();
-			case 68: return createSuccessNode();
-			case 70: return createTupleLiteralNode();
-			case 71: return createTuplePartEdge();
-			case 72: return createTypeLiteralNode();
-			case 73: return createUnknownNode();
-			case 75: return createVerdictRegion();
+			case 66: return createSharedEdge();
+			case 67: return createStringLiteralNode();
+			case 68: return createSuccessEdge();
+			case 69: return createSuccessNode();
+			case 71: return createTupleLiteralNode();
+			case 72: return createTuplePartEdge();
+			case 73: return createTypeLiteralNode();
+			case 74: return createUnknownNode();
+			case 76: return createVerdictRegion();
 			default:
 				throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier");
 		}
@@ -141,11 +142,11 @@
 	@Override
 	public Object createFromString(EDataType eDataType, String initialValue) {
 		switch (eDataType.getClassifierID()) {
-			case 76:
-				return createConnectionRoleFromString(eDataType, initialValue);
 			case 77:
-				return createRoleFromString(eDataType, initialValue);
+				return createConnectionRoleFromString(eDataType, initialValue);
 			case 78:
+				return createRoleFromString(eDataType, initialValue);
+			case 79:
 				return createNumberFromString(eDataType, initialValue);
 			default:
 				throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");
@@ -160,11 +161,11 @@
 	@Override
 	public String convertToString(EDataType eDataType, Object instanceValue) {
 		switch (eDataType.getClassifierID()) {
-			case 76:
-				return convertConnectionRoleToString(eDataType, instanceValue);
 			case 77:
-				return convertRoleToString(eDataType, instanceValue);
+				return convertConnectionRoleToString(eDataType, instanceValue);
 			case 78:
+				return convertRoleToString(eDataType, instanceValue);
+			case 79:
 				return convertNumberToString(eDataType, instanceValue);
 			default:
 				throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier");
@@ -738,6 +739,17 @@
 	 * @generated
 	 */
 	@Override
+	public @NonNull SharedEdge createSharedEdge() {
+		SharedEdgeImpl sharedEdge = new SharedEdgeImpl();
+		return sharedEdge;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
 	public @NonNull StringLiteralNode createStringLiteralNode() {
 		StringLiteralNodeImpl stringLiteralNode = new StringLiteralNodeImpl();
 		return stringLiteralNode;
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/QVTschedulePackageImpl.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/QVTschedulePackageImpl.java
index 1a37404..672bae5 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/QVTschedulePackageImpl.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/QVTschedulePackageImpl.java
@@ -98,6 +98,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.RootRegion;
 import org.eclipse.qvtd.pivot.qvtschedule.ShadowNode;
 import org.eclipse.qvtd.pivot.qvtschedule.ShadowPartEdge;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.StringLiteralNode;
 import org.eclipse.qvtd.pivot.qvtschedule.SuccessEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.SuccessNode;
@@ -303,6 +304,13 @@
 	 * <!-- end-user-doc -->
 	 * @generated
 	 */
+	private EClass sharedEdgeEClass = null;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
 	private EClass stringLiteralNodeEClass = null;
 
 	/**
@@ -1580,6 +1588,26 @@
 	 * @generated
 	 */
 	@Override
+	public EClass getSharedEdge() {
+		return sharedEdgeEClass;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public EReference getSharedEdge_ReferredOppositeProperty() {
+		return (EReference)sharedEdgeEClass.getEStructuralFeatures().get(0);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
 	public EClass getStringLiteralNode() {
 		return stringLiteralNodeEClass;
 	}
@@ -2290,8 +2318,8 @@
 	 * @generated
 	 */
 	@Override
-	public EReference getNodeConnection_MandatoryTargetNodes() {
-		return (EReference)nodeConnectionEClass.getEStructuralFeatures().get(1);
+	public EAttribute getNodeConnection_DataType() {
+		return (EAttribute)nodeConnectionEClass.getEStructuralFeatures().get(1);
 	}
 
 	/**
@@ -2300,7 +2328,7 @@
 	 * @generated
 	 */
 	@Override
-	public EReference getNodeConnection_PassedTargetNodes() {
+	public EReference getNodeConnection_MandatoryTargetNodes() {
 		return (EReference)nodeConnectionEClass.getEStructuralFeatures().get(2);
 	}
 
@@ -2310,7 +2338,7 @@
 	 * @generated
 	 */
 	@Override
-	public EReference getNodeConnection_PreferredTargetNodes() {
+	public EReference getNodeConnection_PassedTargetNodes() {
 		return (EReference)nodeConnectionEClass.getEStructuralFeatures().get(3);
 	}
 
@@ -2320,6 +2348,16 @@
 	 * @generated
 	 */
 	@Override
+	public EReference getNodeConnection_PreferredTargetNodes() {
+		return (EReference)nodeConnectionEClass.getEStructuralFeatures().get(4);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
 	public EClass getNonPartition() {
 		return nonPartitionEClass;
 	}
@@ -3015,9 +3053,10 @@
 
 		nodeConnectionEClass = createEClass(44);
 		createEReference(nodeConnectionEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 7);
-		createEReference(nodeConnectionEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 8);
+		createEAttribute(nodeConnectionEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 8);
 		createEReference(nodeConnectionEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 9);
 		createEReference(nodeConnectionEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 10);
+		createEReference(nodeConnectionEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 11);
 
 		nonPartitionEClass = createEClass(45);
 
@@ -3098,38 +3137,41 @@
 		shadowPartEdgeEClass = createEClass(65);
 		createEReference(shadowPartEdgeEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 6);
 
-		stringLiteralNodeEClass = createEClass(66);
+		sharedEdgeEClass = createEClass(66);
+		createEReference(sharedEdgeEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 8);
+
+		stringLiteralNodeEClass = createEClass(67);
 		createEAttribute(stringLiteralNodeEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 10);
 
-		successEdgeEClass = createEClass(67);
+		successEdgeEClass = createEClass(68);
 
-		successNodeEClass = createEClass(68);
+		successNodeEClass = createEClass(69);
 
-		symbolableEClass = createEClass(69);
+		symbolableEClass = createEClass(70);
 		createEAttribute(symbolableEClass, 0);
 
-		tupleLiteralNodeEClass = createEClass(70);
+		tupleLiteralNodeEClass = createEClass(71);
 
-		tuplePartEdgeEClass = createEClass(71);
+		tuplePartEdgeEClass = createEClass(72);
 		createEReference(tuplePartEdgeEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 6);
 
-		typeLiteralNodeEClass = createEClass(72);
+		typeLiteralNodeEClass = createEClass(73);
 		createEReference(typeLiteralNodeEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 10);
 
-		unknownNodeEClass = createEClass(73);
+		unknownNodeEClass = createEClass(74);
 
-		variableNodeEClass = createEClass(74);
+		variableNodeEClass = createEClass(75);
 		createEReference(variableNodeEClass, ElementImpl.ELEMENT_FEATURE_COUNT + 10);
 
-		verdictRegionEClass = createEClass(75);
+		verdictRegionEClass = createEClass(76);
 		createEReference(verdictRegionEClass, NamedElementImpl.NAMED_ELEMENT_FEATURE_COUNT + 9);
 
 		// Create enums
-		connectionRoleEEnum = createEEnum(76);
-		roleEEnum = createEEnum(77);
+		connectionRoleEEnum = createEEnum(77);
+		roleEEnum = createEEnum(78);
 
 		// Create data types
-		numberEDataType = createEDataType(78);
+		numberEDataType = createEDataType(79);
 	}
 
 	/**
@@ -3235,6 +3277,7 @@
 		scheduleModelEClass.getESuperTypes().add(thePivotPackage.getModel());
 		shadowNodeEClass.getESuperTypes().add(this.getOperationNode());
 		shadowPartEdgeEClass.getESuperTypes().add(this.getArgumentEdge());
+		sharedEdgeEClass.getESuperTypes().add(this.getNavigableEdge());
 		stringLiteralNodeEClass.getESuperTypes().add(this.getOperationNode());
 		successEdgeEClass.getESuperTypes().add(this.getNavigationEdge());
 		successNodeEClass.getESuperTypes().add(this.getMappingNode());
@@ -3418,6 +3461,7 @@
 
 		initEClass(nodeConnectionEClass, NodeConnection.class, "NodeConnection", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
 		initEReference(getNodeConnection_ClassDatum(), this.getClassDatum(), null, "classDatum", null, 1, 1, NodeConnection.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getNodeConnection_DataType(), ecorePackage.getEBoolean(), "dataType", "false", 1, 1, NodeConnection.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
 		initEReference(getNodeConnection_MandatoryTargetNodes(), this.getNode(), null, "mandatoryTargetNodes", null, 0, -1, NodeConnection.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, !IS_ORDERED);
 		initEReference(getNodeConnection_PassedTargetNodes(), this.getNode(), null, "passedTargetNodes", null, 0, -1, NodeConnection.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, !IS_ORDERED);
 		initEReference(getNodeConnection_PreferredTargetNodes(), this.getNode(), null, "preferredTargetNodes", null, 0, -1, NodeConnection.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, !IS_ORDERED);
@@ -3501,6 +3545,9 @@
 		initEClass(shadowPartEdgeEClass, ShadowPartEdge.class, "ShadowPartEdge", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
 		initEReference(getShadowPartEdge_ReferredPart(), thePivotPackage.getShadowPart(), null, "referredPart", null, 1, 1, ShadowPartEdge.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
 
+		initEClass(sharedEdgeEClass, SharedEdge.class, "SharedEdge", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+		initEReference(getSharedEdge_ReferredOppositeProperty(), thePivotPackage.getProperty(), null, "referredOppositeProperty", null, 1, 1, SharedEdge.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
 		initEClass(stringLiteralNodeEClass, StringLiteralNode.class, "StringLiteralNode", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
 		initEAttribute(getStringLiteralNode_StringValue(), thePivotPackage.getString(), "stringValue", null, 1, 1, StringLiteralNode.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
 
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/SharedEdgeImpl.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/SharedEdgeImpl.java
new file mode 100644
index 0000000..e965c94
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/impl/SharedEdgeImpl.java
@@ -0,0 +1,270 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2013, 2018 Willink Transformations and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ *   E.D.Willink - Initial API and implementation
+ *
+ * </copyright>
+ */
+package org.eclipse.qvtd.pivot.qvtschedule.impl;
+
+import org.eclipse.emf.common.notify.Notification;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.InternalEObject;
+
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.Property;
+
+import org.eclipse.ocl.pivot.internal.ElementImpl;
+
+import org.eclipse.ocl.pivot.util.Visitor;
+import org.eclipse.ocl.pivot.utilities.PivotUtil;
+import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder;
+import org.eclipse.qvtd.pivot.qvtbase.graphs.ToGraphHelper;
+import org.eclipse.qvtd.pivot.qvtschedule.QVTschedulePackage;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
+
+import org.eclipse.qvtd.pivot.qvtschedule.util.QVTscheduleVisitor;
+import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleConstants;
+import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model object '<em><b>Shared Edge</b></em>'.
+ * <!-- end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * </p>
+ * <ul>
+ *   <li>{@link org.eclipse.qvtd.pivot.qvtschedule.impl.SharedEdgeImpl#getReferredOppositeProperty <em>Referred Opposite Property</em>}</li>
+ * </ul>
+ *
+ * @generated
+ */
+public class SharedEdgeImpl extends NavigableEdgeImpl implements SharedEdge {
+	/**
+	 * The number of structural features of the '<em>Shared Edge</em>' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SHARED_EDGE_FEATURE_COUNT = NavigableEdgeImpl.NAVIGABLE_EDGE_FEATURE_COUNT + 1;
+
+	/**
+	 * The number of operations of the '<em>Shared Edge</em>' class.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	public static final int SHARED_EDGE_OPERATION_COUNT = NavigableEdgeImpl.NAVIGABLE_EDGE_OPERATION_COUNT + 0;
+
+
+	/**
+	 * The cached value of the '{@link #getReferredOppositeProperty() <em>Referred Opposite Property</em>}' reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getReferredOppositeProperty()
+	 * @generated
+	 * @ordered
+	 */
+	protected Property referredOppositeProperty;
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected SharedEdgeImpl() {
+		super();
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	protected EClass eStaticClass() {
+		return QVTschedulePackage.Literals.SHARED_EDGE;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Property getReferredOppositeProperty() {
+		if (referredOppositeProperty != null && referredOppositeProperty.eIsProxy()) {
+			InternalEObject oldReferredOppositeProperty = (InternalEObject)referredOppositeProperty;
+			referredOppositeProperty = (Property)eResolveProxy(oldReferredOppositeProperty);
+			if (referredOppositeProperty != oldReferredOppositeProperty) {
+				if (eNotificationRequired())
+					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ElementImpl.ELEMENT_FEATURE_COUNT + 8, oldReferredOppositeProperty, referredOppositeProperty));
+			}
+		}
+		return referredOppositeProperty;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public Property basicGetReferredOppositeProperty() {
+		return referredOppositeProperty;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void setReferredOppositeProperty(Property newReferredOppositeProperty) {
+		Property oldReferredOppositeProperty = referredOppositeProperty;
+		referredOppositeProperty = newReferredOppositeProperty;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, ElementImpl.ELEMENT_FEATURE_COUNT + 8, oldReferredOppositeProperty, referredOppositeProperty));
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public Object eGet(int featureID, boolean resolve, boolean coreType) {
+		switch (featureID) {
+			case ElementImpl.ELEMENT_FEATURE_COUNT + 8:
+				if (resolve) return getReferredOppositeProperty();
+				return basicGetReferredOppositeProperty();
+		}
+		return super.eGet(featureID, resolve, coreType);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eSet(int featureID, Object newValue) {
+		switch (featureID) {
+			case ElementImpl.ELEMENT_FEATURE_COUNT + 8:
+				setReferredOppositeProperty((Property)newValue);
+				return;
+		}
+		super.eSet(featureID, newValue);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public void eUnset(int featureID) {
+		switch (featureID) {
+			case ElementImpl.ELEMENT_FEATURE_COUNT + 8:
+				setReferredOppositeProperty((Property)null);
+				return;
+		}
+		super.eUnset(featureID);
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public boolean eIsSet(int featureID) {
+		switch (featureID) {
+			case ElementImpl.ELEMENT_FEATURE_COUNT + 8:
+				return referredOppositeProperty != null;
+		}
+		return super.eIsSet(featureID);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * @generated
+	 */
+	@SuppressWarnings("unchecked")
+	@Override
+	public <R> R accept(@NonNull Visitor<R> visitor) {
+		return (R) ((QVTscheduleVisitor<?>)visitor).visitSharedEdge(this);
+	}
+
+	@Override
+	public void appendEdgeAttributes(@NonNull ToGraphHelper toGraphHelper, @NonNull String sourceName, @NonNull String targetName) {
+		GraphStringBuilder s = toGraphHelper.getGraphStringBuilder();
+		toGraphHelper.setColor(this);
+		String label = getLabel();
+		if (label != null) {
+			s.setHeadlabel(label);
+		}
+		String style = getStyle();
+		if (style != null) {
+			s.setStyle(style);
+		}
+		s.setArrowhead("odiamond");
+		s.setPenwidth(getPenwidth());
+		s.appendAttributedEdge(sourceName, this, targetName);
+	}
+
+	@Override
+	public @NonNull String getDisplayName() {
+		Property target2sourceProperty2 = getReferredOppositeProperty();
+		if (target2sourceProperty2 != null) {
+			return "~" + target2sourceProperty2.getName();
+		}
+		else {
+			return "null";
+		}
+	}
+
+	@Override
+	public @NonNull String getEdgeName() {
+		return "~" + PivotUtil.getName(QVTscheduleUtil.getReferredOppositeProperty(this));
+	}
+
+	@Override
+	public @Nullable String getLabel() {
+		Property target2sourceProperty2 = QVTscheduleUtil.getReferredOppositeProperty(this);
+		return "~" + target2sourceProperty2.getName() + "\\n[1]";
+	}
+
+	@Override
+	public @NonNull Integer getPenwidth() {
+		return 2*QVTscheduleConstants.LINE_WIDTH;
+	}
+
+	@Override
+	public @Nullable String getStyle() {
+		return null;
+	}
+
+	@Override
+	public void initializeProperty(@NonNull Property target2sourceProperty) {
+		setReferredOppositeProperty(target2sourceProperty);
+	}
+
+	@Override
+	public boolean isShared() {
+		return true;
+	}
+} //SharedEdgeImpl
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractDelegatingQVTscheduleVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractDelegatingQVTscheduleVisitor.java
index d07555b..fb7286e 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractDelegatingQVTscheduleVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractDelegatingQVTscheduleVisitor.java
@@ -363,6 +363,11 @@
 	}
 
 	@Override
+	public R visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return delegate.visitSharedEdge(object);
+	}
+
+	@Override
 	public R visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return delegate.visitStringLiteralNode(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractExtendingQVTscheduleVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractExtendingQVTscheduleVisitor.java
index 992ba4d..9e9455f 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractExtendingQVTscheduleVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractExtendingQVTscheduleVisitor.java
@@ -367,6 +367,11 @@
 	}
 
 	@Override
+	public R visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return visitNavigableEdge(object);
+	}
+
+	@Override
 	public R visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return visitOperationNode(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractMergedQVTscheduleVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractMergedQVTscheduleVisitor.java
index 433c93e..053bfc7 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractMergedQVTscheduleVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractMergedQVTscheduleVisitor.java
@@ -359,6 +359,11 @@
 	}
 
 	@Override
+	public R visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return visiting(object);
+	}
+
+	@Override
 	public R visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return visiting(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractNullQVTscheduleVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractNullQVTscheduleVisitor.java
index 10a2a21..90484e7 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractNullQVTscheduleVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractNullQVTscheduleVisitor.java
@@ -367,6 +367,11 @@
 	}
 
 	@Override
+	public R visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return null;
+	}
+
+	@Override
 	public R visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return null;
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleAS2MonikerVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleAS2MonikerVisitor.java
index 7a5035b..6b51ed7 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleAS2MonikerVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleAS2MonikerVisitor.java
@@ -371,6 +371,11 @@
 	}
 
 	@Override
+	public @Nullable Object visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return visitNavigableEdge(object);
+	}
+
+	@Override
 	public @Nullable Object visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return visitOperationNode(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleAS2XMIidVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleAS2XMIidVisitor.java
index 94c18b5..bae588a 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleAS2XMIidVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleAS2XMIidVisitor.java
@@ -373,6 +373,11 @@
 	}
 
 	@Override
+	public @Nullable Boolean visitSharedEdge(@NonNull SharedEdge object) {
+		return visitNavigableEdge(object);
+	}
+
+	@Override
 	public @Nullable Boolean visitStringLiteralNode(@NonNull StringLiteralNode object) {
 		return visitOperationNode(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverLocateVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverLocateVisitor.java
index 9a8e41b..09f16e2 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverLocateVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverLocateVisitor.java
@@ -371,6 +371,11 @@
 	}
 
 	@Override
+	public @Nullable Object visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return visitNavigableEdge(object);
+	}
+
+	@Override
 	public @Nullable Object visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return visitOperationNode(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverNormalizeVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverNormalizeVisitor.java
index 3360f50..09118bc 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverNormalizeVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverNormalizeVisitor.java
@@ -371,6 +371,11 @@
 	}
 
 	@Override
+	public @Nullable Object visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return visitNavigableEdge(object);
+	}
+
+	@Override
 	public @Nullable Object visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return visitOperationNode(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverResolveVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverResolveVisitor.java
index 5748b6d..89a639f 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverResolveVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleASSaverResolveVisitor.java
@@ -371,6 +371,11 @@
 	}
 
 	@Override
+	public @Nullable Object visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return visitNavigableEdge(object);
+	}
+
+	@Override
 	public @Nullable Object visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return visitOperationNode(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromFalseVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromFalseVisitor.java
index d8d1997..dcdd566 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromFalseVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromFalseVisitor.java
@@ -371,6 +371,11 @@
 	}
 
 	@Override
+	public @Nullable Boolean visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return visitNavigableEdge(object);
+	}
+
+	@Override
 	public @Nullable Boolean visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return visitOperationNode(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromNullVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromNullVisitor.java
index 34c9c48..7880cae 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromNullVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromNullVisitor.java
@@ -371,6 +371,11 @@
 	}
 
 	@Override
+	public @Nullable Boolean visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return visitNavigableEdge(object);
+	}
+
+	@Override
 	public @Nullable Boolean visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return visitOperationNode(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromTrueVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromTrueVisitor.java
index cda892b..839ecd0 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromTrueVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleFlowAnalysisDeducerFromTrueVisitor.java
@@ -371,6 +371,11 @@
 	}
 
 	@Override
+	public @Nullable Boolean visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return visitNavigableEdge(object);
+	}
+
+	@Override
 	public @Nullable Boolean visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return visitOperationNode(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleTemplateParameterSubstitutionVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleTemplateParameterSubstitutionVisitor.java
index bfb1edf..f325404 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleTemplateParameterSubstitutionVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractQVTscheduleTemplateParameterSubstitutionVisitor.java
@@ -372,6 +372,11 @@
 	}
 
 	@Override
+	public @Nullable Object visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		return visitNavigableEdge(object);
+	}
+
+	@Override
 	public @Nullable Object visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		return visitOperationNode(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractWrappingQVTscheduleVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractWrappingQVTscheduleVisitor.java
index 960aff0..f711177 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractWrappingQVTscheduleVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/AbstractWrappingQVTscheduleVisitor.java
@@ -814,6 +814,18 @@
 	}
 
 	@Override
+	public R visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object) {
+		@Nullable P prologue = preVisit(object);
+		try {
+			R result = delegate.visitSharedEdge(object);
+			return postVisit(object, prologue, result);
+		}
+		catch (Throwable e) {
+			return badVisit(object, prologue, e);
+		}
+	}
+
+	@Override
 	public R visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object) {
 		@Nullable P prologue = preVisit(object);
 		try {
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleAdapterFactory.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleAdapterFactory.java
index 11b11dc..d6301d2 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleAdapterFactory.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleAdapterFactory.java
@@ -346,6 +346,10 @@
 				return createShadowPartEdgeAdapter();
 			}
 			@Override
+			public Adapter caseSharedEdge(SharedEdge object) {
+				return createSharedEdgeAdapter();
+			}
+			@Override
 			public Adapter caseStringLiteralNode(StringLiteralNode object) {
 				return createStringLiteralNodeAdapter();
 			}
@@ -786,6 +790,20 @@
 	}
 
 	/**
+	 * Creates a new adapter for an object of class '{@link org.eclipse.qvtd.pivot.qvtschedule.SharedEdge <em>Shared Edge</em>}'.
+	 * <!-- begin-user-doc -->
+	 * This default implementation returns null so that we can easily ignore cases;
+	 * it's useful to ignore a case when inheritance will catch all the cases anyway.
+	 * <!-- end-user-doc -->
+	 * @return the new adapter.
+	 * @see org.eclipse.qvtd.pivot.qvtschedule.SharedEdge
+	 * @generated
+	 */
+	public Adapter createSharedEdgeAdapter() {
+		return null;
+	}
+
+	/**
 	 * Creates a new adapter for an object of class '{@link org.eclipse.qvtd.pivot.qvtschedule.StringLiteralNode <em>String Literal Node</em>}'.
 	 * <!-- begin-user-doc -->
 	 * This default implementation returns null so that we can easily ignore cases;
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleSwitch.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleSwitch.java
index cbd52a0..93dc941 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleSwitch.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleSwitch.java
@@ -720,6 +720,16 @@
 				return result;
 			}
 			case 66: {
+				SharedEdge sharedEdge = (SharedEdge)theEObject;
+				T result = caseSharedEdge(sharedEdge);
+				if (result == null) result = caseNavigableEdge(sharedEdge);
+				if (result == null) result = caseEdge(sharedEdge);
+				if (result == null) result = caseConnectionEnd(sharedEdge);
+				if (result == null) result = caseElement(sharedEdge);
+				if (result == null) result = defaultCase(theEObject);
+				return result;
+			}
+			case 67: {
 				StringLiteralNode stringLiteralNode = (StringLiteralNode)theEObject;
 				T result = caseStringLiteralNode(stringLiteralNode);
 				if (result == null) result = caseOperationNode(stringLiteralNode);
@@ -730,7 +740,7 @@
 				if (result == null) result = defaultCase(theEObject);
 				return result;
 			}
-			case 67: {
+			case 68: {
 				SuccessEdge successEdge = (SuccessEdge)theEObject;
 				T result = caseSuccessEdge(successEdge);
 				if (result == null) result = caseNavigationEdge(successEdge);
@@ -741,7 +751,7 @@
 				if (result == null) result = defaultCase(theEObject);
 				return result;
 			}
-			case 68: {
+			case 69: {
 				SuccessNode successNode = (SuccessNode)theEObject;
 				T result = caseSuccessNode(successNode);
 				if (result == null) result = caseMappingNode(successNode);
@@ -751,13 +761,13 @@
 				if (result == null) result = defaultCase(theEObject);
 				return result;
 			}
-			case 69: {
+			case 70: {
 				Symbolable symbolable = (Symbolable)theEObject;
 				T result = caseSymbolable(symbolable);
 				if (result == null) result = defaultCase(theEObject);
 				return result;
 			}
-			case 70: {
+			case 71: {
 				TupleLiteralNode tupleLiteralNode = (TupleLiteralNode)theEObject;
 				T result = caseTupleLiteralNode(tupleLiteralNode);
 				if (result == null) result = caseOperationNode(tupleLiteralNode);
@@ -768,7 +778,7 @@
 				if (result == null) result = defaultCase(theEObject);
 				return result;
 			}
-			case 71: {
+			case 72: {
 				TuplePartEdge tuplePartEdge = (TuplePartEdge)theEObject;
 				T result = caseTuplePartEdge(tuplePartEdge);
 				if (result == null) result = caseArgumentEdge(tuplePartEdge);
@@ -778,7 +788,7 @@
 				if (result == null) result = defaultCase(theEObject);
 				return result;
 			}
-			case 72: {
+			case 73: {
 				TypeLiteralNode typeLiteralNode = (TypeLiteralNode)theEObject;
 				T result = caseTypeLiteralNode(typeLiteralNode);
 				if (result == null) result = caseOperationNode(typeLiteralNode);
@@ -789,7 +799,7 @@
 				if (result == null) result = defaultCase(theEObject);
 				return result;
 			}
-			case 73: {
+			case 74: {
 				UnknownNode unknownNode = (UnknownNode)theEObject;
 				T result = caseUnknownNode(unknownNode);
 				if (result == null) result = caseMappingNode(unknownNode);
@@ -799,7 +809,7 @@
 				if (result == null) result = defaultCase(theEObject);
 				return result;
 			}
-			case 74: {
+			case 75: {
 				VariableNode variableNode = (VariableNode)theEObject;
 				T result = caseVariableNode(variableNode);
 				if (result == null) result = caseMappingNode(variableNode);
@@ -809,7 +819,7 @@
 				if (result == null) result = defaultCase(theEObject);
 				return result;
 			}
-			case 75: {
+			case 76: {
 				VerdictRegion verdictRegion = (VerdictRegion)theEObject;
 				T result = caseVerdictRegion(verdictRegion);
 				if (result == null) result = caseRuleRegion(verdictRegion);
@@ -1216,6 +1226,21 @@
 	}
 
 	/**
+	 * Returns the result of interpreting the object as an instance of '<em>Shared Edge</em>'.
+	 * <!-- begin-user-doc -->
+	 * This implementation returns null;
+	 * returning a non-null result will terminate the switch.
+	 * <!-- end-user-doc -->
+	 * @param object the target of the switch.
+	 * @return the result of interpreting the object as an instance of '<em>Shared Edge</em>'.
+	 * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+	 * @generated
+	 */
+	public T caseSharedEdge(SharedEdge object) {
+		return null;
+	}
+
+	/**
 	 * Returns the result of interpreting the object as an instance of '<em>String Literal Node</em>'.
 	 * <!-- begin-user-doc -->
 	 * This implementation returns null;
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleVisitor.java
index 710a2dc..106b334 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/emf-gen/org/eclipse/qvtd/pivot/qvtschedule/util/QVTscheduleVisitor.java
@@ -91,6 +91,7 @@
 	R visitScheduleModel(org.eclipse.qvtd.pivot.qvtschedule.@NonNull ScheduleModel object);
 	R visitShadowNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull ShadowNode object);
 	R visitShadowPartEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull ShadowPartEdge object);
+	R visitSharedEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SharedEdge object);
 	R visitStringLiteralNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull StringLiteralNode object);
 	R visitSuccessEdge(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SuccessEdge object);
 	R visitSuccessNode(org.eclipse.qvtd.pivot.qvtschedule.@NonNull SuccessNode object);
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/model/QVTschedule.ecore b/plugins/org.eclipse.qvtd.pivot.qvtschedule/model/QVTschedule.ecore
index 37e7240..0df9b54 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/model/QVTschedule.ecore
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/model/QVTschedule.ecore
@@ -426,7 +426,13 @@
     <eStructuralFeatures xsi:type="ecore:EReference" name="classDatum" lowerBound="1"

         eType="#//ClassDatum">

       <eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">

-        <details key="documentation" value="Non-null if this edge is part of a bidirectional pair."/>

+        <details key="documentation" value="The type and typed model of the passed connection element."/>

+      </eAnnotations>

+    </eStructuralFeatures>

+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="dataType" lowerBound="1"

+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean" defaultValueLiteral="false">

+      <eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">

+        <details key="documentation" value="True if the connection input is a DataType for which the output is the  singletone trace element."/>

       </eAnnotations>

     </eStructuralFeatures>

     <eStructuralFeatures xsi:type="ecore:EReference" name="mandatoryTargetNodes" ordered="false"

@@ -649,6 +655,17 @@
       </eAnnotations>

     </eStructuralFeatures>

   </eClassifiers>

+  <eClassifiers xsi:type="ecore:EClass" name="SharedEdge" eSuperTypes="#//NavigableEdge">

+    <eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">

+      <details key="documentation" value="A SharedEdge supports the directed shared aggregation from a DataType node to its aggregator node within a Region."/>

+    </eAnnotations>

+    <eStructuralFeatures xsi:type="ecore:EReference" name="referredOppositeProperty"

+        lowerBound="1" eType="ecore:EClass ../../org.eclipse.ocl.pivot/model/Pivot.ecore#T-pivot-Property">

+      <eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">

+        <details key="documentation" value="The property to navigate from source to target."/>

+      </eAnnotations>

+    </eStructuralFeatures>

+  </eClassifiers>

   <eClassifiers xsi:type="ecore:EClass" name="StringLiteralNode" eSuperTypes="#//OperationNode">

     <eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">

       <details key="documentation" value="A StringLiteralNode supports a String literal value in a QVTs graph."/>

diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/model/QVTschedule.genmodel b/plugins/org.eclipse.qvtd.pivot.qvtschedule/model/QVTschedule.genmodel
index 3823496..d732df5 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/model/QVTschedule.genmodel
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/model/QVTschedule.genmodel
@@ -192,6 +192,7 @@
     </genClasses>
     <genClasses ecoreClass="QVTschedule.ecore#//NodeConnection">
       <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference QVTschedule.ecore#//NodeConnection/classDatum"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute QVTschedule.ecore#//NodeConnection/dataType"/>
       <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference QVTschedule.ecore#//NodeConnection/mandatoryTargetNodes"/>
       <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference QVTschedule.ecore#//NodeConnection/passedTargetNodes"/>
       <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference QVTschedule.ecore#//NodeConnection/preferredTargetNodes"/>
@@ -268,6 +269,9 @@
     <genClasses ecoreClass="QVTschedule.ecore#//ShadowPartEdge">
       <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference QVTschedule.ecore#//ShadowPartEdge/referredPart"/>
     </genClasses>
+    <genClasses ecoreClass="QVTschedule.ecore#//SharedEdge">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference QVTschedule.ecore#//SharedEdge/referredOppositeProperty"/>
+    </genClasses>
     <genClasses ecoreClass="QVTschedule.ecore#//StringLiteralNode">
       <genFeatures createChild="false" ecoreFeature="ecore:EAttribute QVTschedule.ecore#//StringLiteralNode/stringValue"/>
     </genClasses>
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleToStringVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleToStringVisitor.java
index 722500b..4a7b6ed 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleToStringVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleToStringVisitor.java
@@ -83,6 +83,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.RootRegion;
 import org.eclipse.qvtd.pivot.qvtschedule.ShadowNode;
 import org.eclipse.qvtd.pivot.qvtschedule.ShadowPartEdge;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.StringLiteralNode;
 import org.eclipse.qvtd.pivot.qvtschedule.SuccessEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.SuccessNode;
@@ -467,6 +468,11 @@
 	}
 
 	@Override
+	public String visitSharedEdge(@NonNull SharedEdge object) {
+		return visiting(object);
+	}
+
+	@Override
 	public String visitStringLiteralNode(@NonNull StringLiteralNode object) {
 		return visiting(object);
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleUtil.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleUtil.java
index 2eddb28..9803b0b 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleUtil.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/QVTscheduleUtil.java
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.eclipse.qvtd.pivot.qvtschedule.utilities;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.function.BinaryOperator;
@@ -61,6 +62,7 @@
 import org.eclipse.qvtd.pivot.qvtschedule.Region;
 import org.eclipse.qvtd.pivot.qvtschedule.Role;
 import org.eclipse.qvtd.pivot.qvtschedule.ScheduleModel;
+import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
 import org.eclipse.qvtd.pivot.qvtschedule.RootRegion;
 import org.eclipse.qvtd.pivot.qvtschedule.Node.Utility;
 
@@ -427,6 +429,41 @@
 		return ClassUtil.nullFree(node.getOutgoingEdges());
 	}
 
+	public static @Nullable Iterable<@NonNull SharedEdge> getOutgoingSharedEdges(@NonNull Partition partition, @NonNull Node sourceNode) {
+		List<@NonNull SharedEdge> sharedEdges = null;
+		for (@NonNull Edge edge : getOutgoingEdges(sourceNode)) {
+			if (edge.isShared() && (partition.getRole(edge) != null)) {
+				if (sharedEdges == null) {
+					sharedEdges = new ArrayList<>();
+				}
+				sharedEdges.add((SharedEdge)edge);
+			}
+		}
+		return sharedEdges;
+	}
+
+	public static @Nullable Iterable<@NonNull Node> getSharedEdgeTargetNodes(@NonNull Partition partition, @NonNull Node sourceNode) {
+		List<@NonNull Node> targetNodes = null;
+		for (@NonNull Edge edge : getOutgoingEdges(sourceNode)) {
+			if (edge.isShared() && (partition.getRole(edge) != null)) {
+				Node targetNode = getTargetNode(edge);
+				boolean hasOutgoingEdges = false;
+				for (@NonNull Edge edge2 : getOutgoingEdges(targetNode)) {
+					if (partition.getRole(edge2) != null) {
+						hasOutgoingEdges = true;
+					}
+				}
+				if (hasOutgoingEdges) {
+					if (targetNodes == null) {
+						targetNodes = new ArrayList<>();
+					}
+					targetNodes.add(targetNode);
+				}
+			}
+		}
+		return targetNodes;
+	}
+
 	public static @NonNull Iterable<@NonNull ClassDatum> getOwnedClassDatums(@NonNull ScheduleModel scheduleModel) {
 		return ClassUtil.nullFree(scheduleModel.getOwnedClassDatums());
 	}
@@ -583,6 +620,10 @@
 		return ClassUtil.nonNullState(operationCallNode.getReferredOperation());		// FIXME should be declared as [1..1]
 	}
 
+	public static @NonNull Property getReferredOppositeProperty(@NonNull SharedEdge sharedEdge) {
+		return ClassUtil.nonNullState(sharedEdge.getReferredOppositeProperty());
+	}
+
 	public static @NonNull PropertyDatum getReferredPart(@NonNull KeyPartEdge keyPartEdge) {
 		return ClassUtil.nonNullState(keyPartEdge.getReferredPart());
 	}
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/ToGraphPartitionVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/ToGraphPartitionVisitor.java
index 1575d44..bfd5081 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/ToGraphPartitionVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtschedule/src/org/eclipse/qvtd/pivot/qvtschedule/utilities/ToGraphPartitionVisitor.java
@@ -13,9 +13,11 @@
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.ocl.pivot.utilities.ClassUtil;
+import org.eclipse.qvtd.pivot.qvtbase.graphs.DelegatingToGraphHelper;
 import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder;
 import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder.GraphElement;
 import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder.GraphNode;
+import org.eclipse.qvtd.pivot.qvtbase.graphs.ToGraphHelper;
 import org.eclipse.qvtd.pivot.qvtschedule.BasicPartition;
 import org.eclipse.qvtd.pivot.qvtschedule.Connection;
 import org.eclipse.qvtd.pivot.qvtschedule.ConnectionEnd;
@@ -178,7 +180,30 @@
 									sourceNode = (@NonNull Node) sourceEnd;
 								}
 								setScope(sourcePartition);
-								appendEdge(sourceNode, connection, connection);
+								Iterable<@NonNull Node> sharedEdgeTargetNodes = QVTscheduleUtil.getSharedEdgeTargetNodes(sourcePartition, sourceNode);
+								if (sharedEdgeTargetNodes != null) {
+									for (@NonNull Node targetNode : sharedEdgeTargetNodes) {
+										ToGraphHelper sourceGraphHelper = new DelegatingToGraphHelper(this)
+										{
+											@Override
+											public void setColor(@NonNull GraphElement element) {
+												super.setColor(sourceNode);
+											}
+										};
+										context.appendEdge(sourceGraphHelper, sourceNode, connection, connection);
+										ToGraphHelper targetGraphHelper = new DelegatingToGraphHelper(this)
+										{
+											@Override
+											public void setColor(@NonNull GraphElement element) {
+												super.setColor(targetNode);
+											}
+										};
+										context.appendEdge(targetGraphHelper, connection, connection, targetNode);
+									}
+								}
+								else {
+									appendEdge(sourceNode, connection, connection);
+								}
 							}
 						}
 					}
diff --git a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/META-INF/MANIFEST.MF
index 338f1cf..de6f72e 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/META-INF/MANIFEST.MF
@@ -27,5 +27,6 @@
  org.eclipse.debug.core,
  org.eclipse.qvtd.debug.ui;bundle-version="[0.19.0,1.0.0)",
  org.eclipse.ocl.examples.debug.vm;bundle-version="[2.8.0,2.9.0)"
-Export-Package: org.eclipse.qvtd.xtext.qvtrelation.tests
+Export-Package: org.eclipse.qvtd.xtext.qvtrelation.tests,
+ org.eclipse.qvtd.xtext.qvtrelation.tests.helpers
 Automatic-Module-Name: org.eclipse.qvtd.xtext.qvtrelation.tests
diff --git a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Ecore2Pivot.qvtr b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Ecore2Pivot.qvtr
index 1c5580b..bfe6afe 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Ecore2Pivot.qvtr
+++ b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Ecore2Pivot.qvtr
@@ -18,89 +18,37 @@
  */
 	transformation Ecore2Pivot(ecore:ecoreMM, as:pivotMM)
 	{
-		/**
-		 *  ecore::EAttribute <=> pivot::Property
-		 */
-		top relation mapEAttribute {
-			eClass : ecoreMM::EClass;
-			asClass : pivotMM::Class;
-			name : String;
-			/*enforce*/ domain ecore eAttribute : EAttribute {
-				eContainingClass = eClass,
-				name = name
-			};
-			enforce domain as asProperty : Property {
-				owningClass = asClass,
-				name = name
-			};
-			when {
-				mapEClass(eClass, asClass);
-			}
-		}
-		
-		/**
-		 *  ecore::EClass <=> pivot::Class
-		 */
-		top relation mapEClass {
-			ePackage : ecoreMM::EPackage;
-			asPackage : pivotMM::Package;
-			name : String;
-			isAbstract : Boolean;
-			isInterface : Boolean;
-			/*enforce*/ domain ecore eClass : EClass {
-				ePackage = ePackage,
-				name = name,
-				abstract = isAbstract,
-				interface = isInterface
-			};
-			enforce domain as asClass : Class {
-				owningPackage = asPackage,
-				name = name,
-				isAbstract = isAbstract,
-				isInterface = isInterface
-			};
-			when {
-				mapEPackage(ePackage, asPackage);
-			}
-		}
-		
+		query getRootEPackages(ePackage : ecoreMM::EPackage[1]) : Set(ecoreMM::EPackage)[1] implementedby 'org.eclipse.qvtd.xtext.qvtrelation.tests.helpers.GetRootEPackages';
+
 		/**
 		 *  ecore::EPackage <=> pivot::Package
 		 */
-		top relation mapEPackage {
+		top relation mapEPackage_root {
 			name : String;
-			nsPrefix : String;
-			nsURI : String;
+--			nsPrefix : String;
+--			nsURI : String;
+			ePackages : Set(ecore::EPackage) = getRootEPackages(ePackage);
+			asModel : pivotMM::Model;
 			/*enforce*/ domain ecore ePackage : EPackage {
-				name = name,
-				nsPrefix = nsPrefix,
-				nsURI = nsURI
+				eSuperPackage = null,
+				name = name
+--				nsPrefix = nsPrefix,
+--				nsURI = nsURI
 			};
 			enforce domain as asPackage : Package {
 				name = name,
-				nsPrefix = nsPrefix,
-				URI = nsURI
-			};
-		}
-
-		/**
-		 *  ecore::EReference <=> pivot::Property
-		 */
-		top relation mapEReference {
-			eClass : ecoreMM::EClass;
-			asClass : pivotMM::Class;
-			name : String;
-			/*enforce*/ domain ecore eReference : EReference {
-				eContainingClass = eClass,
-				name = name
-			};
-			enforce domain as asProperty : Property {
-				owningClass = asClass,
-				name = name
+--				nsPrefix = nsPrefix,
+--				URI = nsURI,
+				Model = asModel
 			};
 			when {
-				mapEClass(eClass, asClass);
+				mapEPackages(ePackages, asModel);
 			}
 		}
+		
+		relation mapEPackages {
+			/*enforce*/ domain ecore ePackages : Set(ecoreMM::EPackage) {};
+			enforce domain as asModel : Model {};
+		}
 	}
 }
diff --git a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Ecore2Pivot2.qvtr b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Ecore2Pivot2.qvtr
new file mode 100644
index 0000000..ead5257
--- /dev/null
+++ b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Ecore2Pivot2.qvtr
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Willink Transformations and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     E.D.Willink - initial implementation
+ *******************************************************************************/
+import ecoreMM : 'http://www.eclipse.org/emf/2002/Ecore'; 
+import pivotMM : 'http://www.eclipse.org/ocl/2015/Pivot';
+--import pivotMM : 'platform:/resource/org.eclipse.ocl.pivot/model/Pivot.ecore'::pivot;
+
+package org::eclipse::ocl::pivot2::ecore2pivot {
+/**
+ * Transform an Ecore metamodel to a Pivot metamodel
+ */
+	transformation Ecore2Pivot(ecore:ecoreMM, as:pivotMM)
+	{
+		/**
+		 *  ecore::EAttribute <=> pivot::Property
+		 */
+		top relation mapElement_EAttribute {
+			eClass : ecoreMM::EClass;
+			eDataType : ecoreMM::EDataType;
+			asClass : pivotMM::Class;
+--			asDataType : pivotMM::DataType;
+			name : String;
+			lower : Integer;
+			upper : Integer;
+			/*enforce*/ domain ecore eAttribute : EAttribute {
+				eContainingClass = eClass,
+				name = name,
+				eAttributeType = eDataType,
+				lowerBound = lower,
+				upperBound = upper
+			} { (0 <= upper) and (upper <= 1) };
+			enforce domain as asProperty : Property {
+				owningClass = asClass,
+				name = name,
+--				type = asDataType,
+				isRequired = (lower = 1)
+			};
+			when {
+				mapElement_EClass(eClass, asClass);
+--				mapReference_EClassifier(eDataType, asDataType);
+			}
+		}
+		
+		/**
+		 *  ecore::EClass <=> pivot::Class
+		 */
+		top relation mapElement_EClass {
+			ePackage : ecoreMM::EPackage;
+			asPackage : pivotMM::Package;
+			name : String;
+			isAbstract : Boolean;
+			isInterface : Boolean;
+			/*enforce*/ domain ecore eClass : EClass {
+				ePackage = ePackage,
+				name = name,
+				abstract = isAbstract,
+				interface = isInterface
+			};
+			enforce domain as asClass : Class {
+				owningPackage = asPackage,
+				name = name,
+				isAbstract = isAbstract,
+				isInterface = isInterface
+			};
+			when {
+				mapElement_EPackage(ePackage, asPackage);
+			}
+		}
+		
+		/**
+		 *  ecore::mapElement_EClass_eSuperTypes <=> pivot::Class_superClasses
+		 */
+		top relation mapElement_EClass_superClass {
+			/*enforce*/ domain ecore eSubClass : EClass {
+				eSuperTypes = eSuperClass : EClass {}
+			};
+			enforce domain as asSubClass : Class {
+				superClasses = asSuperClass : Class {}
+			};
+			when {
+				mapElement_EClass(eSubClass, asSubClass);
+				mapElement_EClass(eSuperClass, asSuperClass);
+			}
+		}
+		
+		/**
+		 *  ecore::EPackage <=> pivot::Package
+		 */
+		top relation mapElement_EPackage {
+			name : String;
+			nsPrefix : String;
+			nsURI : String;
+			/*enforce*/ domain ecore ePackage : EPackage {
+				name = name,
+				nsPrefix = nsPrefix,
+				nsURI = nsURI
+			};
+			enforce domain as asPackage : Package {
+				name = name,
+				nsPrefix = nsPrefix,
+				URI = nsURI
+			};
+		}
+
+		/**
+		 *  ecore::EReference <=> pivot::Property
+		 */
+		top relation mapElement_EReference {
+			eClass : ecoreMM::EClass;
+			asClass : pivotMM::Class;
+			name : String;
+			/*enforce*/ domain ecore eReference : EReference {
+				eContainingClass = eClass,
+				name = name
+			};
+--			} { (0 <= upper) and (upper <= 1) };
+			enforce domain as asProperty : Property {
+				owningClass = asClass,
+				name = name
+			};
+			when {
+				mapElement_EClass(eClass, asClass);
+			}
+			where {
+				mapElement_EReference_type(eReference, asProperty);
+			}
+		}
+
+		/**
+		 *  ecore::EReference.eType <=> pivot::Property.type
+		 */
+		abstract relation mapElement_EReference_type {
+			/*enforce*/ domain ecore eReference : EReference {};
+			enforce domain as asProperty : Property {};
+		}
+
+		/**
+		 *  ecore::EReference.eType <=> pivot::Property.type
+		 */
+		relation mapElement_EReference_collection_type overrides mapElement_EReference_type {
+			eReferredClass : ecoreMM::EClass;
+			asReferredClass : pivotMM::Class;
+			lower : Integer;
+			upper : Integer;
+			/*enforce*/ domain ecore eReference : EReference {
+				eReferenceType = eReferredClass,
+				lowerBound = lower,
+				upperBound = upper
+			} { (upper < 0) or (1 < upper) };
+			enforce domain as asProperty : Property {
+				type = asReferredClass,
+				isRequired = true --(lower = 1)
+			};
+			when {
+				mapSet_EClass(eReferredClass, lower, upper, asReferredClass);
+			}
+		}
+
+		/**
+		 *  ecore::EReference.eType <=> pivot::Property.type
+		 */
+		relation mapElement_EReference_scalar_type overrides mapElement_EReference_type {
+			eReferredClass : ecoreMM::EClass;
+			asReferredClass : pivotMM::Class;
+			lower : Integer;
+			upper : Integer;
+			/*enforce*/ domain ecore eReference : EReference {
+				eReferenceType = eReferredClass,
+				lowerBound = lower,
+				upperBound = upper
+			} { (0 <= upper) and (upper <= 1) };
+			enforce domain as asProperty : Property {
+				type = asReferredClass,
+				isRequired = false --(lower = 1)
+			};
+			when {
+				mapElement_EClass(eReferredClass, asReferredClass);
+			}
+		}
+		
+		/**
+		 *  ecore::EClassifier <=> pivot::Type
+		 */
+--		abstract relation mapReference_EClassifier {
+--			/*enforce*/ domain ecore eClassifier : EClassifier {};
+--			enforce domain as asClassifier : Type {};
+--		}
+		
+		/**
+		 *  ecore::EClassifier <=> pivot::Type
+		 *
+		relation mapReference_EClass { --overrides mapReference_EClassifier {
+			/ *enforce* / domain ecore eClass : EClass {};
+			enforce domain as asClass : Class {};
+			when {
+				mapElement_EClass(eClass, asClass);
+			}
+		} */
+		
+		/**
+		 *  ecore::EClassifier <=> pivot::Type
+		 *
+		relation mapReference_EString overrides mapReference_EClassifier {
+			/ *enforce* / domain ecore eClass : EClass {};
+			enforce domain as asClassifier : String {};
+		} */
+		
+		/**
+		 *  ecore::EClass <=> pivot::Class
+		 */
+		relation mapSet_EClass {
+			/*enforce*/ domain ecore eClass : EClass{},
+				lower : Integer{},
+				upper : Integer{}
+			;
+			enforce domain as asClass : SetType {
+				elementType = asClass,
+				lower = lower,
+				upper = upper.toUnlimitedNatural()
+			};
+			when {
+				mapElement_EClass(eClass, asClass);
+			}
+		}
+	}
+}
diff --git a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/ExtendedEcore.ecore b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/ExtendedEcore.ecore
new file mode 100644
index 0000000..0c1cc4c
--- /dev/null
+++ b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/ExtendedEcore.ecore
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+    name="ExtendedEcore" nsURI="http://www.eclipse.org/qvtd/xtext/qvtrelation/tests/ExtendedEcore" nsPrefix="extendedEcore">
+  <eAnnotations source="http://www.eclipse.org/OCL/Import">
+    <details key="ecore" value="http://www.eclipse.org/emf/2002/Ecore"/>
+  </eAnnotations>
+  <eClassifiers xsi:type="ecore:EClass" name="EPackageSet">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ePackages" ordered="false" upperBound="-1" eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EPackage"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Families.ecore b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Families.ecore
new file mode 100644
index 0000000..5aee3f2
--- /dev/null
+++ b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Families.ecore
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="Families" nsURI="http://www.eclipse.org/qvtd/xtext/qvtrelation/tests/Families2Persons/1.0/Families"
+    nsPrefix="families">
+  <eClassifiers xsi:type="ecore:EClass" name="Family" eSuperTypes="#//Entity">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="lastName" ordered="false"
+        unique="false" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="father" ordered="false"
+        lowerBound="1" eType="#//Member" containment="true" eOpposite="#//Member/familyFather"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="mother" ordered="false"
+        lowerBound="1" eType="#//Member" containment="true" eOpposite="#//Member/familyMother"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="sons" ordered="false" upperBound="-1"
+        eType="#//Member" containment="true" eOpposite="#//Member/familySon"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="daughters" ordered="false"
+        upperBound="-1" eType="#//Member" containment="true" eOpposite="#//Member/familyDaughter"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Member" eSuperTypes="#//Entity #//Entity2">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="firstName" ordered="false"
+        unique="false" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="familyFather" ordered="false"
+        eType="#//Family" eOpposite="#//Family/father"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="familyMother" ordered="false"
+        eType="#//Family" eOpposite="#//Family/mother"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="familySon" ordered="false"
+        eType="#//Family" eOpposite="#//Family/sons"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="familyDaughter" ordered="false"
+        eType="#//Family" eOpposite="#//Family/daughters"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Entity" abstract="true"/>
+  <eClassifiers xsi:type="ecore:EClass" name="Entity2" abstract="true" interface="true"/>
+</ecore:EPackage>
diff --git a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Families_expected.ecore.oclas b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Families_expected.ecore.oclas
index 79fc335..59be0ce 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Families_expected.ecore.oclas
+++ b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/models/ecore2pivot/Families_expected.ecore.oclas
@@ -2,14 +2,16 @@
 <pivot:Package xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pivot="http://www.eclipse.org/ocl/2015/Pivot"
     xsi:schemaLocation="http://www.eclipse.org/ocl/2015/Pivot java://org.eclipse.ocl.pivot.PivotPackage" xmi:id="AAAAA" URI="http://www.eclipse.org/qvtd/xtext/qvtrelation/tests/Families2Persons/1.0/Families" name="Families"
     nsPrefix="families">
-  <ownedClasses xmi:id="Jhvvd" name="Family">
+  <ownedClasses xmi:id="IDIxc" isAbstract="true" name="Entity"/>
+  <ownedClasses xmi:id="UFOGl" isAbstract="true" isInterface="true" name="Entity2"/>
+  <ownedClasses xmi:id="Jhvvd" name="Family" superClasses="#IDIxc">
     <ownedProperties xmi:id="o4fg5" name="daughters"/>
     <ownedProperties xmi:id="ZkBJD" name="father"/>
     <ownedProperties xmi:id="+nNi4" name="lastName"/>
     <ownedProperties xmi:id="A602P" name="mother"/>
     <ownedProperties xmi:id="ejovP" name="sons"/>
   </ownedClasses>
-  <ownedClasses xmi:id=",dS6p" name="Member">
+  <ownedClasses xmi:id=",dS6p" name="Member" superClasses="#IDIxc #UFOGl">
     <ownedProperties xmi:id="nC3He" name="familyDaughter"/>
     <ownedProperties xmi:id="7,oXz" name="familyFather"/>
     <ownedProperties xmi:id="iVcFA" name="familyMother"/>
diff --git a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/QVTrCompilerTests.java b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/QVTrCompilerTests.java
index a84312d..a225103 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/QVTrCompilerTests.java
+++ b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/QVTrCompilerTests.java
@@ -621,10 +621,22 @@
 		//		AbstractMerger.EARLY.setState(true);
 		//		AbstractMerger.FAILURE.setState(true);
 		//		AbstractMerger.LATE.setState(true);
+		//	TracedHeadAnalysis.TRACED_HEAD_NODE_GROUPS.setState(true);
+		//	TracedHeadAnalysis.TRACED_HEAD_IMMEDIATE_SOURCES.setState(true);
+		//	RuleHeadAnalysis.RULE_HEAD_NODE_GROUPS.setState(true);
+		//	TransformationPartitioner.PARTITION_IMMEDIATE_PREDECESSORS.setState(true);
+		//	TransformationPartitioner.PARTITION_TRANSITIVE_PREDECESSORS.setState(true);
+		//	TransformationPartitioner.PARTITION_TRANSITIVE_SUCCESSORS.setState(true);
+		//	TransformationPartitioner.REGION_IMMEDIATE_PREDECESSORS.setState(true);
+		//	TransformationPartitioner.REGION_TRANSITIVE_PREDECESSORS.setState(true);
+		//	TransformationPartitioner.REGION_TRANSITIVE_SUCCESSORS.setState(true);
 		ConnectivityChecker.CONNECTIVITY_CLASSDATUMS.setState(true);
 		ConnectivityChecker.CONNECTIVITY_CONNECTIONS.setState(true);
 		ConnectivityChecker.CONNECTIVITY_EDGES.setState(true);
 		ConnectivityChecker.CONNECTIVITY_NODES.setState(true);
+		MyQVTrelationTestFileSystemHelper testFileSystemHelper = getTestFileSystemHelper();
+		testFileSystemHelper.addRequiredBundle("org.eclipse.qvtd.xtext.qvtrelation.tests");
+		//	testFileSystemHelper.addExportedPackage("org.eclipse.qvtd.xtext.qvtrelation.tests.helpers");
 		Class<? extends Transformer> txClass1 = null;
 		//		URI txURI1 = URI.createPlatformResourceURI("/org.eclipse.ocl.pivot/model/Ecore2Pivot.qvtr", true);
 		URI txURI1 = getModelsURI("ecore2pivot/Ecore2Pivot.qvtr");
@@ -651,7 +663,8 @@
 		//		MyQVT myQVT2 = new MyQVT(createTestProjectManager(), getTestBundleURI(), "models/families2persons", null);
 		try {
 			myQVT2.createGeneratedExecutor(txClass1);
-			myQVT2.loadInput("ecore", getModelsURI("families2persons/Families.ecore"));
+			//			myQVT2.loadInput("ecore", getModelsURI("families2persons/Families.ecore"));
+			myQVT2.loadInput("ecore", getModelsURI("ecore2pivot/Families.ecore"));
 			myQVT2.executeTransformation();
 			myQVT2.saveOutput("as", asURI2, getModelsURI("ecore2pivot/Families_expected.ecore.oclas"), null);
 		}