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

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.BooleanLiteralExp;
import org.eclipse.ocl.pivot.CallExp;
import org.eclipse.ocl.pivot.CollectionLiteralExp;
import org.eclipse.ocl.pivot.CollectionLiteralPart;
import org.eclipse.ocl.pivot.CollectionRange;
import org.eclipse.ocl.pivot.DataType;
import org.eclipse.ocl.pivot.EnumLiteralExp;
import org.eclipse.ocl.pivot.EnumerationLiteral;
import org.eclipse.ocl.pivot.IfExp;
import org.eclipse.ocl.pivot.MapLiteralExp;
import org.eclipse.ocl.pivot.MapLiteralPart;
import org.eclipse.ocl.pivot.NavigationCallExp;
import org.eclipse.ocl.pivot.NullLiteralExp;
import org.eclipse.ocl.pivot.NumericLiteralExp;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.Parameter;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.ShadowExp;
import org.eclipse.ocl.pivot.ShadowPart;
import org.eclipse.ocl.pivot.StringLiteralExp;
import org.eclipse.ocl.pivot.TupleLiteralExp;
import org.eclipse.ocl.pivot.TupleLiteralPart;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypeExp;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.VariableDeclaration;
import org.eclipse.ocl.pivot.internal.prettyprint.PrettyPrinter;
import org.eclipse.ocl.pivot.utilities.Nameable;
import org.eclipse.ocl.pivot.utilities.PivotConstants;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil;
import org.eclipse.qvtd.pivot.qvtcore.NavigationAssignment;
import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreUtil;
import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil;
import org.eclipse.qvtd.pivot.qvtschedule.BasicPartition;
import org.eclipse.qvtd.pivot.qvtschedule.BooleanLiteralNode;
import org.eclipse.qvtd.pivot.qvtschedule.CastEdge;
import org.eclipse.qvtd.pivot.qvtschedule.ClassDatum;
import org.eclipse.qvtd.pivot.qvtschedule.CollectionLiteralNode;
import org.eclipse.qvtd.pivot.qvtschedule.CollectionPartEdge;
import org.eclipse.qvtd.pivot.qvtschedule.CollectionRangeNode;
import org.eclipse.qvtd.pivot.qvtschedule.CyclicPartition;
import org.eclipse.qvtd.pivot.qvtschedule.DependencyEdge;
import org.eclipse.qvtd.pivot.qvtschedule.DependencyNode;
import org.eclipse.qvtd.pivot.qvtschedule.Edge;
import org.eclipse.qvtd.pivot.qvtschedule.EnumLiteralNode;
import org.eclipse.qvtd.pivot.qvtschedule.ErrorNode;
import org.eclipse.qvtd.pivot.qvtschedule.ExpressionEdge;
import org.eclipse.qvtd.pivot.qvtschedule.IfNode;
import org.eclipse.qvtd.pivot.qvtschedule.InputNode;
import org.eclipse.qvtd.pivot.qvtschedule.IteratedEdge;
import org.eclipse.qvtd.pivot.qvtschedule.IteratorNode;
import org.eclipse.qvtd.pivot.qvtschedule.KeyPartEdge;
import org.eclipse.qvtd.pivot.qvtschedule.KeyedValueNode;
import org.eclipse.qvtd.pivot.qvtschedule.LoadingPartition;
import org.eclipse.qvtd.pivot.qvtschedule.LoadingRegion;
import org.eclipse.qvtd.pivot.qvtschedule.MapLiteralNode;
import org.eclipse.qvtd.pivot.qvtschedule.MapPartEdge;
import org.eclipse.qvtd.pivot.qvtschedule.MapPartNode;
import org.eclipse.qvtd.pivot.qvtschedule.MappingRegion;
import org.eclipse.qvtd.pivot.qvtschedule.MergedPartition;
import org.eclipse.qvtd.pivot.qvtschedule.NavigableEdge;
import org.eclipse.qvtd.pivot.qvtschedule.NavigationEdge;
import org.eclipse.qvtd.pivot.qvtschedule.Node;
import org.eclipse.qvtd.pivot.qvtschedule.NonPartition;
import org.eclipse.qvtd.pivot.qvtschedule.NullLiteralNode;
import org.eclipse.qvtd.pivot.qvtschedule.NumericLiteralNode;
import org.eclipse.qvtd.pivot.qvtschedule.OperationCallNode;
import org.eclipse.qvtd.pivot.qvtschedule.OperationParameterEdge;
import org.eclipse.qvtd.pivot.qvtschedule.OperationSelfEdge;
import org.eclipse.qvtd.pivot.qvtschedule.PatternTypedNode;
import org.eclipse.qvtd.pivot.qvtschedule.PatternVariableNode;
import org.eclipse.qvtd.pivot.qvtschedule.PredicateEdge;
import org.eclipse.qvtd.pivot.qvtschedule.PropertyDatum;
import org.eclipse.qvtd.pivot.qvtschedule.QVTscheduleFactory;
import org.eclipse.qvtd.pivot.qvtschedule.Region;
import org.eclipse.qvtd.pivot.qvtschedule.Role;
import org.eclipse.qvtd.pivot.qvtschedule.RootPartition;
import org.eclipse.qvtd.pivot.qvtschedule.ShadowNode;
import org.eclipse.qvtd.pivot.qvtschedule.ShadowPartEdge;
import org.eclipse.qvtd.pivot.qvtschedule.SharedEdge;
import org.eclipse.qvtd.pivot.qvtschedule.StringLiteralNode;
import org.eclipse.qvtd.pivot.qvtschedule.SuccessEdge;
import org.eclipse.qvtd.pivot.qvtschedule.SuccessNode;
import org.eclipse.qvtd.pivot.qvtschedule.TupleLiteralNode;
import org.eclipse.qvtd.pivot.qvtschedule.TuplePartEdge;
import org.eclipse.qvtd.pivot.qvtschedule.TypeLiteralNode;
import org.eclipse.qvtd.pivot.qvtschedule.UnknownNode;
import org.eclipse.qvtd.pivot.qvtschedule.VariableNode;
import org.eclipse.qvtd.pivot.qvtschedule.utilities.DomainUsage;
import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
import org.eclipse.qvtd.runtime.utilities.QVTruntimeUtil;

import com.google.common.collect.Iterables;

/**
 * A RegionHelper provides stateless utility methods, mostly construction, for use within a Region
 * supervised by a ScheduleManager.
 */
public class RegionHelper<R extends Region> extends QVTscheduleUtil implements Nameable
{
	public static final @NonNull String EQUALS_NAME = "«equals»";
	public static final @NonNull String INCLUDES_NAME = "«includes»";
	public static final @NonNull String LOOP_ITERATOR_NAME = "«iterator»";

	protected final @NonNull ScheduleManager scheduleManager;
	protected final @NonNull R region;

	public RegionHelper(@NonNull ScheduleManager scheduleManager, @NonNull R region) {
		this.scheduleManager = scheduleManager;
		this.region = region;
	}

	public @NonNull BasicPartition createBasicPartition(@NonNull String name, @NonNull Iterable<@NonNull Node> headNodes) {
		BasicPartition basicPartition = QVTscheduleFactory.eINSTANCE.createBasicPartition();
		basicPartition.setName(name);
		//	basicPartition.setRegion(region);
		((MappingRegion)region).getMappingPartitions().add(basicPartition);
		Iterables.addAll(QVTscheduleUtil.Internal.getHeadNodesList(basicPartition), headNodes);
		return basicPartition;
	}

	public @NonNull BooleanLiteralNode createBooleanLiteralNode(boolean isTrue) {
		ClassDatum classDatum = scheduleManager.getBooleanClassDatum();
		BooleanLiteralNode booleanLiteralNode = QVTscheduleFactory.eINSTANCE.createBooleanLiteralNode();
		booleanLiteralNode.initialize(Role.CONSTANT, region, Boolean.toString(isTrue), classDatum);
		booleanLiteralNode.setMatched(true);
		booleanLiteralNode.setBooleanValue(isTrue);
		return booleanLiteralNode;
	}

	public @NonNull BooleanLiteralNode createBooleanLiteralNode(boolean isMatched, boolean booleanValue, @NonNull BooleanLiteralExp booleanLiteralExp) {
		Role nodeRole = getOperationNodePhase(region, booleanLiteralExp);
		BooleanLiteralNode booleanLiteralNode = QVTscheduleFactory.eINSTANCE.createBooleanLiteralNode();
		booleanLiteralNode.initialize(nodeRole, region, Boolean.toString(booleanValue), scheduleManager.getClassDatum(booleanLiteralExp));
		booleanLiteralNode.setMatched(isMatched);
		booleanLiteralNode.setBooleanValue(booleanValue);
		booleanLiteralNode.setOriginatingElement(booleanLiteralExp);
		return booleanLiteralNode;
	}

	public @NonNull CastEdge createCastEdge(@NonNull Node sourceNode, @NonNull ClassDatum classDatum, @NonNull Node targetNode) {
		Role phase = mergeToLessKnownPhase(getNodeRole(sourceNode), getNodeRole(targetNode));
		Role edgeRole = phase;
		CastEdge castEdge = QVTscheduleFactory.eINSTANCE.createCastEdge();
		castEdge.initialize(edgeRole, sourceNode, classDatum, targetNode);
		return castEdge;
	}

	public @NonNull CollectionLiteralNode createCollectionLiteralNode(boolean isMatched, @NonNull String name, @NonNull CollectionLiteralExp collectionLiteralExp, @NonNull Node @NonNull [] partNodes) {
		Role nodeRole = getOperationNodePhase(region, collectionLiteralExp, partNodes);
		CollectionLiteralNode node = QVTscheduleFactory.eINSTANCE.createCollectionLiteralNode();
		node.initialize(nodeRole, region, name, scheduleManager.getClassDatum(collectionLiteralExp));
		node.setMatched(isMatched);
		node.setOriginatingElement(collectionLiteralExp);
		return node;
	}

	public @NonNull Edge createCollectionPartEdge(@NonNull Node sourceNode, @NonNull CollectionLiteralPart collectionPart, @NonNull Node targetNode) {
		Role edgeRole = getNodeRole(sourceNode);
		CollectionPartEdge edge = QVTscheduleFactory.eINSTANCE.createCollectionPartEdge();
		edge.setReferredPart(collectionPart);
		String partName = collectionPart.getName();			// Always null
		String label = partName != null ? "«" + partName + "»" : "«part»";
		edge.initialize(edgeRole, sourceNode, label, targetNode);
		return edge;
	}

	public @NonNull CollectionRangeNode createCollectionRangeNode(boolean isMatched, @NonNull String name, @NonNull CollectionRange collectionRange, @NonNull Node @NonNull [] argNodes) {
		Role nodeRole = getOperationNodePhase(region, collectionRange, argNodes);
		CollectionRangeNode node = QVTscheduleFactory.eINSTANCE.createCollectionRangeNode();
		node.initialize(nodeRole, region, name, scheduleManager.getClassDatum(collectionRange));
		node.setMatched(isMatched);
		node.setOriginatingElement(collectionRange);
		return node;
	}

	/** FIXME make non-static */
	public static @NonNull CyclicPartition createCyclicPartition(@NonNull String name, @NonNull Object scheduleManager) {
		CyclicPartition cyclicPartition = QVTscheduleFactory.eINSTANCE.createCyclicPartition();
		cyclicPartition.setName(name);
		//		cyclicPartition.setRegion(region);
		//		Iterables.addAll(cyclicPartition.getHeadNodes(), headNodes);
		return cyclicPartition;
	}

	public @NonNull Node createDataTypeNode(@NonNull String name, @NonNull Node sourceNode, @NonNull NavigationCallExp navigationCallExp) {
		Property property = PivotUtil.getReferredProperty(navigationCallExp);
		boolean isMatched = sourceNode.isMatched() && isMatched(property);
		Role nodeRole = getPatternNodeRole(sourceNode, property);
		assert sourceNode.isClass() || (property.getOpposite() != null);	// FIXME review is this relevant?
		//		String name = property.getName();
		//		assert name != null;
		PatternTypedNode node = QVTscheduleFactory.eINSTANCE.createPatternTypedNode();
		node.initialize(nodeRole, region, name, scheduleManager.getClassDatum(navigationCallExp));
		node.setMatched(isMatched);
		node.setOriginatingElement(navigationCallExp);
		return node;
	}

	public @NonNull Node createDataTypeNode(@NonNull Node targetNode, @NonNull NavigationAssignment navigationAssignment) {
		Role nodeRole = getNodeRole(targetNode);
		Property property = QVTcoreUtil.getTargetProperty(navigationAssignment);
		//		PatternNodeRole nodeRole = PatternNodeRole.getDataTypeNodeRole(targetNode, property);
		//		assert sourceNode.isClass();	// FIXME review is this relevant?
		String name = property.getName();
		assert name != null;
		org.eclipse.ocl.pivot.Class type = (org.eclipse.ocl.pivot.Class)property.getType();
		assert type != null;
		TypedModel typedModel = getTypedModel(targetNode);
		ClassDatum classDatum = scheduleManager.getClassDatum(typedModel, type);
		PatternTypedNode node = QVTscheduleFactory.eINSTANCE.createPatternTypedNode();
		node.initialize(nodeRole, region, name, classDatum);
		node.setMatched(true);
		node.setOriginatingElement(property);
		return node;
	}

	public @NonNull Node createDataTypeNode(@NonNull Node sourceNode, @NonNull Property property) {
		Role nodeRole = getPatternNodeRole(sourceNode, property);
		return createPatternNode(nodeRole, sourceNode, property, sourceNode.isMatched() && isMatched(property));
	}

	public @NonNull Node createDependencyClassNode(@NonNull Node parentNode, @NonNull NavigationAssignment navigationAssignment) {
		assert parentNode.isClass();
		Property property = QVTcoreUtil.getTargetProperty(navigationAssignment);
		assert property != null;
		org.eclipse.ocl.pivot.Class type = (org.eclipse.ocl.pivot.Class)property.getType();
		assert type != null;
		TypedModel typedModel = getTypedModel(parentNode);
		ClassDatum classDatum = scheduleManager.getClassDatum(typedModel, type);
		//				DomainUsage domainUsage = parentNode.getClassDatumAnalysis().getDomainUsage();
		String name = property.getName();
		assert name != null;
		return createDependencyNode(name, classDatum);
	}

	public @NonNull Edge createDependencyEdge(@NonNull Node sourceNode, @NonNull String name, @NonNull Node targetNode) {
		Role edgeRole = getNodeRole(sourceNode);
		DependencyEdge edge = QVTscheduleFactory.eINSTANCE.createDependencyEdge();
		edge.initialize(edgeRole, sourceNode, name, targetNode);
		return edge;
	}

	public @NonNull Node createDependencyNode(@NonNull String name, @NonNull ClassDatum classDatum) {
		Role nodeRole = Role.PREDICATED;
		DependencyNode node = QVTscheduleFactory.eINSTANCE.createDependencyNode();
		node.initialize(nodeRole, region, name, classDatum);
		return node;
	}

	/**
	 * Create, install and return the edgeRole edge for source2targetProperty from sourceNode to targetNode. If
	 * source2targetProperty has an opposite, the opposite edge is also created and installed.
	 *
	public @NonNull NavigableEdge createEdge(@NonNull Role edgeRole,
			@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode) {
		CastEdge castEdge = QVTscheduleFactory.eINSTANCE.createCastEdge();
		castEdge.initialize(edgeRole, sourceNode, source2targetProperty.getName(), targetNode);
		castEdge.initializeProperty(source2targetProperty);
		return castEdge;
	} */

	public @NonNull EnumLiteralNode createEnumLiteralNode(boolean isMatched, @NonNull EnumerationLiteral enumValue, @NonNull EnumLiteralExp enumLiteralExp) {
		ClassDatum classDatum = scheduleManager.getClassDatum(enumLiteralExp);
		String typeName = PrettyPrinter.printType(enumValue);
		Role nodeRole = getOperationNodePhase(region, enumLiteralExp);
		EnumLiteralNode enumLiteralNode = QVTscheduleFactory.eINSTANCE.createEnumLiteralNode();
		enumLiteralNode.initialize(nodeRole, region, typeName, classDatum);
		enumLiteralNode.setMatched(isMatched);
		enumLiteralNode.setEnumValue(enumValue);
		enumLiteralNode.setOriginatingElement(enumLiteralExp);
		return enumLiteralNode;
	}

	//
	//	equals edges seem to be a legacy relic. They are used to equate two nodes that have been carelessly created as distinct. The difficulties
	//	of ensuring that downstream code accommodates the duality far outweight the difficulties of creating a single node in the first place.
	//
	//	This method is not used by any tests, but one anticipated usage arises if a variable has multiple initializers,
	//	and/or multiple predicates, in which case a hard initializer such as an operation call is preferred,
	//	and then other initializers are checked as predicates using equals edges.
	//
	public @NonNull Edge createEqualsEdge(@NonNull Node sourceNode, @NonNull Node targetNode) {
		if (!region.isOperationRegion()) {
			QVTruntimeUtil.errPrintln("Unexpected " + EQUALS_NAME + " edge in " + region + " from " + sourceNode + " to " + targetNode);
		}
		//		Role edgeRole = getNodeRole(sourceNode);
		//		ExpressionEdge edge = QVTscheduleFactory.eINSTANCE.createEqualsEdge();
		//		edge.initialize(edgeRole, sourceNode, QVTscheduleConstants.EQUALS_NAME, targetNode);
		//		return edge;
		return createPredicateEdge(sourceNode, EQUALS_NAME, targetNode);
	}

	public @NonNull Node createErrorNode(@NonNull String name, @NonNull ClassDatum classDatum) {
		Role nodeRole = Role.OTHER;
		ErrorNode node = QVTscheduleFactory.eINSTANCE.createErrorNode();
		node.initialize(nodeRole, region, name, classDatum);
		return node;
	}

	public @NonNull IfNode createIfNode(boolean isMatched, @NonNull String name, @NonNull IfExp ifExp, @NonNull Node @NonNull [] argNodes) {
		Role nodeRole = getOperationNodePhase(region, ifExp, argNodes);
		IfNode node = QVTscheduleFactory.eINSTANCE.createIfNode();
		node.initialize(nodeRole, region, name, scheduleManager.getClassDatum(ifExp));
		node.setMatched(isMatched);
		node.setOriginatingElement(ifExp);
		return node;
	}
	public @NonNull IfNode createIfNode2(boolean isMatched, @NonNull String name, @NonNull ClassDatum classDatum, @NonNull Node @NonNull [] argNodes) {
		Role nodeRole = getOperationNodePhase(region, null, argNodes);
		IfNode node = QVTscheduleFactory.eINSTANCE.createIfNode();
		node.initialize(nodeRole, region, name, classDatum);
		node.setMatched(isMatched);
		return node;
	}

	public @NonNull Node createInputNode(@NonNull Role nodeRole, @NonNull String name, @NonNull ClassDatum classDatum) {
		InputNode node = QVTscheduleFactory.eINSTANCE.createInputNode();
		node.initialize(nodeRole, region, name, classDatum);
		return node;
	}

	public @NonNull Edge createIteratedEdge(@NonNull Node sourceNode, @NonNull Node targetNode) {
		Role edgeRole = getNodeRole(sourceNode);
		IteratedEdge edge = QVTscheduleFactory.eINSTANCE.createIteratedEdge();
		edge.initialize(edgeRole, sourceNode, LOOP_ITERATOR_NAME, targetNode);
		return edge;
	}

	public @NonNull VariableNode createIteratorNode(@NonNull VariableDeclaration iterator, @NonNull Node sourceNode) {
		Role nodeRole = getNodeRole(sourceNode);
		IteratorNode node = QVTscheduleFactory.eINSTANCE.createIteratorNode();
		node.initialize(nodeRole, region, getName(iterator), scheduleManager.getClassDatum(iterator));
		node.initializeVariable(region, iterator);
		return node;
	}

	public @NonNull Edge createKeyPartEdge(@NonNull Node sourceNode, @NonNull PropertyDatum propertyDatum, @NonNull Node targetNode) {
		Role edgeRole = getNodeRole(sourceNode);
		KeyPartEdge edge = QVTscheduleFactory.eINSTANCE.createKeyPartEdge();
		edge.setReferredPart(propertyDatum);
		Property referredProperty = QVTscheduleUtil.getReferredProperty(propertyDatum);
		String name = "«" + QVTrelationUtil.getName(referredProperty) + "»";
		edge.initialize(edgeRole, sourceNode, name, targetNode);
		return edge;
	}

	public @NonNull Node createKeyedNode(boolean isMatched, @NonNull String name, @NonNull VariableDeclaration templateVariable) {
		ClassDatum classDatum = scheduleManager.getClassDatum(templateVariable);
		KeyedValueNode node = QVTscheduleFactory.eINSTANCE.createKeyedValueNode();
		node.setClassDatumValue(classDatum);
		node.initialize(Role.REALIZED, region, name, classDatum);
		region.addVariableNode(templateVariable, node);
		node.setMatched(isMatched);
		//		node.addTypedElement(templateVariable);
		return node;
	}

	public @NonNull VariableNode createLetVariableNode(@NonNull VariableDeclaration letVariable, @NonNull Node inNode) {
		Role nodeRole = getNodeRole(inNode);
		PatternVariableNode node = QVTscheduleFactory.eINSTANCE.createPatternVariableNode();
		node.initialize(nodeRole, region, getName(letVariable), scheduleManager.getClassDatum(letVariable));
		node.initializeVariable(region, letVariable);
		node.setMatched(inNode.isMatched());
		return node;
	}

	public @NonNull VariableNode createLoadedStepNode(@NonNull VariableDeclaration stepVariable) {
		Role nodeRole = Role.LOADED;
		PatternVariableNode node = QVTscheduleFactory.eINSTANCE.createPatternVariableNode();
		node.initialize(nodeRole, region, getName(stepVariable), scheduleManager.getClassDatum(stepVariable));
		node.initializeVariable(region, stepVariable);
		node.setMatched(true);
		return node;
	}

	public @NonNull LoadingPartition createLoadingPartition() {
		LoadingPartition loadingPartition = QVTscheduleFactory.eINSTANCE.createLoadingPartition();
		loadingPartition.setName(region.getName());
		//	loadingPartition.setRegion(region);
		((LoadingRegion)region).setLoadingPartition(loadingPartition);
		//		Iterables.addAll(loadingPartition.getHeadNodes(), headNodes);
		return loadingPartition;
	}

	public @NonNull MapLiteralNode createMapLiteralNode(boolean isMatched, @NonNull String name, @NonNull MapLiteralExp mapLiteralExp, @NonNull Node @NonNull [] partNodes) {
		Role nodeRole = getOperationNodePhase(region, mapLiteralExp, partNodes);
		MapLiteralNode node = QVTscheduleFactory.eINSTANCE.createMapLiteralNode();
		node.initialize(nodeRole, region, name, scheduleManager.getClassDatum(mapLiteralExp));
		node.setMatched(isMatched);
		node.setOriginatingElement(mapLiteralExp);
		return node;
	}

	public @NonNull Edge createMapPartEdge(@NonNull Node sourceNode, @NonNull MapLiteralPart mapPart, @NonNull Node targetNode) {
		Role edgeRole = getNodeRole(sourceNode);
		MapPartEdge edge = QVTscheduleFactory.eINSTANCE.createMapPartEdge();
		edge.setReferredPart(mapPart);
		String label = "«" + mapPart.toString() + "»";
		edge.initialize(edgeRole, sourceNode, label, targetNode);
		return edge;
	}

	public @NonNull Node createMapPartNode(boolean isMatched, @NonNull String name, @NonNull MapLiteralPart mapLiteralPart, @NonNull Node @NonNull [] argNodes) {
		TypedElement typedElement = QVTbaseUtil.getOwnedValue(mapLiteralPart);		// FIXME delete this
		Role nodeRole = getOperationNodePhase(region, typedElement, argNodes);
		MapPartNode node = QVTscheduleFactory.eINSTANCE.createMapPartNode();
		node.initialize(nodeRole, region, name, scheduleManager.getClassDatum(typedElement));
		node.setMatched(isMatched);
		node.setOriginatingElement(mapLiteralPart);
		return node;
	}

	public @NonNull MergedPartition createMergedPartition(@NonNull String name, @NonNull Iterable<@NonNull Node> headNodes) {
		MergedPartition mergedPartition = QVTscheduleFactory.eINSTANCE.createMergedPartition();
		mergedPartition.setName(name);
		//	basicPartition.setRegion(region);
		((MappingRegion)region).getMappingPartitions().add(mergedPartition);
		Iterables.addAll(QVTscheduleUtil.Internal.getHeadNodesList(mergedPartition), headNodes);
		return mergedPartition;
	}

	public @NonNull NavigableEdge createNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, boolean isPartial) {
		Role phase = mergeToLessKnownPhase(getNodeRole(sourceNode), getNodeRole(targetNode));
		return createNavigationEdge(phase, sourceNode, source2targetProperty, targetNode, isPartial);
	}

	public @NonNull NavigableEdge createNavigationEdge(@NonNull Role edgeRole, @NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, boolean isPartial) {
		NavigationEdge edge = QVTscheduleFactory.eINSTANCE.createNavigationEdge();
		edge.initialize(edgeRole, sourceNode, source2targetProperty.getName(), targetNode);
		edge.initializeProperty(source2targetProperty, isPartial);
		return edge;
	}

	public @NonNull NonPartition createNonPartition(@NonNull String name) {
		NonPartition nonPartition = QVTscheduleFactory.eINSTANCE.createNonPartition();
		nonPartition.setName(name);
		//	nonPartition.setRegion(region);
		((MappingRegion)region).getMappingPartitions().add(nonPartition);
		//		Iterables.addAll(nonPartition.getHeadNodes(), headNodes);
		return nonPartition;
	}

	public @NonNull Node createNullLiteralNode(boolean isMatched, @Nullable NullLiteralExp nullLiteralExp) {
		Role nodeRole = Role.CONSTANT;
		ClassDatum classDatum;
		if (nullLiteralExp != null) {
			classDatum = scheduleManager.getClassDatum(nullLiteralExp);
		}
		else {
			classDatum = scheduleManager.getOclVoidClassDatum();
		}
		NullLiteralNode node = QVTscheduleFactory.eINSTANCE.createNullLiteralNode();
		node.initialize(nodeRole, region, "«null»", classDatum);
		node.setMatched(isMatched);
		if (nullLiteralExp != null) {
			node.setOriginatingElement(nullLiteralExp);
		}
		return node;
	}

	public @NonNull NumericLiteralNode createNumericLiteralNode(boolean isMatched, @NonNull Number numericValue, @NonNull NumericLiteralExp numericLiteralExp) {
		Role nodeRole = getOperationNodePhase(region, numericLiteralExp);
		NumericLiteralNode node = QVTscheduleFactory.eINSTANCE.createNumericLiteralNode();
		node.initialize(nodeRole, region, numericValue.toString(), scheduleManager.getClassDatum(numericLiteralExp));
		node.setMatched(isMatched);
		node.setNumericValue(numericValue);
		node.setOriginatingElement(numericLiteralExp);
		return node;
	}

	public @NonNull VariableNode createOldNode(@NonNull VariableDeclaration variable) {
		DomainUsage domainUsage = scheduleManager.getDomainUsage(variable);
		boolean isEnforceable = domainUsage.isOutput() || domainUsage.isMiddle();
		Role phase = isEnforceable ? Role.PREDICATED : Role.LOADED;
		Role nodeRole = phase;
		PatternVariableNode node = QVTscheduleFactory.eINSTANCE.createPatternVariableNode();
		node.initialize(nodeRole, region, getName(variable), scheduleManager.getClassDatum(variable));
		node.initializeVariable(region, variable);
		node.setMatched(variable.isIsRequired());
		return node;
	}

	public @NonNull OperationCallNode createOperationCallNode(boolean isMatched, @Nullable String nameHint, @NonNull Operation operation, @NonNull TypedElement callExpOrCollectionTemplateExp, @NonNull Node ... argNodes) {
		String name = nameHint;
		if (name == null) {
			name = QVTbaseUtil.getName(operation);
		}
		Role nodeRole = getOperationNodePhase(region, callExpOrCollectionTemplateExp, argNodes);
		OperationCallNode node = QVTscheduleFactory.eINSTANCE.createOperationCallNode();
		node.initialize(nodeRole, region, name, scheduleManager.getClassDatum(callExpOrCollectionTemplateExp));
		node.setMatched(isMatched);
		node.setOriginatingElement(callExpOrCollectionTemplateExp);
		node.setReferredOperation(operation);
		return node;
	}
	public @NonNull OperationCallNode createOperationCallNode2(@NonNull Role nodeRole, boolean isMatched, @Nullable String nameHint, @NonNull Operation operation, @NonNull ClassDatum classDatum, @NonNull Node ... argNodes) {
		String name = nameHint;
		if (name == null) {
			name = QVTbaseUtil.getName(operation);
		}
		assert nodeRole != null;
		OperationCallNode node = QVTscheduleFactory.eINSTANCE.createOperationCallNode();
		node.initialize(nodeRole, region, name, classDatum);
		node.setMatched(isMatched);
		node.setReferredOperation(operation);
		return node;
	}

	public @NonNull Edge createOperationParameterEdge(@NonNull Node sourceNode, @NonNull Parameter parameter, int parameterIndex, @NonNull Node targetNode) {
		Role edgeRole = getNodeRole(sourceNode);
		String name;
		OperationParameterEdge edge = QVTscheduleFactory.eINSTANCE.createOperationParameterEdge();
		edge.setReferredParameter(parameter);
		if (parameterIndex >= 0) {
			//				assert parameter.isIsMany();
			edge.setParameterIndex(parameterIndex);
			name = "«" + parameter.getName() + "-" + parameterIndex + "»";
		}
		else {
			//				assert !parameter.isIsMany();
			name = "«" + parameter.getName() + "»";
		}
		//		edge.setReferredObject(typeOrParameter);		// FIXME redundant
		edge.initialize(edgeRole, sourceNode, name, targetNode);
		return edge;
	}

	public @NonNull Edge createOperationSelfEdge(@NonNull Node sourceNode, @NonNull Type type, @NonNull Node targetNode) {
		Role edgeRole = getNodeRole(sourceNode);
		OperationSelfEdge edge = QVTscheduleFactory.eINSTANCE.createOperationSelfEdge();
		edge.setReferredType(type);
		String name = "«" + PivotConstants.SELF_NAME + "»";
		//		edge.setReferredObject(typeOrParameter);		// FIXME redundant
		edge.initialize(edgeRole, sourceNode, name, targetNode);
		return edge;
	}

	public @NonNull Node createPatternNode(@NonNull Role nodeRole, @NonNull Node sourceNode, @NonNull Property source2targetProperty, boolean isMatched) {
		assert sourceNode.isClass();
		org.eclipse.ocl.pivot.Class type = (org.eclipse.ocl.pivot.Class)source2targetProperty.getType();
		assert type != null;
		Type elementType = PivotUtil.getElementalType(type);
		TypedModel typedModel = elementType instanceof DataType ? scheduleManager.getDomainUsageAnalysis().getPrimitiveTypeModel() : sourceNode.getClassDatum().getReferredTypedModel();
		assert typedModel != null;
		ClassDatum classDatum = scheduleManager.getClassDatum(typedModel, type);
		String name = source2targetProperty.getName();
		assert name != null;
		PatternTypedNode node = QVTscheduleFactory.eINSTANCE.createPatternTypedNode();
		node.initialize(nodeRole, region, name, classDatum);
		node.setMatched(isMatched);
		return node;
	}

	public @NonNull Edge createPredicateEdge(@NonNull Node sourceNode, @Nullable String name, @NonNull Node targetNode) {
		Role edgeRole = getNodeRole(sourceNode);
		PredicateEdge edge = QVTscheduleFactory.eINSTANCE.createPredicateEdge();
		edge.initialize(edgeRole, sourceNode, name, targetNode);
		return edge;
	}

	/*	public @NonNull NavigableEdge createPredicatedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, @Nullable Boolean isPartial) {
		Role edgeRole = Role.PREDICATED;
		NavigationEdge forwardEdge = QVTscheduleFactory.eINSTANCE.createNavigationEdge();
		forwardEdge.initialize(edgeRole, sourceNode, source2targetProperty.getName(), targetNode);
		boolean isPartial2 = QVTscheduleUtil.computeIsPartial(QVTscheduleUtil.getClassDatum(QVTscheduleUtil.getTargetNode(forwardEdge)), source2targetProperty, isPartial);
		forwardEdge.initializeProperty(source2targetProperty, isPartial2);
		return forwardEdge;
	} */

	public @NonNull Node createPredicatedNode(@NonNull String name, @NonNull ClassDatum classDatum, boolean isMatched) {
		PatternTypedNode node = QVTscheduleFactory.eINSTANCE.createPatternTypedNode();
		node.initialize(Role.PREDICATED, region, name, classDatum);
		node.setMatched(isMatched);
		return node;
	}

	public @NonNull Node createPredicatedStepNode(@NonNull Node typedNode, boolean isMatched) {
		String name = getName(typedNode);
		ClassDatum classDatum = getClassDatum(typedNode);
		return createPredicatedNode(name, classDatum, isMatched);
	}

	/**
	 * Create a predicated source2targetProperty success edge from sourceNode to a true/false BooleanValueNode.
	 */
	public @NonNull SuccessEdge createPredicatedSuccess(@NonNull Node sourceNode, @NonNull Property source2targetProperty, boolean isSuccess) {
		BooleanLiteralNode successNode = createBooleanLiteralNode(isSuccess);
		SuccessEdge edge = QVTscheduleFactory.eINSTANCE.createSuccessEdge();
		edge.initialize(Role.PREDICATED, sourceNode, source2targetProperty.getName(), successNode);
		edge.initializeProperty(source2targetProperty, false);
		return edge;
	}

	public @NonNull Node createRealizedDataTypeNode(@NonNull Node sourceNode, @NonNull Property source2targetProperty) {
		Role nodeRole = Role.REALIZED;
		return createPatternNode(nodeRole, sourceNode, source2targetProperty, sourceNode.isMatched());
	}

	public @NonNull Edge createRealizedIncludesEdge(@NonNull Node sourceNode, @NonNull Node targetNode) {
		Role edgeRole = Role.REALIZED;
		ExpressionEdge edge = QVTscheduleFactory.eINSTANCE.createIncludesEdge();
		edge.initialize(edgeRole, sourceNode, INCLUDES_NAME, targetNode);
		return edge;
	}

	public @NonNull NavigableEdge createRealizedNavigationEdge(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @NonNull Node targetNode, boolean isPartial) {
		Role edgeRole = Role.REALIZED;
		NavigationEdge forwardEdge = QVTscheduleFactory.eINSTANCE.createNavigationEdge();
		forwardEdge.initialize(edgeRole, sourceNode, source2targetProperty.getName(), targetNode);
		forwardEdge.initializeProperty(source2targetProperty, isPartial);
		return forwardEdge;
	}

	public @NonNull VariableNode createRealizedNode(@NonNull String name, @NonNull ClassDatum classDatum, boolean isMatched) {
		PatternVariableNode node = QVTscheduleFactory.eINSTANCE.createPatternVariableNode();
		node.initialize(Role.REALIZED, region, name, classDatum);
		node.setMatched(isMatched);
		return node;
	}

	public @NonNull VariableNode createRealizedStepNode(@NonNull VariableDeclaration stepVariable) {
		VariableNode node = createRealizedNode(getName(stepVariable), scheduleManager.getClassDatum(stepVariable), true);
		node.initializeVariable(region, stepVariable);
		return node;
	}

	/**
	 * Create a realized source2targetProperty success edge from sourceNode to a true/false BooleanValueNode if isSuccesss is  non-null,
	 * else to a SuccessNode.
	 */
	public @NonNull SuccessEdge createRealizedSuccess(@NonNull Node sourceNode, @NonNull Property source2targetProperty, @Nullable Boolean isSuccess) {
		ClassDatum classDatum = scheduleManager.getBooleanClassDatum();
		Node node;
		if (isSuccess != null) {
			node = createBooleanLiteralNode(isSuccess);
		}
		else {
			SuccessNode successNode = QVTscheduleFactory.eINSTANCE.createSuccessNode();
			successNode.initialize(Role.REALIZED, region, "«success»", classDatum);
			node = successNode;
		}
		SuccessEdge edge = QVTscheduleFactory.eINSTANCE.createSuccessEdge();
		edge.initialize(Role.REALIZED, sourceNode, source2targetProperty.getName(), node);
		edge.initializeProperty(source2targetProperty, false);
		return edge;
	}

	/** FIXME make non-static */
	public static @NonNull RootPartition createRootPartition(@NonNull String name, @NonNull Object scheduleManager) {
		RootPartition rootPartition = QVTscheduleFactory.eINSTANCE.createRootPartition();
		rootPartition.setName(name);
		//		rootPartition.setRegion(region);
		//		Iterables.addAll(rootPartition.getHeadNodes(), headNodes);
		return rootPartition;
	}

	/*	public @NonNull Edge createRecursionEdge(@NonNull Node sourceNode, @NonNull Node targetNode, boolean isPrimary) {
		Role edgeRole = Role.OTHER;
		RecursionEdge edge = QVTscheduleFactory.eINSTANCE.createRecursionEdge();
		edge.initialize(edgeRole, sourceNode, null, targetNode);
		edge.setPrimary(isPrimary);
		return edge;
	} */

	public @NonNull ShadowNode createShadowNode(boolean isMatched, @NonNull String name, @NonNull ShadowExp shadowExp, @NonNull Node @NonNull [] partNodes) {
		Role nodeRole = getOperationNodePhase(region, shadowExp, partNodes);
		ShadowNode node = QVTscheduleFactory.eINSTANCE.createShadowNode();
		node.initialize(nodeRole, region, name, scheduleManager.getClassDatum(shadowExp));
		node.setMatched(isMatched);
		node.setOriginatingElement(shadowExp);
		return node;
	}

	public @NonNull Edge createShadowPartEdge(@NonNull Node sourceNode, @NonNull ShadowPart shadowPart, @NonNull Node targetNode) {
		Role edgeRole = getNodeRole(sourceNode);
		ShadowPartEdge edge = QVTscheduleFactory.eINSTANCE.createShadowPartEdge();
		edge.setReferredPart(shadowPart);
		String label = "«" + shadowPart.getName() + "»";
		edge.initialize(edgeRole, sourceNode, label, targetNode);
		return edge;
	}

	public @NonNull Edge createSharedEdge(@NonNull Role edgeRole, @NonNull Node sourceNode, @NonNull Property target2sourceProperty, @NonNull Node targetNode) {
		SharedEdge edge = QVTscheduleFactory.eINSTANCE.createSharedEdge();
		edge.initialize(edgeRole, sourceNode, "«shared»", targetNode);
		edge.initializeProperty(target2sourceProperty);
		return edge;
	}

	public @NonNull Node createStepNode(@NonNull String name, @NonNull CallExp callExp, @NonNull Node sourceNode, boolean isMatched) {
		DomainUsage domainUsage = scheduleManager.getDomainUsage(callExp);
		boolean isMiddleOrOutput = domainUsage.isOutput() || domainUsage.isMiddle();
		boolean isDirty = false;
		if (callExp instanceof NavigationCallExp) {
			Property referredProperty = PivotUtil.getReferredProperty((NavigationCallExp)callExp);
			isDirty = scheduleManager.isDirty(referredProperty);
		}
		Role phase = /*sourceNode.isPredicated() ||*/ isMiddleOrOutput || isDirty ? Role.PREDICATED : Role.LOADED;
		Role stepNodeRole = phase;
		PatternTypedNode node = QVTscheduleFactory.eINSTANCE.createPatternTypedNode();
		node.initialize(stepNodeRole, region, name, scheduleManager.getClassDatum(callExp));
		node.setMatched(isMatched);
		node.setOriginatingElement(callExp);
		return node;
	}

	/*	public @NonNull Edge createRecursionEdge(@NonNull Node sourceNode, @NonNull Node targetNode, boolean isPrimary) {
		Role edgeRole = Role.OTHER;
		RecursionEdge edge = QVTscheduleFactory.eINSTANCE.createRecursionEdge();
		edge.initialize(edgeRole, sourceNode, null, targetNode);
		edge.setPrimary(isPrimary);
		return edge;
	} */

	public @NonNull StringLiteralNode createStringLiteralNode(boolean isMatched, @NonNull String stringValue, @NonNull StringLiteralExp stringLiteralExp) {
		Role nodeRole = getOperationNodePhase(region, stringLiteralExp);
		StringLiteralNode node = QVTscheduleFactory.eINSTANCE.createStringLiteralNode();
		node.initialize(nodeRole, region, stringValue, scheduleManager.getClassDatum(stringLiteralExp));
		node.setMatched(isMatched);
		node.setStringValue(stringValue);
		node.setOriginatingElement(stringLiteralExp);
		return node;
	}

	public @NonNull TupleLiteralNode createTupleLiteralNode(boolean isMatched, @NonNull String name, @NonNull TupleLiteralExp tupleLiteralExp, @NonNull Node @NonNull [] partNodes) {
		Role nodeRole = getOperationNodePhase(region, tupleLiteralExp, partNodes);
		TupleLiteralNode node = QVTscheduleFactory.eINSTANCE.createTupleLiteralNode();
		node.initialize(nodeRole, region, name, scheduleManager.getClassDatum(tupleLiteralExp));
		node.setMatched(isMatched);
		node.setOriginatingElement(tupleLiteralExp);
		return node;
	}

	public @NonNull Edge createTuplePartEdge(@NonNull Node sourceNode, @NonNull TupleLiteralPart tuplePart, @NonNull Node targetNode) {
		Role edgeRole = getNodeRole(sourceNode);
		TuplePartEdge edge = QVTscheduleFactory.eINSTANCE.createTuplePartEdge();
		edge.setReferredPart(tuplePart);
		String label = "«" + tuplePart.getName() + "»";
		edge.initialize(edgeRole, sourceNode, label, targetNode);
		return edge;
	}

	public @NonNull TypeLiteralNode createTypeLiteralNode(boolean isMatched, @NonNull Type typeValue, @NonNull TypeExp typeExp) {
		ClassDatum classDatum = scheduleManager.getClassDatum(typeExp);
		//		String typeName = PrettyPrinter.printType(QVTscheduleUtil.getCompleteClass(classDatum));
		Role nodeRole = getOperationNodePhase(region, typeExp);
		TypeLiteralNode typeLiteralNode = QVTscheduleFactory.eINSTANCE.createTypeLiteralNode();
		typeLiteralNode.initialize(nodeRole, region, String.valueOf(typeValue), classDatum);
		typeLiteralNode.setMatched(isMatched);
		typeLiteralNode.setTypeValue(typeValue);
		typeLiteralNode.setOriginatingElement(typeExp);
		return typeLiteralNode;
	}

	public @NonNull Node createUnknownNode(@NonNull String name, @NonNull TypedElement typedElement) {
		Role nodeRole = Role.OTHER;
		UnknownNode node = QVTscheduleFactory.eINSTANCE.createUnknownNode();
		node.initialize(nodeRole, region, name, scheduleManager.getClassDatum(typedElement));
		return node;
	}

	@Override
	public @NonNull String getName() {
		return QVTscheduleUtil.getName(region);
	}

	protected @NonNull Role getPatternNodeRole(@NonNull Node sourceNode, @NonNull Property property) {
		Role phase;
		switch (getNodeRole(sourceNode)) {
			case REALIZED: phase = Role.REALIZED; break;
			case PREDICATED: phase = Role.PREDICATED; break;
			case LOADED: {
				boolean isDirty = scheduleManager.isDirty(property);
				phase = isDirty ? Role.PREDICATED : Role.LOADED; break;
			}
			case CONSTANT_SUCCESS_FALSE: /* fall through */
			case CONSTANT_SUCCESS_TRUE: /* fall through */
			case CONSTANT: phase = Role.CONSTANT; break;
			default: throw new UnsupportedOperationException();
		}
		return phase;
	}

	public @NonNull R getRegion() {
		return region;
	}

	public @NonNull ScheduleManager getScheduleManager() {
		return scheduleManager;
	}
}