/*******************************************************************************
 * Copyright (c) 2015, 2016 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.qvtp2qvts;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CallExp;
import org.eclipse.ocl.pivot.DataType;
import org.eclipse.ocl.pivot.NavigationCallExp;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.VariableDeclaration;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
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.qvtcorebase.NavigationAssignment;
import org.eclipse.qvtd.pivot.qvtcorebase.analysis.DomainUsage;
import org.eclipse.qvtd.pivot.qvtcorebase.utilities.QVTcoreBaseUtil;
import org.eclipse.qvtd.pivot.schedule.ClassDatum;

/**
 * Nodes provides factory instances for creating the various forms of nodes.
 */
public class Nodes
{
	private static enum ClassableEnum { DATATYPE, CLASS };
	private static enum GuardableEnum { STEP, GUARD, HEAD };
	private static enum NavigableEnum { UNNAVIGABLE, NAVIGABLE };

	private static @NonNull ClassableEnum asClassable(boolean isClass) {
		return isClass ? ClassableEnum.CLASS : ClassableEnum.DATATYPE;
	}

	private static @NonNull NavigableEnum asNavigable(boolean isNavigable) {
		return isNavigable ? NavigableEnum.NAVIGABLE : NavigableEnum.UNNAVIGABLE;
	}

	private static abstract class AbstractSimpleNodeRole extends AbstractNodeRole
	{
		protected AbstractSimpleNodeRole(@NonNull Phase phase) {
			super(phase);
		}

		public @NonNull TypedNode createNode(@NonNull Node sourceNode, @NonNull Property source2targetProperty) {
			Region region = sourceNode.getRegion();
			assert sourceNode.isClass();
			SchedulerConstants schedulerConstants = region.getSchedulerConstants();
			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 ? schedulerConstants.getDomainAnalysis().getPrimitiveTypeModel() : sourceNode.getClassDatumAnalysis().getTypedModel();
			assert typedModel != null;
			ClassDatum classDatum = schedulerConstants.getClassDatum(type, typedModel);
			ClassDatumAnalysis classDatumAnalysis = schedulerConstants.getClassDatumAnalysis(classDatum);
			String name = source2targetProperty.getName();
			assert name != null;
			return new TypedNode(this, region, name, classDatumAnalysis);
		}

		@Override
		public @NonNull TypedNode createNode(@NonNull Region region, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis) {
			return new TypedNode(this, region, name, classDatumAnalysis);
		}

		@Override
		public @NonNull TypedNode createNode(@NonNull Region region, @NonNull String name, @NonNull TypedElement typedElement) {
			return new TypedNode(this, region, name, typedElement);
		}
	}

	private static abstract class AbstractVariableNodeRole extends AbstractSimpleNodeRole
	{
		protected final @NonNull ClassableEnum classable;

		protected AbstractVariableNodeRole(@NonNull Phase phase, @NonNull ClassableEnum classable) {
			super(phase);
			this.classable = classable;
		}

		public @NonNull VariableNode createNode(@NonNull Region region, @NonNull VariableDeclaration variable) {
			assert isClass() == !(variable.getType() instanceof DataType);
			return region.createVariableNode(this, variable);
		}

		@Override
		public boolean isClass() {
			return classable == ClassableEnum.CLASS;
		}

		@Override
		public boolean isDataType() {
			return classable == ClassableEnum.DATATYPE;
		}
	}

	private static final class ComposingNodeRole extends AbstractSimpleNodeRole
	{
		public static final @NonNull NodeRole COMPOSING = new ComposingNodeRole();

		protected ComposingNodeRole() {
			super(Role.Phase.LOADED);
		}

		@Override
		public boolean isClass() {
			return true;
		}

		@Override
		public boolean isNavigable() {
			return true;
		}
	}

	private static final class ErrorNodeRole extends AbstractSimpleNodeRole
	{
		public static final @NonNull NodeRole ERROR = new ErrorNodeRole();

		protected ErrorNodeRole() {
			super(Role.Phase.OTHER);
		}

		@Override
		public @NonNull String getColor() {
			return ERROR_COLOR;
		}

		@Override
		public @NonNull Integer getPenwidth() {
			return GUARD_WIDTH;
		}

		@Override
		public @NonNull String getShape() {
			return "circle";
		}
	}

	private static class ExtraGuardNodeRole extends AbstractSimpleNodeRole
	{
		public static final @NonNull NodeRole EXTRA_GUARD = new ExtraGuardNodeRole();

		protected ExtraGuardNodeRole() {
			super(Role.Phase.PREDICATED);
		}

		@Override
		public boolean isDataType() {
			return true;
		}

		@Override
		public boolean isExtraGuardVariable() {
			return true;
		}

		@Override
		public boolean isGuard() {
			return true;
		}

		@Override
		public boolean isHead() {
			return true;
		}
	}

	private static final class InputNodeRole extends AbstractNodeRole
	{
		private static final @NonNull InputNodeRole CONSTANT_INPUT = new InputNodeRole(Role.Phase.CONSTANT); //, true);
		private static final @NonNull InputNodeRole LOADED_INPUT = new InputNodeRole(Role.Phase.LOADED); //, true);
		//		private static final @NonNull InputNodeRole PREDICATED_INPUT = new InputNodeRole(Role.Phase.PREDICATED); //, true);
		//		private static final @NonNull InputNodeRole REALIZED_INPUT = new InputNodeRole(Role.Phase.REALIZED); //, true);

		public static @NonNull Node createInputNode(@NonNull Region region, NodeRole.@NonNull Phase nodeRolePhase, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis) {
			switch (nodeRolePhase) {
				case CONSTANT: return CONSTANT_INPUT.createNode(region, name, classDatumAnalysis);
				case LOADED: return LOADED_INPUT.createNode(region, name, classDatumAnalysis);
				//				case PREDICATED: return PREDICATED_INPUT.createNode(region, name, classDatumAnalysis);
				//				case REALIZED: return REALIZED_INPUT.createNode(region, name, classDatumAnalysis);
			}
			throw new UnsupportedOperationException();
		}

		protected InputNodeRole(@NonNull Phase phase) {
			super(phase);
		}

		@Override
		public @NonNull Node createNode(@NonNull Region region, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis) {
			throw new UnsupportedOperationException(); // FIXME Only used for obsolete cyclic regions.
		}

		@Override

		public @NonNull Node createNode(@NonNull Region region, @NonNull String name, @NonNull TypedElement typedElement) {
			throw new UnsupportedOperationException();
		}

		@Override
		public @NonNull Integer getPenwidth() {
			return Role.HEAD_WIDTH; //isHead ? Role.HEAD_WIDTH : Role.GUARD_WIDTH;
		}

		@Override
		public boolean isHead() {
			return true;
		}
	}

	private static final class IteratorNodeRole extends AbstractVariableNodeRole
	{
		private static final @NonNull IteratorNodeRole CONSTANT_DATATYPE_ITERATOR = new IteratorNodeRole(Role.Phase.CONSTANT, ClassableEnum.DATATYPE);
		private static final @NonNull IteratorNodeRole CONSTANT_CLASS_ITERATOR = new IteratorNodeRole(Role.Phase.CONSTANT, ClassableEnum.CLASS);
		private static final @NonNull IteratorNodeRole LOADED_DATATYPE_ITERATOR = new IteratorNodeRole(Role.Phase.LOADED, ClassableEnum.DATATYPE);
		private static final @NonNull IteratorNodeRole LOADED_CLASS_ITERATOR = new IteratorNodeRole(Role.Phase.LOADED, ClassableEnum.CLASS);
		private static final @NonNull IteratorNodeRole PREDICATED_DATATYPE_ITERATOR = new IteratorNodeRole(Role.Phase.PREDICATED, ClassableEnum.DATATYPE);
		private static final @NonNull IteratorNodeRole PREDICATED_CLASS_ITERATOR = new IteratorNodeRole(Role.Phase.PREDICATED, ClassableEnum.CLASS);

		public static @NonNull IteratorNodeRole getIteratorNodeRole(@NonNull Phase phase, @NonNull ClassableEnum classable) {
			switch (classable) {
				case CLASS: {
					switch (phase) {
						case CONSTANT: return CONSTANT_CLASS_ITERATOR;
						case LOADED: return LOADED_CLASS_ITERATOR;
						case PREDICATED: return PREDICATED_CLASS_ITERATOR;
					}
					break;
				}
				case DATATYPE:  {
					switch (phase) {
						case CONSTANT: return CONSTANT_DATATYPE_ITERATOR;
						case LOADED: return LOADED_DATATYPE_ITERATOR;
						case PREDICATED: return PREDICATED_DATATYPE_ITERATOR;
					}
					break;
				}
			}
			throw new UnsupportedOperationException();
		}

		protected IteratorNodeRole(@NonNull Phase phase, @NonNull ClassableEnum classable) {
			super(phase, classable);
		}

		@Override
		public @NonNull IteratorNodeRole asPhase(@NonNull Phase phase) {
			return getIteratorNodeRole(phase, classable);
		}

		@Override
		public boolean isInternal() {
			return true;
		}

		@Override
		public boolean isIterator() {
			return true;
		}

		@Override
		public @NonNull NodeRole merge(@NonNull NodeRole nodeRole) {
			if (nodeRole instanceof IteratorNodeRole) {
				return RegionUtil.mergeToMoreKnownPhase(this, nodeRole);
			}
			else {
				return super.merge(nodeRole);
			}
		}
	}

	private static class NullNodeRole extends AbstractSimpleNodeRole
	{
		private static final @NonNull NullNodeRole NULL = new NullNodeRole();

		private NullNodeRole() {
			super(Role.Phase.CONSTANT);
		}

		@Override
		public @Nullable String getStyle() {
			return "rounded";
		}

		@Override
		public boolean isNull() {
			return true;
		}

		@Override
		public boolean isPattern() {
			return true;
		}
	}

	private static class OperationNodeRole extends AbstractSimpleNodeRole
	{
		private static final @NonNull OperationNodeRole CONSTANT_OPERATION = new OperationNodeRole(Role.Phase.CONSTANT);
		private static final @NonNull OperationNodeRole LOADED_OPERATION = new OperationNodeRole(Role.Phase.LOADED);
		private static final @NonNull OperationNodeRole PREDICATED_OPERATION = new OperationNodeRole(Role.Phase.PREDICATED);
		private static final @NonNull OperationNodeRole REALIZED_OPERATION = new OperationNodeRole(Role.Phase.REALIZED);

		public static @NonNull Phase getOperationNodePhase(@NonNull Region region, @NonNull TypedElement typedElement, @NonNull Node... argNodes) {
			boolean isLoaded = false;
			boolean isPredicated = false;
			boolean isRealized = false;
			if (argNodes != null) {
				for (Node argNode : argNodes) {
					if (argNode.isRealized()) {
						isRealized = true;
					}
					else if (argNode.isPredicated()) {
						isPredicated = true;
					}
					else if (argNode.isLoaded()) {
						isLoaded = true;
					}
				}
			}
			if (typedElement instanceof OperationCallExp) {
				Operation asOperation = ((OperationCallExp)typedElement).getReferredOperation();
				if (QVTbaseUtil.isIdentification(asOperation)) {
					DomainUsage usage = region.getSchedulerConstants().getDomainUsage(typedElement);
					if (!usage.isInput()) {
						isRealized = true;
					}
				}
			}
			if (isRealized) {
				return Phase.REALIZED;
			}
			else if (isPredicated) {
				return Phase.PREDICATED;
			}
			else if (isLoaded) {
				return Phase.LOADED;
			}
			else {
				return Phase.CONSTANT;
			}
		}

		public static @NonNull OperationNodeRole getOperationNodeRole(@NonNull Phase phase) {
			switch (phase) {
				case CONSTANT: return CONSTANT_OPERATION;
				case LOADED: return LOADED_OPERATION;
				case PREDICATED: return PREDICATED_OPERATION;
				case REALIZED: return REALIZED_OPERATION;
			}
			throw new UnsupportedOperationException();
		}

		protected OperationNodeRole(@NonNull Phase phase) {
			super(phase);
		}

		@Override
		public @NonNull OperationNodeRole asPhase(@NonNull Phase phase) {
			return getOperationNodeRole(phase);
		}

		@Override
		public @NonNull Integer getPenwidth() {
			return LINE_WIDTH;
		}

		@Override
		public @NonNull String getShape() {
			return "ellipse";
		}

		@Override
		public boolean isExpression() {
			return true;
		}

		@Override
		public boolean isOperation() {
			return true;
		}
	}

	private static class PatternNodeRole extends AbstractVariableNodeRole
	{
		private static final @NonNull PatternNodeRole CONSTANT_NAVIGABLE_DATATYPE_STEP = new PatternNodeRole(Role.Phase.CONSTANT, ClassableEnum.DATATYPE, NavigableEnum.NAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole CONSTANT_UNNAVIGABLE_DATATYPE_STEP = new PatternNodeRole(Role.Phase.CONSTANT, ClassableEnum.DATATYPE, NavigableEnum.UNNAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole LOADED_NAVIGABLE_CLASS_HEAD = new PatternNodeRole(Role.Phase.LOADED, ClassableEnum.CLASS, NavigableEnum.NAVIGABLE, GuardableEnum.HEAD);
		private static final @NonNull PatternNodeRole LOADED_NAVIGABLE_DATATYPE_GUARD = new PatternNodeRole(Role.Phase.LOADED, ClassableEnum.DATATYPE, NavigableEnum.NAVIGABLE, GuardableEnum.GUARD);
		private static final @NonNull PatternNodeRole LOADED_NAVIGABLE_CLASS_GUARD = new PatternNodeRole(Role.Phase.LOADED, ClassableEnum.CLASS, NavigableEnum.NAVIGABLE, GuardableEnum.GUARD);
		private static final @NonNull PatternNodeRole LOADED_NAVIGABLE_DATATYPE_STEP = new PatternNodeRole(Role.Phase.LOADED, ClassableEnum.DATATYPE, NavigableEnum.NAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole LOADED_NAVIGABLE_CLASS_STEP = new PatternNodeRole(Role.Phase.LOADED, ClassableEnum.CLASS, NavigableEnum.NAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole LOADED_UNNAVIGABLE_DATATYPE_STEP = new PatternNodeRole(Role.Phase.LOADED, ClassableEnum.DATATYPE, NavigableEnum.UNNAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole LOADED_UNNAVIGABLE_CLASS_STEP = new PatternNodeRole(Role.Phase.LOADED, ClassableEnum.CLASS, NavigableEnum.UNNAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole PREDICATED_NAVIGABLE_CLASS_HEAD = new PatternNodeRole(Role.Phase.PREDICATED, ClassableEnum.CLASS, NavigableEnum.NAVIGABLE, GuardableEnum.HEAD);
		private static final @NonNull PatternNodeRole PREDICATED_NAVIGABLE_DATATYPE_GUARD = new PatternNodeRole(Role.Phase.PREDICATED, ClassableEnum.DATATYPE, NavigableEnum.NAVIGABLE, GuardableEnum.GUARD);
		private static final @NonNull PatternNodeRole PREDICATED_NAVIGABLE_CLASS_GUARD = new PatternNodeRole(Role.Phase.PREDICATED, ClassableEnum.CLASS, NavigableEnum.NAVIGABLE, GuardableEnum.GUARD);
		private static final @NonNull PatternNodeRole PREDICATED_NAVIGABLE_DATATYPE_STEP = new PatternNodeRole(Role.Phase.PREDICATED, ClassableEnum.DATATYPE, NavigableEnum.NAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole PREDICATED_NAVIGABLE_CLASS_STEP = new PatternNodeRole(Role.Phase.PREDICATED, ClassableEnum.CLASS, NavigableEnum.NAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole PREDICATED_UNNAVIGABLE_DATATYPE_HEAD = new PatternNodeRole(Role.Phase.PREDICATED, ClassableEnum.DATATYPE, NavigableEnum.UNNAVIGABLE, GuardableEnum.HEAD);
		private static final @NonNull PatternNodeRole PREDICATED_UNNAVIGABLE_CLASS_HEAD = new PatternNodeRole(Role.Phase.PREDICATED, ClassableEnum.CLASS, NavigableEnum.UNNAVIGABLE, GuardableEnum.HEAD);
		private static final @NonNull PatternNodeRole PREDICATED_UNNAVIGABLE_DATATYPE_STEP = new PatternNodeRole(Role.Phase.PREDICATED, ClassableEnum.DATATYPE, NavigableEnum.UNNAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole PREDICATED_UNNAVIGABLE_CLASS_STEP = new PatternNodeRole(Role.Phase.PREDICATED, ClassableEnum.CLASS, NavigableEnum.UNNAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole REALIZED_NAVIGABLE_DATATYPE_STEP = new PatternNodeRole(Role.Phase.REALIZED, ClassableEnum.DATATYPE, NavigableEnum.NAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole REALIZED_UNNAVIGABLE_CLASS_STEP = new PatternNodeRole(Role.Phase.REALIZED, ClassableEnum.CLASS, NavigableEnum.UNNAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole REALIZED_UNNAVIGABLE_DATATYPE_STEP = new PatternNodeRole(Role.Phase.REALIZED, ClassableEnum.DATATYPE, NavigableEnum.UNNAVIGABLE, GuardableEnum.STEP);
		private static final @NonNull PatternNodeRole SPECULATED_NAVIGABLE_CLASS_HEAD = new PatternNodeRole(Role.Phase.SPECULATED, ClassableEnum.CLASS, NavigableEnum.NAVIGABLE, GuardableEnum.HEAD);
		private static final @NonNull PatternNodeRole SPECULATED_NAVIGABLE_CLASS_GUARD = new PatternNodeRole(Role.Phase.SPECULATED, ClassableEnum.CLASS, NavigableEnum.NAVIGABLE, GuardableEnum.GUARD);
		private static final @NonNull PatternNodeRole SPECULATION_NAVIGABLE_CLASS_STEP = new PatternNodeRole(Role.Phase.SPECULATION, ClassableEnum.CLASS, NavigableEnum.NAVIGABLE, GuardableEnum.STEP);

		public static @NonNull PatternNodeRole getDataTypeNodeRole(@NonNull Node sourceNode, @NonNull Property property) {
			Phase phase;
			switch (sourceNode.getNodeRole().getPhase()) {
				case REALIZED: phase = Phase.REALIZED; break;
				case PREDICATED: phase = Phase.PREDICATED; break;
				case LOADED: {
					boolean isDirty = sourceNode.getRegion().getSchedulerConstants().isDirty(property);
					phase = isDirty ? Phase.PREDICATED : Phase.LOADED; break;
				}
				case CONSTANT: phase = Phase.CONSTANT; break;
				default: throw new UnsupportedOperationException();
			}
			NavigableEnum navigableEnum = Nodes.asNavigable(sourceNode.isNavigable());
			return getPatternNodeRole(phase, ClassableEnum.DATATYPE, navigableEnum, GuardableEnum.STEP);
		}

		public static @NonNull PatternNodeRole getPatternNodeRole(@NonNull Phase phase, @NonNull ClassableEnum classable, @NonNull NavigableEnum navigable, @NonNull GuardableEnum guardable) {
			switch (navigable) {
				case NAVIGABLE: {
					switch (guardable) {
						case HEAD: {
							switch (classable) {
								case CLASS: {
									switch (phase) {
										case LOADED: return LOADED_NAVIGABLE_CLASS_HEAD;
										case PREDICATED: return PREDICATED_NAVIGABLE_CLASS_HEAD;
										case SPECULATED: return SPECULATED_NAVIGABLE_CLASS_HEAD;
									}
									break;
								}
								case DATATYPE: {
									switch (phase) {
									}
									break;
								}
							}
							break;
						}
						case GUARD: {
							switch (classable) {
								case CLASS: {
									switch (phase) {
										case LOADED: return LOADED_NAVIGABLE_CLASS_GUARD;
										case PREDICATED: return PREDICATED_NAVIGABLE_CLASS_GUARD;
										case SPECULATED: return SPECULATED_NAVIGABLE_CLASS_GUARD;
									}
									break;
								}
								case DATATYPE: {
									switch (phase) {
										case LOADED: return LOADED_NAVIGABLE_DATATYPE_GUARD;
										case PREDICATED: return PREDICATED_NAVIGABLE_DATATYPE_GUARD;
									}
									break;
								}
							}
							break;
						}
						case STEP: {
							switch (classable) {
								case CLASS: {
									switch (phase) {
										case LOADED: return LOADED_NAVIGABLE_CLASS_STEP;
										case PREDICATED: return PREDICATED_NAVIGABLE_CLASS_STEP;
										case SPECULATION: return SPECULATION_NAVIGABLE_CLASS_STEP;
									}
									break;
								}
								case DATATYPE: {
									switch (phase) {
										case CONSTANT: return CONSTANT_NAVIGABLE_DATATYPE_STEP;
										case LOADED: return LOADED_NAVIGABLE_DATATYPE_STEP;
										case PREDICATED: return PREDICATED_NAVIGABLE_DATATYPE_STEP;
										case REALIZED: return REALIZED_NAVIGABLE_DATATYPE_STEP;
									}
									break;
								}
							}
							break;
						}
					}
					break;
				}
				case UNNAVIGABLE: {
					switch (guardable) {
						case HEAD: {
							switch (classable) {
								case CLASS: {
									switch (phase) {
										case PREDICATED: return PREDICATED_UNNAVIGABLE_CLASS_HEAD;
									}
									break;
								}
								case DATATYPE: {
									switch (phase) {
										case PREDICATED: return PREDICATED_UNNAVIGABLE_DATATYPE_HEAD;
									}
									break;
								}
							}
							break;
						}
						case GUARD: {
							break;
						}
						case STEP: {
							switch (classable) {
								case CLASS: {
									switch (phase) {
										case LOADED: return LOADED_UNNAVIGABLE_CLASS_STEP;
										case PREDICATED: return PREDICATED_UNNAVIGABLE_CLASS_STEP;
										case REALIZED: return REALIZED_UNNAVIGABLE_CLASS_STEP;
									}
									break;
								}
								case DATATYPE: {
									switch (phase) {
										case CONSTANT: return CONSTANT_UNNAVIGABLE_DATATYPE_STEP;
										case LOADED: return LOADED_UNNAVIGABLE_DATATYPE_STEP;
										case PREDICATED: return PREDICATED_UNNAVIGABLE_DATATYPE_STEP;
										case REALIZED: return REALIZED_UNNAVIGABLE_DATATYPE_STEP;
									}
									break;
								}
							}
							break;
						}
					}
					break;
				}
			}
			throw new UnsupportedOperationException();
		}

		private final @NonNull NavigableEnum navigable;
		private final @NonNull GuardableEnum guardable;

		private PatternNodeRole(@NonNull Phase phase, @NonNull ClassableEnum classable, @NonNull NavigableEnum navigable, @NonNull GuardableEnum guardable) {
			super(phase, classable);
			this.navigable = navigable;
			this.guardable = guardable;
		}

		@Override
		public @NonNull NodeRole asNavigable() {
			return getPatternNodeRole(phase, classable, NavigableEnum.NAVIGABLE, guardable);
		}

		@Override
		public @NonNull PatternNodeRole asPhase(@NonNull Phase phase) {
			return getPatternNodeRole(phase, classable, navigable, guardable);
		}

		@Override
		public @NonNull NodeRole asSpeculated() {
			return getPatternNodeRole(Phase.SPECULATED, classable, NavigableEnum.NAVIGABLE, GuardableEnum.HEAD);
		}

		@Override
		public @NonNull NodeRole asSpeculation() {
			return getPatternNodeRole(Phase.SPECULATION, classable, NavigableEnum.NAVIGABLE, guardable);
		}

		@Override
		public boolean isGuard() {
			return guardable != GuardableEnum.STEP;
		}

		@Override
		public boolean isHead() {
			return guardable == GuardableEnum.HEAD;
		}

		@Override
		public boolean isNavigable() {
			return navigable == NavigableEnum.NAVIGABLE;
		}

		@Override
		public boolean isPattern() {
			return true;
		}

		@Override
		public @NonNull NodeRole merge(@NonNull NodeRole nodeRole) {
			assert nodeRole instanceof PatternNodeRole;
			assert isClass() == nodeRole.isClass();
			Phase mergedPhase = RegionUtil.mergeToMoreKnownPhase(this, nodeRole).getPhase();
			NavigableEnum mergedNavigable;
			GuardableEnum mergedGuardable;
			if (mergedPhase == Phase.REALIZED) {
				mergedNavigable = NavigableEnum.UNNAVIGABLE;
				mergedGuardable = GuardableEnum.STEP;
			}
			else {
				mergedNavigable = Nodes.asNavigable(isNavigable() || nodeRole.isNavigable());
				mergedGuardable = (isHead() && nodeRole.isHead()) ? GuardableEnum.HEAD : isGuard() || nodeRole.isGuard() ? GuardableEnum.GUARD : GuardableEnum.STEP;
			}
			return getPatternNodeRole(mergedPhase, classable, mergedNavigable, mergedGuardable);
		}

		@Override
		public @NonNull NodeRole resetHead() {
			return getPatternNodeRole(phase, classable, navigable, !isGuard() ? GuardableEnum.STEP : GuardableEnum.GUARD);
		}

		@Override
		public @NonNull NodeRole setHead() {
			return getPatternNodeRole(phase, classable, navigable, GuardableEnum.HEAD);
		}

		@Override
		public String toString() {
			return phase + (isNavigable() ? "-Navigable" : "-Unnavigable") + (isClass() ? "-Class" : "-DataType") + (isHead() ? "Head-" : isGuard() ? "Guard-" : "Step-") + getClass().getSimpleName();
		}
	}

	// FIXME Can this be merged into PatternNodeRole ??
	private static final class PredicatedInternalNodeRole extends AbstractSimpleNodeRole
	{
		public static final @NonNull PredicatedInternalNodeRole PREDICATED_INTERNAL_CLASS = new PredicatedInternalNodeRole();

		private PredicatedInternalNodeRole() {
			super(Role.Phase.PREDICATED);
		}

		@Override
		public boolean isDataType() {
			return true;
		}

		@Override
		public boolean isInternal() {
			return true;
		}

		@Override
		public boolean isPattern() {
			return true;
		}

		@Override
		public String toString() {
			return getClass().getSimpleName();
		}
	}

	private static final class TrueNodeRole extends AbstractSimpleNodeRole
	{
		private static final @NonNull TrueNodeRole TRUE = new TrueNodeRole();

		private TrueNodeRole() {
			super(Role.Phase.CONSTANT);
		}

		@Override
		public @Nullable String getStyle() {
			return null;
		}

		@Override
		public boolean isHead() {
			return true;
		}

		@Override
		public boolean isPattern() {
			return true;
		}

		@Override
		public boolean isTrue() {
			return true;
		}
	}

	private static final class UnknownNodeRole extends AbstractSimpleNodeRole
	{
		public static final @NonNull NodeRole UNKNOWN = new UnknownNodeRole();

		protected UnknownNodeRole() {
			super(Role.Phase.OTHER);
		}

		@Override
		public @NonNull String getColor() {
			return ERROR_COLOR;
		}
	}

	public static @NonNull Node createComposingNode(@NonNull Region region, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis) {
		return ComposingNodeRole.COMPOSING.createNode(region, name, classDatumAnalysis);
	}

	public static @NonNull TypedNode createDataTypeNode(@NonNull Node sourceNode, @NonNull Property property) {
		PatternNodeRole patternNodeRole = PatternNodeRole.getDataTypeNodeRole(sourceNode, property);
		return patternNodeRole.createNode(sourceNode, property);
	}

	public static @NonNull TypedNode createDataTypeNode(@NonNull Node sourceNode, @NonNull NavigationCallExp navigationCallExp) {
		Property property = PivotUtil.getReferredProperty(navigationCallExp);
		PatternNodeRole patternNodeRole = PatternNodeRole.getDataTypeNodeRole(sourceNode, property);
		assert sourceNode.isClass();
		String name = property.getName();
		assert name != null;
		return patternNodeRole.createNode(sourceNode.getRegion(), name, navigationCallExp);
	}

	public static @NonNull Node createDataTypeNode(@NonNull Node targetNode, @NonNull NavigationAssignment navigationAssignment) {
		Role.Phase phase;
		switch (targetNode.getNodeRole().getPhase()) {
			case REALIZED: phase = Role.Phase.REALIZED; break;
			case PREDICATED: phase = Role.Phase.PREDICATED; break;
			case LOADED: phase = Role.Phase.LOADED; break;
			case CONSTANT: phase = Role.Phase.CONSTANT; break;
			default: throw new UnsupportedOperationException();
		}
		PatternNodeRole patternNodeRole = PatternNodeRole.getPatternNodeRole(phase, ClassableEnum.DATATYPE, NavigableEnum.NAVIGABLE, GuardableEnum.STEP);
		Property property = QVTcoreBaseUtil.getTargetProperty(navigationAssignment);
		//		PatternNodeRole patternNodeRole = PatternNodeRole.getDataTypeNodeRole(targetNode, property);
		//		assert sourceNode.isClass();
		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 = targetNode.getClassDatumAnalysis().getTypedModel();
		Region region = targetNode.getRegion();
		ClassDatum classDatum = region.getSchedulerConstants().getClassDatum(type, typedModel);
		//				DomainUsage domainUsage = parentNode.getClassDatumAnalysis().getDomainUsage();
		ClassDatumAnalysis classDatumAnalysis = region.getSchedulerConstants().getClassDatumAnalysis(classDatum);
		return patternNodeRole.createNode(region, name, classDatumAnalysis);
	}

	public static @NonNull Node createErrorNode(@NonNull Region region, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis) {
		return ErrorNodeRole.ERROR.createNode(region, name, classDatumAnalysis);
	}

	public static @NonNull Node createExtraGuardNode(@NonNull Region region, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis) {
		return ExtraGuardNodeRole.EXTRA_GUARD.createNode(region, name, classDatumAnalysis);
	}

	public static @NonNull VariableNode createGuardNode(@NonNull Region region, @NonNull VariableDeclaration variable) {
		DomainUsage domainUsage = region.getSchedulerConstants().getDomainUsage(variable);
		boolean isEnforceable = domainUsage.isOutput() || domainUsage.isMiddle();
		ClassableEnum classable = asClassable(!(variable.getType() instanceof DataType));
		Role.Phase phase = isEnforceable ? Role.Phase.PREDICATED : Role.Phase.LOADED;
		PatternNodeRole patternNodeRole = PatternNodeRole.getPatternNodeRole(phase, classable, NavigableEnum.NAVIGABLE, GuardableEnum.GUARD);
		return patternNodeRole.createNode(region, variable);
	}

	public static @NonNull Node createInputNode(@NonNull Region region, NodeRole.@NonNull Phase nodeRolePhase, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis) {
		return InputNodeRole.createInputNode(region, nodeRolePhase, name, classDatumAnalysis);
	}

	public static @NonNull VariableNode createIteratorNode(@NonNull Variable iterator, @NonNull Node sourceNode) {
		ClassableEnum classable = asClassable(!(iterator.getType() instanceof DataType));
		IteratorNodeRole nodeRole = IteratorNodeRole.getIteratorNodeRole(sourceNode.getNodeRole().getPhase(), classable);
		return nodeRole.createNode(sourceNode.getRegion(), iterator);
	}

	public static @NonNull VariableNode createLetVariableNode(@NonNull Variable letVariable, @NonNull Node inNode) {
		ClassableEnum classable = asClassable(!(letVariable.getType() instanceof DataType));
		NavigableEnum resolvedIsNavigable = asNavigable(inNode.isNavigable());
		PatternNodeRole patternNodeRole = PatternNodeRole.getPatternNodeRole(inNode.getNodeRole().getPhase(), classable, resolvedIsNavigable, GuardableEnum.STEP);
		return patternNodeRole.createNode(inNode.getRegion(), letVariable);
	}

	public static @NonNull VariableNode createLoadedStepNode(@NonNull Region region, @NonNull VariableDeclaration stepVariable) {
		ClassableEnum classable = asClassable(!(stepVariable.getType() instanceof DataType));
		PatternNodeRole patternNodeRole = PatternNodeRole.getPatternNodeRole(Role.Phase.LOADED, classable, NavigableEnum.NAVIGABLE, GuardableEnum.STEP);
		return patternNodeRole.createNode(region, stepVariable);
	}

	public static @NonNull TypedNode createNullNode(@NonNull Region region, @Nullable TypedElement typedElement) {
		if (typedElement != null) {
			return NullNodeRole.NULL.createNode(region, "«null»", typedElement);
		}
		else {
			return NullNodeRole.NULL.createNode(region, "«null»", region.getSchedulerConstants().getOclVoidClassDatumAnalysis());
		}
	}

	public static @NonNull TypedNode createOperationElementNode(@NonNull Region region, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis, @NonNull Node sourceNode) {
		PatternNodeRole patternNodeRole = PatternNodeRole.getPatternNodeRole(sourceNode.getNodeRole().getPhase(), ClassableEnum.DATATYPE, NavigableEnum.NAVIGABLE, GuardableEnum.STEP);
		return patternNodeRole.createNode(region, name, classDatumAnalysis);
	}

	public static @NonNull TypedNode createOperationNode(@NonNull Region region, @NonNull String name, @NonNull TypedElement typedElement, @NonNull Node... argNodes) {
		Role.Phase nodePhase = OperationNodeRole.getOperationNodePhase(region, typedElement, argNodes);
		OperationNodeRole nodeRole = OperationNodeRole.getOperationNodeRole(nodePhase);
		return nodeRole.createNode(region, name, typedElement);
	}

	public static @NonNull TypedNode createOperationParameterNode(@NonNull Region region, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis) {
		ClassableEnum classable = asClassable(!(classDatumAnalysis.getClassDatum().getType() instanceof DataType));
		PatternNodeRole patternNodeRole = PatternNodeRole.getPatternNodeRole(Role.Phase.PREDICATED, classable, NavigableEnum.UNNAVIGABLE, GuardableEnum.HEAD);
		return patternNodeRole.createNode(region, name, classDatumAnalysis);
	}

	public static @NonNull TypedNode createOperationResultNode(@NonNull Region region, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis, @NonNull Node sourceNode) {
		ClassableEnum classable = asClassable(!(classDatumAnalysis.getClassDatum().getType() instanceof DataType));
		PatternNodeRole patternNodeRole = PatternNodeRole.getPatternNodeRole(sourceNode.getNodeRole().getPhase(), classable, NavigableEnum.UNNAVIGABLE, GuardableEnum.STEP);
		return patternNodeRole.createNode(region, name, classDatumAnalysis);
	}

	public static @NonNull Node createPredicatedInternalClassNode(@NonNull Node parentNode, @NonNull NavigationAssignment navigationAssignment) {
		assert parentNode.isClass();
		SchedulerConstants schedulerConstants = parentNode.getRegion().getSchedulerConstants();
		Property property = QVTcoreBaseUtil.getTargetProperty(navigationAssignment);
		assert property != null;
		org.eclipse.ocl.pivot.Class type = (org.eclipse.ocl.pivot.Class)property.getType();
		assert type != null;
		TypedModel typedModel = parentNode.getClassDatumAnalysis().getTypedModel();
		ClassDatum classDatum = schedulerConstants.getClassDatum(type, typedModel);
		//				DomainUsage domainUsage = parentNode.getClassDatumAnalysis().getDomainUsage();
		ClassDatumAnalysis classDatumAnalysis = schedulerConstants.getClassDatumAnalysis(classDatum);
		String name = property.getName();
		assert name != null;
		return PredicatedInternalNodeRole.PREDICATED_INTERNAL_CLASS.createNode(parentNode.getRegion(), name, classDatumAnalysis);
	}

	public static @NonNull Node createPredicatedInternalClassNode(@NonNull Region region, @NonNull String name, @NonNull ClassDatumAnalysis classDatumAnalysis) {
		return PredicatedInternalNodeRole.PREDICATED_INTERNAL_CLASS.createNode(region, name, classDatumAnalysis);
	}

	public static @NonNull TypedNode createRealizedDataTypeNode(@NonNull Node sourceNode, @NonNull Property source2targetProperty) {
		PatternNodeRole patternNodeRole = PatternNodeRole.getPatternNodeRole(Role.Phase.REALIZED, ClassableEnum.DATATYPE, NavigableEnum.UNNAVIGABLE, GuardableEnum.STEP);
		return patternNodeRole.createNode(sourceNode, source2targetProperty);
	}

	public static @NonNull VariableNode createRealizedStepNode(@NonNull Region region, @NonNull Variable stepVariable) {
		ClassableEnum classable = asClassable(!(stepVariable.getType() instanceof DataType));
		PatternNodeRole patternNodeRole = PatternNodeRole.getPatternNodeRole(Role.Phase.REALIZED, classable, NavigableEnum.UNNAVIGABLE, GuardableEnum.STEP);
		return patternNodeRole.createNode(region, stepVariable);
	}

	public static @NonNull TypedNode createStepNode(@NonNull String name, @NonNull CallExp callExp, @NonNull Node sourceNode, boolean isNavigable) {
		Region region = sourceNode.getRegion();
		DomainUsage domainUsage = region.getSchedulerConstants().getDomainUsage(callExp);
		boolean isMiddleOrOutput = domainUsage.isOutput() || domainUsage.isMiddle();
		boolean isDirty = false;
		if (callExp instanceof NavigationCallExp) {
			Property referredProperty = PivotUtil.getReferredProperty((NavigationCallExp)callExp);
			isDirty = region.getSchedulerConstants().isDirty(referredProperty);
		}
		Role.Phase phase = sourceNode.isPredicated() || isMiddleOrOutput || isDirty ? Role.Phase.PREDICATED : Role.Phase.LOADED;
		NavigableEnum navigableEnum = isNavigable ? NavigableEnum.NAVIGABLE : NavigableEnum.UNNAVIGABLE;
		ClassableEnum classable = asClassable(sourceNode.isClass());
		PatternNodeRole stepNodeRole = PatternNodeRole.getPatternNodeRole(phase, classable, navigableEnum, GuardableEnum.STEP);
		return stepNodeRole.createNode(region, name, callExp);
	}

	public static @NonNull Node createStepNode(@NonNull Region region, @NonNull TypedNode typedNode) {
		NodeRole stepNodeRole = PatternNodeRole.getPatternNodeRole(Role.Phase.PREDICATED, asClassable(typedNode.isClass()), NavigableEnum.NAVIGABLE, GuardableEnum.STEP);
		return stepNodeRole.createNode(region, typedNode.getName(), typedNode.getClassDatumAnalysis());
	}

	public static @NonNull TypedNode createTrueNode(@NonNull Region region) {
		SchedulerConstants schedulerConstants = region.getSchedulerConstants();
		org.eclipse.ocl.pivot.Class booleanType = schedulerConstants.getStandardLibrary().getBooleanType();
		DomainUsage primitiveUsage = schedulerConstants.getDomainAnalysis().getPrimitiveUsage();
		ClassDatumAnalysis classDatumAnalysis = schedulerConstants.getClassDatumAnalysis(booleanType, ClassUtil.nonNullState(primitiveUsage.getTypedModel(null)));
		return TrueNodeRole.TRUE.createNode(region, "«true»", classDatumAnalysis);
	}

	public static @NonNull Node createUnknownNode(@NonNull Region region, @NonNull String name, @NonNull TypedElement typedElement) {
		return UnknownNodeRole.UNKNOWN.createNode(region, name, typedElement);
	}

	/*	public static @NonNull VariableNode createUnrealizedStepNode(@NonNull Region region, @NonNull VariableDeclaration stepVariable) {
	/*	SchedulerConstants schedulerConstants = region.getSchedulerConstants();
		org.eclipse.ocl.pivot.Class type = (org.eclipse.ocl.pivot.Class)stepVariable.getType();
		assert type != null;
		Type elementType = QVTbaseUtil.getElementalType(type);
		TypedModel typedModel = elementType instanceof DataType ? schedulerConstants.getDomainAnalysis().getPrimitiveTypeModel() : sourceNode.getClassDatumAnalysis().getTypedModel();
		assert typedModel != null;
		ClassDatum classDatum = schedulerConstants.getClassDatum(type, typedModel);
		ClassDatumAnalysis classDatumAnalysis = schedulerConstants.getClassDatumAnalysis(classDatum); * /
	//	throw new UnsupportedOperationException();			// FIXME experimenting
		ClassableEnum classable = asClassable(!(stepVariable.getType() instanceof DataType));
		PatternNodeRole patternNodeRole = PatternNodeRole.getPatternNodeRole(Role.Phase.LOADDED, classable, NavigableEnum.NAVIGABLE, GuardableEnum.STEP);
		return patternNodeRole.createNode(region, stepVariable);
	} */
}