/*******************************************************************************
 * Copyright (c) 2016, 2018 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.ocl.pivot.utilities;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
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.CollectionItem;
import org.eclipse.ocl.pivot.CollectionLiteralExp;
import org.eclipse.ocl.pivot.CollectionLiteralPart;
import org.eclipse.ocl.pivot.CollectionRange;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.Comment;
import org.eclipse.ocl.pivot.CompleteClass;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.EnumLiteralExp;
import org.eclipse.ocl.pivot.EnumerationLiteral;
import org.eclipse.ocl.pivot.ExpressionInOCL;
import org.eclipse.ocl.pivot.IfExp;
import org.eclipse.ocl.pivot.Import;
import org.eclipse.ocl.pivot.IntegerLiteralExp;
import org.eclipse.ocl.pivot.InvalidLiteralExp;
import org.eclipse.ocl.pivot.IterateExp;
import org.eclipse.ocl.pivot.Iteration;
import org.eclipse.ocl.pivot.IteratorExp;
import org.eclipse.ocl.pivot.IteratorVariable;
import org.eclipse.ocl.pivot.LetExp;
import org.eclipse.ocl.pivot.LetVariable;
import org.eclipse.ocl.pivot.MapLiteralExp;
import org.eclipse.ocl.pivot.MapLiteralPart;
import org.eclipse.ocl.pivot.MapType;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.Namespace;
import org.eclipse.ocl.pivot.NavigationCallExp;
import org.eclipse.ocl.pivot.NullLiteralExp;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.Package;
import org.eclipse.ocl.pivot.Parameter;
import org.eclipse.ocl.pivot.ParameterVariable;
import org.eclipse.ocl.pivot.PivotFactory;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.PropertyCallExp;
import org.eclipse.ocl.pivot.RealLiteralExp;
import org.eclipse.ocl.pivot.ResultVariable;
import org.eclipse.ocl.pivot.SelfType;
import org.eclipse.ocl.pivot.ShadowExp;
import org.eclipse.ocl.pivot.ShadowPart;
import org.eclipse.ocl.pivot.StandardLibrary;
import org.eclipse.ocl.pivot.StringLiteralExp;
import org.eclipse.ocl.pivot.TemplateParameter;
import org.eclipse.ocl.pivot.TupleLiteralExp;
import org.eclipse.ocl.pivot.TupleLiteralPart;
import org.eclipse.ocl.pivot.TupleType;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypeExp;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.UnlimitedNaturalLiteralExp;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.VariableDeclaration;
import org.eclipse.ocl.pivot.VariableExp;
import org.eclipse.ocl.pivot.ids.TypeId;
import org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager;
import org.eclipse.ocl.pivot.internal.manager.TemplateParameterSubstitutionHelper;
import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal;
import org.eclipse.ocl.pivot.library.LibraryFeature;
import org.eclipse.ocl.pivot.values.TemplateParameterSubstitutions;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

/**
 * PivotHelper provides helper routines to assist creation of Pivot model elements.
 * @since 1.3
 */
public class PivotHelper
{
	protected final @NonNull EnvironmentFactory environmentFactory;
	protected final @NonNull StandardLibrary standardLibrary;
	private final @NonNull PivotMetamodelManager metamodelManager;

	public PivotHelper(@NonNull EnvironmentFactory environmentFactory) {
		this.environmentFactory = environmentFactory;
		this.standardLibrary = environmentFactory.getStandardLibrary();
		this.metamodelManager = (PivotMetamodelManager) environmentFactory.getMetamodelManager();			// FIXME avoid this cast;
	}

	public @NonNull BooleanLiteralExp createBooleanLiteralExp(boolean booleanSymbol) {
		BooleanLiteralExp asBoolean = PivotFactory.eINSTANCE.createBooleanLiteralExp();
		asBoolean.setBooleanSymbol(booleanSymbol);
		asBoolean.setType(standardLibrary.getBooleanType());
		asBoolean.setIsRequired(true);
		return asBoolean;
	}

	/**
	 * @since 1.4
	 */
	public @NonNull OCLExpression createCoercionCallExp(@NonNull OCLExpression asExpression, @NonNull Operation coercion) {
		if (asExpression instanceof IntegerLiteralExp) {
			IntegerLiteralExp asIntegerLiteralExp = (IntegerLiteralExp)asExpression;
			Number integerSymbol = asIntegerLiteralExp.getIntegerSymbol();
			if (integerSymbol.longValue() >= 0) {
				org.eclipse.ocl.pivot.Class integerType = standardLibrary.getIntegerType();
				Operation asCoercion = NameUtil.getNameable(integerType.getOwnedOperations(), "toUnlimitedNatural");
				if (coercion == asCoercion) {
					return createUnlimitedNaturalLiteralExp(integerSymbol);
				}
			}
		}
		OperationCallExp asCoercionCallExp = PivotFactory.eINSTANCE.createOperationCallExp();
		asCoercionCallExp.setOwnedSource(asExpression);
		asCoercionCallExp.setReferredOperation(coercion);
		asCoercionCallExp.setType(coercion.getType());
		asCoercionCallExp.setIsRequired(coercion.isIsRequired());
		return asCoercionCallExp;
	}

	public @NonNull CollectionItem createCollectionItem(@NonNull OCLExpression asItem) {
		CollectionItem collectionItem = PivotFactory.eINSTANCE.createCollectionItem();
		collectionItem.setOwnedItem(asItem);
		collectionItem.setType(asItem.getType());
		collectionItem.setIsRequired(asItem.isIsRequired());
		return collectionItem;
	}

	public @NonNull CollectionLiteralExp createCollectionLiteralExp(@NonNull CollectionType asType, @NonNull Iterable<CollectionLiteralPart> asParts) {
		CollectionLiteralExp collectionLiteralExp = PivotFactory.eINSTANCE.createCollectionLiteralExp();
		Iterables.addAll(collectionLiteralExp.getOwnedParts(), asParts);
		collectionLiteralExp.setType(asType);
		collectionLiteralExp.setKind(TypeUtil.getCollectionKind(asType));
		collectionLiteralExp.setIsRequired(true);
		return collectionLiteralExp;
	}

	public @NonNull CollectionRange createCollectionRange(@NonNull OCLExpression asFirst, @NonNull OCLExpression asLast) {
		CollectionRange collectionRange = PivotFactory.eINSTANCE.createCollectionRange();
		collectionRange.setOwnedFirst(asFirst);
		collectionRange.setOwnedLast(asLast);
		collectionRange.setType(standardLibrary.getIntegerType());
		collectionRange.setIsRequired(true);
		return collectionRange;
	}

	public @NonNull Comment createComment(@NonNull String comment) {
		Comment asComment = PivotFactory.eINSTANCE.createComment();
		asComment.setBody(comment);
		return asComment;
	}

	/**
	 * @since 1.10
	 */
	public @NonNull EnumLiteralExp createEnumLiteralExp(@NonNull EnumerationLiteral value) {
		EnumLiteralExp asEnumLiteralExp = PivotFactory.eINSTANCE.createEnumLiteralExp();
		asEnumLiteralExp.setReferredLiteral(value);
		asEnumLiteralExp.setType(value.getOwningEnumeration());
		asEnumLiteralExp.setIsRequired(true);
		return asEnumLiteralExp;
	}

	public @NonNull IfExp createIfExp(@NonNull OCLExpression asCondition, @NonNull OCLExpression asThen, @NonNull OCLExpression asElse) {
		Type commonType = metamodelManager.getCommonType(ClassUtil.nonNullState(asThen.getType()), TemplateParameterSubstitutions.EMPTY,
			ClassUtil.nonNullState(asElse.getType()), TemplateParameterSubstitutions.EMPTY);
		IfExp asIf = PivotFactory.eINSTANCE.createIfExp();
		asIf.setOwnedCondition(asCondition);
		asIf.setOwnedThen(asThen);
		asIf.setOwnedElse(asElse);
		asIf.setType(commonType);
		asIf.setIsRequired(asThen.isIsRequired() && asElse.isIsRequired());
		return asIf;
	}

	public  @NonNull Import createImport(@Nullable String name, @NonNull Namespace namespace) {
		Import asImport = PivotFactory.eINSTANCE.createImport();
		asImport.setName(name);
		asImport.setImportedNamespace(namespace);
		asImport.setXmiidVersion(PivotConstants.XMIIDS_CURRENT);
		return asImport;
	}

	public @NonNull IntegerLiteralExp createIntegerLiteralExp(@NonNull Number integerSymbol) {
		IntegerLiteralExp asInteger = PivotFactory.eINSTANCE.createIntegerLiteralExp();
		asInteger.setIntegerSymbol(integerSymbol);
		asInteger.setType(standardLibrary.getIntegerType());
		asInteger.setIsRequired(true);
		return asInteger;
	}

	public @NonNull InvalidLiteralExp createInvalidExpression(/*Object object, String boundMessage, Throwable e*/) {
		InvalidLiteralExp invalidLiteralExp = PivotFactory.eINSTANCE.createInvalidLiteralExp();
		invalidLiteralExp.setType(standardLibrary.getOclInvalidType());
		//		invalidLiteralExp.setObject(object);
		//		invalidLiteralExp.setReason(boundMessage);
		//		invalidLiteralExp.setThrowable(e);
		return invalidLiteralExp;
	}

	public @NonNull IterateExp createIterateExp(@NonNull OCLExpression asSource, @NonNull Iteration asIteration, @NonNull List<@NonNull ? extends Variable> asIterators, @NonNull Variable asResult, @NonNull OCLExpression asBody) {
		IterateExp asCallExp = PivotFactory.eINSTANCE.createIterateExp();
		asCallExp.setReferredIteration(asIteration);
		asCallExp.setName(asIteration.getName());
		asCallExp.setOwnedSource(asSource);
		asCallExp.getOwnedIterators().addAll(asIterators);
		asCallExp.setOwnedResult(asResult);
		asCallExp.setOwnedBody(asBody);
		setOperationReturnType(asCallExp, asIteration);
		return asCallExp;
	}

	public @NonNull IteratorExp createIteratorExp(@NonNull OCLExpression asSource, @NonNull Iteration asIteration, @NonNull List<@NonNull ? extends Variable> asIterators, @NonNull OCLExpression asBody) {
		IteratorExp asCallExp = PivotFactory.eINSTANCE.createIteratorExp();
		asCallExp.setReferredIteration(asIteration);
		asCallExp.setName(asIteration.getName());
		asCallExp.setOwnedSource(asSource);
		asCallExp.getOwnedIterators().addAll(asIterators);
		asCallExp.setOwnedBody(asBody);
		setOperationReturnType(asCallExp, asIteration);
		return asCallExp;
	}

	public @NonNull IteratorVariable createIteratorVariable(@NonNull String name, @NonNull Type asType, boolean isRequired) {
		IteratorVariable asVariable = PivotFactory.eINSTANCE.createIteratorVariable();
		asVariable.setName(name);
		asVariable.setType(asType);
		asVariable.setIsRequired(isRequired);
		return asVariable;
	}

	public @NonNull LetExp createLetExp(@NonNull Variable asVariable, @NonNull OCLExpression asInExpression) {
		LetExp asLetExp = PivotFactory.eINSTANCE.createLetExp();
		asLetExp.setOwnedVariable(asVariable);
		asLetExp.setOwnedIn(asInExpression);;
		asLetExp.setType(asInExpression.getType());
		asLetExp.setIsRequired(asInExpression.isIsRequired());
		asLetExp.setOwnedVariable(asVariable);
		return asLetExp;
	}

	public @NonNull LetVariable createLetVariable(@NonNull String name, @NonNull OCLExpression asInitExpression) {
		LetVariable asVariable = PivotFactory.eINSTANCE.createLetVariable();
		asVariable.setName(name);
		asVariable.setType(asInitExpression.getType());
		asVariable.setIsRequired(asInitExpression.isIsRequired());
		asVariable.setOwnedInit(asInitExpression);
		return asVariable;
	}

	public @NonNull LetVariable createLetVariable(@NonNull String name, @NonNull Type asType, boolean isRequired) {
		LetVariable asVariable = PivotFactory.eINSTANCE.createLetVariable();
		asVariable.setName(name);
		asVariable.setType(asType);
		asVariable.setIsRequired(isRequired);
		return asVariable;
	}

	public @NonNull LetVariable createLetVariable(@NonNull String name, @NonNull Type asType, boolean isRequired, @NonNull OCLExpression asInitExpression) {
		LetVariable asVariable = PivotFactory.eINSTANCE.createLetVariable();
		asVariable.setName(name);
		asVariable.setType(asType);
		asVariable.setIsRequired(isRequired);
		asVariable.setOwnedInit(asInitExpression);
		return asVariable;
	}

	public @NonNull OCLExpression createMapLiteralExp(@NonNull MapType asType, @NonNull Iterable<MapLiteralPart> asParts) {
		MapLiteralExp mapLiteralExp = PivotFactory.eINSTANCE.createMapLiteralExp();
		Iterables.addAll(mapLiteralExp.getOwnedParts(), asParts);
		mapLiteralExp.setType(asType);
		mapLiteralExp.setIsRequired(true);
		return mapLiteralExp;
	}

	public @NonNull MapLiteralPart createMapLiteralPart(@NonNull OCLExpression asKey, @NonNull OCLExpression asValue) {
		MapLiteralPart mapLiteralPart = PivotFactory.eINSTANCE.createMapLiteralPart();
		mapLiteralPart.setOwnedKey(asKey);
		mapLiteralPart.setOwnedValue(asValue);
		//		mapLiteralPart.setType(asItem.getType());
		//		mapLiteralPart.setIsRequired(true);
		return mapLiteralPart;
	}

	@SuppressWarnings("deprecation")
	public @NonNull NavigationCallExp createNavigationCallExp(@NonNull OCLExpression asSourceExpression, @NonNull Property asProperty) {
		return PivotUtil.createNavigationCallExp(asSourceExpression, asProperty);
	}

	public @NonNull NullLiteralExp createNullLiteralExp() {
		NullLiteralExp asNull = PivotFactory.eINSTANCE.createNullLiteralExp();
		asNull.setType(standardLibrary.getOclVoidType());
		asNull.setIsRequired(false);
		return asNull;
	}

	public @NonNull OperationCallExp createOperationCallExp(@NonNull OCLExpression asSourceExpression, @NonNull String opName, @NonNull OCLExpression... asArguments) {
		Type asType = ClassUtil.nonNullState(asSourceExpression.getType());
		CompleteClass completeClass = environmentFactory.getCompleteModel().getCompleteClass(asType);
		int argumentCount = asArguments != null ? asArguments.length : 0;
		int bestMatches = -1;
		Operation bestOperation = null;
		for (@NonNull Operation asOperation : completeClass.getOperations(FeatureFilter.SELECT_NON_STATIC, opName)) {
			List<@NonNull ? extends TypedElement> asParameters = ClassUtil.nullFree(asOperation.getOwnedParameters());
			if ((asParameters.size() == argumentCount) && (asArguments != null)) {
				int exactMatches = 0;
				boolean gotOne = true;
				for (int i = 0; i < argumentCount; i++) {
					Type asParameterType = ClassUtil.nonNullState(asParameters.get(i).getType());
					if (asParameterType instanceof SelfType) {
						Type asArgumentType = asArguments[i].getType();
						if (asArgumentType.conformsTo(standardLibrary, asType) && asType.conformsTo(standardLibrary, asArgumentType)) {
							exactMatches++;
						}
					}
					else {
						Type asArgumentType = asArguments[i].getType();
						if (!asArgumentType.conformsTo(standardLibrary, asParameterType)) {
							gotOne = false;
							break;
						}
						if (asParameterType.conformsTo(standardLibrary, asArgumentType)) {
							exactMatches++;
						}
					}
				}
				if (gotOne) {
					if (exactMatches > bestMatches) {
						bestMatches = exactMatches;
						bestOperation = asOperation;
					}
					else if (exactMatches > bestMatches) {
						bestOperation = null;
					}
				}
			}
		}
		if (bestMatches < 0) {
			throw new IllegalStateException("No match found for " + opName);
		}
		if (bestOperation == null) {
			throw new IllegalStateException("Ambiguous match found for " + opName);
		}
		return createOperationCallExp(asSourceExpression, bestOperation, asArguments != null ? Lists.newArrayList(asArguments) : null);
	}

	//	public @NonNull OperationCallExp createOperationCallExp(@Nullable OCLExpression asSourceExpression, @NonNull Operation asOperation, @NonNull OCLExpression... asArguments) {
	//		return createOperationCallExp(asSourceExpression, asOperation, asArguments != null ? Lists.newArrayList(asArguments) : null);
	//	}

	public @NonNull OperationCallExp createOperationCallExp(@Nullable OCLExpression asSourceExpression, @NonNull Operation asOperation, @Nullable List<@NonNull OCLExpression> asArguments) {
		OperationCallExp asOperationCallExp = PivotFactory.eINSTANCE.createOperationCallExp();
		asOperationCallExp.setOwnedSource(asSourceExpression);
		asOperationCallExp.setReferredOperation(asOperation);
		asOperationCallExp.setName(asOperation.getName());
		if (asArguments != null) {
			asOperationCallExp.getOwnedArguments().addAll(asArguments);
		}
		setOperationReturnType(asOperationCallExp, asOperation);
		return asOperationCallExp;
	}

	public org.eclipse.ocl.pivot.@NonNull Package createPackage(@NonNull String name, @Nullable String nsPrefix, @Nullable String nsURI) {
		Package asPackage = PivotFactory.eINSTANCE.createPackage();
		asPackage.setName(name);
		if (nsPrefix != null) {
			asPackage.setNsPrefix(nsPrefix);
		}
		if (nsURI != null) {
			asPackage.setURI(nsURI);
		}
		return asPackage;
	}

	public @NonNull Parameter createParameter(@NonNull TypedElement typedElement) {
		String name = ClassUtil.nonNullState(typedElement.getName());
		Type type = ClassUtil.nonNullState(typedElement.getType());
		Parameter asParameter = PivotUtil.createParameter(name, type, typedElement.isIsRequired());
		return asParameter;
	}

	/**
	 * @since 1.11
	 */
	public @NonNull Parameter createParameter(@NonNull String name, @NonNull Type asType, boolean isRequired) {
		return PivotUtil.createParameter(name, asType, isRequired);
	}

	@Deprecated /* supply a representedParameter */
	public @NonNull ParameterVariable createParameterVariable(@NonNull String name, @NonNull Type asType, boolean isRequired) {
		ParameterVariable asVariable = PivotFactory.eINSTANCE.createParameterVariable();
		asVariable.setName(name);
		asVariable.setType(asType);
		asVariable.setIsRequired(isRequired);
		return asVariable;
	}

	/**
	 * @since 1.10
	 */
	public @NonNull ParameterVariable createParameterVariable(@NonNull Parameter asParameter) {
		ParameterVariable asParameterVariable = PivotFactory.eINSTANCE.createParameterVariable();
		asParameterVariable.setName(asParameter.getName());
		asParameterVariable.setType(asParameter.getType());
		asParameterVariable.setIsRequired(asParameter.isIsRequired());
		asParameterVariable.setRepresentedParameter(asParameter);
		return asParameterVariable;
	}

	/**
	 * @since 1.11
	 */
	public @NonNull PropertyCallExp createPropertyCallExp(@NonNull OCLExpression asSource, @NonNull Property asProperty) {
		return PivotUtil.createPropertyCallExp(asSource, asProperty);
	}

	public @NonNull RealLiteralExp createRealLiteralExp(@NonNull Number realSymbol) {
		RealLiteralExp asReal = PivotFactory.eINSTANCE.createRealLiteralExp();
		asReal.setRealSymbol(realSymbol);
		asReal.setType(standardLibrary.getRealType());
		asReal.setIsRequired(true);
		return asReal;
	}

	public @NonNull ResultVariable createResultVariable(@NonNull String name, @NonNull Type asType, boolean isRequired, @NonNull OCLExpression asInitExpression) {
		ResultVariable asVariable = PivotFactory.eINSTANCE.createResultVariable();
		asVariable.setName(name);
		asVariable.setType(asType);
		asVariable.setIsRequired(isRequired);
		asVariable.setOwnedInit(asInitExpression);
		return asVariable;
	}

	public @NonNull OCLExpression createShadowExp(org.eclipse.ocl.pivot.@NonNull Class asClass, @NonNull Iterable<ShadowPart> asParts) {
		ShadowExp shadowExp = PivotFactory.eINSTANCE.createShadowExp();
		Iterables.addAll(shadowExp.getOwnedParts(), asParts);
		shadowExp.setType(asClass);
		shadowExp.setIsRequired(true);
		return shadowExp;
	}

	public @NonNull ShadowPart createShadowPart(@NonNull Property asProperty, @NonNull OCLExpression asValue) {
		ShadowPart shadowPart = PivotFactory.eINSTANCE.createShadowPart();
		shadowPart.setReferredProperty(asProperty);
		shadowPart.setType(asProperty.getType());
		shadowPart.setIsRequired(asProperty.isIsRequired());
		shadowPart.setOwnedInit(asValue);
		return shadowPart;
	}

	public @NonNull StringLiteralExp createStringLiteralExp(@NonNull String stringSymbol) {
		StringLiteralExp asString = PivotFactory.eINSTANCE.createStringLiteralExp();
		asString.setStringSymbol(stringSymbol);
		asString.setType(standardLibrary.getStringType());
		asString.setIsRequired(true);
		return asString;
	}

	public @NonNull TupleLiteralExp createTupleLiteralExp(@NonNull TupleType asType, @NonNull Iterable<TupleLiteralPart> asParts) {
		TupleLiteralExp tupleLiteralExp = PivotFactory.eINSTANCE.createTupleLiteralExp();
		Iterables.addAll(tupleLiteralExp.getOwnedParts(), asParts);
		tupleLiteralExp.setType(asType);
		tupleLiteralExp.setIsRequired(true);
		return tupleLiteralExp;
	}

	public @NonNull TupleLiteralPart createTupleLiteralPart(@NonNull String name, @NonNull Type asType, boolean isRequired, @NonNull OCLExpression asValue) {
		TupleLiteralPart tupleLiteralPart = PivotFactory.eINSTANCE.createTupleLiteralPart();
		tupleLiteralPart.setName(name);
		tupleLiteralPart.setType(asType);
		tupleLiteralPart.setIsRequired(isRequired);
		tupleLiteralPart.setOwnedInit(asValue);
		return tupleLiteralPart;
	}

	public @NonNull TypeExp createTypeExp(@NonNull Type type) {
		TypeExp asTypeExp = PivotFactory.eINSTANCE.createTypeExp();
		asTypeExp.setIsRequired(true);
		asTypeExp.setReferredType(type);
		asTypeExp.setName(type.getName());
		asTypeExp.setType(type instanceof TemplateParameter ? metamodelManager.getOclType("TemplateParameter") : standardLibrary.getClassType());
		asTypeExp.setTypeValue(type);
		return asTypeExp;
	}

	public @NonNull UnlimitedNaturalLiteralExp createUnlimitedNaturalLiteralExp(@NonNull Number unlimitedNaturalSymbol) {
		UnlimitedNaturalLiteralExp asUnlimitedNatural = PivotFactory.eINSTANCE.createUnlimitedNaturalLiteralExp();
		asUnlimitedNatural.setUnlimitedNaturalSymbol(unlimitedNaturalSymbol);
		asUnlimitedNatural.setType(standardLibrary.getUnlimitedNaturalType());
		asUnlimitedNatural.setIsRequired(true);
		return asUnlimitedNatural;
	}

	/** @deprecated Use appropriate derived Variable */
	@Deprecated
	public @NonNull Variable createVariable(@NonNull String name, @NonNull OCLExpression asInitExpression) {
		Variable asVariable = PivotUtil.createVariable(name, asInitExpression);
		return asVariable;
	}

	/** @deprecated Use appropriate derived Variable */
	@Deprecated
	public @NonNull Variable createVariable(@NonNull String name, @NonNull Type asType, boolean isRequired, @Nullable OCLExpression asInitExpression) {
		Variable asVariable = PivotUtil.createVariable(name, asType, isRequired, asInitExpression);
		return asVariable;
	}

	/** @deprecated Use appropriate derived Variable */
	@Deprecated
	public @NonNull Variable createVariable(@NonNull TypedElement typedElement) {
		String name = ClassUtil.nonNullState(typedElement.getName());
		Type type = ClassUtil.nonNullState(typedElement.getType());
		Variable asVariable = PivotUtil.createVariable(name, type, typedElement.isIsRequired(), null);
		return asVariable;
	}

	public @NonNull VariableExp createVariableExp(@NonNull VariableDeclaration asVariable) {
		VariableExp asVariableExp = PivotUtil.createVariableExp(asVariable);
		return asVariableExp;
	}

	public org.eclipse.ocl.pivot.@NonNull Class getDataTypeClass() {
		return ClassUtil.nonNullState(metamodelManager.getASClass(TypeId.DATA_TYPE_NAME));
	}

	public @NonNull Property getDataTypeValueProperty() {
		return ClassUtil.nonNullState(NameUtil.getNameable(getDataTypeClass().getOwnedProperties(), PivotConstants.DATA_TYPE_VALUE_NAME));
	}

	public @NonNull EnvironmentFactory getEnvironmentFactory() {
		return environmentFactory;
	}

	protected @NonNull PivotMetamodelManager getMetamodelManager() {
		return metamodelManager;
	}

	public @NonNull StandardLibrary getStandardLibrary() {
		return standardLibrary;
	}

	/**
	 * @since 1.4
	 */
	public <T extends EObject> void refreshList(@Nullable List<? super T> oldElements, @Nullable List<? extends T> newElements) {
		PivotUtilInternal.refreshList(oldElements, newElements);
	}

	/**
	 * @since 1.4
	 */
	public void refreshName(@NonNull NamedElement pivotNamedElement, @Nullable String newName) {
		String oldName = pivotNamedElement.getName();
		if ((newName != oldName) && ((newName == null) || !newName.equals(oldName))) {
			pivotNamedElement.setName(newName);
		}
	}

	/**
	 * @since 1.4
	 */
	public void refreshNsURI(org.eclipse.ocl.pivot.@NonNull Package pivotPackage, String newNsURI) {
		String oldNsURI = pivotPackage.getURI();
		if ((newNsURI != oldNsURI) && ((newNsURI == null) || !newNsURI.equals(oldNsURI))) {
			pivotPackage.setURI(newNsURI);
		}
	}

	/**
	 * Rewrite asTree and all its descendants to replace all "?." and "?->" navigations by their safe counterparts.
	 * @since 1.3
	 */
	public void rewriteSafeNavigations(@NonNull Element asTree) {
		//
		//	Locate all unsafe calls first to avoid CME from concurrent locate/rewrite.
		//
		List<@NonNull CallExp> unsafeCallExps = null;
		if (asTree instanceof CallExp) {
			unsafeCallExps = rewriteUnsafeCallExp_Gather(unsafeCallExps, (CallExp)asTree);
		}
		for (TreeIterator<EObject> tit = asTree.eAllContents(); tit.hasNext(); ) {
			EObject eObject = tit.next();
			if (eObject instanceof CallExp) {
				unsafeCallExps = rewriteUnsafeCallExp_Gather(unsafeCallExps, (CallExp)eObject);
			}
		}
		//
		//	Rewrite the unsafe calls
		//
		if (unsafeCallExps != null) {
			org.eclipse.ocl.pivot.Class oclAnyType = standardLibrary.getOclAnyType();
			Operation oclEqualsOperation = NameUtil.getNameable(oclAnyType.getOwnedOperations(), "=");
			assert oclEqualsOperation != null;
			org.eclipse.ocl.pivot.Class collectionType = standardLibrary.getCollectionType();
			Operation excludingOperation = NameUtil.getNameable(collectionType.getOwnedOperations(), "excluding");
			assert excludingOperation != null;
			for (CallExp unsafeCallExp : unsafeCallExps) {
				OCLExpression source = unsafeCallExp.getOwnedSource();
				assert source != null;
				if (source.getType() instanceof CollectionType) {
					rewriteUnsafeCollectionCallExp(metamodelManager, excludingOperation, unsafeCallExp);
				}
				else {
					rewriteUnsafeObjectCallExp(metamodelManager, oclEqualsOperation, unsafeCallExp);
				}
			}
		}
	}

	private @Nullable List<@NonNull CallExp> rewriteUnsafeCallExp_Gather(@Nullable List<@NonNull CallExp> unsafeCallExps, @NonNull CallExp callExp) {
		OCLExpression source = callExp.getOwnedSource();
		if ((source != null) && callExp.isIsSafe()) {
			if (unsafeCallExps == null) {
				unsafeCallExps = new ArrayList<@NonNull CallExp>();
			}
			unsafeCallExps.add(callExp);
		}
		return unsafeCallExps;
	}

	private void rewriteUnsafeCollectionCallExp(@NonNull PivotMetamodelManager metamodelManager, @NonNull Operation excludingOperation, @NonNull CallExp unsafeCollectionCallExp) {
		unsafeCollectionCallExp.setIsSafe(false);
		EObject eContainer = unsafeCollectionCallExp.eContainer();
		EReference eContainmentFeature = unsafeCollectionCallExp.eContainmentFeature();
		PivotUtilInternal.resetContainer(unsafeCollectionCallExp);
		//
		OCLExpression nullExpression = metamodelManager.createNullLiteralExp();
		OCLExpression safeCollectionCallExp = createOperationCallExp(unsafeCollectionCallExp, excludingOperation, Collections.singletonList(nullExpression));
		//
		eContainer.eSet(eContainmentFeature, safeCollectionCallExp);
	}

	/**
	 * @since 1.4
	 */
	private  void rewriteUnsafeObjectCallExp(@NonNull PivotMetamodelManager metamodelManager, @NonNull Operation oclEqualsOperation, @NonNull CallExp unsafeObjectCallExp) {
		unsafeObjectCallExp.setIsSafe(false);
		EObject eContainer = unsafeObjectCallExp.eContainer();
		EReference eContainmentFeature = unsafeObjectCallExp.eContainmentFeature();
		PivotUtilInternal.resetContainer(unsafeObjectCallExp);
		OCLExpression oldSourceExpression = unsafeObjectCallExp.getOwnedSource();
		assert oldSourceExpression != null;
		//
		LetVariable unsafeSourceVariable = createLetVariable("unsafe", oldSourceExpression);
		OCLExpression unsafeSourceExpression1 = createVariableExp(unsafeSourceVariable);
		unsafeObjectCallExp.setOwnedSource(unsafeSourceExpression1);
		//
		OCLExpression unsafeSourceExpression2 = createVariableExp(unsafeSourceVariable);
		OCLExpression nullExpression = metamodelManager.createNullLiteralExp();
		OCLExpression isUnsafeExpression = createOperationCallExp(unsafeSourceExpression2, oclEqualsOperation, Collections.singletonList(nullExpression));
		//
		OCLExpression thenExpression = metamodelManager.createNullLiteralExp();
		OCLExpression safeObjectCallExp = metamodelManager.createIfExp(isUnsafeExpression, thenExpression, unsafeObjectCallExp);
		//
		LetExp safeExp = createLetExp(unsafeSourceVariable, safeObjectCallExp);
		//
		eContainer.eSet(eContainmentFeature, safeExp);
	}

	/**
	 * @since 1.4
	 */
	@Deprecated /* @deprecated not used -doesn't set behavioral type */
	public void setBehavioralType(@NonNull TypedElement targetElement, @NonNull TypedElement sourceElement) {
		if (!sourceElement.eIsProxy()) {
			Type type = PivotUtil.getBehavioralType(sourceElement);
			if ((type != null) && type.eIsProxy()) {
				type = null;
			}
			boolean isRequired = sourceElement.isIsRequired();
			setType(targetElement, type, isRequired);
		}
	}

	/**
	 * @since 1.4
	 */
	public void setContextVariable(@NonNull ExpressionInOCL pivotSpecification, @NonNull String selfVariableName, @Nullable Type contextType, @Nullable Type contextInstance) {
		Variable contextVariable = pivotSpecification.getOwnedContext();
		if (contextVariable == null) {
			@NonNull ParameterVariable nonNullContextVariable = PivotFactory.eINSTANCE.createParameterVariable();
			contextVariable = nonNullContextVariable;
			pivotSpecification.setOwnedContext(contextVariable);
			if (contextType == null) {
				contextType = standardLibrary.getOclVoidType();
			}
		}
		refreshName(contextVariable, selfVariableName);
		setType(contextVariable, contextType, contextVariable.isIsRequired(), contextInstance);
	}

	/**
	 * Set the operation/iteration return type and nullity in the asCallExp. This may involve creating a specialization
	 * of the operation/iteration return type and may require the use of a TemplateParameterSubstitutionHelper to
	 * compute inadequately modelled unique/ordered/size/nullity.
	 *
	 * @since 1.4
	 */
	public void setOperationReturnType(@NonNull CallExp asCallExp, @NonNull Operation asOperation) {
		OCLExpression asSourceExpression = asCallExp.getOwnedSource();
		Type sourceType;
		Type sourceTypeValue;
		if (asSourceExpression != null) {
			sourceType = asSourceExpression.getType();
			sourceTypeValue = asSourceExpression.getTypeValue();
		}
		else {
			sourceType = null;
			sourceTypeValue = null;
		}
		Type returnType = null;
		Type formalType = asOperation.getType();
		boolean isTypeof = asOperation.isIsTypeof();
		boolean returnIsRequired = asOperation.isIsRequired();
		if ((formalType != null) && (sourceType != null)) {
			if (isTypeof) {
				returnType = metamodelManager.specializeType(formalType, asCallExp, sourceType, null);
			}
			else {
				returnType = metamodelManager.specializeType(formalType, asCallExp, sourceType, sourceTypeValue);
			}
		}
		//
		//	The flattening of collect() and consequently implicit-collect is not modelled accurately.
		//	Other library operations have subtle non-null/size computations.
		//	Therefore allow an operation-specific TemplateParameterSubstitutionHelper to adjust the regular functionality above.
		//
		LibraryFeature implementationClass = asOperation.getImplementation();
		if (implementationClass != null) {
			Class<? extends LibraryFeature> libraryClass = implementationClass.getClass();
			TemplateParameterSubstitutionHelper substitutionHelper = TemplateParameterSubstitutionHelper.getHelper(libraryClass);
			if (substitutionHelper != null) {
				returnType = substitutionHelper.resolveReturnType(metamodelManager, asCallExp, returnType);
				returnIsRequired = substitutionHelper.resolveReturnNullity(metamodelManager, asCallExp, returnIsRequired);
			}
		}
		Type returnTypeValue;
		if (isTypeof) {
			returnTypeValue = returnType;
			returnType = standardLibrary.getClassType();
		}
		else {
			returnTypeValue = null;
		}
		setType(asCallExp, returnType, returnIsRequired, returnTypeValue);
	}

	public void setType(@NonNull OCLExpression asExpression, Type type, boolean isRequired, @Nullable Type typeValue) {
		setType(asExpression, type, isRequired);
		Type primaryTypeValue = typeValue != null ? metamodelManager.getPrimaryType(typeValue) : null;
		if (primaryTypeValue != asExpression.getTypeValue()) {
			asExpression.setTypeValue(primaryTypeValue);
		}
	}

	/**
	 * @since 1.4
	 */
	public void setType(@NonNull VariableDeclaration asVariable, Type type, boolean isRequired, @Nullable Type typeValue) {
		setType(asVariable, type, isRequired);
		Type primaryTypeValue = typeValue != null ? metamodelManager.getPrimaryType(typeValue) : null;
		if (primaryTypeValue != asVariable.getTypeValue()) {
			asVariable.setTypeValue(primaryTypeValue);
		}
	}

	public void setType(@NonNull TypedElement asTypedElement, Type type, boolean isRequired) {
		Type primaryType = type != null ? metamodelManager.getPrimaryType(type) : null;
		if (primaryType != asTypedElement.getType()) {
			asTypedElement.setType(primaryType);
		}
		boolean wasRequired = asTypedElement.isIsRequired();
		if (wasRequired != isRequired) {
			asTypedElement.setIsRequired(isRequired);
		}
		if (primaryType != null) {
			PivotUtil.debugWellContainedness(primaryType);
		}
	}
}