/*******************************************************************************
 * Copyright (c) 2016, 2017 Willink Transformations and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     E.D.Willink - initial API and implementation
 ******************************************************************************/
package org.eclipse.qvtd.compiler.internal.qvtr2qvtc;

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

import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
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.Parameter;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.VariableDeclaration;
import org.eclipse.ocl.pivot.VariableExp;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.TreeIterable;
import org.eclipse.qvtd.compiler.CompilerChainException;
import org.eclipse.qvtd.compiler.internal.qvtr2qvtc.analysis.RelationAnalysis;
import org.eclipse.qvtd.compiler.internal.qvtr2qvtc.analysis.TransformationAnalysis;
import org.eclipse.qvtd.compiler.internal.qvtr2qvtc.analysis.VariablesAnalysis;
import org.eclipse.qvtd.compiler.internal.qvtr2qvtc.trace.RelationalTransformation2TracePackage;
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.Assignment;
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.utilities.QVTcoreUtil;
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;

/**
 * VariablesAnalysis manages all the variables in use by a Relation and its corresponding Mapping.
 */
/*public*/ class Variables2Variables extends VariablesAnalysis
{
	//	public static void gatherBoundVariables(@NonNull Map<@NonNull Variable, @Nullable TemplateExp> boundVariables, @NonNull Iterable<@NonNull ? extends Element> asRoots) {
	//		for (Element asRoot : asRoots) {
	//			gatherBoundVariables(boundVariables, asRoot);
	//		}
	//	}
	/**
	 * Return a Map from each bound variable to the TemplateExp for which it is the TempateExp.getBindsTo().
	 */
	public static @NonNull Map<@NonNull Variable, @NonNull TemplateExp> gatherBoundVariables(@NonNull Element asRoot) {
		Map<@NonNull Variable, @NonNull TemplateExp> boundVariables = new HashMap<>();
		for (EObject eObject : new TreeIterable(asRoot, true)) {
			if (eObject instanceof TemplateExp) {
				Variable bindsTo = QVTrelationUtil.getBindsTo((TemplateExp)eObject);
				TemplateExp oldTemplateExp = boundVariables.put(bindsTo, (TemplateExp)eObject);
				assert oldTemplateExp == null;
			}
		}
		return boundVariables;
	}

	/**
	 * Return a Map from each member variable to the CollectionTemplateExp's for which it is a CollectionTempateExp.member.referredVariable.
	 */
	public static @Nullable Map<@NonNull Variable, @NonNull List<@NonNull CollectionTemplateExp>> gatherMemberVariables(@NonNull Element asRoot) {
		Map<@NonNull Variable, @NonNull List<@NonNull CollectionTemplateExp>> memberVariable2collectionTemplateExps = null;
		for (EObject eObject : new TreeIterable(asRoot, true)) {
			if (eObject instanceof CollectionTemplateExp) {
				CollectionTemplateExp collectionTemplateExp = (CollectionTemplateExp)eObject;
				for (@NonNull OCLExpression member : QVTrelationUtil.getOwnedMembers(collectionTemplateExp)) {
					if (member instanceof VariableExp) {
						Variable memberVariable = QVTrelationUtil.getReferredVariable((VariableExp)member);
						if (memberVariable2collectionTemplateExps == null) {
							memberVariable2collectionTemplateExps = new HashMap<>();
						}
						List<@NonNull CollectionTemplateExp> collectionTemplateExps = memberVariable2collectionTemplateExps.get(memberVariable);
						if (collectionTemplateExps == null) {
							collectionTemplateExps = new ArrayList<>();
							memberVariable2collectionTemplateExps.put(memberVariable, collectionTemplateExps);
						}
						if (!collectionTemplateExps.contains(collectionTemplateExp)) {
							collectionTemplateExps.add(collectionTemplateExp);
						}
					}
				}
			}
		}
		return memberVariable2collectionTemplateExps;
	}

	/**
	 * Return all variables referenced within the composition tree of each of asRoots.
	 */
	public static void gatherReferredVariables(@NonNull Set<@NonNull Variable> referredVariables, @NonNull Iterable<@NonNull ? extends Element> asRoots) {
		for (@NonNull Element asRoot : asRoots) {
			gatherReferredVariables(referredVariables, asRoot);
		}
	}
	public static void gatherReferredVariables(@NonNull Set<@NonNull Variable> referredVariables, @NonNull Element asRoot) {
		for (@NonNull EObject eObject : new TreeIterable(asRoot, true)) {
			if (eObject instanceof VariableExp) {
				VariableDeclaration referredVariable = ((VariableExp)eObject).getReferredVariable();
				if (referredVariable instanceof Variable) {
					referredVariables.add((Variable)referredVariable);
				}
			}
			else if (eObject instanceof Variable) {
				referredVariables.add((Variable)eObject);
			}
			else if (eObject instanceof TemplateExp) {
				Variable bindsTo = ((TemplateExp)eObject).getBindsTo();
				if (bindsTo != null) {
					referredVariables.add(bindsTo);
				}
				if (eObject instanceof CollectionTemplateExp) {				// Member variable are contained VariableExp's
					Variable rest = ((CollectionTemplateExp)eObject).getRest();
					if ((rest != null) && !rest.isIsImplicit()) {
						referredVariables.add(rest);
					}
				}
			}
		}
	}
	public static void gatherReferredVariablesWithTypedModels(@NonNull Map<@NonNull Variable, @Nullable TypedModel> referredVariable2typedModel, @NonNull Element asRoot) {
		for (EObject eObject : new TreeIterable(asRoot, true)) {
			if (eObject instanceof VariableExp) {
				VariableDeclaration referredVariable = ((VariableExp)eObject).getReferredVariable();
				if (referredVariable instanceof Variable) {
					EObject eContainer = eObject.eContainer();
					if (eContainer instanceof RelationCallExp) {
						RelationCallExp relationCallExp = (RelationCallExp)eContainer;
						int argument = relationCallExp.getArgument().indexOf(eObject);
						assert argument >= 0;
						Relation referredRelation = ClassUtil.nonNullState(relationCallExp.getReferredRelation());
						List<@NonNull Variable> rootVariables = QVTrelationUtil.getRootVariables(referredRelation);
						assert argument < rootVariables.size();
						Variable rootVariable = rootVariables.get(argument);
						RelationDomain relationDomain = QVTrelationUtil.getRootVariableDomain(rootVariable);
						gatherReferredVariablesWithTypedModelsAdd(referredVariable2typedModel, (Variable)referredVariable, relationDomain.getTypedModel());
					}
					else {
						gatherReferredVariablesWithTypedModelsAdd(referredVariable2typedModel, (Variable)referredVariable, null);
					}
				}
			}
			else if (eObject instanceof Variable) {
				gatherReferredVariablesWithTypedModelsAdd(referredVariable2typedModel, (Variable)eObject, null);
			}
			else if (eObject instanceof TemplateExp) {
				Variable bindsTo = ((TemplateExp)eObject).getBindsTo();
				if (bindsTo != null) {
					gatherReferredVariablesWithTypedModelsAdd(referredVariable2typedModel, bindsTo, null);
				}
				if (eObject instanceof CollectionTemplateExp) {
					Variable rest = ((CollectionTemplateExp)eObject).getRest();
					if ((rest != null) && !rest.isIsImplicit()) {
						gatherReferredVariablesWithTypedModelsAdd(referredVariable2typedModel, rest, null);
					}
				}
			}
		}
	}
	private static void gatherReferredVariablesWithTypedModelsAdd(@NonNull Map<@NonNull Variable, @Nullable TypedModel> referredVariable2typedModel,
			@NonNull Variable variable, @Nullable TypedModel rTypedModel) {
		if (rTypedModel != null) {
			TypedModel oldTypedModel = referredVariable2typedModel.put(variable, rTypedModel);
			assert (oldTypedModel == rTypedModel) || (oldTypedModel == null);
		}
		else if (!referredVariable2typedModel.containsKey(variable)) {
			referredVariable2typedModel.put(variable, null);
		}
	}

	/**
	 * Return a Map from each rest variable to the CollectionTemplateExp for which it is a CollectionTempateExp.rest.
	 */
	public static @Nullable Map<@NonNull Variable, @NonNull CollectionTemplateExp> gatherRestVariables(@NonNull Element asRoot) {
		Map<@NonNull Variable, @NonNull CollectionTemplateExp> restVariable2collectionTemplateExp = null;
		for (EObject eObject : new TreeIterable(asRoot, true)) {
			if (eObject instanceof CollectionTemplateExp) {
				CollectionTemplateExp collectionTemplateExp = (CollectionTemplateExp)eObject;
				Variable rest = collectionTemplateExp.getRest();
				if (rest != null) {
					if (restVariable2collectionTemplateExp == null) {
						restVariable2collectionTemplateExp = new HashMap<>();
					}
					CollectionTemplateExp oldCollectionTemplateExp = restVariable2collectionTemplateExp.put(rest, collectionTemplateExp);
					assert oldCollectionTemplateExp == null;
				}
			}
		}
		return restVariable2collectionTemplateExp;
	}

	// TODO bug 453863 // ?? this is suspect for more than 2 domains. // FIXME What is 'shared'? a) any two domains b) output/any-input c) all domains
	/**
	 * Return the variables that are used by more than one domain of the relation and so must be middle variables.
	 */
	public static @NonNull Set<@NonNull Variable> getMiddleDomainVariables(@NonNull Relation rRelation) {
		Set<@NonNull Variable> rSomeDomainVariables = new HashSet<>();
		Set<@NonNull Variable> rMiddleDomainVariables = new HashSet<>();
		for (@NonNull RelationDomain rDomain : QVTrelationUtil.getOwnedDomains(rRelation)) {
			Set<@NonNull Variable> rThisDomainVariables = new HashSet<>();
			Variables2Variables.gatherReferredVariables(rThisDomainVariables, rDomain);
			for (@NonNull Variable rVariable : rThisDomainVariables) {
				if (!rSomeDomainVariables.add(rVariable)) {
					rMiddleDomainVariables.add(rVariable);				// Accumulate second (and higher) usages
				}
			}
		}
		return rMiddleDomainVariables;
	}

	//	protected final @NonNull QVTr2QVTc qvtr2qvtc;
	protected final @NonNull RelationalTransformation2TracePackage relationalTransformation2tracePackage;
	protected final @NonNull CoreDomain cEnforcedDomain;
	protected final @NonNull Mapping cMapping;
	protected final @NonNull Transformation cTransformation;
	protected final @NonNull BottomPattern cMiddleBottomPattern;
	protected final @NonNull GuardPattern cMiddleGuardPattern;
	protected final @Nullable VariableDeclaration cMiddleVariable;		// tcv: The trace class variable (the middle variable identifying the middle object)
	protected final @NonNull Variable rThisVariable;
	protected final @NonNull Variable cThisVariable;

	/**
	 * Map from the each core variable name in use to an originating object, typically the VariableAnalysis of a relation variable,
	 * but the RelationCallExp of a where, the invoking relation of a call-from invocation, or this for the middle variable.
	 */
	private @NonNull Map<@NonNull String, @NonNull Variable2Variable> name2originator = new HashMap<>();

	/**
	 * The analysis of each relation variable.
	 */
	private final @NonNull Map<@NonNull VariableDeclaration, @NonNull Variable2Variable> rVariable2analysis = new HashMap<>();

	/**
	 * The analysis of each core variable.
	 */
	private final @NonNull Map<@NonNull VariableDeclaration, @NonNull Variable2Variable> cVariable2analysis = new HashMap<>();

	public Variables2Variables(@NonNull RelationAnalysis relationAnalysis, @NonNull RelationDomain rEnforcedDomain,
			@NonNull CoreDomain cEnforcedDomain, @Nullable Type traceClass, boolean isWhened, boolean isWhered) throws CompilerChainException {
		super(relationAnalysis, isWhened, isWhered);
		TransformationAnalysis transformationAnalysis = relationAnalysis.getTransformationAnalysis();
		QVTr2QVTc qvtr2qvtc = transformationAnalysis.getQVTr2QVTc();
		this.relationalTransformation2tracePackage = qvtr2qvtc.getRelationalTransformation2TracePackage(transformationAnalysis);
		this.cEnforcedDomain = cEnforcedDomain;
		this.cMapping = ClassUtil.nonNullState(QVTcoreUtil.getContainingMapping(cEnforcedDomain));
		this.cTransformation = ClassUtil.nonNullState(cMapping.getTransformation());
		this.cMiddleBottomPattern = ClassUtil.nonNullState(cMapping.getBottomPattern());
		this.cMiddleGuardPattern = ClassUtil.nonNullState(cMapping.getGuardPattern());
		//
		this.cMiddleVariable = (traceClass != null) ? relationAnalysis.traceIsRealized() ? addCoreRealizedVariable("trace", traceClass) : addCoreGuardVariable("trace", traceClass) : null;

		this.rThisVariable = QVTbaseUtil.getContextVariable(environmentFactory.getStandardLibrary(), QVTbaseUtil.getContainingTransformation(rEnforcedDomain));
		this.cThisVariable = QVTbaseUtil.getContextVariable(environmentFactory.getStandardLibrary(), cTransformation);
		ThisVariable2Variable thisVariableAnalysis = new ThisVariable2Variable(this, rThisVariable, cThisVariable);
		addVariableAnalysis(thisVariableAnalysis);
	}

	/**
	 * Add the predicate "cLeftExpression = cRightExpression" to cCorePattern.
	 * @throws CompilerChainException
	 */
	protected void addConditionPredicate(@NonNull CorePattern cCorePattern, @NonNull OCLExpression cLeftExpression, @NonNull OCLExpression cRightExpression) throws CompilerChainException {
		OperationCallExp eTerm = createOperationCallExp(cLeftExpression, "=", cRightExpression);
		addPredicate(cCorePattern, eTerm);
	}

	/**
	 * Create a core Variable with a name and type in the middle guard pattern. The variable has no corresponding relation variable.
	 * @throws CompilerChainException
	 */
	public @NonNull Variable addCoreGuardVariable(@NonNull String name, @NonNull Type type) throws CompilerChainException {
		CoreVariable2Variable analysis = new CoreVariable2Variable(this, name, type, null);
		Variable cVariable = analysis.getCoreVariable();
		addVariableAnalysis(analysis);
		cMiddleGuardPattern.getVariable().add(cVariable);
		return cVariable;
	}

	/**
	 * Create a core RealizedVariable with a name and type in the middle bottom pattern. The variable has no corresponding relation variable.
	 * @throws CompilerChainException
	 */
	public @NonNull RealizedVariable addCoreRealizedVariable(@NonNull String name, @NonNull Type type) throws CompilerChainException {
		CoreVariable2Variable analysis = new CoreVariable2Variable(this, name, type);
		RealizedVariable cVariable = analysis.getCoreRealizedVariable();
		addVariableAnalysis(analysis);
		cMiddleBottomPattern.getRealizedVariable().add(cVariable);
		return cVariable;
	}

	public @NonNull Variable addCoreVariable(@NonNull String name, @NonNull OCLExpression mMember) throws CompilerChainException {
		CoreVariable2Variable analysis = new CoreVariable2Variable(this, name, ClassUtil.nonNullState(mMember.getType()), mMember);
		Variable cVariable = analysis.getCoreVariable();
		addVariableAnalysis(analysis);
		cMiddleGuardPattern.getVariable().add(cVariable);
		return cVariable;
	}

	public void addNavigationAssignment(@NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression cExpression, @Nullable Boolean isPartial) throws CompilerChainException {
		getVariableAnalysis(rTargetVariable).addNavigationAssignment(targetProperty, cExpression, isPartial);
	}

	public void addNavigationPredicate(@NonNull CorePattern cCorePattern, @NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression cExpression) throws CompilerChainException {
		Variable cTargetVariable = getCoreVariable(rTargetVariable);
		NavigationCallExp cNavigationExp = createNavigationCallExp(createVariableExp(cTargetVariable), targetProperty);
		if (cExpression instanceof VariableExp) {
			addConditionPredicate(cCorePattern, cExpression, cNavigationExp);
		}
		else {
			addConditionPredicate(cCorePattern, cNavigationExp, cExpression);
		}
	}

	protected void addPredicate(@NonNull CorePattern cExpectedCorePattern, @NonNull OCLExpression cExpression) throws CompilerChainException {
		assert cMapping == QVTcoreUtil.getContainingMapping(cExpectedCorePattern);
		QVTr2QVTc.SYNTHESIS.println("  addPredicate " + cExpression);
		Set<@NonNull Variable> cReferredVariables = new HashSet<>();
		gatherReferredVariables(cReferredVariables, cExpression);
		boolean isGuard = true;
		boolean isMiddle = false;
		CorePattern cReferredPattern = null;
		for (@NonNull Variable cReferredVariable : cReferredVariables) {
			Variable2Variable analysis = cVariable2analysis.get(cReferredVariable);
			if (analysis == null) {
				isGuard = false;
				isMiddle = true;
				break;
			}
			else {
				CorePattern corePattern = analysis.getCorePattern();
				if (corePattern == null) {
				}
				else if (!(corePattern instanceof GuardPattern)) {
					isGuard = false;
				}
				if (cReferredPattern == null) {
					cReferredPattern = corePattern;
				}
				else if (cReferredPattern != corePattern) {
					isMiddle = true;
				}
			}
		}
		if (isMiddle) {
			cReferredPattern = isGuard ? cMiddleGuardPattern : cMiddleBottomPattern;
		}
		else if (cReferredPattern != null) {
			cReferredPattern = isGuard ? cReferredPattern.getArea().getGuardPattern() : cReferredPattern.getArea().getBottomPattern();
		}
		//		assert cExpectedCorePattern == cReferredPattern;
		if (cReferredPattern != null) {
			Predicate cPredicate = createPredicate(cExpression);
			/*cExpectedCorePattern*/cReferredPattern.getPredicate().add(cPredicate);
		}
	}

	/**
	 * Add the assignment for rVariable to the middle BottomPattern. If isOptional, a missing trace property is ignored.
	 *
	 * Returns the core variant of the relation variable.
	 */
	public @NonNull Variable addTraceNavigationAssignment(@NonNull Variable rVariable, boolean isOptional) throws CompilerChainException {
		@SuppressWarnings("unused")
		boolean traceIsRealized = getRelationAnalysis().traceIsRealized();
		//		assert traceIsRealized;
		VariableDeclaration cMiddleRealizedVariable2 = getMiddleVariable();
		Variable cVariable = getCoreVariable(rVariable); //getCoreRealizedVariable(rTargetVariable);
		Property cTargetProperty = relationalTransformation2tracePackage.basicGetTraceProperty(QVTrelationUtil.getType(cMiddleRealizedVariable2), rVariable);
		if (!isOptional && (cTargetProperty == null)) {		// FIXME debugging
			cTargetProperty = relationalTransformation2tracePackage.basicGetTraceProperty(QVTrelationUtil.getType(cMiddleRealizedVariable2), rVariable);
		}
		assert isOptional || (cTargetProperty != null);
		if (cTargetProperty != null) {
			assert (!cTargetProperty.isIsMany() || (cVariable.getType() instanceof CollectionType));
			VariableExp cSlotVariableExp = createVariableExp(cMiddleRealizedVariable2);
			OCLExpression cExpression = createVariableExp(cVariable);
			NavigationAssignment cAssignment = createNavigationAssignment(cSlotVariableExp, cTargetProperty, cExpression, false);
			QVTr2QVTc.SYNTHESIS.println("  addPropertyAssignment " + cAssignment);
			assertNewAssignment(QVTcoreUtil.getOwnedAssignments(cMiddleBottomPattern), cAssignment);
			cMiddleBottomPattern.getAssignment().add(cAssignment);
		}
		return cVariable;
	}

	public @NonNull Variable addTraceNavigationAssignment(@NonNull Property cTargetProperty, @NonNull Variable cVariable) throws CompilerChainException {
		@SuppressWarnings("unused")
		boolean traceIsRealized = getRelationAnalysis().traceIsRealized();
		//		assert traceIsRealized;
		assert (!cTargetProperty.isIsMany() || (cVariable.getType() instanceof CollectionType));
		VariableDeclaration cMiddleRealizedVariable2 = getMiddleVariable();
		VariableExp cSlotVariableExp = createVariableExp(cMiddleRealizedVariable2);
		OCLExpression cExpression = createVariableExp(cVariable);
		NavigationAssignment cAssignment = createNavigationAssignment(cSlotVariableExp, cTargetProperty, cExpression, false);
		QVTr2QVTc.SYNTHESIS.println("  addPropertyAssignment " + cAssignment);
		assertNewAssignment(QVTcoreUtil.getOwnedAssignments(cMiddleBottomPattern), cAssignment);
		cMiddleBottomPattern.getAssignment().add(cAssignment);
		return cVariable;
	}

	/**
	 * Add a predicate for rVariable wrt its trace in the middle GuardPattern.
	 *
	 * Returns the core variant of the relation variable.
	 */
	public @NonNull Variable addTraceNavigationPredicate(@NonNull Variable rVariable) throws CompilerChainException {
		VariableDeclaration cMiddleRealizedVariable2 = getMiddleVariable();
		Variable cVariable = getCoreVariable(rVariable); //getCoreRealizedVariable(rTargetVariable);
		Property cTargetProperty = relationalTransformation2tracePackage.basicGetTraceProperty(QVTrelationUtil.getType(cMiddleRealizedVariable2), rVariable);
		assert cTargetProperty != null;
		assert (!cTargetProperty.isIsMany() || (cVariable.getType() instanceof CollectionType));
		VariableExp cSlotVariableExp = createVariableExp(cMiddleRealizedVariable2);
		OCLExpression cRightExp = createVariableExp(cVariable);
		NavigationCallExp cLeftExp = createNavigationCallExp(cSlotVariableExp, cTargetProperty);
		//			QVTr2QVTc.SYNTHESIS.println("  addPropertyAssignment " + cAssignment);
		addConditionPredicate(cMiddleGuardPattern, cLeftExp, cRightExp);
		return cVariable;
	}

	public void addVariableAnalysis(@NonNull Variable2Variable analysis) {
		Variable cVariable = analysis.getCoreVariable();
		cVariable2analysis.put(cVariable, analysis);
		VariableDeclaration rVariable = analysis.getRelationVariable();
		if (rVariable != null) {
			rVariable2analysis.put(rVariable, analysis);
		}
	}

	public void assertNewAssignment(@NonNull Iterable<@NonNull Assignment> oldAssignments, @NonNull NavigationAssignment newAssignment) {
		//		if ("tr.action := sm".equals(newAssignment.toString())) {
		//			newAssignment.toString();
		//		}
		OCLExpression newSlotExpression = newAssignment.getSlotExpression();
		if (newSlotExpression instanceof VariableExp) {
			VariableDeclaration newVariable = ((VariableExp)newSlotExpression).getReferredVariable();
			Property targetProperty = QVTcoreUtil.getTargetProperty(newAssignment);
			for (@NonNull Assignment oldAssignment : oldAssignments) {
				if (oldAssignment instanceof NavigationAssignment) {
					if (QVTcoreUtil.getTargetProperty((NavigationAssignment)oldAssignment) == targetProperty) {
						OCLExpression oldSlotExpression = ((NavigationAssignment)oldAssignment).getSlotExpression();
						if (oldSlotExpression instanceof VariableExp) {
							VariableDeclaration oldVariable = ((VariableExp)oldSlotExpression).getReferredVariable();
							assert oldVariable != newVariable : "Repeated assignment: \"" + oldAssignment + "\", \"" + newAssignment + "\"";
						}
					}
				}
			}
		}
	}

	protected @Nullable Variable2Variable basicGetVariableAnalysis(@NonNull Variable relationVariable) {
		return rVariable2analysis.get(relationVariable);
	}

	public void check() {
		for (@NonNull Variable2Variable analysis : rVariable2analysis.values()) {
			analysis.check();
		}
	}

	public @NonNull Iterable<@NonNull Variable2Variable> getAnalyses() {
		return rVariable2analysis.values();
	}

	public @NonNull CoreDomain getCoreDomain(@NonNull TypedModel rTypedModel) {
		TypedModel cTypedModel = relationAnalysis.getTransformationAnalysis().getQVTr2QVTc().getCoreTypedModel(rTypedModel);
		return QVTcoreUtil.getDomain(cMapping, cTypedModel);
	}

	public @NonNull Variable getCoreThisVariable() {
		return cThisVariable;
	}

	public @NonNull Variable getCoreVariable(@NonNull Variable rVariable) {			// doRVarToMVar
		return getVariableAnalysis(rVariable).getCoreVariable();
	}

	protected @NonNull Variable2Variable getCoreVariableAnalysis(@NonNull VariableDeclaration coreVariable) {
		return ClassUtil.nonNullState(cVariable2analysis.get(coreVariable));
	}

	public @NonNull BottomPattern getMiddleBottomPattern() {
		return cMiddleBottomPattern;
	}

	public @NonNull GuardPattern getMiddleGuardPattern() {
		return cMiddleGuardPattern;
	}

	public @NonNull VariableDeclaration getMiddleVariable() {
		return ClassUtil.nonNullState(cMiddleVariable);
	}

	public @NonNull RelationAnalysis getRelationAnalysis() {
		return relationAnalysis;
	}

	@Nullable OCLExpression getTemplateExp(@NonNull ObjectTemplateExp objectTemplateExp, @NonNull Parameter keyParameter) {
		String keyParameterName = keyParameter.getName();
		for (@NonNull PropertyTemplateItem propertyTemplateItem : ClassUtil.nullFree(objectTemplateExp.getPart())) {
			Property property = propertyTemplateItem.getReferredProperty();
			if (ClassUtil.safeEquals(property.getName(), keyParameterName)) {
				return propertyTemplateItem.getValue();
			}
		}
		EObject eContainer = objectTemplateExp.eContainer();
		if (eContainer instanceof PropertyTemplateItem) {
			PropertyTemplateItem containingPropertyTemplateItem = (PropertyTemplateItem)eContainer;
			Property property = containingPropertyTemplateItem.getReferredProperty();
			Property oppositeProperty = property != null ? property.getOpposite() : null;
			if ((oppositeProperty != null) && ClassUtil.safeEquals(oppositeProperty.getName(), keyParameterName)) {
				return containingPropertyTemplateItem.getObjContainer();
			}
		}
		return null;
	}

	public @NonNull String getUniqueVariableName(@NonNull String name, @NonNull Variable2Variable originator) {
		Object oldOriginator = name2originator.get(name);
		if (oldOriginator != null) {
			assert oldOriginator != originator;		// Lazy re-creation should not occur.
			for (int i = 0; true; i++) {
				String newName = name + "_" + i;
				if (!name2originator.containsKey(newName)) {
					name = newName;
					break;
				}
			}
		}
		name2originator.put(name, originator);
		return name;
	}

	protected @NonNull Variable2Variable getVariableAnalysis(@NonNull Variable relationVariable) {
		Variable2Variable analysis = rVariable2analysis.get(relationVariable);
		if (analysis == null) {
			assert QVTbaseUtil.basicGetContainingTransformation(relationVariable) instanceof RelationalTransformation;
			if (relationVariable instanceof IteratorVariable) {
				analysis = new IteratorVariable2Variable(this, (IteratorVariable)relationVariable);
			}
			else if (relationVariable instanceof LetVariable) {
				analysis = new LetVariable2Variable(this, (LetVariable)relationVariable);
			}
			else {
				analysis = new RelationVariable2Variable(this, relationVariable);
			}
			rVariable2analysis.put(relationVariable, analysis);
		}
		return analysis;
	}

	public boolean isAbstract() {
		return relationAnalysis.getRelation().isIsAbstract();
	}

	@Override
	public String toString() {
		StringBuilder s = new StringBuilder();
		List<@NonNull String> names = new ArrayList<>(name2originator.keySet());
		Collections.sort(names);
		for (@NonNull String name : names) {
			if (s.length() > 0) {
				s.append("\n");
			}
			s.append(name + " => " );
			Object originator = name2originator.get(name);
			if (originator != this) {
				s.append(originator);
			}
		}
		return s.toString();
	}
}
