/*******************************************************************************
 * Copyright (c) 2014, 2016 The University of York and Willink Transformations.
 * 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:
 *     Horacio Hoyos - initial API and implementation
 ******************************************************************************/
package org.eclipse.qvtd.compiler.internal.qvtr2qvtc;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CollectionLiteralExp;
import org.eclipse.ocl.pivot.CollectionLiteralPart;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.IteratorVariable;
import org.eclipse.ocl.pivot.LetVariable;
import org.eclipse.ocl.pivot.NavigationCallExp;
import org.eclipse.ocl.pivot.OCLExpression;
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.VariableExp;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.qvtd.compiler.CompilerChainException;
import org.eclipse.qvtd.pivot.qvtbase.Domain;
import org.eclipse.qvtd.pivot.qvtbase.Pattern;
import org.eclipse.qvtd.pivot.qvtbase.Predicate;
import org.eclipse.qvtd.pivot.qvtbase.Transformation;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil;
import org.eclipse.qvtd.pivot.qvtcore.BottomPattern;
import org.eclipse.qvtd.pivot.qvtcore.CoreDomain;
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;
import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreUtil;
import org.eclipse.qvtd.pivot.qvtrelation.DomainPattern;
import org.eclipse.qvtd.pivot.qvtrelation.Key;
import org.eclipse.qvtd.pivot.qvtrelation.Relation;
import org.eclipse.qvtd.pivot.qvtrelation.RelationCallExp;
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.qvttemplate.CollectionTemplateExp;
import org.eclipse.qvtd.pivot.qvttemplate.ObjectTemplateExp;
import org.eclipse.qvtd.pivot.qvttemplate.PropertyTemplateItem;
import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;

/**
 * AbstractQVTr2QVTcRelations defines the mapping from a Relation, with a nested AbstractEnforceableRelationDomain2CoreMapping
 * for each distinct enforcement of that relation and a further nested AbstractOtherRelationDomain2CoreDomain for each
 * other domain of the distinct enforcement.
 */
/*public*/ abstract class AbstractQVTr2QVTcRelations extends QVTcoreHelper
{
	/**
	 * The AbstractEnforceableRelationDomain2CoreMapping supervises the conversion of the enforced
	 * domains while enforcing a relation for a particular enforced domain.
	 */
	protected abstract class AbstractEnforceableRelationDomain2CoreMapping
	{
		/**
		 * The AbstractOtherRelationDomain2CoreDomain supervises the conversion of one of the not-enforced
		 * domains while enforcing a relation for a particular enforced domain.
		 */
		protected abstract class AbstractOtherRelationDomain2CoreDomain
		{
			// relations
			/**
			 *  The not-enforced domain being converted
			 */
			protected final @NonNull RelationDomain rOtherDomain;
			/**
			 * The name of the not-enforced domain: rOtherDomain.getName()
			 */
			protected final @NonNull String rOtherDomainName;
			/**
			 * The relations TypedModel of the not-enforced domain: rOtherDomain.getTypedModel()
			 */
			protected final @NonNull TypedModel rOtherTypedModel;
			/**
			 *  Mapping from each bound variable in the not-enforced relation domain to the TemplateExp that bindsTo it.
			 *  Excludes CollectionTemplateExp.member, CollectionTemplateExp.rest.
			 */
			protected final @NonNull Map<@NonNull Variable, @NonNull TemplateExp> rOtherBoundVariables;
			/**
			 *  Mapping from each member variable in the not-enforced relation domain to each CollectionTemplateExp that
			 *  has a  VariableExp member that refers to it.
			 */
			protected final @Nullable Map<@NonNull Variable, @NonNull List<@NonNull CollectionTemplateExp>> rOtherMemberVariables;
			/**
			 *  Mapping from each rest variable in the not-enforced relation domain to its CollectionTemplateExp.
			 */
			protected final @Nullable Map<@NonNull Variable, @NonNull CollectionTemplateExp> rOtherRestVariables;
			/**
			 *  All variables defined or referenced in this other domain
			 */
			protected final @NonNull Set<@NonNull Variable> rOtherReferredVariables;
			/**
			 *  The template expression variables (the root variables of this other domain pattern)
			 */
			protected final @NonNull List<@NonNull Variable> rOtherRootVariables;
			// core
			/**
			 * The corresponding core TypedModel of the not-enforced domain: cOtherDomain.getTypedModel()
			 */
			protected final @NonNull TypedModel cOtherTypedModel;
			/**
			 * The converted not-enforced domain.
			 */
			protected final @NonNull CoreDomain cOtherDomain;
			/**
			 * The guard pattern of the not-enforced domain: cOtherDomain.getOwnedGuardPattern().
			 */
			protected final @NonNull GuardPattern cOtherGuardPattern;
			/**
			 * The bottom pattern of the not-enforced domain: cOtherDomain.getOwnedBottomPattern().
			 */
			protected final @NonNull BottomPattern cOtherBottomPattern;

			public AbstractOtherRelationDomain2CoreDomain(@NonNull RelationDomain rOtherDomain) {
				this.rOtherDomain = rOtherDomain;
				this.rOtherDomainName = ClassUtil.nonNullState(rOtherDomain.getName());
				this.rOtherTypedModel = QVTrelationUtil.getTypedModel(rOtherDomain);
				this.rOtherBoundVariables = VariablesAnalysis.gatherBoundVariables(rOtherDomain);
				this.rOtherMemberVariables = VariablesAnalysis.gatherMemberVariables(rOtherDomain);
				this.rOtherRestVariables = VariablesAnalysis.gatherRestVariables(rOtherDomain);
				this.rOtherReferredVariables = new HashSet<>();
				VariablesAnalysis.gatherReferredVariables(rOtherReferredVariables, rOtherDomain);
				this.rOtherRootVariables = QVTrelationUtil.getRootVariables(rOtherDomain);
				//
				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());
				//
				for (@NonNull Variable rVariable : rOtherBoundVariables.keySet()) {
					variablesAnalysis.getVariableAnalysis(rVariable).setOtherBound(cOtherDomain);
				}
				for (@NonNull Variable rVariable : rOtherReferredVariables) {
					variablesAnalysis.getVariableAnalysis(rVariable).setOtherReferred(cOtherDomain);
				}
				for (@NonNull Variable rVariable : rOtherRootVariables) {
					variablesAnalysis.getVariableAnalysis(rVariable).setIsRoot();
				}
			}

			// new
			private void mapOtherCollectionTemplateExpression(@NonNull CollectionTemplateExp cte) throws CompilerChainException {
				Variable vcte = QVTrelationUtil.getBindsTo(cte);
				Variable mvcte = variablesAnalysis.getCoreVariable(vcte);
				/**
				 * Each CollectionTemplateExp member that is not a variable
				 * converts to a VariableAssignment of a new variable the member expression.
				 *
				 * ve1:T1{tp = ve2:Collection{a++b}}		=>   a := a;
				 */
				Map<@NonNull OCLExpression, @NonNull Variable> rMember2mVariable = new HashMap<>();
				List<@NonNull OCLExpression> rMembers = QVTrelationUtil.Internal.getOwnedMembersList(cte);
				for (@NonNull OCLExpression rMember : rMembers) {
					Variable mVariable;
					if (rMember instanceof TemplateExp) {
						TemplateExp rTemplateExp = (TemplateExp)rMember;
						mapOtherTemplateExpression(rTemplateExp);
						Variable rVariable = QVTrelationUtil.getBindsTo(rTemplateExp);
						mVariable = variablesAnalysis.getCoreVariable(rVariable);
					}
					else if (rMember instanceof VariableExp) {
						Variable rVariable = QVTrelationUtil.getReferredVariable((VariableExp)rMember);
						mVariable = variablesAnalysis.getCoreVariable(rVariable);
					}
					else {
						OCLExpression mMember = mapExpression(rMember);
						mVariable = variablesAnalysis.addCoreVariable("member", mMember);
					}
					rMember2mVariable.put(rMember, mVariable);
				}
				//				CollectionTemplateExp cte = (CollectionTemplateExp) ptv;
				//				Variable vcte = ClassUtil.nonNullState(cte.getBindsTo());
				//				Variable mvcte = doRVarToMVar(vcte);
				//				PropertyCallExp pce =  createPropertyCallExp(ve1, tp);
				//				VariableAssignment a = createVariableAssignment(mvcte, pce);
				//				mb.getAssignment().add(a);


				CollectionType collectionType = QVTrelationUtil.getReferredCollectionType(cte);
				int size = rMembers.size();
				Variable rRest = cte.getRest();
				if (rRest == null) {
					/**
					 * 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};
					 */
					List<@NonNull CollectionLiteralPart> mParts = new ArrayList<>();
					for (@NonNull OCLExpression rMember : rMembers) {
						Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
						CollectionLiteralPart mItem = createCollectionItem(createVariableExp(mVariable));
						mParts.add(mItem);
					}
					CollectionLiteralExp cle = createCollectionLiteralExp(collectionType, mParts);
					variablesAnalysis.addConditionPredicate(cMiddleBottomPattern, createVariableExp(mvcte), cle);
				}
				/*				else if (collectionType.isOrdered()) {
					if (!rRest.isIsImplicit()) {
						/**
				 * The assignment for an ordered CollectionTemplateExp rest variable is a sub-collection assignment.
				 *
				 * ve1:T1{tp = ve2:Collection{a,b++c}}		=>   c := ve2->subCollection(3,ve2->size());
				 * /
						Variable mRest = variablesAnalysis.getCoreVariable(rRest);
						String opName = collectionType.isUnique() ? "subOrderedSet" : "subSequence";
						IntegerLiteralExp eStart = createIntegerLiteralExp(size);
						OCLExpression eFinish = createOperationCallExp(createVariableExp(mvcte), "size");
						OCLExpression eTail = createOperationCallExp(createVariableExp(mvcte), opName, eStart, eFinish);
						VariableAssignment aRest = createVariableAssignment(mRest, eTail);
						cMiddleBottomPattern.getAssignment().add(aRest);
					}
					/**
				 * The predicates for each ordered CollectionTemplateExp member variable is an element comparison.
				 *
				 * ve1:T1{tp = ve2:Collection{a,b++c}}		=>   a = ve2->at(1);
				 * /
					for (int i = 0; i < size; i++) {
						IntegerLiteralExp eIndex = createIntegerLiteralExp(i+1);
						OCLExpression vElement = createOperationCallExp(createVariableExp(mvcte), "at", eIndex);
						OCLExpression rMember = rMembers.get(i);
						Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
						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);
						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);
					}
				}
			}

			// loop body of RDomainPatternToMDBottomPatternComposite
			private void mapOtherObjectTemplateExpression(@NonNull ObjectTemplateExp rTemplateExpression) throws CompilerChainException {
				Variable rTemplateVariable = QVTrelationUtil.getBindsTo(rTemplateExpression);
				for (@NonNull PropertyTemplateItem propertyTemplateItem : QVTrelationUtil.getOwnedParts(rTemplateExpression)) {
					Property partProperty = QVTrelationUtil.getReferredProperty(propertyTemplateItem);
					Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
					OCLExpression propertyTemplateValue = QVTrelationUtil.getOwnedValue(propertyTemplateItem);
					if (propertyTemplateValue instanceof VariableExp) {
						// body of RDomainPatternToMDBottomPatternSimpleSharedVarExpr and RDomainPatternToMDBottomPatternSimpleUnSharedVarExpr
						/**
						 * Each PropertyTemplateItem whose value is a simple VariableExp
						 * converts to a domain(unshared) / middle(shared) PropertyAssignment.
						 *
						 * ve1:T{tp = ve2}   =>   ve1.tp := ve2;
						 */
						Variable rVariable/*vpte*/ = QVTrelationUtil.getReferredVariable((VariableExp)propertyTemplateValue);
						Variable cVariable/*mvpte*/ = variablesAnalysis.getCoreVariable(rVariable);
						//				BottomPattern cBottomPattern = rSharedVariables.contains(rVariable) ? cMiddleBottomPattern : cEnforcedBottomPattern;
						variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, createVariableExp(cVariable));
					}
					else if (propertyTemplateValue instanceof CollectionTemplateExp) {
						/**
						 * Each PropertyTemplateItem whose value is a CollectionTemplateExp
						 * converts to a VariableAssignment and Predicates.
						 *
						 * ve1:T1{tp = ve2:Collection{a++b}}		=>   ve2 := ve1.tp;
						 */
						CollectionTemplateExp cte = (CollectionTemplateExp)propertyTemplateValue;
						Variable vcte = QVTrelationUtil.getBindsTo(cte);
						Variable mvcte = variablesAnalysis.getCoreVariable(vcte);
						NavigationCallExp pce =  createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
						VariableAssignment a = createVariableAssignment(mvcte, pce);
						cMiddleBottomPattern.getAssignment().add(a);
						mapOtherTemplateExpression(cte);
					}
					else if (propertyTemplateValue instanceof ObjectTemplateExp) {
						if (partProperty.isIsMany()) {
							/**
							 * Each PropertyTemplateItem whose value is an ObjectTemplateExp
							 * converts to a PropertyAssignment.
							 *
							 * ve1:T1{tp = ve2:T2{...}}   =>   ve1.tp := ve2;
							 */
							ObjectTemplateExp pte = (ObjectTemplateExp)propertyTemplateValue;
							Variable vpte = QVTrelationUtil.getBindsTo(pte);
							Variable mvpte = variablesAnalysis.getCoreVariable(vpte);
							NavigationCallExp cNavigationExp = createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
							OperationCallExp eTerm = createOperationCallExp(cNavigationExp, "includes", createVariableExp(mvpte));
							variablesAnalysis.addPredicate(cOtherBottomPattern, eTerm);
							mapOtherTemplateExpression(pte);
						}
						else {
							/**
							 * Each PropertyTemplateItem whose value is an ObjectTemplateExp
							 * converts to a PropertyAssignment.
							 *
							 * ve1:T1{tp = ve2:T2{...}}   =>   ve1.tp := ve2;
							 */
							ObjectTemplateExp pte = (ObjectTemplateExp)propertyTemplateValue;
							Variable vpte = QVTrelationUtil.getBindsTo(pte);
							Variable mvpte = variablesAnalysis.getCoreVariable(vpte);
							variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, createVariableExp(mvpte));
							mapOtherTemplateExpression(pte);
						}
					}
					else {
						// loop body of RDomainPatternToMDBottomPatternSimpleNonVarExpr
						/**
						 * Each PropertyTemplateItem whose value is not a TemplateExp and not a VariableExp
						 * converts to a PropertyAssignment.
						 *
						 * ve1:T{tp = me}   =>   ve1.tp := me;
						 */
						variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, mapExpression(propertyTemplateValue));
					}
				}
			}

			// RDomainPatternToMDBottomPattern
			protected void mapOtherTemplateExpression(@NonNull TemplateExp rTemplateExpression) throws CompilerChainException {
				if (rTemplateExpression instanceof ObjectTemplateExp) {
					mapOtherObjectTemplateExpression((ObjectTemplateExp)rTemplateExpression);
				}
				else if (rTemplateExpression instanceof CollectionTemplateExp) {
					mapOtherCollectionTemplateExpression((CollectionTemplateExp)rTemplateExpression);
				}
				OCLExpression rGuardPredicate = rTemplateExpression.getWhere();
				if (rGuardPredicate != null) {
					cMiddleBottomPattern.getPredicate().add(createPredicate(mapExpression(rGuardPredicate)));
				}
			}

			public void synthesize() throws CompilerChainException {
				List<@NonNull TemplateExp> rOtherTemplateExpressions = getRootTemplateExpressions(rOtherDomain);
				for (@NonNull TemplateExp rOtherTemplateExpression : rOtherTemplateExpressions) {
					mapOtherTemplateExpression(rOtherTemplateExpression);
				}
			}
		}

		/**
		 * An ExpressionCopier deep copies an OCLExpression tree, exploiting the forward traceability of context to
		 * update references and using sibling to distinguish multiple targets.
		 */
		@SuppressWarnings("serial")
		protected class ExpressionCopier extends EcoreUtil.Copier
		{	// FIXME enforce unique names on let-variables, iterators
			@Override
			public EObject get(Object oIn) {
				if (oIn instanceof Element) {
					List<@NonNull Element> oOuts = source2targets.get(oIn);
					if (oOuts != null) {
						assert oOuts.size() == 1;
						return oOuts.get(0);
					}
					oOuts = qvtr2qvtc.getGlobalTargets((Element) oIn);
					if (oOuts != null) {
						assert oOuts.size() == 1;
						return oOuts.get(0);
					}
				}
				return super.get(oIn);
			}

			@Override
			public EObject copy(EObject oIn) {
				try {
					if (oIn instanceof IteratorVariable) {
						return variablesAnalysis.getCoreVariable((IteratorVariable)oIn);
					}
					else if (oIn instanceof LetVariable) {
						return variablesAnalysis.getCoreVariable((LetVariable)oIn);
					}
				} catch (CompilerChainException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return super.copy(oIn);
			}
		}

		// Relations
		/**
		 *  rd: The relation domain to be enforced
		 */
		protected final @NonNull RelationDomain rEnforcedDomain;
		/**
		 *  The TypedModel of the enforced domain: rEnforcedDomain.getTypedModel()
		 */
		protected final @NonNull TypedModel rEnforcedTypedModel;
		/**
		 * The name of the enforced domain: rEnforcedDomain.getName()
		 */
		protected final @NonNull String rEnforcedDomainName;
		/**
		 *  Mapping from each bound variable in the enforced relation domain to the TemplateExp that bindsTo it.
		 *  Excludes CollectionTemplateExp.member, CollectionTemplateExp.rest.
		 */
		protected final @NonNull Map<@NonNull Variable, @NonNull TemplateExp> rEnforcedBoundVariables;
		/**
		 *  Mapping from each member variable in the enforced relation domain to each CollectionTemplateExp that
		 *  has a  VariableExp member that refers to it.
		 */
		protected final @Nullable Map<@NonNull Variable, @NonNull List<@NonNull CollectionTemplateExp>> rEnforcedMemberVariables;
		/**
		 *  Mapping from each rest variable in the enforced relation domain to its CollectionTemplateExp.
		 */
		protected final @Nullable Map<@NonNull Variable, @NonNull CollectionTemplateExp> rEnforcedRestVariables;
		/**
		 *  All variables defined or referenced in the enforced relation domain
		 */
		protected final @NonNull Set<@NonNull Variable> rEnforcedReferredVariables;
		/**
		 *  te: The template expressions defining the roots of the enforced domain pattern
		 */
		protected final @NonNull List<@NonNull/*Object*/TemplateExp> rEnforcedRootTemplateExpressions;
		/**
		 *  tev: The template expression root variables (the root variables of the enforced domain pattern)
		 */
		protected final @NonNull List<@NonNull Variable> rEnforcedRootVariables;
		/**
		 * The conversion for each other domains sharing the parent of this domain
		 */
		protected final @NonNull List<@NonNull AbstractOtherRelationDomain2CoreDomain> otherDomain2coreDomains;
		/**
		 *  All variables defined in other domains
		 */
		protected final @NonNull Set<@NonNull Variable> rAllOtherBoundVariables;
		/**
		 *  All variables defined or referenced in other domains
		 */
		protected final @NonNull Set<@NonNull Variable> rAllOtherReferredVariables;
		// Core
		/**
		 *  m: The resultant mapping
		 */
		protected final @NonNull Mapping cMapping;
		/**
		 *  mg: The resultant mapping guard pattern: cMapping.getOwnedGuardPattern()
		 */
		protected final @NonNull GuardPattern cMiddleGuardPattern;
		/**
		 *  mb : The resultant mapping bottom pattern: cMapping.getOwnedBottomPattern()
		 */
		protected final @NonNull BottomPattern cMiddleBottomPattern;
		/**
		 *  mdir: The resultant enforced typed model
		 */
		protected final @NonNull TypedModel cEnforcedTypedModel;
		/**
		 *  md: The resultant enforced domain
		 */
		protected final @NonNull CoreDomain cEnforcedDomain;
		/**
		 *  dg: The resultant enforced domain guard pattern
		 */
		protected final @NonNull GuardPattern cEnforcedGuardPattern;
		/**
		 *  db: The resultant enforced domain bottom pattern
		 */
		protected final @NonNull BottomPattern cEnforcedBottomPattern;
		/**
		 *  The analysis of each viariable in the relation.
		 */
		protected final @NonNull VariablesAnalysis variablesAnalysis;
		/**
		 * tcv: The trace class variable (the middle variable identifying the middle object)
		 */
		protected final @NonNull RealizedVariable cMiddleRealizedVariable;
		/**
		 * Mapping from each relation element to its corresponding core element(s).
		 */
		private final @NonNull Map<@NonNull Element, @NonNull List<@NonNull Element>> source2targets = new HashMap<>();
		/**
		 * Mapping from each core element to its corresponding relation element.
		 */
		private final @NonNull Map<@NonNull Element, @NonNull Element> target2source = new HashMap<>();

		public AbstractEnforceableRelationDomain2CoreMapping(@NonNull RelationDomain rEnforcedDomain, @NonNull String cMappingName) throws CompilerChainException {
			this.rEnforcedDomain = rEnforcedDomain;
			//
			this.rEnforcedBoundVariables = VariablesAnalysis.gatherBoundVariables(rEnforcedDomain);
			this.rEnforcedMemberVariables = VariablesAnalysis.gatherMemberVariables(rEnforcedDomain);
			this.rEnforcedRestVariables = VariablesAnalysis.gatherRestVariables(rEnforcedDomain);
			this.rEnforcedReferredVariables = new HashSet<>();
			VariablesAnalysis.gatherReferredVariables(rEnforcedReferredVariables, rEnforcedDomain);
			this.rEnforcedRootTemplateExpressions = getRootTemplateExpressions(rEnforcedDomain);
			this.rEnforcedRootVariables = QVTrelationUtil.getRootVariables(rEnforcedDomain);
			this.rEnforcedTypedModel = QVTrelationUtil.getTypedModel(rEnforcedDomain);
			this.rEnforcedDomainName = ClassUtil.nonNullState(rEnforcedDomain.getName());
			@NonNull Type traceClass = qvtr2qvtc.getTraceClass(rRelation);
			//
			this.cEnforcedTypedModel = getCoreTypedModel(rEnforcedTypedModel);
			this.cMapping = qvtr2qvtc.createMapping(rRelation, cMappingName);
			this.cMiddleGuardPattern = ClassUtil.nonNullState(cMapping.getGuardPattern());
			this.cMiddleBottomPattern = ClassUtil.nonNullState(cMapping.getBottomPattern());
			this.cEnforcedDomain = createCoreDomain(cEnforcedTypedModel, true);
			this.cEnforcedGuardPattern = ClassUtil.nonNullState(cEnforcedDomain.getGuardPattern());
			this.cEnforcedBottomPattern = ClassUtil.nonNullState(cEnforcedDomain.getBottomPattern());
			//
			this.variablesAnalysis = createVariablesAnalysis(rEnforcedDomain, traceClass);
			this.cMiddleRealizedVariable = variablesAnalysis.getMiddleRealizedVariable();
			//			putTrace(cMiddleRealizedVariable, cMiddleBottomPattern);
			//
			this.otherDomain2coreDomains = new ArrayList<>();
			this.rAllOtherBoundVariables = new HashSet<>();
			for (@NonNull Domain rDomain : ClassUtil.nullFree(rEnforcedDomain.getRule().getDomain())) {
				if ((rDomain != rEnforcedDomain) && (rDomain instanceof RelationDomain)) {
					RelationDomain rRelationDomain = (RelationDomain)rDomain;
					otherDomain2coreDomains.add(createOtherDomain2CoreDomain(rRelationDomain));
				}
			}
			Set<@NonNull Variable> rUnsharedEnforcedDomainVariables = new HashSet<>(rEnforcedReferredVariables);
			rUnsharedEnforcedDomainVariables.removeAll(rSharedVariables);
			this.rAllOtherReferredVariables = new HashSet<>(rAllVariables);
			rAllOtherReferredVariables.removeAll(rUnsharedEnforcedDomainVariables);
			//
			for (Map.Entry<@NonNull Variable, @Nullable TypedModel> entry : rWhenVariable2rTypedModel.entrySet()) {
				TypedModel rWhenTypedModel = entry.getValue();
				if (rWhenTypedModel != null) {
					variablesAnalysis.getVariableAnalysis(entry.getKey()).setWhen(getCoreDomain(rWhenTypedModel));
				}
			}
			for (Map.Entry<@NonNull Variable, @Nullable TypedModel> entry : rWhereVariable2rTypedModel.entrySet()) {
				TypedModel rWhereTypedModel = entry.getValue();
				if (rWhereTypedModel != null) {
					variablesAnalysis.getVariableAnalysis(entry.getKey()).setWhere(getCoreDomain(rWhereTypedModel));
				}
			}
			for (@NonNull Variable rVariable : rEnforcedBoundVariables.keySet()) {
				Key rKey = qvtr2qvtc.getKeyForType(QVTrelationUtil.getType(rVariable));
				variablesAnalysis.getVariableAnalysis(rVariable).setIsEnforcedBound(rEnforcedBoundVariables.get(rVariable), rEnforcedTypedModel, rKey);
			}
			for (@NonNull Variable rVariable : rEnforcedReferredVariables) {
				variablesAnalysis.getVariableAnalysis(rVariable).setIsEnforcedReferred();
			}
			for (@NonNull Variable rVariable : rEnforcedRootVariables) {
				variablesAnalysis.getVariableAnalysis(rVariable).setIsRoot();
			}
			//
			for (Map.Entry<@NonNull Variable, @Nullable TypedModel> entry : rWhenVariable2rTypedModel.entrySet()) {
				Variable rWhenVariable = entry.getKey();
				TypedModel rWhenTypedModel = entry.getValue();
				VariableAnalysis variableAnalysis = variablesAnalysis.getVariableAnalysis(rWhenVariable);
				if (rWhenTypedModel == null) {
					OCLExpression rWhenInit = rWhenVariable.getOwnedInit();
					if (rWhenInit != null) {
						Set<@NonNull Variable> rReferredVariables = new HashSet<>();
						VariablesAnalysis.gatherReferredVariables(rReferredVariables, rWhenInit);
						for (Variable rReferredVariable : rReferredVariables) {
							VariableAnalysis referredVariableAnalysis = variablesAnalysis.basicGetVariableAnalysis(rReferredVariable);
							if (referredVariableAnalysis != null) {
								CorePattern corePattern = referredVariableAnalysis.getCorePattern();
								if (corePattern != null) {
									variableAnalysis.setPredicate(ClassUtil.nonNullState(corePattern.getArea()));	// FIXME need QVTrDomainAnalayis
								}
								break;
							}
						}
					}
				}
			}
			//
			QVTr2QVTc.VARIABLES.println(" In " + cMapping + "\n\t\t" + variablesAnalysis.toString().replace("\n", "\n\t\t"));
			for (@NonNull VariableAnalysis analysis : variablesAnalysis.getAnalyses()) {
				Variable rVariable = analysis.getRelationVariable();
				if (rVariable != null) {
					Variable cVariable = analysis.getCoreVariable();
					putTrace(cVariable, rVariable);
				}
			}
			for (@NonNull VariableAnalysis analysis : variablesAnalysis.getAnalyses()) {
				Variable rVariable = analysis.getRelationVariable();
				if (rVariable != null) {
					OCLExpression rOwnedInit = rVariable.getOwnedInit();
					if (rOwnedInit != null) {
						Variable cVariable = analysis.getCoreVariable();
						cVariable.setOwnedInit(mapExpression(rOwnedInit));
						//					variablesAnalysis.addConditionPredicate(analysis.getCorePattern(), createVariableExp(cVariable), mapExpression(rOwnedInit));
					}
				}
			}
		}

		// Quad call of RDomainPatternExprToMappingXXXX
		private void addPropertyAssignmentToMiddleBottomPattern(@NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression rExpression) throws CompilerChainException {
			Variable cTargetVariable = null;
			OCLExpression cExpression = null;
			if (rExpression instanceof ObjectTemplateExp) {
				// body of RDomainPatternExprToMappingDomainTemplateVarAssignment
				Variable rBoundVariable = ClassUtil.nonNullState(((ObjectTemplateExp)rExpression).getBindsTo());
				if (!rSharedVariables.contains(rBoundVariable)) {
					Variable cBoundVariable = variablesAnalysis.getCoreVariable(rBoundVariable);  // FIXME whenVariable(cMiddleBottomPattern, rBoundVariable);
					cExpression = createVariableExp(cBoundVariable);
					cTargetVariable = variablesAnalysis.addTraceNavigationAssignment(rBoundVariable, false);
				}
			}
			else if (rExpression instanceof VariableExp) {
				cTargetVariable = variablesAnalysis.getCoreVariable(rTargetVariable);		// getCoreVariable should do and be uniform
				Variable rReferredVariable = ClassUtil.nonNullState((Variable) ((VariableExp)rExpression).getReferredVariable());
				Variable cReferredVariable = variablesAnalysis.getCoreVariable(rReferredVariable);
				if (rSharedVariables.contains(rReferredVariable) ) {
					// body of RDomainPatternExprToMappingBottomVarAssignment
				}
				else {
					// body of RDomainPatternExprToMappingDomainVarAssignment
					if (!cEnforcedBottomPattern.getRealizedVariable().contains(cTargetVariable)) {
						// FIXME variables should have been plotted earlier
						cEnforcedBottomPattern.getRealizedVariable().add((RealizedVariable)cTargetVariable);
					}
				}
				cExpression = createVariableExp(cReferredVariable);
			}
			else {
				// body of RDomainPatternExprToMappingDomainAssignment
				cTargetVariable = variablesAnalysis.getCoreVariable(rTargetVariable);
				cExpression = mapExpression(rExpression);
			}
			if ((cTargetVariable != null) && (cExpression != null)) {
				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;
		}

		protected abstract @NonNull AbstractOtherRelationDomain2CoreDomain createOtherDomain2CoreDomain(@NonNull RelationDomain rRelationDomain);

		protected abstract @NonNull VariablesAnalysis createVariablesAnalysis(@NonNull RelationDomain rEnforcedDomain, @NonNull Type traceClass) throws CompilerChainException;

		//		protected @NonNull CoreDomain getCoreDomain(@NonNull RelationDomain rDomain) {
		//			return getCoreDomain(QVTrelationUtil.getTypedModel(rDomain));
		//		}

		protected @NonNull CoreDomain getCoreDomain(@NonNull TypedModel rTypedModel) {
			TypedModel cTypedModel = getCoreTypedModel(rTypedModel);
			for (@NonNull Domain cDomain : ClassUtil.nullFree(cMapping.getDomain())) {	// FIXME provide a Map cache
				if (QVTcoreUtil.getTypedModel(cDomain) == cTypedModel) {
					return (CoreDomain) cDomain;
				}
			}
			throw new IllegalStateException();
		}

		public @NonNull Mapping getCoreMapping() {
			return cMapping;
		}

		protected @NonNull TypedModel getCoreTypedModel(@NonNull TypedModel rTypedModel) {
			String name = PivotUtil.getName(rTypedModel);
			Iterable<org.eclipse.ocl.pivot.@NonNull Package> usedPackages = QVTrelationUtil.getUsedPackages(rTypedModel);
			for (@NonNull TypedModel cTypedModel : QVTcoreUtil.getModelParameters(cTransformation)) {
				if (name.equals(cTypedModel.getName())) {
					assert cTypedModel.getUsedPackage().equals(usedPackages);
					return cTypedModel;
				}
			}
			return ClassUtil.nonNullState(null);
		}

		protected abstract @NonNull Set<@NonNull Variable> getEnforcedBottomDomainVariables();

		//		protected abstract @NonNull Set<@NonNull Variable> getEnforcedDomainGuardVariables(@NonNull Set<@NonNull Variable> rEnforcedBottomDomainVariables);

		protected @NonNull Set<@NonNull RelationDomain> getOtherRelationDomains() {
			Set<@NonNull RelationDomain> relationDomains = new HashSet<>();
			for (@NonNull Domain relationDomain : QVTrelationUtil.getOwnedDomains(rRelation)) {
				relationDomains.add((RelationDomain) relationDomain);
			}
			relationDomains.remove(rEnforcedDomain);
			return relationDomains;
		}

		protected @NonNull List<@NonNull TemplateExp> getRootTemplateExpressions(@NonNull RelationDomain rRelationDomain) {
			List<@NonNull TemplateExp> rTemplateExpressions = new ArrayList<>();
			for (@NonNull DomainPattern rDomainPattern : QVTrelationUtil.getOwnedPatterns(rRelationDomain)) {
				rTemplateExpressions.add(QVTrelationUtil.getOwnedTemplateExpression(rDomainPattern));
			}
			return rTemplateExpressions;
		}

		private boolean isVarBoundToSomeOtherTemplate(ObjectTemplateExp rootTe, /*Object*/TemplateExp skipTe, Variable v) {
			if (rootTe == skipTe) {
				return false;
			}
			if (rootTe.getBindsTo().equals(v)) {
				return true;
			} else {
				boolean exists = false;
				for (PropertyTemplateItem p : rootTe.getPart()) {
					if (p.getValue() instanceof ObjectTemplateExp) {
						exists |= isVarBoundToSomeOtherTemplate((ObjectTemplateExp) p.getValue(), skipTe, v);
					}
				}
				return exists;
			}
		}

		protected void mapEnforcedCollectionTemplateExpression(@NonNull CollectionTemplateExp rEnforcedCollectionTemplateExp, @Nullable Key key) throws CompilerChainException {
			//			Property partProperty = ClassUtil.nonNullState(propertyTemplateItem.getReferredProperty());
			//			Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
			@NonNull CollectionTemplateExp cte = rEnforcedCollectionTemplateExp;
			/**
			 * Each PropertyTemplateItem whose value is a CollectionTemplateExp
			 * converts to a VariableAssignment and Predicates.
			 *
			 * ve1:T1{tp = ve2:Collection{a++b}}		=>   ve2 := ve1.tp;
			 */
			Variable vcte = QVTrelationUtil.getBindsTo(cte);
			Variable mvcte = variablesAnalysis.getCoreVariable(vcte);
			/*			NavigationCallExp pce =  createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
			VariableAssignment a = createVariableAssignment(mvcte, pce);
			cMiddleBottomPattern.getAssignment().add(a);
			/**
			 * Each CollectionTemplateExp member that is not a variable
			 * converts to a VariableAssignment of a new variable the member expression.
			 *
			 * ve1:T1{tp = ve2:Collection{a++b}}		=>   a := a;
			 */
			Map<@NonNull OCLExpression, @NonNull Variable> rMember2mVariable = new HashMap<>();
			List<@NonNull OCLExpression> rMembers = QVTrelationUtil.Internal.getOwnedMembersList(cte);
			for (@NonNull OCLExpression rMember : rMembers) {
				Variable mVariable;
				if (rMember instanceof TemplateExp) {
					TemplateExp rTemplateExp = (TemplateExp)rMember;
					mapEnforcedTemplateExpression(rTemplateExp);
					Variable rVariable = QVTrelationUtil.getBindsTo(rTemplateExp);
					mVariable = variablesAnalysis.getCoreVariable(rVariable);
				}
				else if (rMember instanceof VariableExp) {
					Variable rVariable = QVTrelationUtil.getReferredVariable((VariableExp)rMember);
					mVariable = variablesAnalysis.getCoreVariable(rVariable);
				}
				else {
					OCLExpression mMember = mapExpression(rMember);
					mVariable = variablesAnalysis.addCoreVariable("member", mMember);
				}
				rMember2mVariable.put(rMember, mVariable);
			}
			//				CollectionTemplateExp cte = (CollectionTemplateExp) ptv;
			//				Variable vcte = ClassUtil.nonNullState(cte.getBindsTo());
			//				Variable mvcte = doRVarToMVar(vcte);
			//				PropertyCallExp pce =  createPropertyCallExp(ve1, tp);
			//				VariableAssignment a = createVariableAssignment(mvcte, pce);
			//				mb.getAssignment().add(a);

			CollectionType collectionType = QVTrelationUtil.getReferredCollectionType(cte);
			Variable rRest = cte.getRest();
			if (rRest == null) {
				/**
				 * 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};
				 */
				List<@NonNull CollectionLiteralPart> mParts = new ArrayList<>();
				for (@NonNull OCLExpression rMember : rMembers) {
					Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
					CollectionLiteralPart mItem = createCollectionItem(createVariableExp(mVariable));
					mParts.add(mItem);
				}
				CollectionLiteralExp cle = createCollectionLiteralExp(collectionType, mParts);
				variablesAnalysis.addConditionPredicate(cMiddleBottomPattern, createVariableExp(mvcte), cle);
			}
			/*				else if (collectionType.isOrdered()) {
				if (!rRest.isIsImplicit()) {
					/**
			 * The assignment for an ordered CollectionTemplateExp rest variable is a sub-collection assignment.
			 *
			 * ve1:T1{tp = ve2:Collection{a,b++c}}		=>   c := ve2->subCollection(3,ve2->size());
			 * /
					Variable mRest = variablesAnalysis.getCoreVariable(rRest);
					String opName = collectionType.isUnique() ? "subOrderedSet" : "subSequence";
					IntegerLiteralExp eStart = createIntegerLiteralExp(size);
					OCLExpression eFinish = createOperationCallExp(createVariableExp(mvcte), "size");
					OCLExpression eTail = createOperationCallExp(createVariableExp(mvcte), opName, eStart, eFinish);
					VariableAssignment aRest = createVariableAssignment(mRest, eTail);
					cMiddleBottomPattern.getAssignment().add(aRest);
				}
				/**
			 * The predicates for each ordered CollectionTemplateExp member variable is an element comparison.
			 *
			 * ve1:T1{tp = ve2:Collection{a,b++c}}		=>   a = ve2->at(1);
			 * /
				for (int i = 0; i < size; i++) {
					IntegerLiteralExp eIndex = createIntegerLiteralExp(i+1);
					OCLExpression vElement = createOperationCallExp(createVariableExp(mvcte), "at", eIndex);
					OCLExpression rMember = rMembers.get(i);
					Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
					variablesAnalysis.addConditionPredicate(cMiddleBottomPattern, createVariableExp(mVariable), vElement);
				}
			} */
			else if (rRest.isIsImplicit()) {
				PropertyTemplateItem rPropertyTemplateItem = (PropertyTemplateItem) cte.eContainer();
				assert rPropertyTemplateItem != null;
				ObjectTemplateExp rObjectTemplateExp = QVTrelationUtil.getOwningObjectTemplateExp(rPropertyTemplateItem);
				Variable vote = QVTrelationUtil.getBindsTo(rObjectTemplateExp);
				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);
				}
			}
			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)
		protected void mapEnforcedDomainPatterns() throws CompilerChainException {
			for (@NonNull TemplateExp rEnforcedRootTemplateExpression/*te*/ : rEnforcedRootTemplateExpressions) {
				mapEnforcedTemplateExpression(rEnforcedRootTemplateExpression);
			}
		}

		protected void mapEnforcedObjectTemplateExpression(@NonNull ObjectTemplateExp rEnforcedObjectTemplateExpression, @Nullable Key key) throws CompilerChainException {
			Variable rTemplateVariable/*v*/ = QVTrelationUtil.getBindsTo(rEnforcedObjectTemplateExpression);
			for (@NonNull PropertyTemplateItem pt : QVTrelationUtil.getOwnedParts(rEnforcedObjectTemplateExpression)) {
				Property partProperty = QVTrelationUtil.getReferredProperty(pt);
				OCLExpression rPartValue/*pte*/ = QVTrelationUtil.getOwnedValue(pt);
				if ((key != null) && key.getPart().contains(partProperty)) {
					//  body of RDomainToMDBottomForEnforcementOfIdentityProp
					addPropertyAssignmentToMiddleBottomPattern(rTemplateVariable, partProperty, rPartValue);
				}
				else if (rPartValue instanceof CollectionTemplateExp) {
					// body of RDomainToMDBottomForEnforcementOfNonIdentityPropObject
					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 = QVTrelationUtil.getBindsTo(cte);
					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), null);
					mapEnforcedTemplateExpression(ote);
					//					Property cTargetProperty2 = qvtr2qvtc.getProperty(cMiddleRealizedVariable.getType(), cTargetVariable);
					//					variablesAnalysis.addNavigationAssignment(rMiddleRealizedVariable, cTargetProperty2, createVariableExp(cTargetVariable));
				}
				else if (rPartValue instanceof VariableExp) {
					// body of RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive
					//					Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
					//RDomainToMComposedMappingGuardrEnforcedDomain
					Variable rPartVariable = QVTrelationUtil.getReferredVariable((VariableExp)rPartValue);
					for (@NonNull TemplateExp rTemplateExpression : rEnforcedRootTemplateExpressions) {
						if (rTemplateExpression instanceof ObjectTemplateExp) {
							// check
							if (isVarBoundToSomeOtherTemplate((ObjectTemplateExp) rTemplateExpression, rEnforcedObjectTemplateExpression, rPartVariable)) {
								Variable cReferredVariable = variablesAnalysis.getCoreVariable(rPartVariable);
								Property cTargetProperty = qvtr2qvtc.getTraceProperty(QVTrelationUtil.getType(cReferredVariable), cReferredVariable);
								NavigationCallExp cPropertyCallExp = createNavigationCallExp(createVariableExp(cMiddleRealizedVariable), cTargetProperty);
								variablesAnalysis.addConditionPredicate(cMiddleGuardPattern, cPropertyCallExp, createVariableExp(cReferredVariable));
								cEnforcedGuardPattern.getBindsTo().add(cReferredVariable);
							}
						}
					}
					variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(rPartValue), null);
					if (!rAllOtherReferredVariables.contains(rPartVariable)) {						// Avoid duplicate assignment
						variablesAnalysis.addTraceNavigationAssignment(rPartVariable, false);
					}
				}
				else {
					// body of RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive
					//					Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
					//RDomainToMComposedMappingGuardrEnforcedDomain
					variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(rPartValue), null);
				}
			}
		}

		// RDomainToMDBottomForEnforcement
		private void mapEnforcedTemplateExpression(@NonNull TemplateExp rEnforcedTemplateExpression/*te*/) throws CompilerChainException {
			Variable rTemplateVariable/*v*/ = QVTrelationUtil.getBindsTo(rEnforcedTemplateExpression);
			Type rTemplateVariableType/*c*/ = QVTrelationUtil.getType(rTemplateVariable);
			Key key = qvtr2qvtc.getKeyForType(rTemplateVariableType);
			VariableAnalysis variableAnalysis = variablesAnalysis.getVariableAnalysis(rTemplateVariable);
			if (variableAnalysis.hasWhenDomain()) {
				key = null;
			}
			//			if (key == null){
			//				// Nothing to do
			//			}
			/*else*/ if (rEnforcedTemplateExpression instanceof ObjectTemplateExp) {
				mapEnforcedObjectTemplateExpression((ObjectTemplateExp)rEnforcedTemplateExpression, key);
			}
			else if (rEnforcedTemplateExpression instanceof CollectionTemplateExp) {
				mapEnforcedCollectionTemplateExpression((CollectionTemplateExp)rEnforcedTemplateExpression, key);
			}
			else {
				throw new CompilerChainException("Missing mapEnforcedTemplateExpression support " + rEnforcedTemplateExpression.eClass().getName());
			}
			// This call is wrong as the trace variable is realized, it can't be guarded.
			// This should only be done in a nested mapping or later mapping
			//doRDomainToMBottomPredicateForEnforcement(r, rd, te, predicatesWithoutVarBindings, unboundDomainVars, mb);
			/*
			 * Creates the assignment of the middle model to the L/R models
			 */
			// RDomainVarToMDBottomAssignmnetForEnforcement
			variablesAnalysis.addTraceNavigationAssignment(rTemplateVariable, false);
			OCLExpression rGuardPredicate = rEnforcedTemplateExpression.getWhere();
			if (rGuardPredicate != null) {
				cMiddleGuardPattern.getPredicate().add(createPredicate(mapExpression(rGuardPredicate)));
			}
		}

		// 15
		/*
		 * Creates a Predicate, who's ConditionExpression is an
		 * OperationCallExp:
		 * 		trace.<v.name> = v;
		 * TODO Suggest better name: RDomainPatternVariableToTracePredicate?
		 *
		private void doRDomainToMBottomPredicateForEnforcement(@NonNull Set<@NonNull Predicate> predicatesWithoutVarBindings, @NonNull Set<@NonNull Variable> unboundDomainVars) throws CompilerChainException
		{
			Set<@NonNull Variable> remainingUnBoundDomainVars = new HashSet<>(unboundDomainVars);
			remainingUnBoundDomainVars.removeAll(rEnforcedRootVariables);
			Set<@NonNull Predicate> predicatesWithVarBindings =
					selectPredicatesThatReferToVariables(predicatesWithoutVarBindings, remainingUnBoundDomainVars);
			mapPredicatesToPredicates(predicatesWithVarBindings);
				// assign
			for (@NonNull Variable v : rEnforcedRootVariables) {
				@NonNull Variable mv = getCoreVariable(v);
				Property pep = getProperty(cMiddleRealizedVariable.getType(), v);
				NavigationCallExp pe = createNavigationCallExp(createVariableExp(cMiddleRealizedVariable), pep);
				addConditionPredicate(cMiddleBottomPattern, pe, createVariableExp(mv));
			}
		} */

		/*
		 * The issue with this method is that all variables should have been
		 * transformed so all variable references can be correctly pointed.
		 * However, if we call it after all variable modifying relations it
		 * should work.
		 */
		// 25
		protected @NonNull OCLExpression mapExpression(@NonNull OCLExpression rExpression) {
			EcoreUtil.Copier copier = new ExpressionCopier();
			OCLExpression eOut = (OCLExpression) copier.copy(rExpression);
			copier.copyReferences();
			for (EObject eSource : copier.keySet()) {
				EObject eTarget = copier.get(eSource);
				if (eTarget != null) {
					assert eSource != null;
					putTrace((Element)eTarget, (Element)eSource);
				}
			}
			assert eOut != null;
			return eOut;
		}

		protected void mapIncomingInvocation() throws CompilerChainException {}

		// IROppositeDomainsToMappingForEnforcement
		protected void mapOtherDomainPatterns() throws CompilerChainException {
			for (@NonNull AbstractOtherRelationDomain2CoreDomain otherDomain2coreDomain : otherDomain2coreDomains) {
				otherDomain2coreDomain.synthesize();
			}
		}

		// ROppositeDomainVarsToTraceClassProps
		protected void mapOtherDomainVariables(@NonNull Set<@NonNull Variable> rDomainVariables) throws CompilerChainException {
			for (@NonNull Variable rDomainVariable : rDomainVariables) {
				//				VariableAnalysis analysis = getVariableAnalysis(rDomainVariable);
				//				TemplateExp rTemplateExp = analysis.getTemplateExp();
				//				if (dvte instanceof ObjectTemplateExp) {
				// tp=dv:T{...} => tcv.tp := dv;
				variablesAnalysis.addTraceNavigationAssignment(rDomainVariable, true);
				//				}
				/*				else if (dvte instanceof CollectionTemplateExp) {
					// tp=dv:T{...} => tcv.tp := dv;
					Variable mdv = doRVarToMVar(dv);
//					VariableExp ve1 = createVariableExp(tcv);
					VariableExp ve2 = createVariableExp(mdv);
					VariableAssignment a = createVariableAssignment(mdv, ve2);
					mb.getAssignment().add(a);
				} */
				/*				else if (dvte instanceof CollectionTemplateExp) {
					CollectionTemplateExp collectionTemplateExp = (CollectionTemplateExp)dvte;
				} */
			}
		}

		//		protected @NonNull Variable mapRealizedVariable(@NonNull Variable rVariable) {
		//			return whenRealizedVariable(cEnforcedBottomPattern, rVariable);
		//		}

		protected abstract @NonNull AbstractEnforceableRelationDomain2CoreMapping mapOverrides(@NonNull AbstractQVTr2QVTcRelations relation2Mappings);

		/**
		 * Transform a rule implemented by a black box into an enforcement operation
		 *
		 * @param rRelation the r
		 * @param rEnforcedDomain the rd
		 * @param cMiddleBottomPattern the mb
		 */
		// RRelImplToMBottomEnforcementOperation
		protected void mapRelationImplementation() {
			// TODO Code this when testing transformations with operational implementations.
		}

		//		protected void mapVariables(@NonNull Iterable<@NonNull Variable> rVariables, @NonNull CorePattern cPattern) {		// RVarSetToDGVarSet, RVarSetToMBVarSet
		//			for (@NonNull Variable rVariable : rVariables) {
		//				whenVariable(cPattern, rVariable);
		//			}
		//		}

		// RWhenPatternToMGuardPattern
		protected void mapWhenPattern() throws CompilerChainException {
			Pattern rWhenPattern = rRelation.getWhen();
			if (rWhenPattern != null) {
				Set<@NonNull Variable> rMiddleGuardDomainVariables = new HashSet<>(rWhenVariable2rTypedModel.keySet());
				rMiddleGuardDomainVariables.removeAll(rAllVariables);
				//
				for (@NonNull Predicate rWhenPredicate : QVTrelationUtil.getOwnedPredicates(rWhenPattern)) {
					OCLExpression rConditionExpression = QVTrelationUtil.getConditionExpression(rWhenPredicate);
					if (rConditionExpression instanceof RelationCallExp) {
						// body of RWhenRelCallToMGuard
						RelationCallExp rInvocation = (RelationCallExp)rConditionExpression;
						Relation rInvokedRelation = QVTrelationUtil.getReferredRelation(rInvocation);
						List<@NonNull OCLExpression> rArguments = QVTrelationUtil.Internal.getOwnedArgumentsList(rInvocation);
						List<@NonNull Variable> rParameters = qvtr2qvtc.getRootVariables(rInvokedRelation);
						int iSize = rArguments.size();
						assert iSize == rParameters.size();
						if (rInvokedRelation.isIsTopLevel()) {
							Type invokedTraceClass/*tc*/ = qvtr2qvtc.getTraceClass(rInvokedRelation);
							//
							String invokedName = "when_" + invokedTraceClass.getName()/* + vdId*/;
							Variable cCalledVariable/*vd*/ = variablesAnalysis.addCoreGuardVariable(invokedName, invokedTraceClass);	// FIXME
							for (int i = 0; i < iSize; i++) {
								VariableExp rArgument/*ve*/ = (VariableExp) rArguments.get(i);
								Variable rParameter/*dv*/ = rParameters.get(i);
								//RWhenRelCallArgToMGuardPredicate
								Variable rArgumentVariable/*v*/ = QVTbaseUtil.getReferredVariable(rArgument);
								Variable cArgumentVariable/*mv*/ = variablesAnalysis.getCoreVariable(rArgumentVariable);
								Property cCalledProperty/*pep*/ = qvtr2qvtc.getTraceProperty(QVTrelationUtil.getType(cCalledVariable), rParameter);
								NavigationCallExp cCalledValue/*pe*/ = createNavigationCallExp(createVariableExp(cCalledVariable), cCalledProperty);
								variablesAnalysis.addConditionPredicate(cMiddleGuardPattern, cCalledValue, createVariableExp(cArgumentVariable));
							}
						}
						else {
							Type invokedSignatureClass = qvtr2qvtc.getSignatureClass(rInvokedRelation);
							String invokedName = "when_" + invokedSignatureClass.getName()/* + vdId*/;
							Variable cInvocationVariable = variablesAnalysis.addCoreRealizedVariable(invokedName, invokedSignatureClass);	// FIXME
							Property cInvocationProperty = qvtr2qvtc.getTraceProperty(rInvocation);
							variablesAnalysis.addTraceNavigationAssignment(cInvocationProperty, cInvocationVariable);
							VariableAnalysis signatureVariableAnalysis = variablesAnalysis.getCoreVariableAnalysis(cInvocationVariable);
							for (int i = 0; i < iSize; i++) {
								VariableExp rArgument = (VariableExp) rArguments.get(i);
								Variable rParameter = rParameters.get(i);
								Variable cArgumentVariable = variablesAnalysis.getCoreVariable(QVTbaseUtil.getReferredVariable(rArgument));
								Property cCalledProperty = qvtr2qvtc.getSignatureProperty(QVTrelationUtil.getClass(cInvocationVariable), rParameter);
								signatureVariableAnalysis.addNavigationAssignment(cCalledProperty, createVariableExp(cArgumentVariable), false);
							}

						}
					}
					else {
						// body of RSimplePatternToMPattern
						OCLExpression cConditionExpression = mapExpression(rConditionExpression);
						variablesAnalysis.addPredicate(cMiddleGuardPattern, cConditionExpression);
						//						Predicate mpd = createPredicate(mapExpression(rConditionExpression));		// FIXME orphan
						//						addPredicate(composedMappingGuardPattern, cConditionExpression);
					}
				}
				//doUnsharedWhenVarsToMgVars(unsharedWhenVars, mg);
				//				mapVariables(rMiddleGuardDomainVariables, cMiddleGuardPattern);
			}
		}

		// RPredicateSetToMBPredicateSet
		protected void mapWhereBottomPredicates(@NonNull Iterable<@NonNull Predicate> rWherePredicates) throws CompilerChainException {
			for (@NonNull Predicate rWherePredicate : rWherePredicates) {
				OCLExpression rExpression = QVTrelationUtil.getConditionExpression(rWherePredicate);
				variablesAnalysis.addPredicate(cMiddleBottomPattern, mapExpression(rExpression));
			}
			/*
			// check
			if(predSeq.isEmpty()) {
				return;
			}
			Predicate rp = predSeq.remove(0);
			OCLExpression re = rp.getConditionExpression();
			assert re != null;
			// init
			@NonNull Predicate mp = createPredicate();
			// when
			@NonNull OCLExpression me = doRExpToMExp(re);
			doRPredicateSetToMBPredicateSet(predSeq, mb);
			// assign
			mp.setConditionExpression(me);
			mb.getPredicate().add(mp); */
		}

		// RDomainToMDBottomForEnforcement (first half)
		protected void mapWhereGuardPredicates(@NonNull Set<@NonNull Predicate> rWhereGuardPredicates,  @NonNull Set<@NonNull Variable> rEnforcedBottomDomainVariables) throws CompilerChainException
		{
			Set<@NonNull Variable> nonRootEnforcedBottomDomainVariables = new HashSet<>(rEnforcedBottomDomainVariables);
			nonRootEnforcedBottomDomainVariables.removeAll(rEnforcedRootVariables);
			//
			Set<@NonNull Predicate> wherePredicatesWithVarBindings = selectPredicatesThatReferToVariables(rWhereGuardPredicates, nonRootEnforcedBottomDomainVariables);
			Set<@NonNull Predicate> remainingWherePredicatesWithoutVarBindings = new HashSet<>(rWhereGuardPredicates);
			remainingWherePredicatesWithoutVarBindings.removeAll(wherePredicatesWithVarBindings);
			// FIXME How does this do anything?
		}

		protected void mapWherePattern() throws CompilerChainException {
			Pattern rWherePattern = rRelation.getWhere();
			if (rWherePattern != null) {
				//				Set<@NonNull Variable> rMiddleBottomDomainVariables = new HashSet<>(rWhenVariable2rTypedModel.keySet());
				//				rMiddleGuardDomainVariables.removeAll(rAllVariables);
				//
				for (@NonNull Predicate rWherePredicate : QVTrelationUtil.getOwnedPredicates(rWherePattern)) {
					OCLExpression rConditionExpression = QVTrelationUtil.getConditionExpression(rWherePredicate);
					if (rConditionExpression instanceof RelationCallExp) {
						RelationCallExp rInvocation = (RelationCallExp)rConditionExpression;
						Relation rInvokedRelation = QVTrelationUtil.getReferredRelation(rInvocation);
						Type invokedSignatureClass/*tc*/ = qvtr2qvtc.getSignatureClass(rInvokedRelation);
						List<@NonNull OCLExpression> rArguments = QVTrelationUtil.Internal.getOwnedArgumentsList(rInvocation);
						String invokedName = "where_" + invokedSignatureClass.getName()/* + vdId*/;
						Variable cInvocationVariable/*vd*/ = variablesAnalysis.addCoreRealizedVariable(invokedName, invokedSignatureClass);	// FIXME
						Property cInvocationProperty/*pep*/ = qvtr2qvtc.getTraceProperty(rInvocation);
						variablesAnalysis.addTraceNavigationAssignment(cInvocationProperty, cInvocationVariable);
						VariableAnalysis signatureVariableAnalysis = variablesAnalysis.getCoreVariableAnalysis(cInvocationVariable);
						List<@NonNull Variable> rParameters = qvtr2qvtc.getRootVariables(rInvokedRelation);
						int iSize = rArguments.size();
						assert iSize == rParameters.size();
						for (int i = 0; i < iSize; i++) {
							VariableExp rArgument = (VariableExp) rArguments.get(i);
							Variable rParameter = rParameters.get(i);
							Variable cArgumentVariable = variablesAnalysis.getCoreVariable(QVTbaseUtil.getReferredVariable(rArgument));
							Property cCalledProperty = qvtr2qvtc.getSignatureProperty(QVTrelationUtil.getClass(cInvocationVariable), rParameter);
							signatureVariableAnalysis.addNavigationAssignment(cCalledProperty, createVariableExp(cArgumentVariable), false);
						}
					}
					else {
						// body of RSimplePatternToMPattern
						//						OCLExpression cConditionExpression = mapExpression(rConditionExpression);
						//						variablesAnalysis.addPredicate(cMiddleGuardPattern, cConditionExpression);
						//						Predicate mpd = createPredicate(mapExpression(rConditionExpression));		// FIXME orphan
						//						addPredicate(composedMappingGuardPattern, cConditionExpression);
					}
				}
				//doUnsharedWhenVarsToMgVars(unsharedWhenVars, mg);
				//				mapVariables(rMiddleGuardDomainVariables, cMiddleGuardPattern);
			}
		}

		private void putTrace(@NonNull Element coreElement, @NonNull Element relationElement) {
			Element oldRelationElement = target2source.put(coreElement, relationElement);
			assert (oldRelationElement == relationElement) || (oldRelationElement == null);
			List<@NonNull Element> targets = source2targets.get(relationElement);
			if (targets == null) {
				targets = new ArrayList<>();
				source2targets.put(relationElement, targets);
			}
			targets.add(coreElement);
		}

		protected @NonNull Set<@NonNull Predicate> selectPredicatesThatReferToVariables(@NonNull Set<@NonNull Predicate> rPredicates, @NonNull Set<@NonNull Variable> rVariables) {
			Set<@NonNull Predicate> rPredicatesThatReferToVariables = new HashSet<>();
			for (@NonNull Predicate rPredicate : rPredicates) {
				//				OCLExpression conditionExpression = rPredicate.getConditionExpression();
				//				assert conditionExpression != null;
				Set<@NonNull Variable> rPredicateVariables = new HashSet<>();
				VariablesAnalysis.gatherReferredVariables(rPredicateVariables, rPredicate);
				rPredicateVariables.retainAll(rVariables);
				if (rPredicateVariables.isEmpty()) {		// FIXME smelly polarity
					rPredicatesThatReferToVariables.add(rPredicate);
				}
			}
			return rPredicatesThatReferToVariables;
		}

		/**
		 * Exploit the constructed/analyzed context to synthesize the Core constructs.
		 * @throws CompilerChainException
		 */
		protected void synthesize() throws CompilerChainException {
			//			Relation rOverride = QVTrelationUtil.basicGetOverridden(rRelation);
			//			if (rOverride != null) {
			//				AbstractQVTr2QVTcRelations overriddenRelation2Mappings = qvtr2qvtc.getRelation2Mappings(rOverride);
			//				AbstractEnforceableRelationDomain2CoreMapping overridenDomain2Mapping = mapOverrides(overriddenRelation2Mappings);
			//				cMapping.getSpecification().add(overridenDomain2Mapping.getCoreMapping());
			//			}
			Set<@NonNull Variable> rEnforcedBottomDomainVariables = getEnforcedBottomDomainVariables();
			//
			Set<@NonNull Predicate> rWhereBottomPredicates = selectPredicatesThatReferToVariables(rWherePredicates, rEnforcedBottomDomainVariables);
			Set<@NonNull Predicate> rWhereGuardPredicates = new HashSet<>(rWherePredicates);
			rWhereGuardPredicates.removeAll(rWhereBottomPredicates);
			//
			//			Set<@NonNull Variable> rEnforcedDomainGuardVariables = getEnforcedDomainGuardVariables(rEnforcedBottomDomainVariables);
			// Relation Calls
			mapWhereBottomPredicates(rWhereBottomPredicates);
			//			mapVariables(rEnforcedDomainGuardVariables, cEnforcedGuardPattern);
			//			mapVariables(rMiddleBottomDomainVariables, cMiddleBottomPattern);
			mapOtherDomainPatterns();
			// Invoked here so the variables are instantiated
			mapIncomingInvocation();			// Only for Invoked rather than Top relation
			mapOtherDomainVariables(rAllOtherReferredVariables);
			mapWhenPattern();
			mapWhereGuardPredicates(rWhereGuardPredicates, rEnforcedBottomDomainVariables);
			mapEnforcedDomainPatterns();
			mapWherePattern();
			if (rEnforcedMemberVariables != null) {	// FIXME mapOtherDomainVariables duploication/irregularity
				for (@NonNull Variable rMemberVariable : rEnforcedMemberVariables.keySet()) {
					variablesAnalysis.addTraceNavigationAssignment(rMemberVariable, true);
				}
			}
			mapRelationImplementation();
			//			Rule rOverrides = rRelation.getOverrides();
			//			if (rOverrides != null) {
			//				AbstractQVTr2QVTcRelations overridesRelation2mapping = qvtr2qvtc.getRelation2Mappings(rOverride)relation2relation2mapping.get(rOverrides);
			//				if (overridesRelation2mapping != null) {
			//					Mapping cMapping = relation2mapping.get
			//				}
			//			}
		}

		@Override
		public @NonNull String toString() {
			return rRelationName + "::" + rEnforcedDomainName + " => " + cMapping.getName() + "::" + cEnforcedDomain.getName();
		}
	}

	/**
	 * The overall QVTr2QVTc transformation
	 */
	protected @NonNull final QVTr2QVTc qvtr2qvtc;

	// Relations
	/**
	 * r: The relation being transformed
	 */
	protected final @NonNull Relation rRelation;

	/**
	 * The transformation containing the rRelation. i.e. rRelation.getOwningTransformation()
	 */
	protected final @NonNull RelationalTransformation rTransformation;

	/**
	 * The name of the rRelation. i.e. rRelation.getName()
	 */
	protected final @NonNull String rRelationName;

	/**
	 *  All variables that are defined or referenced in any way within the relation's containment tree.
	 *  Includes CollectionTemplateExp member/rest, Let/Iterator variables.
	 */
	protected final @NonNull Set<@NonNull Variable> rAllVariables;

	/**
	 * Mapping from each variable used as a when RelationCallExp argument to the typedModel of its corresponding argument.
	 */
	protected final @NonNull Map<@NonNull Variable, @Nullable TypedModel> rWhenVariable2rTypedModel;

	/**
	 * Mapping from each variable used as a where RelationCallExp argument to the typedModel of its corresponding argument.
	 */
	protected final @NonNull Map<@NonNull Variable, @Nullable TypedModel> rWhereVariable2rTypedModel;

	/**
	 * All when predicates that are not RelationCallExp
	 */
	protected final @NonNull Set<@NonNull Predicate> rWhenPredicates;

	/**
	 * All where predicates that are not RelationCallExp
	 */
	protected final @NonNull Set<@NonNull Predicate> rWherePredicates;

	/**
	 *  All variables defined/referenced by more than one domain. i.e. primitives
	 */
	protected final @NonNull Set<@NonNull Variable> rSharedVariables;

	/**
	 *  All relations, including this one, that this relation overrides.
	 */
	protected final @NonNull Set<@NonNull Relation> rAllOverrides = new HashSet<>();

	// Core
	/**
	 * mt: The transformation containing the result mapping
	 */
	protected final @NonNull Transformation cTransformation;

	protected AbstractQVTr2QVTcRelations(@NonNull QVTr2QVTc qvtr2qvtc, @NonNull Relation rRelation) {
		super(qvtr2qvtc.getEnvironmentFactory());
		this.qvtr2qvtc = qvtr2qvtc;
		this.rRelation = rRelation;
		this.rTransformation = QVTrelationUtil.getTransformation(rRelation);
		this.rRelationName = PivotUtil.getName(rRelation);
		//
		this.rWhenVariable2rTypedModel = new HashMap<>();
		this.rWhenPredicates = new HashSet<>();
		Pattern rWhenPattern = rRelation.getWhen();
		if (rWhenPattern != null) {
			VariablesAnalysis.gatherReferredVariablesWithTypedModels(rWhenVariable2rTypedModel, rWhenPattern);
			// FIXME	assert rWhenPattern.getBindsTo().equals(rWhenVariables);
			//			rWhenPattern.getBindsTo().addAll(rWhenVariables);
			for (@NonNull Predicate rWhenPredicate : QVTrelationUtil.getOwnedPredicates(rWhenPattern)) {
				if (!(rWhenPredicate.getConditionExpression() instanceof RelationCallExp)) {		// FIXME Eliminate this redundant distinction
					rWhenPredicates.add(rWhenPredicate);
				}
			}
		}
		//
		this.rWhereVariable2rTypedModel = new HashMap<>();
		this.rWherePredicates = new HashSet<>();
		Pattern rWherePattern = rRelation.getWhere();
		if (rWherePattern != null) {
			VariablesAnalysis.gatherReferredVariablesWithTypedModels(rWhereVariable2rTypedModel, rWherePattern);
			// FIXME	assert rWherePattern.getBindsTo().equals(rWhereVariables);
			//			rWherePattern.getBindsTo().addAll(rWhereVariables);
			for (@NonNull Predicate rWherePredicate : QVTrelationUtil.getOwnedPredicates(rWherePattern)) {
				if (!(rWherePredicate.getConditionExpression() instanceof RelationCallExp)) {
					rWherePredicates.add(rWherePredicate);
				}
			}
		}
		//
		this.rAllVariables = new HashSet<>();
		VariablesAnalysis.gatherReferredVariables(rAllVariables, QVTrelationUtil.getOwnedDomains(rRelation));
		if (rWhenPattern != null) {
			VariablesAnalysis.gatherReferredVariables(rAllVariables, rWhenPattern);
		}
		if (rWherePattern != null) {
			VariablesAnalysis.gatherReferredVariables(rAllVariables, rWherePattern);
		}
		//
		this.rSharedVariables = VariablesAnalysis.getMiddleDomainVariables(rRelation);
		//
		gatherOverrides(rRelation);
		//
		this.cTransformation = qvtr2qvtc.getCoreTransformation(rTransformation);
	}

	private void gatherOverrides(@NonNull Relation rOverriding) {
		if (rAllOverrides.add(rOverriding)) {
			Relation rOverridden = QVTrelationUtil.basicGetOverridden(rOverriding);
			if (rOverridden != null) {
				gatherOverrides(rOverridden);
			}
		}
		else {
			System.err.println("Override cycle for " + this + " at " + rOverriding);
		};
	}

	/**
	 * Create an AbstractEnforceableRelationDomain2CoreMapping for each Core Mapping that is to be synthesized.
	 */
	public abstract void analyze() throws CompilerChainException;

	public @NonNull Relation getRelation() {
		return rRelation;
	}

	public @NonNull AbstractEnforceableRelationDomain2CoreMapping getTopRelationDomain2CoreMapping(@NonNull TypedModel rEnforcedTypedModel) {
		throw new IllegalStateException();
	}

	protected @Nullable Iterable<@NonNull RelationCallExp> getWhenInvocations() {
		return null;
	}

	public @NonNull AbstractEnforceableRelationDomain2CoreMapping getWhenRelationDomain2CoreMapping(@NonNull TypedModel rEnforcedTypedModel) {
		throw new IllegalStateException();
	}

	protected @Nullable Iterable<@NonNull RelationCallExp> getWhereInvocations() {
		return null;
	}

	public @NonNull AbstractEnforceableRelationDomain2CoreMapping getWhereRelationDomain2CoreMapping(@NonNull TypedModel rEnforcedTypedModel) {
		throw new IllegalStateException();
	}

	public abstract void synthesize() throws CompilerChainException;

	@Override
	public @NonNull String toString() {
		return PivotUtil.getName(rTransformation) + "::" + rRelationName;
	}
}
