[509858] Use isPartial PropertyAssignment rather thahn includes
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 8e71674..84a5b7c 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
@@ -220,14 +220,16 @@
 		js.appendValueName(cgMappingCallBinding.getOwnedValue());
 	}
 
-	protected void appendEcoreSet(@NonNull CGValuedElement cgSlot, @NonNull EStructuralFeature eStructuralFeature, @NonNull CGValuedElement cgInit) {
+	protected void appendEcoreSet(@NonNull CGValuedElement cgSlot, @NonNull EStructuralFeature eStructuralFeature, @NonNull CGValuedElement cgInit, boolean isPartial) {
 		if (eStructuralFeature.isMany()) {
 			String getAccessor = genModelHelper.getGetAccessor(eStructuralFeature);
 			//
 			js.appendValueName(cgSlot);
 			js.append(".");
 			js.append(getAccessor);
-			js.append("().addAll(");
+			js.append("().");
+			js.append(isPartial ? "add" : "addAll");
+			js.append("(");
 			js.appendAtomicReferenceTo(cgInit);
 			js.append(");\n");
 		}
@@ -2090,6 +2092,7 @@
 		//		Property pivotProperty = cgPropertyCallExp.getReferredProperty();
 		//		CGTypeId cgTypeId = analyzer.getTypeId(pivotProperty.getOwningType().getTypeId());
 		//		JavaTypeDescriptor requiredTypeDescriptor = context.getJavaTypeDescriptor(cgTypeId, false);
+		SetStatement asSetStatement = QVTiCGUtil.getAST(cgPropertyAssignment);
 		EStructuralFeature eStructuralFeature = QVTiCGUtil.getEStructuralFeature(cgPropertyAssignment);
 		CGValuedElement cgSlot = getExpression(QVTiCGUtil.getOwnedSlotValue(cgPropertyAssignment));
 		CGValuedElement cgInit = getExpression(QVTiCGUtil.getOwnedInitValue(cgPropertyAssignment));
@@ -2103,7 +2106,7 @@
 		if (!js.appendLocalStatements(cgInit)) {
 			return false;
 		}
-		appendEcoreSet(cgSlot, eStructuralFeature, cgInit);
+		appendEcoreSet(cgSlot, eStructuralFeature, cgInit, asSetStatement.isIsPartial());
 		doAssigned(cgPropertyAssignment);
 		return true;
 	}
diff --git a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java
index e0f0572..65452ba 100644
--- a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java
+++ b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/utilities/QVTiCGUtil.java
@@ -44,6 +44,7 @@
 import org.eclipse.qvtd.pivot.qvtimperative.SimpleParameter;
 import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeUtil;
 import org.eclipse.qvtd.pivot.qvtimperative.NewStatement;
+import org.eclipse.qvtd.pivot.qvtimperative.SetStatement;
 
 public class QVTiCGUtil extends CGUtil
 {
@@ -68,6 +69,10 @@
 		return ClassUtil.nonNullState((MappingCall)cgMappingCall.getAst());
 	}
 
+	public static @NonNull SetStatement getAST(@NonNull CGPropertyAssignment cgPropertyAssignment) {
+		return ClassUtil.nonNullState((SetStatement)cgPropertyAssignment.getAst());
+	}
+
 	public static @NonNull NewStatement getAST(@NonNull CGRealizedVariable cgRealizedVariable) {
 		return ClassUtil.nonNullState((NewStatement)cgRealizedVariable.getAst());
 	}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/common/AbstractQVTc2QVTc.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/common/AbstractQVTc2QVTc.java
index 03c20d2..039cee5 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/common/AbstractQVTc2QVTc.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/common/AbstractQVTc2QVTc.java
@@ -341,6 +341,9 @@
 			if (paIn.eIsSet(QVTcorePackage.Literals.ASSIGNMENT__IS_DEFAULT)) {
 				paOut.setIsDefault(paIn.isIsDefault());
 			}
+			if (paIn.eIsSet(QVTcorePackage.Literals.ASSIGNMENT__IS_PARTIAL)) {
+				paOut.setIsPartial(paIn.isIsPartial());
+			}
 			paOut.setTargetProperty(paIn.getTargetProperty());
 			createAll(paIn.getOwnedComments(), paOut.getOwnedComments());
 			return paOut;
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/BasicMappingRegion.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/BasicMappingRegion.java
index aa5a529..ac0da8f 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/BasicMappingRegion.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/BasicMappingRegion.java
@@ -313,7 +313,7 @@
 				if (!referredProperty.isIsMany()) {
 					Edge predicateEdge = sourceNode.getPredicateEdge(referredProperty);
 					if (predicateEdge == null) {
-						RegionUtil.createNavigationEdge(sourceNode, referredProperty, targetNode);
+						RegionUtil.createNavigationEdge(sourceNode, referredProperty, targetNode, false);
 					}
 					else {
 						assert predicateEdge.getTarget() == targetNode;
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Edge.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Edge.java
index bd58d68..0970711 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Edge.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/Edge.java
@@ -23,7 +23,7 @@
 	/**
 	 * Create an edgeRole edge from sourceNode to targetNode with the same name as this edge.
 	 */
-	@NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode);
+	@NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial);
 
 	void destroy();
 
@@ -136,6 +136,11 @@
 	boolean isNavigation();
 
 	/**
+	 * Return true if this edge is for a partial many-to-one relationship.
+	 */
+	boolean isPartial();
+
+	/**
 	 * Return true if this edge is for a predicate.
 	 */
 	boolean isPredicate();
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/ExpressionAnalyzer.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/ExpressionAnalyzer.java
index a0e430a..693154d 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/ExpressionAnalyzer.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/ExpressionAnalyzer.java
@@ -21,6 +21,7 @@
 import org.eclipse.ocl.pivot.CollectionLiteralExp;
 import org.eclipse.ocl.pivot.CollectionLiteralPart;
 import org.eclipse.ocl.pivot.CollectionRange;
+import org.eclipse.ocl.pivot.CollectionType;
 import org.eclipse.ocl.pivot.CompleteClass;
 import org.eclipse.ocl.pivot.DataType;
 import org.eclipse.ocl.pivot.Element;
@@ -89,11 +90,6 @@
 		}
 
 		@Override
-		protected @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
-			return RegionUtil.createNavigationEdge(sourceNode, source2targetProperty, targetNode);
-		}
-
-		@Override
 		protected @NonNull Node createStepNode(@NonNull String name, @NonNull CallExp callExp, @NonNull Node sourceNode) {
 			return RegionUtil.createStepNode(name, callExp, sourceNode, false);
 		}
@@ -216,7 +212,7 @@
 		String name = operationCallExp.getReferredOperation().getName();
 		assert name != null;
 		Node oclContainerNode = createStepNode(name, operationCallExp, sourceNode);
-		oclContainerEdge = createNavigationEdge(sourceNode, oclContainerProperty, oclContainerNode);
+		oclContainerEdge = createNavigationEdge(sourceNode, oclContainerProperty, oclContainerNode, false);
 		return oclContainerNode;
 		/*		String name = operationCallExp.getReferredOperation().getName();
 		assert name != null;
@@ -328,21 +324,22 @@
 	}
 
 	protected @NonNull NavigableEdge createNavigableNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
-		return RegionUtil.createNavigationEdge(sourceNode, source2targetProperty, targetNode);
+		return RegionUtil.createNavigationEdge(sourceNode, source2targetProperty, targetNode, false);
 	}
 
-	protected @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
-		return RegionUtil.createNavigationEdge(sourceNode, source2targetProperty, targetNode);
+	protected @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
+		return RegionUtil.createNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial);
 	}
 
 	protected @NonNull NavigableEdge createNavigationOrRealizedEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable NavigationAssignment navigationAssignment) {
 		NavigableEdge navigationEdge = sourceNode.getNavigationEdge(source2targetProperty);
 		assert navigationEdge == null;
+		Boolean isPartial = navigationAssignment != null ? navigationAssignment.isIsPartial() : null;
 		if ((navigationAssignment != null) || context.isPropertyAssignment(sourceNode, source2targetProperty)) {
-			navigationEdge = createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode);
+			navigationEdge = createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial);
 		}
 		else {
-			navigationEdge = createNavigationEdge(sourceNode, source2targetProperty, targetNode);
+			navigationEdge = createNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial);
 		}
 		return navigationEdge;
 	}
@@ -371,8 +368,8 @@
 		return RegionUtil.createRealizedExpressionEdge(sourceNode, name, targetNode);
 	}
 
-	protected @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
-		return RegionUtil.createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode);
+	protected @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
+		return RegionUtil.createRealizedNavigationEdge(sourceNode, source2targetProperty, targetNode, isPartial);
 	}
 
 	protected @NonNull Node createStepNode(@NonNull String name, @NonNull CallExp callExp, @NonNull Node sourceNode) {
@@ -548,7 +545,7 @@
 				String name = referenceTargetNode.getName();
 				ClassDatumAnalysis classDatumAnalysis = referenceTargetNode.getClassDatumAnalysis();
 				Node instantiatedTargetNode = createDependencyNode(name, classDatumAnalysis);
-				createNavigationEdge(instantiatedNode, referenceEdge.getProperty(), instantiatedTargetNode);
+				createNavigationEdge(instantiatedNode, referenceEdge.getProperty(), instantiatedTargetNode, false);
 				instantiate(instantiatedTargetNode, referenceTargetNode);
 			}
 		}
@@ -626,7 +623,7 @@
 		else {
 			Node varNode = createLetNode(ownedVariable, initNode);
 			Property castProperty = scheduler.getCastProperty(type);
-			createNavigationEdge(initNode, castProperty, varNode);
+			createNavigationEdge(initNode, castProperty, varNode, false);
 		}
 		return analyze(letExp.getOwnedIn());
 	}
@@ -714,7 +711,10 @@
 		NavigableEdge navigationEdge = getNavigationEdge(slotNode, property, targetNode, asNavigationAssignment);
 		Node valueNode = navigationEdge.getTarget();
 		CompleteClass valueCompleteClass = valueNode.getCompleteClass();
-		Type propertyType = ClassUtil.nonNullState(property.getType());
+		Type propertyType = PivotUtil.getType(property);
+		if (asNavigationAssignment.isIsPartial()) {
+			propertyType = PivotUtil.getElementType(((CollectionType)propertyType));
+		}
 		CompleteClass targetCompleteClass = environmentFactory.getCompleteModel().getCompleteClass(propertyType);
 		if (!valueCompleteClass.conformsTo(targetCompleteClass)) {
 			// FIXME we could synthesize a cast, but it's easier to do oclAsType() in QVTm/QVTp
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/NavigableEdge.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/NavigableEdge.java
index de9aac7..6ae09d2 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/NavigableEdge.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/NavigableEdge.java
@@ -25,7 +25,7 @@
 	 * Create an edgeRole edge from sourceNode to targetNode with the same property as this edge.	 * @param edgeRole
 	 */
 	@Override
-	@NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode);
+	@NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial);
 
 	@Override
 	@NonNull NavigableEdge getForwardEdge();
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/OperationRegion.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/OperationRegion.java
index 2fe98cf..4324231 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/OperationRegion.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/OperationRegion.java
@@ -150,7 +150,7 @@
 								ClassDatumAnalysis elementClassDatumAnalysis = schedulerConstants.getClassDatumAnalysis((@NonNull Class) elementType, typedModel2);
 								Node elementNode = RegionUtil.createOperationElementNode(this, name, elementClassDatumAnalysis, dependencyNode2);
 								//(region, name, typedElement, argNodes)Node(region, name, callExp, sourceNode)Node(this, name, iterateProperty, dependencyNode2);
-								RegionUtil.createNavigationEdge(dependencyNode2, iterateProperty, elementNode);
+								RegionUtil.createNavigationEdge(dependencyNode2, iterateProperty, elementNode, false);
 								dependencyNode2 = elementNode;
 							}
 							//							assert !dependencyNode2.isMatched();
@@ -161,7 +161,7 @@
 							else {
 								nextNode = RegionUtil.createDataTypeNode(dependencyNode2, property);
 							}
-							RegionUtil.createNavigationEdge(dependencyNode2, property, nextNode);
+							RegionUtil.createNavigationEdge(dependencyNode2, property, nextNode, false);
 							dependencyNode2 = nextNode;
 						}
 					}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RegionUtil.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RegionUtil.java
index b800c4d..e3340f2 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RegionUtil.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RegionUtil.java
@@ -181,10 +181,10 @@
 		return PatternVariableNodeImpl.create(nodeRole, region, stepVariable, true);
 	}
 
-	public static @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
+	public static @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
 		EdgeRole.Phase phase = mergeToLessKnownPhase(sourceNode.getNodeRole(), targetNode.getNodeRole()).getPhase();
 		EdgeRole edgeRole = EdgeRoleImpl.getEdgeRole(phase);
-		return NavigationEdgeImpl.createEdge(edgeRole, sourceNode, source2targetProperty, targetNode);
+		return NavigationEdgeImpl.createEdge(edgeRole, sourceNode, source2targetProperty, targetNode, isPartial);
 	}
 
 	public static @NonNull Node createNullNode(@NonNull Region region, boolean isMatched, @Nullable TypedElement typedElement) {
@@ -263,9 +263,9 @@
 		return ExpressionEdgeImpl.create(edgeRole, sourceNode, name, targetNode);
 	}
 
-	public static @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
+	public static @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
 		EdgeRole edgeRole = EdgeRoleImpl.getEdgeRole(Role.Phase.REALIZED);
-		return NavigationEdgeImpl.createEdge(edgeRole, sourceNode, source2targetProperty, targetNode);
+		return NavigationEdgeImpl.createEdge(edgeRole, sourceNode, source2targetProperty, targetNode, isPartial);
 	}
 
 	public static @NonNull VariableNodeImpl createRealizedStepNode(@NonNull Region region, @NonNull Variable stepVariable) {
@@ -533,7 +533,7 @@
 		return isUnconditional(typedElement);
 	}
 
-	public static boolean isRealizedIncludes(@NonNull Edge edge) {	// FIXME includes should be a pseudo-navigation edge
+	/*	public static boolean isRealizedIncludes(@NonNull Edge edge) {	// FIXME includes should be a pseudo-navigation edge
 		if (!edge.isRealized()) {
 			return false;
 		}
@@ -541,7 +541,7 @@
 			return false;
 		}
 		return "«includes»".equals(edge.getName()) || "«includesAll»".equals(edge.getName());
-	}
+	} */
 
 	public static boolean isUnconditional(@NonNull TypedElement typedElement) {
 		EObject eContainer = typedElement.eContainer();
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RootCompositionRegion.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RootCompositionRegion.java
index ddc46b1..2c6ef29 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RootCompositionRegion.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/RootCompositionRegion.java
@@ -114,7 +114,7 @@
 			if (introducedNode == null) {
 				introducedNode = RegionUtil.createComposingNode(this, "«" + elementType.getName() + "-null»", childrenClassDatumAnalysis);
 				property2node.put(null, introducedNode);
-				RegionUtil.createNavigationEdge(getNullNode(), parent2childProperty, introducedNode);
+				RegionUtil.createNavigationEdge(getNullNode(), parent2childProperty, introducedNode, false);
 			}
 		}
 		else if (containingClassDatumAnalysis != null) {								// Non-root oclContainer ownership
@@ -128,7 +128,7 @@
 				introducedNode = RegionUtil.createComposingNode(this, "«" + elementType.getName() + "-oclContents»", childrenClassDatumAnalysis);
 				type2node.put(containingClassDatumAnalysis, introducedNode);
 				Node containerNode = RegionUtil.createComposingNode(this, "«" + containingClassDatumAnalysis.getCompleteClass().getName() + "-oclContainer»", containingClassDatumAnalysis);
-				RegionUtil.createNavigationEdge(containerNode, parent2childProperty, introducedNode);
+				RegionUtil.createNavigationEdge(containerNode, parent2childProperty, introducedNode, false);
 			}
 		}
 		else {																			// Knonw distinctive containment
@@ -145,7 +145,7 @@
 				assert owningClass != null;
 				containingClassDatumAnalysis = scheduler.getClassDatumAnalysis(owningClass, typedModel);
 				Node containerNode = RegionUtil.createComposingNode(this, "«" + owningClass.getName() + "-" + parent2childProperty.getName() + "»", containingClassDatumAnalysis);
-				RegionUtil.createNavigationEdge(containerNode, parent2childProperty, introducedNode);
+				RegionUtil.createNavigationEdge(containerNode, parent2childProperty, introducedNode, false);
 			}
 		}
 		return introducedNode;
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/CastEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/CastEdgeImpl.java
index c1e4444..9bfc6b4 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/CastEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/CastEdgeImpl.java
@@ -44,7 +44,7 @@
 	}
 
 	@Override
-	public @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
+	public @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
 		return createEdge(edgeRole, sourceNode, getProperty(), targetNode);
 	}
 
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/EdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/EdgeImpl.java
index 12bb83e..eec0afb 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/EdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/EdgeImpl.java
@@ -285,6 +285,11 @@
 	}
 
 	@Override
+	public boolean isPartial() {
+		return false;
+	}
+
+	@Override
 	public boolean isPredicate() {
 		return false;
 	}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/ExpressionEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/ExpressionEdgeImpl.java
index 10e6e05..3ad6899 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/ExpressionEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/ExpressionEdgeImpl.java
@@ -25,7 +25,7 @@
 	}
 
 	@Override
-	public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
+	public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
 		return create(edgeRole, sourceNode, getName(), targetNode);
 	}
 
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/IteratedEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/IteratedEdgeImpl.java
index f861ee4..9cf0b5b 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/IteratedEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/IteratedEdgeImpl.java
@@ -25,7 +25,7 @@
 	}
 
 	@Override
-	public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
+	public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
 		return create(edgeRole, sourceNode, getName(), targetNode);
 	}
 
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigationEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigationEdgeImpl.java
index cdd97b6..f37fbb6 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigationEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/NavigationEdgeImpl.java
@@ -12,19 +12,23 @@
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.CollectionType;
+import org.eclipse.ocl.pivot.CompleteClass;
 import org.eclipse.ocl.pivot.Property;
+import org.eclipse.ocl.pivot.Type;
+import org.eclipse.ocl.pivot.utilities.PivotUtil;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.EdgeRole;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.NavigableEdge;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Node;
 
 public class NavigationEdgeImpl extends NavigableEdgeImpl
 {
-	private static @NonNull NavigationEdgeImpl create(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
-		if ("ownedCallExp".equals(source2targetProperty.getName())) {
+	private static @NonNull NavigationEdgeImpl create(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
+		if ("outTransition".equals(source2targetProperty.getName())) {
 			edgeRole.toString();
 		}
 		NavigationEdgeImpl edge = new NavigationEdgeImpl();
-		edge.initialize(edgeRole, sourceNode, source2targetProperty, targetNode);
+		edge.initialize(edgeRole, sourceNode, source2targetProperty, targetNode, isPartial);
 		return edge;
 	}
 
@@ -33,22 +37,63 @@
 	 * source2targetProperty has an opposite, the opposite edge is also created and installed.
 	 */
 	public static @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole,
-			@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
-		NavigationEdgeImpl forwardEdge = create(edgeRole, sourceNode, source2targetProperty, targetNode);
+			@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
+		NavigationEdgeImpl forwardEdge = create(edgeRole, sourceNode, source2targetProperty, targetNode, isPartial);
 		Property target2sourceProperty = source2targetProperty.getOpposite();
 		if ((target2sourceProperty != null) && !targetNode.isExplicitNull()) {
-			assert (targetNode.getNavigationEdge(target2sourceProperty) == null) || target2sourceProperty.isIsMany();
+			assert (targetNode.getNavigationEdge(target2sourceProperty) == null) || target2sourceProperty.isIsMany() || (isPartial == Boolean.TRUE);
 			if (!source2targetProperty.isIsMany() && !target2sourceProperty.isIsMany() /*&& target2sourceProperty.isIsRequired()*/) {		// FIXME do we need stronger type conformance here ??
-				NavigationEdgeImpl reverseEdge = create(edgeRole, targetNode, target2sourceProperty, sourceNode);
+				NavigationEdgeImpl reverseEdge = create(edgeRole, targetNode, target2sourceProperty, sourceNode, isPartial);
 				forwardEdge.initializeOpposite(reverseEdge);
 			}
 		}
 		return forwardEdge;
 	}
 
+	/**
+	 * True if this edge is a partial many-to-one relationship.
+	 */
+	private boolean isPartial = false;
+
 	@Override
-	public @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
-		return createEdge(edgeRole, sourceNode, getProperty(), targetNode);
+	public @NonNull NavigableEdge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
+		return createEdge(edgeRole, sourceNode, getProperty(), targetNode, isPartial);
+	}
+
+	@Override
+	public @Nullable String getLabel() {
+		if (isPartial) {
+			return "«includes»\\n" + super.getLabel();
+		}
+		else {
+			return super.getLabel();
+		}
+	}
+
+	public void initialize(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Property source2targetProperty,
+			@NonNull Node targetNode, @Nullable Boolean isPartial) {
+		super.initialize(edgeRole, sourceNode, source2targetProperty, targetNode);
+		boolean isComputedPartial = false;
+		Type propertyTargetType = PivotUtil.getType(source2targetProperty);
+		CompleteClass targetClass = targetNode.getCompleteClass();
+		if (!targetClass.conformsTo(propertyTargetType)) {
+			if (propertyTargetType instanceof CollectionType) {
+				Type elementType = PivotUtil.getElementType(((CollectionType)propertyTargetType));
+				if (targetClass.conformsTo(elementType)) {
+					isComputedPartial = true;
+				}
+			}
+		}
+		if (isPartial == null) {
+			isPartial = isComputedPartial;
+		}
+		assert isPartial == isComputedPartial;
+		setIsPartial(isPartial);
+	}
+
+	@Override
+	public final boolean isPartial() {
+		return isPartial;
 	}
 
 	@Override
@@ -56,6 +101,10 @@
 		return true;
 	}
 
+	public void setIsPartial(boolean isPartial) {
+		this.isPartial  = isPartial;
+	}
+
 	@Override
 	public void setSource(@Nullable Node sourceNode) {
 		assert (sourceNode == null) || !sourceNode.isExplicitNull();
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/PredicateEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/PredicateEdgeImpl.java
index 55a542b..91f07db 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/PredicateEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/PredicateEdgeImpl.java
@@ -25,7 +25,7 @@
 	}
 
 	@Override
-	public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
+	public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
 		return create(edgeRole, sourceNode, getName(), targetNode);
 	}
 
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/RecursionEdgeImpl.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/RecursionEdgeImpl.java
index 21d0cf5..bf40c53 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/RecursionEdgeImpl.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtp2qvts/impl/RecursionEdgeImpl.java
@@ -11,6 +11,7 @@
 package org.eclipse.qvtd.compiler.internal.qvtp2qvts.impl;
 
 import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Edge;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.EdgeRole;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Node;
@@ -28,7 +29,7 @@
 	private boolean isPrimary = false;
 
 	@Override
-	public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode) {
+	public @NonNull Edge createEdge(@NonNull EdgeRole edgeRole, @NonNull Node sourceNode, @NonNull Node targetNode, @Nullable Boolean isPartial) {
 		return create(edgeRole, sourceNode, targetNode, isPrimary);
 	}
 
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java
index 41895ba..00e39ee 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java
@@ -46,6 +46,7 @@
 import org.eclipse.qvtd.pivot.qvtcore.CorePattern;
 import org.eclipse.qvtd.pivot.qvtcore.GuardPattern;
 import org.eclipse.qvtd.pivot.qvtcore.Mapping;
+import org.eclipse.qvtd.pivot.qvtcore.NavigationAssignment;
 import org.eclipse.qvtd.pivot.qvtcore.RealizedVariable;
 import org.eclipse.qvtd.pivot.qvtcore.VariableAssignment;
 import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreHelper;
@@ -91,6 +92,7 @@
 				this.cOtherTypedModel = getCoreTypedModel(rOtherTypedModel);
 				this.cOtherDomain = createCoreDomain(cOtherTypedModel, false);
 				cOtherDomain.setIsCheckable(rOtherDomain.isIsCheckable());
+				cOtherDomain.setIsEnforceable(false);
 				this.cOtherGuardPattern = ClassUtil.nonNullState(cOtherDomain.getGuardPattern());
 				this.cOtherBottomPattern = ClassUtil.nonNullState(cOtherDomain.getBottomPattern());
 
@@ -156,7 +158,7 @@
 					/**
 					 * The predicate for a CollectionTemplateExp without a rest variable is a total comparison.
 					 *
-					 * ve1:T1{tp = ve2:Collection{a++b}}		=>   ve2 := ve1.tp; ve2 = Collection{a,b};
+					 * ve1:T1{tp = ve2:Collection{a,b}}		=>   ve2 := ve1.tp; ve2 = Collection{a,b};
 					 */
 					List<@NonNull CollectionLiteralPart> mParts = new ArrayList<>();
 					for (@NonNull OCLExpression rMember : rMembers) {
@@ -249,7 +251,7 @@
 						Variable rVariable/*vpte*/ = ClassUtil.nonNullState((Variable) ((VariableExp)propertyTemplateValue).getReferredVariable());
 						Variable cVariable/*mvpte*/ = variablesAnalysis.getCoreVariable(rVariable);
 						//				BottomPattern cBottomPattern = rSharedVariables.contains(rVariable) ? cMiddleBottomPattern : cEnforcedBottomPattern;
-						variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(cVariable));
+						variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, createVariableExp(cVariable));
 					}
 					else if (propertyTemplateValue instanceof CollectionTemplateExp) {
 						/**
@@ -264,7 +266,7 @@
 						NavigationCallExp pce =  createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
 						VariableAssignment a = createVariableAssignment(mvcte, pce);
 						cMiddleBottomPattern.getAssignment().add(a);
-						mapOtherCollectionTemplateExpression(cte);
+						mapOtherTemplateExpression(cte);
 					}
 					else if (propertyTemplateValue instanceof ObjectTemplateExp) {
 						/**
@@ -276,8 +278,8 @@
 						ObjectTemplateExp pte = (ObjectTemplateExp)propertyTemplateValue;
 						Variable vpte = ClassUtil.nonNullState(pte.getBindsTo());
 						Variable mvpte = variablesAnalysis.getCoreVariable(vpte);
-						variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(mvpte));
-						mapOtherObjectTemplateExpression(pte);
+						variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, createVariableExp(mvpte));
+						mapOtherTemplateExpression(pte);
 					}
 					else {
 						// loop body of RDomainPatternToMDBottomPatternSimpleNonVarExpr
@@ -287,7 +289,7 @@
 						 *
 						 * ve1:T{tp = me}   =>   ve1.tp := me;
 						 */
-						variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(propertyTemplateValue));
+						variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, mapExpression(propertyTemplateValue));
 					}
 				}
 			}
@@ -506,12 +508,13 @@
 				cExpression = mapExpression(rExpression);
 			}
 			if ((cTargetVariable != null) && (cExpression != null)) {
-				variablesAnalysis.addNavigationAssignment(rTargetVariable, targetProperty, cExpression);
+				variablesAnalysis.addNavigationAssignment(rTargetVariable, targetProperty, cExpression, false);
 			}
 		}
 
 		private @NonNull CoreDomain createCoreDomain(@NonNull TypedModel cTypedModel, boolean isEnforced) {
 			CoreDomain coreDomain = qvtr2qvtc.createCoreDomain(cTypedModel);
+			coreDomain.setIsCheckable(false);
 			coreDomain.setIsEnforceable(isEnforced);
 			coreDomain.setRule(cMapping);
 			return coreDomain;
@@ -635,7 +638,7 @@
 				/**
 				 * The predicate for a CollectionTemplateExp without a rest variable is a total comparison.
 				 *
-				 * ve1:T1{tp = ve2:Collection{a++b}}		=>   ve2 := ve1.tp; ve2 = Collection{a,b};
+				 * ve1:T1{tp = ve2:Collection{a,b}}		=>   ve2 := ve1.tp; ve2 = Collection{a,b};
 				 */
 				List<@NonNull CollectionLiteralPart> mParts = new ArrayList<>();
 				for (@NonNull OCLExpression rMember : rMembers) {
@@ -674,41 +677,39 @@
 					variablesAnalysis.addConditionPredicate(cMiddleBottomPattern, createVariableExp(mVariable), vElement);
 				}
 			} */
-			else {
-				if (!rRest.isIsImplicit()) {
-					/**
-					 * The assignment for an unordered CollectionTemplateExp rest variable is a cumulative exclusion.
-					 *
-					 * ve1:T1{tp = ve2:Collection{a,b++c}}		=>   c := ve2->excluding(a)->excluding(b);
-					 */
-					Variable mRest = variablesAnalysis.getCoreVariable(rRest);
-					OCLExpression exclusions = createVariableExp(mvcte);
-					for (@NonNull OCLExpression rMember : rMembers) {
-						Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
-						exclusions = createOperationCallExp(exclusions, "excluding", createVariableExp(mVariable));
-					}
-					VariableAssignment aRest = createVariableAssignment(mRest, exclusions);
+			else if (rRest.isIsImplicit()) {
+				PropertyTemplateItem rPropertyTemplateItem = (PropertyTemplateItem) cte.eContainer();
+				ObjectTemplateExp rObjectTemplateExp = rPropertyTemplateItem.getObjContainer();
+				Variable vote = ClassUtil.nonNullState(rObjectTemplateExp.getBindsTo());
+				Variable cvote = variablesAnalysis.getCoreVariable(vote);
+				/**
+				 * The assignment for a CollectionTemplateExp variable is a literal for the members and an addition of the rest.
+				 *
+				 * ve1:T1{tp = ve2:Collection{a,b++_}}		=>   ve1.tp += a; ve1.tp += b;
+				 */
+				for (@NonNull OCLExpression rMember : rMembers) {
+					Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
+					NavigationAssignment aRest = createNavigationAssignment(createVariableExp(cvote), QVTrelationUtil.getReferredProperty(rPropertyTemplateItem), createVariableExp(mVariable), true);
 					cMiddleBottomPattern.getAssignment().add(aRest);
 				}
-				/**
-				 * The predicates for each unordered CollectionTemplateExp member variable is an excluded inclusion test.
-				 *
-				 * ve1:T1{tp = ve2:Collection{a,b++c}}		=>   ve2->excluding(a)->includes(b);
-				 */
-				for (int i = 0; i < size; i++) {
-					@NonNull OCLExpression eTerm = createVariableExp(mvcte);
-					for (int j = 0; j < i; j++) {
-						OCLExpression rMember = rMembers.get(j);
-						Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
-						eTerm = createOperationCallExp(eTerm, "excluding", createVariableExp(mVariable));
-					}
-					OCLExpression rMember = rMembers.get(i);
-					Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
-					eTerm = createOperationCallExp(eTerm, "includes", createVariableExp(mVariable));
-					variablesAnalysis.addPredicate(cMiddleBottomPattern, eTerm);
-				}
 			}
-			//		}
+			else {
+				/**
+				 * The assignment for a CollectionTemplateExp variable is a literal for the members and an addition of the rest.
+				 *
+				 * ve1:T1{tp = ve2:Collection{a,b++c}}		=>   ve2 := Collection{a,b}->includingAll(c);
+				 */
+				List<@NonNull CollectionLiteralPart> ownedParts = new ArrayList<>();
+				for (@NonNull OCLExpression rMember : rMembers) {
+					Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
+					ownedParts.add(createCollectionItem(createVariableExp(mVariable)));
+				}
+				OCLExpression cExpression = createCollectionLiteralExp(collectionType, ownedParts);
+				Variable mRest = variablesAnalysis.getCoreVariable(rRest);
+				cExpression = createOperationCallExp(cExpression, "includingAll", createVariableExp(mRest));
+				VariableAssignment aRest = createVariableAssignment(mvcte, cExpression);
+				cMiddleBottomPattern.getAssignment().add(aRest);
+			}
 		}
 
 		// RDomainToMDBottomForEnforcement (second half)
@@ -727,23 +728,40 @@
 					//  body of RDomainToMDBottomForEnforcementOfIdentityProp
 					addPropertyAssignmentToMiddleBottomPattern(rTemplateVariable, partProperty, rPartValue);
 				}
-				else if (rPartValue instanceof TemplateExp) {
+				else if (rPartValue instanceof CollectionTemplateExp) {
 					// body of RDomainToMDBottomForEnforcementOfNonIdentityPropObject
-					TemplateExp pte = (TemplateExp)rPartValue;
-					Variable pv = ClassUtil.nonNullState(pte.getBindsTo());
+					CollectionTemplateExp cte = (CollectionTemplateExp)rPartValue;
+					/**
+					 * Each PropertyTemplateItem whose value is a CollectionTemplateExp
+					 * converts to a VariableAssignment and Predicates.
+					 *
+					 * ve1:T1{tp = ve2:Collection{a++b}}		=>   ve2 := ve1.tp;
+					 */
+					/*Realized*/Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
+					Variable vcte = ClassUtil.nonNullState(cte.getBindsTo());
+					Variable mvcte = variablesAnalysis.getCoreVariable(vcte);
+					NavigationCallExp pce =  createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
+					VariableAssignment a = createVariableAssignment(mvcte, pce);
+					cMiddleBottomPattern.getAssignment().add(a);
+					mapEnforcedTemplateExpression(cte);
+				}
+				else if (rPartValue instanceof ObjectTemplateExp) {
+					// body of RDomainToMDBottomForEnforcementOfNonIdentityPropObject
+					ObjectTemplateExp ote = (ObjectTemplateExp)rPartValue;
+					Variable pv = ClassUtil.nonNullState(ote.getBindsTo());
 					/*Realized*/Variable cTargetVariable/*mpv*/ = variablesAnalysis.getCoreVariable(pv); //rWhenVariables.contains(pv) ? getCoreVariable(pv) : whenRealizedVariable(cEnforcedBottomPattern, pv);
 					//					Variable cTemplateVariable/*mv*/ = variablesAnalysis.getCoreVariable(rTemplateVariable);
-					variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(cTargetVariable));
-					mapEnforcedTemplateExpression(pte);
+					variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(cTargetVariable), null);
+					mapEnforcedTemplateExpression(ote);
 					//					Property cTargetProperty2 = qvtr2qvtc.getProperty(cMiddleRealizedVariable.getType(), cTargetVariable);
 					//					variablesAnalysis.addNavigationAssignment(rMiddleRealizedVariable, cTargetProperty2, createVariableExp(cTargetVariable));
 				}
-				else {
+				else if (rPartValue instanceof VariableExp) {
 					// body of RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive
 					//					Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
 					//RDomainToMComposedMappingGuardrEnforcedDomain
 					for (@NonNull TemplateExp rTemplateExpression : rEnforcedRootTemplateExpressions) {
-						if ((rPartValue instanceof VariableExp) && (rTemplateExpression instanceof ObjectTemplateExp)) {
+						if (rTemplateExpression instanceof ObjectTemplateExp) {
 							// check
 							Variable rReferredVariable = (Variable) ClassUtil.nonNullState(((VariableExp) rPartValue).getReferredVariable());
 							if (isVarBoundToSomeOtherTemplate((ObjectTemplateExp) rTemplateExpression, rEnforcedObjectTemplateExpression, rReferredVariable)) {
@@ -754,8 +772,14 @@
 								cEnforcedGuardPattern.getBindsTo().add(cReferredVariable);
 							}
 						}
-						variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(rPartValue));
 					}
+					variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(rPartValue), null);
+				}
+				else {
+					// body of RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive
+					//					Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
+					//RDomainToMComposedMappingGuardrEnforcedDomain
+					variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(rPartValue), null);
 				}
 			}
 		}
@@ -909,7 +933,7 @@
 						Relation rInvokedRelation = QVTrelationUtil.getReferredRelation(rInvocation);
 						Type invokedTraceClass/*tc*/ = qvtr2qvtc.getTraceClass(rInvokedRelation);
 						//
-						List<@NonNull OCLExpression> rArguments = QVTrelationUtil.getOwnedArguments(rInvocation);
+						List<@NonNull OCLExpression> rArguments = QVTrelationUtil.Internal.getOwnedArgumentsList(rInvocation);
 						/*						StringBuilder s = new StringBuilder();
 						for (OCLExpression rArgument : rArguments) {
 							VariableExp a = (VariableExp) rArgument;
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractVariableAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractVariableAnalysis.java
index 279a07d..e71e5e9 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractVariableAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractVariableAnalysis.java
@@ -43,7 +43,7 @@
 	}
 
 	@Override
-	public void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression) {
+	public void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression, @Nullable Boolean isPartial) {
 		System.out.println("Unexpected " + getClass().getSimpleName() + ".addNavigationAssignment for " + this);
 	}
 
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationVariableAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationVariableAnalysis.java
index 7a938d6..20303f6 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationVariableAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationVariableAnalysis.java
@@ -69,7 +69,7 @@
 	 * of a Collection element assignment to "cExpression.cOppositeProperty := cVariable".
 	 */
 	@Override
-	public void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression) {
+	public void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression, @Nullable Boolean isPartial) {
 		Key rKey2 = rKey;
 		if (isKeyed() && (rKey2 != null)) {
 			if (rKey2.getPart().contains(targetProperty)) {
@@ -81,24 +81,27 @@
 		}
 		Variable cVariable2 = getCoreVariable();
 		List<@NonNull Assignment> cMiddleBottomAssignments = QVTcoreUtil.getOwnedAssignments(variablesAnalysis.getMiddleBottomPattern());
-		if (!targetProperty.isIsMany() || (cExpression.getType() instanceof CollectionType)) {
-			VariableExp cSlotVariableExp = variablesAnalysis.createVariableExp(cVariable2);
-			NavigationAssignment cAssignment = variablesAnalysis.createNavigationAssignment(cSlotVariableExp, targetProperty, cExpression);
-			QVTr2QVTc.SYNTHESIS.println("  addPropertyAssignment " + cAssignment);
-			variablesAnalysis.assertNewAssignment(cMiddleBottomAssignments, cAssignment);
-			cMiddleBottomAssignments.add(cAssignment);
-			return;
+		if (isPartial == null) {
+			isPartial = targetProperty.isIsMany() && !(cExpression.getType() instanceof CollectionType);
 		}
-		Property cOppositeProperty = targetProperty.getOpposite();
+		//		if (isPartial == isPartial2) {
+		VariableExp cSlotVariableExp = variablesAnalysis.createVariableExp(cVariable2);
+		NavigationAssignment cAssignment = variablesAnalysis.createNavigationAssignment(cSlotVariableExp, targetProperty, cExpression, isPartial);
+		QVTr2QVTc.SYNTHESIS.println("  addPropertyAssignment " + cAssignment);
+		variablesAnalysis.assertNewAssignment(cMiddleBottomAssignments, cAssignment);
+		cMiddleBottomAssignments.add(cAssignment);
+		return;
+		//		}
+		/*		Property cOppositeProperty = targetProperty.getOpposite();
 		if ((cOppositeProperty != null) && (cExpression instanceof VariableExp) && (!cOppositeProperty.isIsMany() || (cVariable2.getType() instanceof CollectionType))) {
 			VariableExp cSlotVariableExp = (VariableExp)cExpression;
-			NavigationAssignment cAssignment = variablesAnalysis.createNavigationAssignment(cSlotVariableExp, cOppositeProperty, variablesAnalysis.createVariableExp(cVariable2));
+			NavigationAssignment cAssignment = variablesAnalysis.createNavigationAssignment(cSlotVariableExp, cOppositeProperty, variablesAnalysis.createVariableExp(cVariable2), isPartial);
 			QVTr2QVTc.SYNTHESIS.println("  addOppositePropertyAssignment " + cAssignment);
 			variablesAnalysis.assertNewAssignment(cMiddleBottomAssignments, cAssignment);
 			cMiddleBottomAssignments.add(cAssignment);
 			return;
-		}
-		throw new IllegalStateException("Unsupported collection assign " + cVariable2 + " . " + targetProperty + " := " + cExpression);
+		} */
+		//		throw new IllegalStateException("Unsupported collection assign " + cVariable2 + " . " + targetProperty + " := " + cExpression);
 	}
 
 	public @Nullable RealizedVariable basicGetCoreRealizedVariable() {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariableAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariableAnalysis.java
index 26283a0..0c980d9 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariableAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariableAnalysis.java
@@ -32,7 +32,7 @@
 	 * Add the NavigationAssignment "cVariable.cProperty := cExpression" to the cBottomPattern inverting the usage
 	 * of a Collection element assignment to "cExpression.cOppositeProperty := cVariable".
 	 */
-	void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression);
+	void addNavigationAssignment(@NonNull Property targetProperty, @NonNull OCLExpression cExpression, @Nullable Boolean isPartial);
 
 	/**
 	 * Perform diagnostic checks at the end of the analysis.
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java
index 0f75658..f48d59d 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java
@@ -23,6 +23,7 @@
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.ocl.pivot.CollectionType;
 import org.eclipse.ocl.pivot.Element;
+import org.eclipse.ocl.pivot.NavigationCallExp;
 import org.eclipse.ocl.pivot.OCLExpression;
 import org.eclipse.ocl.pivot.OperationCallExp;
 import org.eclipse.ocl.pivot.Parameter;
@@ -273,8 +274,14 @@
 		return cVariable;
 	}
 
-	public void addNavigationAssignment(@NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression cExpression) {
-		getVariableAnalysis(rTargetVariable).addNavigationAssignment(targetProperty, cExpression);
+	public void addNavigationAssignment(@NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression cExpression, @Nullable Boolean isPartial) {
+		getVariableAnalysis(rTargetVariable).addNavigationAssignment(targetProperty, cExpression, isPartial);
+	}
+
+	public void addNavigationPredicate(@NonNull CorePattern cCorePattern, @NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression cExpression) {
+		Variable cTargetVariable = getCoreVariable(rTargetVariable);
+		NavigationCallExp cNavigationExp = createNavigationCallExp(createVariableExp(cTargetVariable), targetProperty);
+		addConditionPredicate(cCorePattern, cNavigationExp, cExpression);
 	}
 
 	protected void addPredicate(@NonNull CorePattern cExpectedCorePattern, @NonNull OCLExpression cExpression) {
@@ -333,7 +340,7 @@
 			assert (!cTargetProperty.isIsMany() || (cVariable.getType() instanceof CollectionType));
 			VariableExp cSlotVariableExp = createVariableExp(cMiddleRealizedVariable);
 			OCLExpression cExpression = createVariableExp(cVariable);
-			NavigationAssignment cAssignment = createNavigationAssignment(cSlotVariableExp, cTargetProperty, cExpression);
+			NavigationAssignment cAssignment = createNavigationAssignment(cSlotVariableExp, cTargetProperty, cExpression, false);
 			QVTr2QVTc.SYNTHESIS.println("  addPropertyAssignment " + cAssignment);
 			assertNewAssignment(QVTcoreUtil.getOwnedAssignments(cMiddleBottomPattern), cAssignment);
 			cMiddleBottomPattern.getAssignment().add(cAssignment);
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java
index e8744ae..8d23031 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvti/BasicRegion2Mapping.java
@@ -71,7 +71,6 @@
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Node;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.NodeConnection;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Region;
-import org.eclipse.qvtd.compiler.internal.qvtp2qvts.RegionUtil;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.SchedulerConstants;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.analysis.ClassDatumAnalysis;
 import org.eclipse.qvtd.pivot.qvtbase.Function;
@@ -798,7 +797,7 @@
 				Property property = edge.getProperty();
 				OCLExpression targetVariableExp = createVariableExp(targetNode);
 				boolean isNotify = isHazardousWrite(edge);
-				SetStatement setStatement = QVTimperativeUtil.createSetStatement(slotVariable, property, targetVariableExp, isNotify);
+				SetStatement setStatement = QVTimperativeUtil.createSetStatement(slotVariable, property, targetVariableExp, edge.isPartial(), isNotify);
 				mapping.getOwnedStatements().add(setStatement);
 			}
 		}
@@ -821,7 +820,7 @@
 			}
 		} */
 		for (@NonNull Edge edge : region.getEdges()) {
-			if (edge.isPredicate() && !RegionUtil.isRealizedIncludes(edge)) {
+			if (edge.isPredicate()) {
 				ExpressionCreator expressionCreator = new ExpressionCreator();
 				ExpressionCreator inlineExpressionCreator = expressionCreator.getInlineExpressionCreator();
 				Node sourceNode = edge.getSource();
@@ -1004,19 +1003,19 @@
 		for (@NonNull NavigableEdge traversedEdge : navigationForest.getForestNavigations()) {
 			Node sourceNode = traversedEdge.getSource();
 			Node targetNode = traversedEdge.getTarget();
-			Boolean isJustRealizedIncludes = null;
-			for (@NonNull Edge outgoingEdge : targetNode.getOutgoingEdges()) {
-				if (!RegionUtil.isRealizedIncludes(outgoingEdge)) {
-					isJustRealizedIncludes = false;
-					break;
-				}
-				else {
-					isJustRealizedIncludes = true;
-				}
-			}
-			if (isJustRealizedIncludes == Boolean.TRUE) {
-				continue;
-			}
+			//			Boolean isJustRealizedIncludes = null;
+			//			for (@NonNull Edge outgoingEdge : targetNode.getOutgoingEdges()) {
+			//				if (!RegionUtil.isRealizedIncludes(outgoingEdge)) {
+			//					isJustRealizedIncludes = false;
+			//					break;
+			//				}
+			//				else {
+			//					isJustRealizedIncludes = true;
+			//				}
+			//			}
+			//			if (isJustRealizedIncludes == Boolean.TRUE) {
+			//				continue;
+			//			}
 			Property property = traversedEdge.getProperty();
 			OCLExpression sourceExp = createVariableExp(sourceNode);
 			OCLExpression source2targetExp = createCallExp(sourceExp, property);
@@ -1199,7 +1198,7 @@
 				}
 				if (valueExp != null) {
 					boolean isNotify = isHazardousWrite(edge);
-					SetStatement setStatement = QVTimperativeUtil.createSetStatement(asVariable, property, valueExp, isNotify);
+					SetStatement setStatement = QVTimperativeUtil.createSetStatement(asVariable, property, valueExp, edge.isPartial(), isNotify);
 					//					addObservedProperties(setStatement);
 					mapping.getOwnedStatements().add(setStatement);
 				}
@@ -1233,12 +1232,12 @@
 		List<@NonNull Edge> realizedIncludesEdges = null;
 		//		ImperativeBottomPattern bottomPattern = (ImperativeBottomPattern) mapping.getBottomPattern();
 		for (@NonNull Edge edge : region.getRealizedEdges()) {
-			if (RegionUtil.isRealizedIncludes(edge)) {
-				if (realizedIncludesEdges == null) {
-					realizedIncludesEdges = new ArrayList<>();
-				}
-				realizedIncludesEdges.add(edge);
-			}
+			//			if (RegionUtil.isRealizedIncludes(edge)) {
+			//				if (realizedIncludesEdges == null) {
+			//					realizedIncludesEdges = new ArrayList<>();
+			//				}
+			//				realizedIncludesEdges.add(edge);
+			//			}
 		}
 		if (realizedIncludesEdges != null) {
 			if (realizedIncludesEdges.size() > 1) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/merger/EdgeMerger.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/merger/EdgeMerger.java
index a6e738c..49e8882 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/merger/EdgeMerger.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/merger/EdgeMerger.java
@@ -60,7 +60,7 @@
 		Edge newEdge2 = newEdge;
 		assert newEdge2 == null;
 		for (@NonNull Edge oldEdge : oldEdges) {
-			newEdge2 = newEdge = oldEdge.createEdge(edgeRole, sourceNodeMerger, targetNodeMerger);
+			newEdge2 = newEdge = oldEdge.createEdge(edgeRole, sourceNodeMerger, targetNodeMerger, oldEdge.isPartial());
 			break;
 		}
 		if (newEdge2 == null) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java
index c9d24b8..5fef65d 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java
@@ -30,7 +30,6 @@
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Node;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.QVTp2QVTs;
 import org.eclipse.qvtd.compiler.internal.qvtp2qvts.Region;
-import org.eclipse.qvtd.compiler.internal.qvtp2qvts.RegionUtil;
 import org.eclipse.qvtd.compiler.internal.utilities.CompilerUtil;
 
 import com.google.common.collect.Iterables;
@@ -217,7 +216,7 @@
 						}
 					}
 				}
-				else if (RegionUtil.isRealizedIncludes(edge)) {
+				/*				else if (RegionUtil.isRealizedIncludes(edge)) {
 					realizedEdges.add(edge);
 					Node sourceNode = edge.getSource();
 					if (!realizedMiddleNodes.contains(sourceNode) && (sourceNode.isPredicated() || sourceNode.isRealized())) {
@@ -229,7 +228,7 @@
 					if (edge.getTarget().isLoaded() && edge.getSource().getClassDatumAnalysis().getDomainUsage().isMiddle()) {
 						//							navigableEdges.add(navigationEdge);
 					}
-				}
+				} */
 			}
 		}
 		for (@NonNull NavigableEdge edge : region.getNavigationEdges()) {
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitioningVisitor.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitioningVisitor.java
index 121dcc0..239553d 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitioningVisitor.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/PartitioningVisitor.java
@@ -100,7 +100,7 @@
 		if (edgeRole == null) {
 			return null;
 		}
-		return edge.createEdge(edgeRole, partialSourceNode, partialTargetNode);
+		return edge.createEdge(edgeRole, partialSourceNode, partialTargetNode, edge.isPartial());
 	}
 
 	@Override
@@ -142,7 +142,7 @@
 		if (edgeRole == null) {
 			return null;
 		}
-		return navigableEdge.createEdge(edgeRole, partialSourceNode, partialTargetNode);
+		return navigableEdge.createEdge(edgeRole, partialSourceNode, partialTargetNode, navigableEdge.isPartial());
 	}
 
 	@Override
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtcore/emf-gen/org/eclipse/qvtd/pivot/qvtcore/impl/PropertyAssignmentImpl.java b/plugins/org.eclipse.qvtd.pivot.qvtcore/emf-gen/org/eclipse/qvtd/pivot/qvtcore/impl/PropertyAssignmentImpl.java
index 8175b09..c104323 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtcore/emf-gen/org/eclipse/qvtd/pivot/qvtcore/impl/PropertyAssignmentImpl.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtcore/emf-gen/org/eclipse/qvtd/pivot/qvtcore/impl/PropertyAssignmentImpl.java
@@ -338,7 +338,7 @@
 		else {
 			/*@Caught*/ @NonNull Object CAUGHT_result;
 			try {
-				final /*@NonInvalid*/ boolean isPartial = this.isIsPartial();
+				final /*@NonInvalid*/ java.lang.@Nullable Boolean isPartial = this.isIsPartial();
 				final /*@NonInvalid*/ java.lang.@Nullable Boolean not = BooleanNotOperation.INSTANCE.evaluate(isPartial);
 				if (not == null) {
 					throw new InvalidValueException("Null if condition");
@@ -448,7 +448,7 @@
 		else {
 			@SuppressWarnings("null")
 			final /*@NonInvalid*/ org.eclipse.ocl.pivot.@NonNull Property targetProperty = this.getTargetProperty();
-			final /*@NonInvalid*/ boolean isImplicit = targetProperty.isIsImplicit();
+			final /*@NonInvalid*/ java.lang.@Nullable Boolean isImplicit = targetProperty.isIsImplicit();
 			final /*@NonInvalid*/ java.lang.@Nullable Boolean result = BooleanNotOperation.INSTANCE.evaluate(isImplicit);
 			final /*@NonInvalid*/ boolean logDiagnostic = CGStringLogDiagnosticOperation.INSTANCE.evaluate(executor, TypeId.BOOLEAN, QVTcoreTables.STR_PropertyAssignment_c_c_PropertyIsNotImplicit, this, (Object)null, diagnostics, context, (Object)null, severity_0, result, QVTcoreTables.INT_0).booleanValue();
 			symbol_0 = logDiagnostic;
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java b/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java
index 2bfebe6..34ee7ec 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java
@@ -67,7 +67,7 @@
 		return coreMapping;
 	}
 
-	public @NonNull NavigationAssignment createNavigationAssignment(@NonNull OCLExpression asSlotExpression, @NonNull Property asProperty, @NonNull OCLExpression asValueExpression) {
+	public @NonNull NavigationAssignment createNavigationAssignment(@NonNull OCLExpression asSlotExpression, @NonNull Property asProperty, @NonNull OCLExpression asValueExpression, boolean isPartial) {
 		NavigationAssignment asNavigationAssignment;
 		if (asProperty.isIsImplicit()) {
 			OppositePropertyAssignment asPropertyAssignment = QVTcoreFactory.eINSTANCE.createOppositePropertyAssignment();
@@ -81,6 +81,8 @@
 		}
 		asNavigationAssignment.setSlotExpression(asSlotExpression);
 		asNavigationAssignment.setValue(asValueExpression);
+		asNavigationAssignment.setIsDefault(false);
+		asNavigationAssignment.setIsPartial(isPartial);
 		return asNavigationAssignment;
 	}
 
@@ -96,6 +98,8 @@
 		VariableAssignment asVariableAssignment = QVTcoreFactory.eINSTANCE.createVariableAssignment();
 		asVariableAssignment.setTargetVariable(asVariable);
 		asVariableAssignment.setValue(asValueExpression);
+		asVariableAssignment.setIsDefault(false);
+		asVariableAssignment.setIsPartial(false);
 		return asVariableAssignment;
 	}
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreToStringVisitor.java b/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreToStringVisitor.java
index 4fab8fe..4cb3d19 100644
--- a/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreToStringVisitor.java
+++ b/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreToStringVisitor.java
@@ -133,7 +133,7 @@
 		safeVisit(asNavigationAssignment.getSlotExpression());
 		append(".");
 		appendName(QVTcoreUtil.getTargetProperty(asNavigationAssignment));
-		append(" := ");
+		append(asNavigationAssignment.isIsPartial() ? " += " : " := ");
 		safeVisit(asNavigationAssignment.getValue());
 		return null;
 	}
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 3d4769c..eae6352 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
@@ -200,7 +200,7 @@
 		return newStatement;
 	}
 
-	public static @NonNull SetStatement createSetStatement(@NonNull VariableDeclaration asVariable, @NonNull Property asProperty, @NonNull OCLExpression asValueExpression, boolean isNotify) {
+	public static @NonNull SetStatement createSetStatement(@NonNull VariableDeclaration asVariable, @NonNull Property asProperty, @NonNull OCLExpression asValueExpression, boolean isPartial, boolean isNotify) {
 		SetStatement asSetAssignment = QVTimperativeFactory.eINSTANCE.createSetStatement();
 		if (asProperty.isIsImplicit()) {
 			asSetAssignment.setTargetProperty(asProperty.getOpposite());
@@ -212,7 +212,9 @@
 		}
 		asSetAssignment.setTargetVariable(asVariable);
 		asSetAssignment.setOwnedExpression(asValueExpression);
+		asSetAssignment.setIsPartial(isPartial);
 		asSetAssignment.setIsNotify(isNotify);
+		assert isPartial == ((asSetAssignment.getTargetProperty().getType() instanceof CollectionType) && !(asValueExpression.getType() instanceof CollectionType));	// FIXME inadequate for nested types but good for initial debugging
 		return asSetAssignment;
 	}
 
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 f0a125c..d36b0f7 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
@@ -20,6 +20,7 @@
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.ocl.pivot.OCLExpression;
+import org.eclipse.ocl.pivot.Property;
 import org.eclipse.ocl.pivot.Variable;
 import org.eclipse.ocl.pivot.utilities.ClassUtil;
 import org.eclipse.qvtd.pivot.qvtbase.Domain;
@@ -34,12 +35,23 @@
 import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain;
 import org.eclipse.qvtd.pivot.qvtrelation.RelationModel;
 import org.eclipse.qvtd.pivot.qvtrelation.RelationalTransformation;
+import org.eclipse.qvtd.pivot.qvttemplate.CollectionTemplateExp;
+import org.eclipse.qvtd.pivot.qvttemplate.ObjectTemplateExp;
+import org.eclipse.qvtd.pivot.qvttemplate.PropertyTemplateItem;
 import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
 
 import com.google.common.collect.Iterables;
 
 public class QVTrelationUtil extends QVTbaseUtil
 {
+
+	public static class Internal extends QVTbaseUtil.Internal
+	{
+		public static List<@NonNull OCLExpression> getOwnedArgumentsList(@NonNull RelationCallExp rInvocation) {
+			return ClassUtil.nullFree(rInvocation.getArgument());
+		}
+	}
+
 	public static final @NonNull String DUMMY_VARIABLE_NAME = "_";
 
 	public static @Nullable Relation getContainingRelation(@Nullable EObject eObject) {
@@ -55,7 +67,7 @@
 		return ClassUtil.nonNullState(rKey.getIdentifies());
 	}
 
-	public static @NonNull List<@NonNull OCLExpression> getOwnedArguments(@NonNull RelationCallExp rInvocation) {
+	public static @NonNull Iterable<@NonNull OCLExpression> getOwnedArguments(@NonNull RelationCallExp rInvocation) {
 		return ClassUtil.nullFree(rInvocation.getArgument());
 	}
 
@@ -67,6 +79,14 @@
 		return ClassUtil.nullFree(rTransformation.getOwnedKey());
 	}
 
+	public static @NonNull Iterable<@NonNull OCLExpression> getOwnedMembers(@NonNull CollectionTemplateExp rCollectionTemplateExp) {
+		return ClassUtil.nullFree(rCollectionTemplateExp.getMember());
+	}
+
+	public static @NonNull Iterable<@NonNull PropertyTemplateItem> getOwnedParts(@NonNull ObjectTemplateExp eObject) {
+		return ClassUtil.nullFree(eObject.getPart());
+	}
+
 	public static @NonNull Iterable<@NonNull DomainPattern> getOwnedPatterns(@NonNull RelationDomain rRelationDomain) {
 		return ClassUtil.nullFree(rRelationDomain.getPattern());
 	}
@@ -75,6 +95,18 @@
 		return Iterables.filter(ClassUtil.nullFree(rTransformation.getRule()), Relation.class);
 	}
 
+	public static @NonNull OCLExpression getOwnedValue(@NonNull PropertyTemplateItem rPropertyTemplateItem) {
+		return ClassUtil.nonNullState(rPropertyTemplateItem.getValue());
+	}
+
+	public static @NonNull Iterable<@NonNull Variable> getOwnedVariable(@NonNull Relation rRelation) {
+		return ClassUtil.nullFree(rRelation.getVariable());
+	}
+
+	public static @NonNull Property getReferredProperty(@NonNull PropertyTemplateItem rPropertyTemplateItem) {
+		return ClassUtil.nonNullState(rPropertyTemplateItem.getReferredProperty());
+	}
+
 	public static @NonNull Relation getReferredRelation(@NonNull RelationCallExp rInvocation) {
 		return ClassUtil.nonNullState(rInvocation.getReferredRelation());
 	}
diff --git a/plugins/org.eclipse.qvtd.xtext.qvtcore/src/org/eclipse/qvtd/xtext/qvtcore/as2cs/QVTcoreDeclarationVisitor.java b/plugins/org.eclipse.qvtd.xtext.qvtcore/src/org/eclipse/qvtd/xtext/qvtcore/as2cs/QVTcoreDeclarationVisitor.java
index 7d1604f..d8c7429 100644
--- a/plugins/org.eclipse.qvtd.xtext.qvtcore/src/org/eclipse/qvtd/xtext/qvtcore/as2cs/QVTcoreDeclarationVisitor.java
+++ b/plugins/org.eclipse.qvtd.xtext.qvtcore/src/org/eclipse/qvtd/xtext/qvtcore/as2cs/QVTcoreDeclarationVisitor.java
@@ -325,7 +325,7 @@
 	public ElementCS visitBottomPattern(@NonNull BottomPattern asBottomPattern) {
 		BottomPatternCS csBottomPattern = context.refreshElement(BottomPatternCS.class, QVTcoreCSPackage.Literals.BOTTOM_PATTERN_CS, asBottomPattern);
 		csBottomPattern.setPivot(asBottomPattern);
-		List<Element> asConstraints = new ArrayList<Element>(asBottomPattern.getAssignment());
+		List<Element> asConstraints = new ArrayList<>(asBottomPattern.getAssignment());
 		asConstraints.addAll(asBottomPattern.getPredicate());
 		context.refreshList(csBottomPattern.getOwnedConstraints(), context.visitDeclarations(PredicateOrAssignmentCS.class, asConstraints, null));
 		context.refreshList(csBottomPattern.getOwnedRealizedVariables(), context.visitDeclarations(RealizedVariableCS.class, asBottomPattern.getRealizedVariable(), null));
@@ -361,13 +361,13 @@
 
 		List<Mapping> asMappings = null;
 		List<Function> asQueries = null;
-		List<Transformation> asTransformations = new ArrayList<Transformation>();
+		List<Transformation> asTransformations = new ArrayList<>();
 		gatherTransformations(asTransformations, asModel.getOwnedPackages());
 		for (Transformation asTransformation : asTransformations) {
 			for (Rule asRule : asTransformation.getRule()) {
 				if (asRule instanceof Mapping) {
 					if (asMappings == null) {
-						asMappings = new ArrayList<Mapping>();
+						asMappings = new ArrayList<>();
 					}
 					asMappings.add((Mapping) asRule);
 				}
@@ -375,7 +375,7 @@
 			for (Operation asOperation : asTransformation.getOwnedOperations()) {
 				if (asOperation instanceof Function) {
 					if (asQueries == null) {
-						asQueries = new ArrayList<Function>();
+						asQueries = new ArrayList<>();
 					}
 					asQueries.add((Function) asOperation);
 				}
diff --git a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/pn2sc/PetriNet2StateChart.qvtr b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/pn2sc/PetriNet2StateChart.qvtr
index 34cea4d..af8e2ad 100644
--- a/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/pn2sc/PetriNet2StateChart.qvtr
+++ b/tests/org.eclipse.qvtd.xtext.qvtrelation.tests/src/org/eclipse/qvtd/xtext/qvtrelation/tests/pn2sc/PetriNet2StateChart.qvtr
@@ -68,22 +68,25 @@
 	        }
 	    } */
 
-		top relation Transition2HyperEdge {  -- no need to do both bidirectionals
-	        postps: OrderedSet(pnMM::Place);
-	        rnexts: OrderedSet(scMM::Basic);
+		top relation Transition2HyperEdge {
 			domain pn t : Transition {
-				name = transitionName : String{},
---				prep = preps:OrderedSet(Place){prep:Place{} ++ _},
-				postp = postps:OrderedSet(Place){postp:Place{} ++ _}
+				name = transitionName : String{}
 			};	   
 			enforce domain sc e : HyperEdge {
-				name = transitionName,
---				next = nexts:OrderedSet(State){next:State{} ++ _},
-				rnext = rnexts:OrderedSet(State){rnext:State{} ++ _}
+				name = transitionName
+			};
+		}
+
+		top relation Transition2HyperEdge_Content {  -- no need to do both bidirectionals
+			domain pn postp:Place {
+				pret = t:Transition{}
+			};	   
+			enforce domain sc rnext:State {
+				rnext = e:HyperEdge{}
 			};
 			when {
---				Place2Basic(prep, next);
 				Place2Basic(postp, rnext);
+				Transition2HyperEdge(t, e);
 			}
 		}