/*******************************************************************************
 * Copyright (c) 2010,2013 E.D.Willink 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
 *   E.D.Willink (CEA LIST) - Bug 388493
 * 	 E.D.Willink (Obeo) - Bug 416287 - tuple-valued constraints
 *******************************************************************************/
package org.eclipse.ocl.examples.xtext.essentialocl.cs2as;

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

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.examples.domain.elements.DomainOperation;
import org.eclipse.ocl.examples.domain.elements.FeatureFilter;
import org.eclipse.ocl.examples.domain.utilities.DomainUtil;
import org.eclipse.ocl.examples.library.collection.CollectionFlattenOperation;
import org.eclipse.ocl.examples.pivot.BooleanLiteralExp;
import org.eclipse.ocl.examples.pivot.CallExp;
import org.eclipse.ocl.examples.pivot.CollectionItem;
import org.eclipse.ocl.examples.pivot.CollectionLiteralExp;
import org.eclipse.ocl.examples.pivot.CollectionLiteralPart;
import org.eclipse.ocl.examples.pivot.CollectionRange;
import org.eclipse.ocl.examples.pivot.CollectionType;
import org.eclipse.ocl.examples.pivot.ConstructorExp;
import org.eclipse.ocl.examples.pivot.ConstructorPart;
import org.eclipse.ocl.examples.pivot.Element;
import org.eclipse.ocl.examples.pivot.ElementExtension;
import org.eclipse.ocl.examples.pivot.EnumLiteralExp;
import org.eclipse.ocl.examples.pivot.EnumerationLiteral;
import org.eclipse.ocl.examples.pivot.Environment;
import org.eclipse.ocl.examples.pivot.ExpressionInOCL;
import org.eclipse.ocl.examples.pivot.FeatureCallExp;
import org.eclipse.ocl.examples.pivot.IfExp;
import org.eclipse.ocl.examples.pivot.IntegerLiteralExp;
import org.eclipse.ocl.examples.pivot.InvalidLiteralExp;
import org.eclipse.ocl.examples.pivot.InvalidType;
import org.eclipse.ocl.examples.pivot.IterateExp;
import org.eclipse.ocl.examples.pivot.Iteration;
import org.eclipse.ocl.examples.pivot.IteratorExp;
import org.eclipse.ocl.examples.pivot.LetExp;
import org.eclipse.ocl.examples.pivot.LoopExp;
import org.eclipse.ocl.examples.pivot.Metaclass;
import org.eclipse.ocl.examples.pivot.NamedElement;
import org.eclipse.ocl.examples.pivot.NavigationCallExp;
import org.eclipse.ocl.examples.pivot.NullLiteralExp;
import org.eclipse.ocl.examples.pivot.NumericLiteralExp;
import org.eclipse.ocl.examples.pivot.OCLExpression;
import org.eclipse.ocl.examples.pivot.Operation;
import org.eclipse.ocl.examples.pivot.OperationCallExp;
import org.eclipse.ocl.examples.pivot.OppositePropertyCallExp;
import org.eclipse.ocl.examples.pivot.Parameter;
import org.eclipse.ocl.examples.pivot.ParameterableElement;
import org.eclipse.ocl.examples.pivot.PivotConstants;
import org.eclipse.ocl.examples.pivot.PivotPackage;
import org.eclipse.ocl.examples.pivot.Property;
import org.eclipse.ocl.examples.pivot.PropertyCallExp;
import org.eclipse.ocl.examples.pivot.State;
import org.eclipse.ocl.examples.pivot.StateExp;
import org.eclipse.ocl.examples.pivot.StringLiteralExp;
import org.eclipse.ocl.examples.pivot.TemplateParameter;
import org.eclipse.ocl.examples.pivot.TemplateSignature;
import org.eclipse.ocl.examples.pivot.TupleLiteralExp;
import org.eclipse.ocl.examples.pivot.TupleLiteralPart;
import org.eclipse.ocl.examples.pivot.Type;
import org.eclipse.ocl.examples.pivot.TypeExp;
import org.eclipse.ocl.examples.pivot.TypedElement;
import org.eclipse.ocl.examples.pivot.UnlimitedNaturalLiteralExp;
import org.eclipse.ocl.examples.pivot.Variable;
import org.eclipse.ocl.examples.pivot.VariableDeclaration;
import org.eclipse.ocl.examples.pivot.VariableExp;
import org.eclipse.ocl.examples.pivot.lookup.ISingleResultEnvironment;
import org.eclipse.ocl.examples.pivot.lookup.NewPivotNameResolver;
import org.eclipse.ocl.examples.pivot.manager.MetaModelManager;
import org.eclipse.ocl.examples.pivot.messages.OCLMessages;
import org.eclipse.ocl.examples.pivot.scoping.EnvironmentView;
import org.eclipse.ocl.examples.pivot.scoping.ScopeFilter;
import org.eclipse.ocl.examples.pivot.scoping.ScopeView;
import org.eclipse.ocl.examples.pivot.utilities.PivotUtil;
import org.eclipse.ocl.examples.xtext.base.basecs.ElementCS;
import org.eclipse.ocl.examples.xtext.base.basecs.ModelElementCS;
import org.eclipse.ocl.examples.xtext.base.basecs.PathElementCS;
import org.eclipse.ocl.examples.xtext.base.basecs.PathNameCS;
import org.eclipse.ocl.examples.xtext.base.basecs.TypedRefCS;
import org.eclipse.ocl.examples.xtext.base.cs2as.CS2Pivot;
import org.eclipse.ocl.examples.xtext.base.cs2as.CS2PivotConversion;
import org.eclipse.ocl.examples.xtext.base.scoping.BaseScopeView;
import org.eclipse.ocl.examples.xtext.base.utilities.ElementUtil;
import org.eclipse.ocl.examples.xtext.essentialocl.attributes.BinaryOperationFilter;
import org.eclipse.ocl.examples.xtext.essentialocl.attributes.ImplicitCollectFilter;
import org.eclipse.ocl.examples.xtext.essentialocl.attributes.ImplicitCollectionFilter;
import org.eclipse.ocl.examples.xtext.essentialocl.attributes.UnaryOperationFilter;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.AbstractNameExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.BinaryOperatorCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.BooleanLiteralExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.CollectionLiteralExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.CollectionLiteralPartCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.CollectionTypeCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.ConstructorExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.ConstructorPartCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.ContextCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.ExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.IfExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.IndexExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.InfixExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.InvalidLiteralExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.InvocationExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.LetExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.LetVariableCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.NameExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.NavigatingArgCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.NavigationOperatorCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.NavigationRole;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.NestedExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.NullLiteralExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.NumberLiteralExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.OperatorCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.PrefixExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.SelfExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.StringLiteralExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.TupleLiteralExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.TupleLiteralPartCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.TypeLiteralExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.UnaryOperatorCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.UnlimitedNaturalLiteralExpCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.VariableCS;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialoclcs.util.AbstractEssentialOCLCSLeft2RightVisitor;

public class EssentialOCLCSLeft2RightVisitor extends AbstractEssentialOCLCSLeft2RightVisitor
{
	/**
	 * Configure use of the new auto-generated lookup or the old manually coded lookup.
	 * @since 3.5
	 */
	public static boolean AUTOGENERATED_LOOKUP = true;

	private static final class TypeArgumentFilter implements ScopeFilter
	{
		public static TypeArgumentFilter INSTANCE = new TypeArgumentFilter();
		
		public int compareMatches(@NonNull MetaModelManager metaModelManager, @NonNull Object match1, @Nullable Map<TemplateParameter, ParameterableElement> bindings1,
				@NonNull Object match2, @Nullable Map<TemplateParameter, ParameterableElement> bindings2) {
			return 0;
		}

		public boolean matches(@NonNull EnvironmentView environmentView, @NonNull Object object) {
			if (object instanceof Type) {
				return true;
			}
			if (object instanceof TypedElement) {
				return ((TypedElement)object).getType() instanceof Metaclass<?>;
			}
			return false;
		}
	}

	      
//	private static final Logger logger = Logger.getLogger(EssentialOCLLeft2RightVisitor.class);

	protected final @NonNull MetaModelManager metaModelManager;
	/**
	 * @since 3.5
	 */
	protected final @NonNull NewPivotNameResolver lResolver;
	
	public EssentialOCLCSLeft2RightVisitor(@NonNull CS2PivotConversion context) {
		super(context);
		this.metaModelManager = context.getMetaModelManager();
		this.lResolver = new NewPivotNameResolver(metaModelManager); // FIXME factory method
	}

/*	protected OCLExpression zzcheckImplementation(NamedExpCS csNavigatingExp,
			Feature feature, CallExp callExp, OCLExpression expression) {
		LibraryFeature implementation;
		try {
			implementation = metaModelManager.getImplementation(feature);
		} catch (Exception e) {
			return context.addBadExpressionError(csNavigatingExp, "Failed to load '" + feature.getImplementationClass() + "': " + e);
		}
		if (implementation != null) {
			LibraryValidator validator = implementation.getValidator(metaModelManager);
			if (validator != null) {
				Diagnostic diagnostic = validator.validate(metaModelManager, callExp);
				if (diagnostic != null) {
					context.addDiagnostic(csNavigatingExp, diagnostic);
				}
			}
		}
		return expression;
	} */

	protected void checkForInvalidImplicitSourceType(@NonNull ExpCS csInvocationExp) {
		for (ImplicitSourceTypeIterator it = new ImplicitSourceTypeIterator(csInvocationExp); it.hasNext(); ) {
			if (isInvalidType(it.next())) {
				csInvocationExp.setHasError(true);
				break;
			}
		}
	}

	protected ImplicitSourceTypeIterator createImplicitSourceTypeIterator(@NonNull ElementCS csElement) {
		return new ImplicitSourceTypeIterator(csElement);
	}

	protected @NonNull OCLExpression createImplicitSourceVariableExp(@NonNull AbstractNameExpCS csNameExp, Type owningType) {
		VariableDeclaration sourceVariable = owningType != null ? getImplicitSource(csNameExp, owningType) : null;
		if (sourceVariable == null) {
			@SuppressWarnings("unused") VariableDeclaration sourceVariable2 = owningType != null ? getImplicitSource(csNameExp, owningType) : null;
			return context.addBadExpressionError(csNameExp, "No implicit source");
		}
		else {
			return createImplicitVariableExp(sourceVariable);
		}
	}

	protected @NonNull VariableExp createImplicitVariableExp(@NonNull VariableDeclaration variable) {
		VariableExp variableExp = context.refreshModelElement(VariableExp.class, PivotPackage.Literals.VARIABLE_EXP, null); // FIXME reuse
		variableExp.setReferredVariable(variable);
		variableExp.setImplicit(true);
		context.setType(variableExp, variable.getType(), variable.isRequired());
		return variableExp;
	}

/*	private TemplateParameterSubstitution findFormalParameter(TemplateParameter formalTemplateParameter, Type actualType) {
		for (TemplateBinding actualTemplateBinding : actualType.getTemplateBinding()) {
			for (TemplateParameterSubstitution actualTemplateParameterSubstitution : actualTemplateBinding.getParameterSubstitution()) {
				TemplateParameter actualFormal = actualTemplateParameterSubstitution.getFormal();
				if (actualFormal == formalTemplateParameter) {
					return actualTemplateParameterSubstitution;
				}
			}
		}
		if (actualType instanceof org.eclipse.ocl.examples.pivot.Class) {
			for (org.eclipse.ocl.examples.pivot.Class superClass : ((org.eclipse.ocl.examples.pivot.Class)actualType).getSuperClass()) {
				TemplateParameterSubstitution actualTemplateParameterSubstitution = findFormalParameter(formalTemplateParameter, superClass);
				if (actualTemplateParameterSubstitution != null) {
					return actualTemplateParameterSubstitution;
				}
			}
		}
		return null;
	} */
	
	protected @Nullable Iteration getBestIteration(@NonNull List<NamedElement> invocations) {
		Iteration bestIteration = null;
		Type bestType = null;
		int bestIteratorsSize = Integer.MAX_VALUE;
		for (NamedElement operation : invocations) {
			if (operation instanceof Iteration) {
				Iteration iteration = (Iteration) operation;
				int iteratorsSize = iteration.getOwnedIterator().size();
				if ((bestIteration == null) || (iteratorsSize <= bestIteratorsSize)) {
					Type specializedType = iteration.getOwningType();
					if (specializedType != null) {
						Type unspecializedType = PivotUtil.getUnspecializedTemplateableElement(specializedType);
						if ((bestType == null) || !metaModelManager.isSuperClassOf(unspecializedType, bestType)) {
							bestIteration = iteration;
							bestType = unspecializedType;
							bestIteratorsSize = iteratorsSize;
						}
					}
				}
			}
		}
		return bestIteration;
	}

	protected @Nullable Operation getExampleOperation(@NonNull List<NamedElement> invocations) {
		if (invocations.size() <= 1) {
			NamedElement namedElement = invocations.get(0);
			return namedElement instanceof Operation ? (Operation)namedElement : null;
		}
		@SuppressWarnings("null")@NonNull EReference aReferredOperation = PivotPackage.Literals.OPERATION_CALL_EXP__REFERRED_OPERATION;
		EnvironmentView environmentView = new EnvironmentView(metaModelManager, aReferredOperation, null);
		environmentView.addElements(invocations);
		environmentView.resolveDuplicates();
		Object content = environmentView.getEntries().iterator().next().getValue();
		if (content instanceof List<?>) {
			content = ((List<?>)content).get(0);
		}
		return (Operation) content;
	}

/*	private TemplateParameter getFormal(List<TemplateBinding> templateBindings, TemplateParameter templateParameter) {
		for (TemplateBinding templateBinding : templateBindings) {
			for (TemplateParameterSubstitution templateParameterSubstitution : templateBinding.getParameterSubstitution()) {
				if (templateParameter == templateParameterSubstitution.getFormal()) {
					return templateParameterSubstitution.getActual().getOwningTemplateParameter();
				}
			}
		}
		return null;
	} */
	
	protected @Nullable List<NamedElement> getInvocations(@Nullable OCLExpression sourceExp, @NonNull InvocationExpCS csInvocationExp) {
		NameExpCS csNameExp = csInvocationExp.getNameExp();
		if (csNameExp == null) {
			return null;
		}
		PathNameCS csPathName = csNameExp.getPathName();
		if (csPathName == null) {
			return null;
		}
		List<PathElementCS> csPathElements = csPathName.getPath();
		if (csPathElements == null) {
			return null;
		}
		int pathSize = csPathElements.size();
		if (pathSize <= 0) {
			return null;
		}
		PathElementCS csLastPathElement = csPathElements.get(pathSize-1);
		if (csLastPathElement == null) {
			return null;
		}
		Element asElement = csLastPathElement.basicGetElement();
		if ((asElement instanceof Operation) && !asElement.eIsProxy()) {
			return Collections.singletonList((NamedElement)asElement);
		}
		String name = ElementUtil.getTextName(csLastPathElement);
		if (name == null) {
			return null;
		}
		int iteratorCount = 0;
		int expressionCount = 0;
		for (NavigatingArgCS csArg : csInvocationExp.getArgument()) {
			if (csArg.getRole() == NavigationRole.ITERATOR) {
				iteratorCount++;
			}
			else if (csArg.getRole() == NavigationRole.EXPRESSION) {
				expressionCount++;
			}
		}
		if (pathSize > 1) {											// Search for B::b() or a.B::b() candidates in B
			Element asScope = csPathElements.get(pathSize - 2).getElement();
			if (!(asScope instanceof Type)) {
				return null;
			}
			Type asType = (Type)asScope;
			List<NamedElement> invocations = getInvocations(asType, name, iteratorCount, expressionCount);
			if ((invocations == null) && name.startsWith("_")) {
				@SuppressWarnings("null")@NonNull String unescapedName = name.substring(1);				// FIXME Compatibility
				invocations = getInvocations(asType, unescapedName, iteratorCount, expressionCount);
			}
			return invocations;
		}
		else if (sourceExp != null) {								// Search for a.b() candidates in type of a
			Type asType = sourceExp.getType();
			if (asType == null) {
				return null;
			}
			if (asType.getOwningTemplateParameter() != null) {
				asType = metaModelManager.getOclAnyType();
			}
			List<NamedElement> invocations = getInvocations(asType, name, iteratorCount, expressionCount);
			if ((invocations == null) && name.startsWith("_")) {
				@SuppressWarnings("null")@NonNull String unescapedName = name.substring(1);				// FIXME Compatibility
				invocations = getInvocations(asType, unescapedName, iteratorCount, expressionCount);
			}
			return invocations;
		}
		else {														// Search for a() candidates in implicit source variable types
			List<NamedElement> invocations = null;
			for (ImplicitSourceTypeIterator it = createImplicitSourceTypeIterator(csInvocationExp); (invocations == null) && it.hasNext(); ) {
				Type asType = it.next();
				invocations = getInvocations(asType, name, iteratorCount, expressionCount);
			}
			if ((invocations == null) && name.startsWith("_")) {
				@SuppressWarnings("null")@NonNull String unescapedName = name.substring(1);				// FIXME Compatibility
				for (ImplicitSourceTypeIterator it = createImplicitSourceTypeIterator(csInvocationExp); (invocations == null) && it.hasNext(); ) {
					Type asType = it.next();
					invocations = getInvocations(asType, unescapedName, iteratorCount, expressionCount);
				}
			}
			return invocations;
		}
	}

	protected @Nullable VariableDeclaration getImplicitSource(@NonNull ModelElementCS csExp, @NonNull Type requiredType) {
		@Nullable VariableDeclaration lastVariable = null;
		for (ImplicitSourceVariableIterator it = new ImplicitSourceVariableIterator(csExp); it.hasNext(); )  {
			@NonNull Variable variable = it.next();
			lastVariable = variable;
			Type type = variable.getType();
			if ((type != null) && type.conformsTo(metaModelManager, requiredType)) {
				return variable;
			}
		}
		return lastVariable;		// If no good variable found, the outermost variable is the least bad.
	}			// FIXME report all possible variables as bad to user

	/**
	 * Return all operations/iterations in asType and its superclasses whose name is name. For iterations the number of iteration iterators must
	 * match iteratorCount unless iteratorCount is zero. For operations the number of parameters must be expressionCount. Returns null if
	 * nothing is found.
	 */
	protected @Nullable List<NamedElement> getInvocations(@NonNull Type asType, @NonNull String name, int iteratorCount, int expressionCount) {
		Iterable<? extends DomainOperation> instanceOperations = metaModelManager.getAllOperations(asType, FeatureFilter.SELECT_NON_STATIC, name);
		List<NamedElement> invocations = getInvocationsInternal(null, instanceOperations, iteratorCount, expressionCount);
		if (asType instanceof ElementExtension) {
			Type asStereotype = ((ElementExtension)asType).getStereotype();
			if (asStereotype != null) {
				Iterable<? extends DomainOperation> stereotypeOperations = metaModelManager.getAllOperations(asStereotype, FeatureFilter.SELECT_NON_STATIC, name);
				invocations = getInvocationsInternal(invocations, stereotypeOperations, iteratorCount, expressionCount);
			}
		}
		if (asType instanceof Metaclass<?>) {
			Type instanceType = ((Metaclass<?>)asType).getInstanceType();
			if (instanceType != null) {
				Iterable<? extends DomainOperation> classOperations = metaModelManager.getAllOperations(instanceType, FeatureFilter.SELECT_STATIC, name);
				invocations = getInvocationsInternal(invocations, classOperations, iteratorCount, expressionCount);
			}
		}
		return invocations;
	}
	protected @Nullable List<NamedElement> getInvocationsInternal(@Nullable List<NamedElement> invocations,
			@NonNull Iterable<? extends DomainOperation> allOperations, int iteratorCount, int expressionCount) {
		for (DomainOperation operation : allOperations) {
			Operation asOperation = null;
			if (operation instanceof Iteration) {
				Iteration candidateIteration = (Iteration) operation;
				int iteratorsSize = candidateIteration.getOwnedIterator().size();
				if ((iteratorCount == 0) || (iteratorCount == iteratorsSize)) {
					asOperation = candidateIteration;
				}
			}
			else if (operation instanceof Operation){
				Operation candidateOperation = (Operation) operation;
				int operationsSize = candidateOperation.getOwnedParameter().size();
				if (expressionCount == operationsSize) {
					asOperation = candidateOperation;
				}
			}
			if (asOperation != null) {
				if (invocations == null) {
					invocations = new ArrayList<NamedElement>();
				}
				invocations.add(asOperation);
			}
		}
		return invocations;
	}

	protected boolean isInvalidType(@Nullable Type type) {
		return (type == null) || (type instanceof InvalidType)
		 || ((type instanceof CollectionType) && (((CollectionType)type).getElementType() instanceof InvalidType));
	}

	protected @NonNull OperationCallExp refreshOperationCallExp(@NonNull InvocationExpCS csInvocationExp, @NonNull OCLExpression sourceExp) {
		OperationCallExp callExp = context.refreshModelElement(OperationCallExp.class, PivotPackage.Literals.OPERATION_CALL_EXP, csInvocationExp);
		callExp.setSource(sourceExp);			
		return callExp;
	}

	protected @NonNull OppositePropertyCallExp refreshOppositePropertyCallExp(@NonNull NameExpCS csNameExp, @NonNull OCLExpression sourceExp, @NonNull Property property) {
		OppositePropertyCallExp callExp = context.refreshModelElement(OppositePropertyCallExp.class, PivotPackage.Literals.OPPOSITE_PROPERTY_CALL_EXP, csNameExp);
		callExp.setSource(sourceExp);			
		callExp.setReferredProperty(property.getOpposite());
		return callExp;
	}

	protected @NonNull PropertyCallExp refreshPropertyCallExp(@NonNull NameExpCS csNameExp, @NonNull OCLExpression sourceExp, @NonNull Property property) {
		PropertyCallExp callExp = context.refreshModelElement(PropertyCallExp.class, PivotPackage.Literals.PROPERTY_CALL_EXP, csNameExp);
		callExp.setSource(sourceExp);			
		callExp.setReferredProperty(property);
		return callExp;
	}

	protected void resolveAtPre(@Nullable NameExpCS csNameExp, @NonNull FeatureCallExp featureCallExp) {
		if (csNameExp != null) {
			featureCallExp.setIsPre(csNameExp.isAtPre());
		}
	}

	/**
	 * Resolve an invocation such as name() or source.name(...)  or source->name(...) to the best candidate from invocations.
	 * <p>
	 * sourceExp is null for an implicit source invocation.
	 * <p>
	 * csInvocationExp.getNamedElement() must be invoked once, after the left-hand context has been established to enable the lokup to
	 * proceed in a simple (perhaps rivial) fashion.
	 */
	protected @Nullable OCLExpression resolveBestInvocation(@Nullable OCLExpression sourceExp, @NonNull InvocationExpCS csInvocationExp, @NonNull List<NamedElement> invocations) {
		Iteration iteration = getBestIteration(invocations);
		if (iteration != null) {
			if (sourceExp == null) {
				sourceExp = createImplicitSourceVariableExp(csInvocationExp, iteration.getOwningType());
			}
			LoopExp iterationCallExp = resolveIterationCallExp(csInvocationExp, sourceExp, iteration);
			@SuppressWarnings("unused")NamedElement namedElement = csInvocationExp.getNamedElement();	// Now let Xtext find the iteration
			resolveIterationContent(csInvocationExp, iterationCallExp);
			return iterationCallExp;
		}
		else {
			Operation exampleOperation = getExampleOperation(invocations);
			if (exampleOperation != null) {
				if (sourceExp == null) {
					sourceExp = createImplicitSourceVariableExp(csInvocationExp, exampleOperation.getOwningType());
				}
				OperationCallExp operationCallExp = refreshOperationCallExp(csInvocationExp, sourceExp);
				if (invocations.size() == 1) {
					context.setReferredOperation(operationCallExp, exampleOperation);
				}
				//
				//	Need to resolve types for operation arguments in order to disambiguate operation names.
				//
				resolveOperationArgumentTypes(csInvocationExp);
				//
				//	Resolve the static operation/iteration by name and known operation argument types.
				//
				NamedElement namedElement = csInvocationExp.getNamedElement();								// Now let Xtext resolve the operation
				if (namedElement instanceof Operation) {
					return resolveOperationCallExp(csInvocationExp, operationCallExp, (Operation)namedElement);
				}
			}
		}
		return null;
	}

	protected @NonNull EnumLiteralExp resolveEnumLiteral(@NonNull ExpCS csExp, @NonNull EnumerationLiteral enumerationLiteral) {
		EnumLiteralExp expression = context.refreshModelElement(EnumLiteralExp.class, PivotPackage.Literals.ENUM_LITERAL_EXP, csExp);
		context.setType(expression, enumerationLiteral.getEnumeration(), true);
		expression.setReferredEnumLiteral(enumerationLiteral);
		return expression;
	}

	/**
	 * Resolve an invocation such as source.name  or source->name
	 */
	protected @NonNull OCLExpression resolveExplicitSourceNavigation(@NonNull OCLExpression sourceExp, @NonNull NameExpCS csNamedExp) {
		NamedElement namedElement = csNamedExp.getNamedElement();
		if ((namedElement instanceof Property) && !namedElement.eIsProxy()) {
			CallExp callExp = resolvePropertyCallExp(sourceExp, csNamedExp, (Property)namedElement);
			return callExp;
		}
		PropertyCallExp expression = refreshPropertyCallExp(csNamedExp, sourceExp, metaModelManager.getOclInvalidProperty());
		context.setType(expression, metaModelManager.getOclInvalidType(), false);
		return expression;
	}

	protected @NonNull OCLExpression resolveImplicitAsSet(@NonNull OCLExpression sourceExp, @NonNull Type sourceType, @NonNull NavigationOperatorCS csOperator) {
		OperationCallExp expression = context.refreshModelElement(OperationCallExp.class, PivotPackage.Literals.OPERATION_CALL_EXP, null);
		expression.setImplicit(true);
		PivotUtil.resetContainer(sourceExp);
		expression.setSource(sourceExp);
		expression.setName("oclAsSet");
		resolveOperationCall(expression, csOperator, new ImplicitCollectionFilter(sourceType));
		return expression;
	}

	/**
	 * Return a non-null implicit collect() call if a sourceExp for a csElement requires an implicit collect.
	 * The return call has noo bosdy or return type since they cannot be synmthesized until the body is synthesized.
	 */
	protected @Nullable IteratorExp resolveImplicitCollectExp(@NonNull OCLExpression sourceExp, @NonNull AbstractNameExpCS csElement) {
		OperatorCS parent = csElement.getParent();
		if (!(parent instanceof NavigationOperatorCS)) {
			return null;
		}
		if (parent.getSource() == csElement) {
			return null;
		}
		NavigationOperatorCS navigationOperatorCS = (NavigationOperatorCS)parent;
		if (!PivotConstants.OBJECT_NAVIGATION_OPERATOR.equals(navigationOperatorCS.getName())) {
			return null;
		}
		Type actualSourceType = sourceExp.getType();
		if (!(actualSourceType instanceof CollectionType)) {
			return null;
		}
		Type elementType = ((CollectionType)actualSourceType).getElementType();
		if (elementType == null) {
			return null;
		}
		IteratorExp implicitCollectExp = context.refreshModelElement(IteratorExp.class, PivotPackage.Literals.ITERATOR_EXP, null);
		implicitCollectExp.setSource(sourceExp);
		implicitCollectExp.setImplicit(true);
		@SuppressWarnings("null") @NonNull EReference eReference = PivotPackage.Literals.LOOP_EXP__REFERRED_ITERATION;
		EnvironmentView environmentView = new EnvironmentView(metaModelManager, eReference, "collect");
		environmentView.addFilter(new ImplicitCollectFilter((CollectionType) actualSourceType, elementType));
		Type lowerBoundType = (Type) PivotUtil.getLowerBound(actualSourceType);
		environmentView.computeLookups(lowerBoundType, null);
		Iteration resolvedIteration = (Iteration)environmentView.getContent();
		if (resolvedIteration == null) {
			return null;
		}
		context.setReferredIteration(implicitCollectExp, resolvedIteration);
		Variable iterator = context.refreshModelElement(Variable.class, PivotPackage.Literals.VARIABLE, null); // FIXME reuse
		Parameter resolvedIterator = resolvedIteration.getOwnedIterator().get(0);
		iterator.setRepresentedParameter(resolvedIterator);
		context.refreshName(iterator, "1_");
		context.setType(iterator, elementType, false);
		iterator.setImplicit(true);
		implicitCollectExp.getIterator().add(iterator);
		return implicitCollectExp;
	}

	/**
	 * Resolve an invocation such as name() or source.name(...)  or source->name(...)
	 */
	protected @NonNull OCLExpression resolveInvocation(@Nullable OCLExpression sourceExp, @NonNull InvocationExpCS csInvocationExp) {
		List<NamedElement> invocations = getInvocations(sourceExp, csInvocationExp);
		if (invocations != null) {
			OCLExpression invocationExp = resolveBestInvocation(sourceExp, csInvocationExp, invocations);
			if (invocationExp != null) {
				return invocationExp;
			}
		}
		else {
			checkForInvalidImplicitSourceType(csInvocationExp);
			csInvocationExp.getNamedElement();													// Now let Xtext register the unresolved operation
		}
		if (sourceExp == null) {
			sourceExp = createImplicitSourceVariableExp(csInvocationExp, metaModelManager.getOclAnyType());
		}
		OperationCallExp operationCallExp = refreshOperationCallExp(csInvocationExp, sourceExp);
		context.setReferredOperation(operationCallExp, metaModelManager.getOclInvalidOperation());
		context.installPivotUsage(csInvocationExp, operationCallExp);		
		context.setType(operationCallExp, metaModelManager.getOclInvalidType(), false);
		return operationCallExp;
	}

	protected void resolveIterationAccumulators(@NonNull InvocationExpCS csInvocationExp, @NonNull LoopExp expression) {
		Iteration iteration = expression.getReferredIteration();
		List<Variable> pivotAccumulators = new ArrayList<Variable>();
		//
		//	Explicit accumulator
		//
		for (NavigatingArgCS csArgument : csInvocationExp.getArgument()) {
			if (csArgument.getRole() != NavigationRole.ACCUMULATOR) {
				continue;
			}
			ExpCS csName = csArgument.getName();
			Variable acc = PivotUtil.getPivot(Variable.class, csName);
			if (acc != null) {
				context.installPivotUsage(csArgument, acc);
				ExpCS csInit = csArgument.getInit();
				if (csInit != null) {
					OCLExpression initExpression = context.visitLeft2Right(OCLExpression.class, csInit);
					acc.setInitExpression(initExpression);
					TypedRefCS csAccType = csArgument.getOwnedType();
					Type initType = initExpression.getType();
					Type accType;
					if (csAccType != null) {
						accType = PivotUtil.getPivot(Type.class, csAccType);
					}
					else {
						accType = initType;
					}
					if (metaModelManager.isUnderspecified(initType)) {
						initExpression.setType(accType);
					}
					context.setType(acc, accType, false);
				}
				acc.setRepresentedParameter(iteration.getOwnedAccumulator().get(pivotAccumulators.size()));
				pivotAccumulators.add(acc);
			}
			if (csArgument.getInit() == null) {
				context.addDiagnostic(csArgument, "Missing initializer for accumulator");
			}
//			if (csArgument.getOwnedType() != null) {
//				context.addError(csArgument, "Unexpected type for parameter");
//			}
		}
		//
		//	Implicit Accumulator
		//
		if (expression instanceof IterateExp) {
			IterateExp iterateExp = (IterateExp)expression;
			if (pivotAccumulators.size() > 1) {
				context.addDiagnostic(csInvocationExp, "Iterate '" + csInvocationExp.getPathName() + "' cannot have more than one accumulator");			
			}
			else {
				iterateExp.setResult(pivotAccumulators.get(0));
			}
		}
		else if (pivotAccumulators.size() > 0) {
			context.addDiagnostic(csInvocationExp, "Iteration '" + csInvocationExp.getPathName() + "' cannot have an accumulator");			
		}
	}

	protected void resolveIterationBody(@NonNull InvocationExpCS csInvocationExp, @NonNull LoopExp expression) {
		List<OCLExpression> pivotBodies = new ArrayList<OCLExpression>();
		for (NavigatingArgCS csArgument : csInvocationExp.getArgument()) {
			if (csArgument.getRole() == NavigationRole.EXPRESSION) {
				if (csArgument.getInit() != null) {
					context.addDiagnostic(csArgument, "Unexpected initializer for expression");
				}
				if (csArgument.getOwnedType() != null) {
					context.addDiagnostic(csArgument, "Unexpected type for expression");
				}
				ExpCS name = csArgument.getName();
				assert name != null;
				OCLExpression exp = context.visitLeft2Right(OCLExpression.class, name);
//				context.installPivotElement(csArgument, exp);
				if (exp != null) {
					context.installPivotUsage(csArgument, exp);
					pivotBodies.add(exp);
				}
				else {
					pivotBodies.add(context.addBadExpressionError(csArgument, "Invalid '" + csInvocationExp.getPathName() + "' iteration body"));
				}
			}
		}
		if (pivotBodies.size() != 1) {
			expression.setBody(context.addBadExpressionError(csInvocationExp, "Iteration '" + csInvocationExp.getPathName() + "' must have exactly one body"));
		}
		else {
			expression.setBody(pivotBodies.get(0));
		}
	}

	protected @NonNull LoopExp resolveIterationCallExp(@NonNull InvocationExpCS csInvocationExp, @NonNull OCLExpression sourceExp, @NonNull Iteration iteration) {
		LoopExp expression;
		if (iteration.getOwnedAccumulator().size() > 0) {
			expression = context.refreshModelElement(IterateExp.class, PivotPackage.Literals.ITERATE_EXP, csInvocationExp);
		}
		else {
			expression = context.refreshModelElement(IteratorExp.class, PivotPackage.Literals.ITERATOR_EXP, csInvocationExp);
		}
		expression.setSource(sourceExp);
		context.setReferredIteration(expression, iteration);
		return expression;
	}

	protected void resolveIterationContent(@NonNull InvocationExpCS csInvocationExp, @NonNull LoopExp expression) {
		OCLExpression source = DomainUtil.nonNullState(expression.getSource());
		resolveIterationIterators(csInvocationExp, source, expression);
		resolveIterationAccumulators(csInvocationExp, expression);
		resolveOperationArgumentTypes(csInvocationExp);
		resolveIterationBody(csInvocationExp, expression);
		resolveOperationReturnType(expression);
	}

	protected void resolveIterationIterators(@NonNull InvocationExpCS csInvocationExp, @NonNull OCLExpression source, @NonNull LoopExp expression) {
		Iteration iteration = expression.getReferredIteration();
		List<Variable> pivotIterators = new ArrayList<Variable>();
		//
		//	Explicit iterators
		//
		int iterationIteratorsSize = iteration.getOwnedIterator().size();
		Type sourceType = ((CollectionType)csInvocationExp.getSourceType()).getElementType();
		Type sourceElementType = sourceType != null ? metaModelManager.getPrimaryType(sourceType) : null;
		for (int argIndex = 0; argIndex < csInvocationExp.getArgument().size(); argIndex++) {
			NavigatingArgCS csArgument = csInvocationExp.getArgument().get(argIndex);
			if (csArgument.getRole() != NavigationRole.ITERATOR) {
				continue;
			}
			if (iterationIteratorsSize <= argIndex) {
				context.addWarning(csArgument, OCLMessages.RedundantIterator_WARNING_, iteration.getName());
				continue;
			}
			if (csArgument.getInit() != null) {
				context.addDiagnostic(csArgument, "Unexpected initializer for iterator");
			}
//			if (csArgument.getOwnedType() == null) {
//				context.addError(csArgument, "Missing type for iterator");
//			}
			ExpCS csName = csArgument.getName();
			Variable iterator = PivotUtil.getPivot(Variable.class, csName);
			if (iterator != null) {
				context.installPivotUsage(csArgument, iterator);
				iterator.setRepresentedParameter(iteration.getOwnedIterator().get(pivotIterators.size()));
				TypedRefCS csType = csArgument.getOwnedType();
				Type varType = csType != null ? PivotUtil.getPivot(Type.class, csType) : sourceElementType;
				if (varType == null) {
					varType = sourceElementType;
				}
				context.setType(iterator, varType, false);
				pivotIterators.add(iterator);
			}
		}
		//
		//	Implicit Iterators
		//
		while (pivotIterators.size() < iterationIteratorsSize) {
			String varName = Integer.toString(pivotIterators.size()+1) + "_";
			Variable iterator = context.refreshModelElement(Variable.class, PivotPackage.Literals.VARIABLE, null);
			context.refreshName(iterator, varName);
			context.setType(iterator, sourceElementType, false);
			iterator.setImplicit(true);
			iterator.setRepresentedParameter(iteration.getOwnedIterator().get(pivotIterators.size()));
			pivotIterators.add(iterator);
		}
		context.refreshList(expression.getIterator(), pivotIterators);
	}

	/**
	 * Determine the type of each operation argument so that the appropriate operation overload can be selected.
	 * Arguments aligned with type (MetaClass) parameters are set to be parsed as types avoiding ambiguities from
	 * implicit opposite properties. Iterator bodies are left unresolved.
	 */
	protected void resolveOperationArgumentTypes(@NonNull InvocationExpCS csInvocationExp) {
		int argIndex = 0;
		for (NavigatingArgCS csArgument : csInvocationExp.getArgument()) {
			if (csArgument.getRole() == NavigationRole.ITERATOR) {
				break;
			}
			else if (csArgument.getRole() == NavigationRole.ACCUMULATOR) {
				break;
			}
			else if (csArgument.getRole() == NavigationRole.EXPRESSION) {
				ExpCS csName = csArgument.getName();
				if (csName != null) {
					if (csName instanceof NameExpCS) {
						PathNameCS csPathName = ((NameExpCS)csName).getPathName();
						if (csPathName != null) {
							Element callExp = csInvocationExp.getPivot();
							if (callExp instanceof OperationCallExp) {
								Operation operation = ((OperationCallExp)callExp).getReferredOperation();
								if (operation != null) {
									List<Parameter> parameters = operation.getOwnedParameter();
									if (argIndex < parameters.size()) {
										Type type = parameters.get(argIndex).getType();
										if (type instanceof Metaclass<?>) {
											CS2Pivot.setElementType(csPathName, PivotPackage.Literals.NAMED_ELEMENT, csName, TypeArgumentFilter.INSTANCE);
										}
									}
								}
							}
						}
					}
					OCLExpression arg = context.visitLeft2Right(OCLExpression.class, csName);
					if (arg != null) {
						context.installPivotUsage(csArgument, arg);
					}
				}
				argIndex++;
			}
		}
	}

	/**
	 * Complete the installation of each operation argument in its operation call.
	 */
	protected void resolveOperationArguments(@NonNull InvocationExpCS csInvocationExp, @NonNull Operation operation, @NonNull OperationCallExp expression) {
		List<OCLExpression> pivotArguments = new ArrayList<OCLExpression>();
		List<NavigatingArgCS> csArguments = csInvocationExp.getArgument();
		List<Parameter> ownedParameters = operation.getOwnedParameter();
		int parametersCount = ownedParameters.size();
		int csArgumentCount = csArguments.size();
		if (csArgumentCount > 0) {
			if (csArguments.get(0).getRole() != NavigationRole.EXPRESSION) {
				context.addDiagnostic(csInvocationExp, "Operation calls can only specify expressions");			
			}
			for (int argIndex = 0; argIndex < csArgumentCount; argIndex++) {
				NavigatingArgCS csArgument = csArguments.get(argIndex);
				if (csArgument.getInit() != null) {
					context.addDiagnostic(csArgument, "Unexpected initializer for expression");
				}
				if (csArgument.getOwnedType() != null) {
					context.addDiagnostic(csArgument, "Unexpected type for expression");
				}
				OCLExpression arg = PivotUtil.getPivot(OCLExpression.class, csArgument);
				if (arg != null) {
					pivotArguments.add(arg);
				}
			}
		}
		if ((csArgumentCount != parametersCount) && (operation != metaModelManager.basicGetOclInvalidOperation())) {
			String boundMessage = DomainUtil.bind(OCLMessages.MismatchedArgumentCount_ERROR_, csArgumentCount, parametersCount);
			context.addDiagnostic(csInvocationExp, boundMessage);			
		}
		context.refreshList(expression.getArgument(), pivotArguments);
	}

	protected void resolveOperationCall(@NonNull OperationCallExp expression, @NonNull OperatorCS csOperator, @NonNull ScopeFilter filter) {
		Type sourceType = PivotUtil.getType(expression.getSource());
		Operation operation = null;
		if (!AUTOGENERATED_LOOKUP) {
			@SuppressWarnings("null") @NonNull EReference eReference = PivotPackage.Literals.OPERATION_CALL_EXP__REFERRED_OPERATION;
			EnvironmentView environmentView = new EnvironmentView(metaModelManager, eReference, expression.getName());
			environmentView.addFilter(filter);
			int size = 0;
			if (sourceType != null) {
				Type lowerBoundType = (Type) PivotUtil.getLowerBound(sourceType);
				size = environmentView.computeLookups(lowerBoundType, null);
			}
			if (size == 1) {
				operation = (Operation)environmentView.getContent();
			}
		}
		else {
			ISingleResultEnvironment env = lResolver.computeReferredOperationLookup(expression, filter);
			if (env.getSize() == 1) {
				operation = (Operation) env.getSingleResult();
			}
		}
		if (operation != null) {	
			context.setReferredOperation(expression, operation);
			resolveOperationReturnType(expression);
		}
		else {
			StringBuilder s = new StringBuilder();
			for (OCLExpression argument : expression.getArgument()) {
				Type argumentType = PivotUtil.getType(argument);
				if (s.length() > 0) {
					s.append(",");
				}
				if (argumentType != null) {
					s.append(argumentType.toString());
				}
			}
			String boundMessage;
			
			if (s.length() > 0) {
				boundMessage = DomainUtil.bind(OCLMessages.UnresolvedOperationCall_ERROR_, csOperator, sourceType, s.toString());
			}
			else {
				boundMessage = DomainUtil.bind(OCLMessages.UnresolvedOperation_ERROR_, csOperator, sourceType);
			}
//			context.addBadExpressionError(csOperator, boundMessage);
			context.addDiagnostic(csOperator, boundMessage);
			context.setReferredOperation(expression, metaModelManager.getOclInvalidOperation());
			context.setType(expression, metaModelManager.getOclInvalidType(), false);
		}
	}

	protected @NonNull OperationCallExp resolveOperationCallExp(@NonNull InvocationExpCS csInvocationExp, @NonNull OperationCallExp operationCallExp, @NonNull Operation operation) {
		context.setReferredOperation(operationCallExp, operation);
		resolveAtPre(csInvocationExp.getNameExp(), operationCallExp);
		context.installPivotUsage(csInvocationExp, operationCallExp);
		resolveOperationArguments(csInvocationExp, operation, operationCallExp);
		resolveOperationReturnType(operationCallExp);
		return operationCallExp;
	}

	protected void resolveOperationReturnType(@NonNull CallExp callExp) {
		Operation operation = null;
		if (callExp instanceof OperationCallExp) {
			operation = ((OperationCallExp)callExp).getReferredOperation();
		}
		else if (callExp instanceof LoopExp) {
			operation = ((LoopExp)callExp).getReferredIteration();
		}
		if (operation == null) {
			return;
		}
		Map<TemplateParameter, ParameterableElement> templateBindings = new HashMap<TemplateParameter, ParameterableElement>();
		Type sourceType = null;
		OCLExpression source = callExp.getSource();
		if (source != null) {
			sourceType = source.getType();
		}
		if (sourceType != null) {
			if (operation.isStatic() && (sourceType instanceof Metaclass<?>)) {
				sourceType = ((Metaclass<?>)sourceType).getInstanceType();
			}
			templateBindings.put(null, sourceType);		// Use the null key to pass OclSelf without creating an object
		}
		PivotUtil.getAllTemplateParameterSubstitutions(templateBindings, sourceType);
//		PivotUtil.getAllTemplateParameterSubstitutions(templateBindings, operation);
		TemplateSignature templateSignature = operation.getOwnedTemplateSignature();
		if (templateSignature != null) {
			for (TemplateParameter templateParameter : templateSignature.getOwnedParameter()) {
				templateBindings.put(templateParameter, null);
			}
		}
		String implementationClass = operation.getImplementationClass();
		if ((implementationClass != null) && implementationClass.equals(CollectionFlattenOperation.class.getName())) {	// FIXME Use Tree(T) to make this modellable
			Type elementType = sourceType;
			while (elementType instanceof CollectionType) {
				elementType = ((CollectionType)elementType).getElementType();
			}
			if (elementType != null) {
				templateBindings.put(operation.getOwnedTemplateSignature().getOwnedParameter().get(0), elementType);
			}
		}
		@SuppressWarnings("unused")		// Should never happen; just for debugging
		boolean isConformant = true;
		if (callExp instanceof OperationCallExp) {
			List<Parameter> parameters = operation.getOwnedParameter();
			List<OCLExpression> arguments = ((OperationCallExp)callExp).getArgument();
			int iMax = Math.min(parameters.size(), arguments.size());
			for (int i = 0; i < iMax; i++) {
				Parameter parameter = parameters.get(i);
				OCLExpression argument = arguments.get(i);
				Type parameterType = PivotUtil.getType(parameter);
				Type argumentType = PivotUtil.getType(argument);
				if ((parameterType != null) && (argumentType != null)) {
					if (!metaModelManager.conformsTo(argumentType, parameterType, templateBindings)) {
						isConformant = false;
					}
				}
			}
		}
		else if (callExp instanceof LoopExp) {
			if (callExp instanceof IterateExp) {
				List<Parameter> accumulators = ((Iteration)operation).getOwnedAccumulator();
				if (accumulators.size() >= 1) {
					Parameter accumulator = accumulators.get(0);
					Variable result = ((IterateExp)callExp).getResult();
					Type accumulatorType = PivotUtil.getType(accumulator);
					Type resultType = PivotUtil.getType(result);
					if ((accumulatorType != null) && (resultType != null)) {
						if (!metaModelManager.conformsTo(resultType, accumulatorType, templateBindings)) {
							isConformant = false;
						}
					}
				}
			}
			List<Parameter> parameters = ((Iteration)operation).getOwnedParameter();
			if (parameters.size() >= 1) {
				Parameter parameter = parameters.get(0);
				OCLExpression body = ((LoopExp)callExp).getBody();
				Type parameterType = PivotUtil.getType(parameter);
				Type bodyType = PivotUtil.getType(body);
				if ((bodyType != null) && (parameterType != null)) {
					if (!metaModelManager.conformsTo(bodyType, parameterType, templateBindings)) {
						isConformant = false;
					}
				}
			}
		}
		Type behavioralType = PivotUtil.getType(operation);
		Type returnType = behavioralType != null ? metaModelManager.getSpecializedType(behavioralType, templateBindings) : null;
		if (operation instanceof Iteration) {
			List<Parameter> formalIterators = ((Iteration)operation).getOwnedIterator();
			List<Variable> actualIterators = ((LoopExp)callExp).getIterator();
			int iMax = Math.min(formalIterators.size(), actualIterators.size());
			for (int i = 0; i < iMax; i++) {
				Parameter iterator = formalIterators.get(i);
				Variable actualVariable = actualIterators.get(i);
				Type behavioralIteratorType = PivotUtil.getType(iterator);
				Type iteratorType = behavioralIteratorType != null ? metaModelManager.getSpecializedType(behavioralIteratorType, templateBindings) : null;
				actualVariable.setType(iteratorType);
			}
		}
		//
		//	The flattening of collect() and consequently implicit-collect is not modelled accurately so we need to code it.
		//
		if ((operation instanceof Iteration) && "collect".equals(operation.getName()) && (callExp instanceof LoopExp) && (returnType instanceof CollectionType)) {
			OCLExpression body = ((LoopExp)callExp).getBody();
			Type bodyType = PivotUtil.getType(body);
			if (bodyType != null) {
				if (bodyType instanceof CollectionType) {
					@NonNull Type elementType = bodyType;
					while (elementType instanceof CollectionType) {
						Type elementType2 = ((CollectionType)elementType).getElementType();
						if (elementType2 != null) {
							elementType = elementType2;
						}
					}
					boolean isOrdered = ((CollectionType)returnType).isOrdered();
					returnType = metaModelManager.getCollectionType(isOrdered, false, elementType, null, null);	// FIXME null, null
				}
			}
		}
		if (operation.isStatic() && (behavioralType != null) && (behavioralType.getOwningTemplateParameter() != null) && (returnType != null)) {
			returnType = metaModelManager.getMetaclass(returnType);
		}
		context.setType(callExp, returnType, operation.isRequired());
	}

	protected @NonNull CallExp resolvePropertyCallExp(@NonNull OCLExpression sourceExp, @NonNull NameExpCS csNameExp, @NonNull Property property) {
		NavigationCallExp callExp;
		if (property.isImplicit()) {
			callExp = refreshOppositePropertyCallExp(csNameExp, sourceExp, property);
		}
		else {
			callExp = refreshPropertyCallExp(csNameExp, sourceExp, property);
		}
//		if (isInvalidType(property.getType())) {
//			EssentialOCLUtils.setHasError(csNameExp);
//		}
		resolveAtPre(csNameExp, callExp);
		Type returnType = resolvePropertyReturnType(sourceExp, csNameExp, property);
		context.setType(callExp, returnType, property.isRequired());
		return callExp;
	}

	protected Type resolvePropertyReturnType(@NonNull OCLExpression sourceExp, @NonNull NameExpCS csNameExp, @NonNull Property property) {
		Map<TemplateParameter, ParameterableElement> templateBindings = new HashMap<TemplateParameter, ParameterableElement>();
		Type sourceType = sourceExp.getType();
		if (sourceType != null) {
			if (property.isStatic() && (sourceType instanceof Metaclass<?>)) {
				sourceType = ((Metaclass<?>)sourceType).getInstanceType();
			}
			templateBindings.put(null, sourceType);		// Use the null key to pass OclSelf without creating an object
			Type owningType = property.getOwningType();
			if (owningType instanceof Metaclass) {
				owningType = PivotUtil.getUnspecializedTemplateableElement(owningType);
				templateBindings.put(owningType.getOwnedTemplateSignature().getOwnedParameter().get(0), sourceType);		// Use the null key to pass OclSelf without creating an object
			}
		}
		PivotUtil.getAllTemplateParameterSubstitutions(templateBindings, sourceType);
		Type returnType = null;
		Type behavioralType = PivotUtil.getType(property);
		if (behavioralType != null) {
			returnType = metaModelManager.getSpecializedType(behavioralType, templateBindings);
			if (property.isStatic() && (behavioralType.getOwningTemplateParameter() != null)) {
				returnType = metaModelManager.getMetaclass(returnType);
			}
		}
		return returnType;
	}

	protected StateExp resolveStateExp(@NonNull ExpCS csExp, @NonNull State state) {
		StateExp expression = context.refreshModelElement(StateExp.class, PivotPackage.Literals.STATE_EXP, csExp);
		context.setType(expression, metaModelManager.getPivotType("State"), true);		// FIXME What should this be
		expression.setReferredState(state);
		return expression;
	}

	protected @NonNull TypeExp resolveTypeExp(@NonNull ExpCS csExp, @NonNull Type type) {
		TypeExp expression = context.refreshModelElement(TypeExp.class, PivotPackage.Literals.TYPE_EXP, csExp);
		context.setType(expression, metaModelManager.getMetaclass(type), true);
		expression.setReferredType(type);
		return expression;
	}

	protected @NonNull VariableExp resolveVariableExp(@NonNull AbstractNameExpCS csNameExp, @NonNull VariableDeclaration variableDeclaration) {
		VariableExp expression = context.refreshModelElement(VariableExp.class, PivotPackage.Literals.VARIABLE_EXP, csNameExp);
		expression.setReferredVariable(variableDeclaration);
		context.setType(expression, variableDeclaration.getType(), variableDeclaration.isRequired());
		return expression;
	}
	  
	@Override
	public @NonNull Element visitBinaryOperatorCS(@NonNull BinaryOperatorCS csOperator) {
		OperationCallExp expression = context.refreshModelElement(OperationCallExp.class, PivotPackage.Literals.OPERATION_CALL_EXP, csOperator);
		String name = csOperator.getName();
		assert name != null;
		context.refreshName(expression, name);
		ExpCS csSource = csOperator.getSource();
		if (csSource != null) {
			OCLExpression source = context.visitLeft2Right(OCLExpression.class, csSource);
			expression.setSource(source);
			ExpCS csArgument = csOperator.getArgument();
			if (csArgument != null) {
				OCLExpression argument = context.visitLeft2Right(OCLExpression.class, csArgument);
				List<? extends OCLExpression> newElements = argument != null ? Collections.singletonList(argument) : Collections.<OCLExpression>emptyList();
				context.refreshList(expression.getArgument(), newElements);
				Type sourceType = PivotUtil.getType(source);
				Type argumentType = PivotUtil.getType(argument);
				if ((sourceType != null) && (argumentType != null)) {
					resolveOperationCall(expression, csOperator, new BinaryOperationFilter(sourceType, argumentType));
				}
			}
		}
		return expression;
	}

	@Override
	public Element visitBooleanLiteralExpCS(@NonNull BooleanLiteralExpCS csBooleanLiteralExp) {
		BooleanLiteralExp expression = PivotUtil.getPivot(BooleanLiteralExp.class, csBooleanLiteralExp);
		if (expression != null) {
			expression.setBooleanSymbol(Boolean.valueOf(csBooleanLiteralExp.getName()));
			context.setType(expression, metaModelManager.getBooleanType(), true);
		}
		return expression;
	}

	@Override
	public Element visitCollectionLiteralExpCS(@NonNull CollectionLiteralExpCS csCollectionLiteralExp) {
		Type commonType = null;
//		InvalidLiteralExp invalidValue = null;
		for (CollectionLiteralPartCS csPart : csCollectionLiteralExp.getOwnedParts()) {
			assert csPart != null;
			CollectionLiteralPart pivotPart = context.visitLeft2Right(CollectionLiteralPart.class, csPart);
			Type type = pivotPart.getType();
//			if (type instanceof InvalidType) {	// FIXME Use propagated reason via InvalidType
//				if (invalidValue == null) {
//					invalidValue = metaModelManager.createInvalidValue(csPart, null, "Invalid Collection content", null);
//				}
//			}
//			else
			if (type != null) {
				if (commonType == null) {
					commonType = type;
				}
				else if (commonType != type) {
					commonType = metaModelManager.getCommonType(commonType, type, null);
				}
			}
		}
//		if (invalidValue != null) {
//			context.installPivotElement(csCollectionLiteralExp, invalidValue);
//			return invalidValue;
//		}
		CollectionLiteralExp expression = PivotUtil.getPivot(CollectionLiteralExp.class, csCollectionLiteralExp);
		if (expression != null) {
			CollectionTypeCS ownedCollectionType = csCollectionLiteralExp.getOwnedType();
			String collectionTypeName = ownedCollectionType.getName();
			assert collectionTypeName != null;
			TypedRefCS ownedElementType = ownedCollectionType.getOwnedType();
			if (ownedElementType != null) {
				commonType = (Type) ownedElementType.getPivot();
			}
			if (commonType == null) {
				commonType = metaModelManager.createUnspecifiedType();
			}
			Type type = metaModelManager.getCollectionType(collectionTypeName, commonType, null, null);
			context.setType(expression, type, true);
			expression.setKind(PivotUtil.getCollectionKind((CollectionType) type));
		}
		return expression;
	}

	@Override
	public Element visitCollectionLiteralPartCS(@NonNull CollectionLiteralPartCS csCollectionLiteralPart) {
		ExpCS csFirst = csCollectionLiteralPart.getExpressionCS();
		if (csFirst == null) {
			return null;
		}
		OCLExpression pivotFirst = context.visitLeft2Right(OCLExpression.class, csFirst);
		ExpCS csLast = csCollectionLiteralPart.getLastExpressionCS();
		if (csLast == null) {
			CollectionItem expression = PivotUtil.getPivot(CollectionItem.class, csCollectionLiteralPart);	
			if (expression != null) {
				expression.setItem(pivotFirst);
			}
		}
		else {
			CollectionRange expression = PivotUtil.getPivot(CollectionRange.class, csCollectionLiteralPart);
			if (expression != null) {
				expression.setFirst(pivotFirst);
				OCLExpression pivotLast = context.visitLeft2Right(OCLExpression.class, csLast);
				expression.setLast(pivotLast);
			}
		}
		Type type = pivotFirst.getType();
		if (type == null) {
			return null;
		}
		boolean isRequired = pivotFirst.isRequired();
		if (csLast != null) {
			OCLExpression pivotLast = PivotUtil.getPivot(OCLExpression.class, csLast);
			if (pivotLast != null) {
				Type secondType = pivotLast.getType();
				if (secondType != null) {
					type = metaModelManager.getCommonType(type, secondType, null);
				}
				isRequired &= pivotLast.isRequired();
			}
		}
		CollectionLiteralPart expression = PivotUtil.getPivot(CollectionLiteralPart.class, csCollectionLiteralPart);
		if (expression != null) {
			context.setType(expression, type, isRequired);
		}
		return expression;
	}

	@Override
	public Element visitCollectionTypeCS(@NonNull CollectionTypeCS object) {
		return null;
	}

	@Override
	public Element visitConstructorExpCS(@NonNull ConstructorExpCS csConstructorExp) {
		ConstructorExp expression = PivotUtil.getPivot(ConstructorExp.class, csConstructorExp);	
		if (expression != null) {
			expression.setType((Type) csConstructorExp.getNamedElement());
			for (ConstructorPartCS csPart : csConstructorExp.getOwnedParts()) {
				assert csPart != null;
				context.visitLeft2Right(ConstructorPart.class, csPart);
			}
		}
		return expression;
	}

	@Override
	public Element visitConstructorPartCS(@NonNull ConstructorPartCS csConstructorPart) {
		ConstructorPart pivotElement = PivotUtil.getPivot(ConstructorPart.class, csConstructorPart);	
		if (pivotElement != null) {
			Property property = csConstructorPart.getProperty();
			pivotElement.setReferredProperty(property);
			context.refreshName(pivotElement, property.getName());
			context.setType(pivotElement, property.getType(), property.isRequired());
			ExpCS csInitExpression = csConstructorPart.getInitExpression();
			if (csInitExpression != null) {
				OCLExpression initExpression = context.visitLeft2Right(OCLExpression.class, csInitExpression);
				pivotElement.setInitExpression(initExpression);
			}
		}
		return pivotElement;
	}

	@Override
	public Element visitContextCS(@NonNull ContextCS csContext) {
		ExpressionInOCL pivotElement = PivotUtil.getPivot(ExpressionInOCL.class, csContext);
		if (pivotElement != null) {
			pivotElement.getLanguage().clear();
			pivotElement.getBody().clear();
			ExpCS csExpression = csContext.getOwnedExpression();
			if (csExpression != null) {
				pivotElement.getLanguage().add("OCL");
				pivotElement.getBody().add(csExpression.toString());
				OCLExpression expression = context.visitLeft2Right(OCLExpression.class, csExpression);
				if (expression != null) {
					PivotUtil.setBody(pivotElement, expression, ElementUtil.getExpressionText(csExpression));
					context.setType(pivotElement, expression.getType(), expression.isRequired());
				}
			}
		}
		return pivotElement;
	}

	@Override
	public Element visitExpCS(@NonNull ExpCS object) {
		return null;
	}

	@Override
	public Element visitIfExpCS(@NonNull IfExpCS csIfExp) {
		IfExp expression = PivotUtil.getPivot(IfExp.class, csIfExp);
		if (expression != null) {
			ExpCS csIf = csIfExp.getCondition();
			ExpCS csThen = csIfExp.getThenExpression();
			ExpCS csElse = csIfExp.getElseExpression();
			if ((csIf != null) && (csThen != null) && (csElse != null)) {
				expression.setCondition(context.visitLeft2Right(OCLExpression.class, csIf));
				OCLExpression thenExpression = context.visitLeft2Right(OCLExpression.class, csThen);
				expression.setThenExpression(thenExpression);
				OCLExpression elseExpression = context.visitLeft2Right(OCLExpression.class, csElse);
				expression.setElseExpression(elseExpression);
				Type thenType = thenExpression != null ? thenExpression.getType() : null;
				Type elseType = elseExpression != null ? elseExpression.getType() : null;
				Type commonType = (thenType != null) && (elseType != null) ? metaModelManager.getCommonType(thenType, elseType, null) : null;
				boolean isRequired = ((thenExpression != null) && thenExpression.isRequired()) && ((elseExpression != null) && elseExpression.isRequired());
				context.setType(expression, commonType, isRequired);
			}
		}
		return expression;
	}

	@Override
	public Element visitIndexExpCS(@NonNull IndexExpCS csIndexExp) {
		// Navigating completions are orchestrated by the SimpleNamedExpCS.
		return null;
	}

	@Override
	public Element visitInfixExpCS(@NonNull InfixExpCS csInfixExp) {
		//
		//	Find the root.
		//
		OperatorCS csRoot = csInfixExp.getOwnedOperator().get(0);
		for (OperatorCS csParent = csRoot.getParent(); csParent != null; csParent = csParent.getParent()) {
			csRoot = csParent;
		}
		//
		//	Build the corresponding AST and reuse as the Infix node.
		//
		OCLExpression pivot = context.visitLeft2Right(OCLExpression.class, csRoot);		
		if (pivot != null) {
			context.installPivotUsage(csInfixExp, pivot);
		}
		return pivot;
	}

	@Override
	public Element visitInvalidLiteralExpCS(@NonNull InvalidLiteralExpCS csInvalidLiteralExp) {
		InvalidLiteralExp expression = PivotUtil.getPivot(InvalidLiteralExp.class, csInvalidLiteralExp);
		if (expression == null) {
			expression = metaModelManager.createInvalidExpression();
		}
//		expression.setType(metaModelManager.getOclInvalidType());
		context.installPivotUsage(csInvalidLiteralExp, expression);
		return expression;
	}

	/**
	 * Resolve an invocation such as name()
	 */
	@Override
	public Element visitInvocationExpCS(@NonNull InvocationExpCS csInvocationExp) {
		OperatorCS csParent = csInvocationExp.getParent();
		if ((csParent instanceof NavigationOperatorCS) && (csInvocationExp != csParent.getSource())) {
			// source.name(), source->name() are resolved by the parent NavigationOperatorCS
			return PivotUtil.getPivot(OCLExpression.class, csInvocationExp);
		}
		return resolveInvocation(null, csInvocationExp);
	}

	@Override
	public Element visitLetExpCS(@NonNull LetExpCS csLetExp) {
		// Each CS Let Variable becomes a Pivot LetExpression and Variable
		// The CS Let therefore just re-uses the Pivot of the first CS Let Variable
		LetExp firstLetExp = null;
		LetExp lastLetExp = null;
		for (LetVariableCS csLetVariable : csLetExp.getVariable()) {
			Variable variable = PivotUtil.getPivot(Variable.class, csLetVariable);
			if (variable != null) {
				LetExp letExp;
				EObject variableContainer = variable.eContainer();
				if (variableContainer instanceof LetExp) {
					letExp = (LetExp)variableContainer;
				}
				else {
					letExp = context.refreshModelElement(LetExp.class, PivotPackage.Literals.LET_EXP, null); // FIXME reuse
				}
				letExp.setVariable(variable);		
				ExpCS csInitExpression = csLetVariable.getInitExpression();
				if (csInitExpression != null) {
					OCLExpression initExpression = context.visitLeft2Right(OCLExpression.class, csInitExpression);
					variable.setInitExpression(initExpression);
					Type initType = initExpression != null ? initExpression.getType() : null;
					boolean isRequired = variable.isRequired() && (initExpression != null) && initExpression.isRequired();
					TypedRefCS csVariableType = csLetVariable.getOwnedType();
					Type variableType = csVariableType != null ? PivotUtil.getPivot(Type.class, csVariableType) : null;
					if (variableType == null) {
						variableType = initType;
					}
					else if ((initExpression != null) && metaModelManager.isUnderspecified(initType)) {
						initExpression.setType(variableType);
					}
					context.setType(variable, variableType, isRequired);
					if (lastLetExp != null) {
						lastLetExp.setIn(letExp);
						context.installPivotUsage(csLetExp, letExp);
					}
					else {
						firstLetExp = letExp;
						context.installPivotUsage(csLetExp, firstLetExp);
					}
					lastLetExp = letExp;
				}
			}
		}
		if (lastLetExp != null) {
			ExpCS csIn = csLetExp.getIn();
			if (csIn != null) {
				OCLExpression in = context.visitLeft2Right(OCLExpression.class, csIn);
				lastLetExp.setIn(in);
				if (in != null) {
					Type type = in.getType();
					for (OCLExpression letExp = firstLetExp; (letExp != in) && (letExp != null); letExp = ((LetExp)letExp).getIn()) {
						context.setType(letExp, type, in.isRequired());
					}
				}
			}
		}
		return firstLetExp;
	}

	@Override
	public Element visitLetVariableCS(@NonNull LetVariableCS csLetVariable) {
		return null;	// Handled by parent
	}

	@Override
	public Element visitNameExpCS(@NonNull NameExpCS csNameExp) {
		checkForInvalidImplicitSourceType(csNameExp);
		Element element = csNameExp.getNamedElement();
		if ((element == null) || element.eIsProxy()) {
			Element pivot = csNameExp.getPivot();
			if (pivot instanceof InvalidLiteralExp) {
				return pivot;
			}
			InvalidLiteralExp invalidLiteralExp = metaModelManager.createInvalidExpression();
			context.installPivotUsage(csNameExp, invalidLiteralExp);
			return invalidLiteralExp;
		}
		else if (element instanceof VariableDeclaration) {
			return resolveVariableExp(csNameExp, (VariableDeclaration)element);
		}
		else if (element instanceof Property) {
			Property property = (Property) element;
			OCLExpression sourceExp = createImplicitSourceVariableExp(csNameExp, property.getOwningType());
			return resolvePropertyCallExp(sourceExp, csNameExp, property);
		}
		else if (element instanceof Operation) {
			return context.addBadExpressionError(csNameExp, "No parameters for operation " + ((Operation)element).getName());
		}
		else if (element instanceof Type) {
			return resolveTypeExp(csNameExp, (Type) element);
		}
		else if (element instanceof EnumerationLiteral) {
			return resolveEnumLiteral(csNameExp, (EnumerationLiteral) element);
		}
		else if (element instanceof State) {
			return resolveStateExp(csNameExp, (State) element);
		}
		else {
			return context.addBadExpressionError(csNameExp, "Unsupported NameExpCS " + element.eClass().getName());		// FIXME
		}
	}

	@Override
	public Element visitNavigatingArgCS(@NonNull NavigatingArgCS csNavigatingArg) {
		OCLExpression pivot = PivotUtil.getPivot(OCLExpression.class, csNavigatingArg.getName());
		if (pivot != null) {
			context.installPivotUsage(csNavigatingArg, pivot);
		}
		return pivot;
	}

	@Override
	public OCLExpression visitNavigationOperatorCS(@NonNull NavigationOperatorCS csOperator) {
		OCLExpression navigatingExp = null;
		ExpCS csSource = csOperator.getSource();
		if (csSource != null) {
			OCLExpression sourceExp = context.visitLeft2Right(OCLExpression.class, csSource);
			if (sourceExp != null) {
				Type actualSourceType = PivotUtil.getType(sourceExp);
				if (actualSourceType != null) {
					ExpCS argument = csOperator.getArgument();
					if (argument instanceof AbstractNameExpCS) {
						AbstractNameExpCS csNameExp = (AbstractNameExpCS) argument;
						LoopExp implicitCollectExp = null;
						OCLExpression collectedSourceExp = sourceExp;
						//
						//	Condition the source for implicit set or implicit collect
						//
						String navigationOperatorName = csOperator.getName();
						if (actualSourceType instanceof CollectionType) {
							if (PivotConstants.OBJECT_NAVIGATION_OPERATOR.equals(navigationOperatorName)) {
								implicitCollectExp = resolveImplicitCollectExp(sourceExp, csNameExp);
								if (implicitCollectExp != null) {
									@SuppressWarnings("null")@NonNull Variable iterator = implicitCollectExp.getIterator().get(0);
									collectedSourceExp = createImplicitVariableExp(iterator);
								}
							}
						}
						else {
							if (PivotConstants.COLLECTION_NAVIGATION_OPERATOR.equals(navigationOperatorName)) {
								collectedSourceExp = resolveImplicitAsSet(sourceExp, actualSourceType, csOperator);
							}
						}
						csNameExp.setSourceType(collectedSourceExp.getType());
						//
						//	Resolve the inner call expression 
						//
						OCLExpression callExp;
						if (csNameExp instanceof InvocationExpCS) {
							callExp = resolveInvocation(collectedSourceExp, (InvocationExpCS) csNameExp);
						}
						else if (argument instanceof NameExpCS) {
							callExp = resolveExplicitSourceNavigation(collectedSourceExp, (NameExpCS) argument);
						}
						else {
							callExp = context.addBadExpressionError(argument, "bad navigation argument");
						}
						//
						//	Complete the wrapping of the inner call expression in an outer implicit collect expression
						//
						if (callExp instanceof CallExp) {
							if (implicitCollectExp != null) {
								implicitCollectExp.setBody(callExp);
								resolveOperationReturnType(implicitCollectExp);
								navigatingExp = implicitCollectExp;
							}
							else {
								navigatingExp = callExp;
							}
						}
						else {
							navigatingExp = callExp;		// Place holder for an error
						}
					}
					else if (argument != null) {
						navigatingExp = context.addBadExpressionError(argument, "bad navigation argument");
					}
				}
			}
			if (navigatingExp != null) {
				context.installPivotUsage(csOperator, navigatingExp);
			}
		}
		return navigatingExp;
	}

	@Override
	public Element visitNestedExpCS(@NonNull NestedExpCS csNestedExp) {
		ExpCS csSource = csNestedExp.getSource();
		if (csSource == null) {
			return null;
		}
		OCLExpression pivot = context.visitLeft2Right(OCLExpression.class, csSource);
		if (pivot != null) {
			context.installPivotUsage(csNestedExp, pivot);
		}
		return pivot;
	}

	@Override
	public Element visitNullLiteralExpCS(@NonNull NullLiteralExpCS csNullLiteralExp) {
		NullLiteralExp expression = PivotUtil.getPivot(NullLiteralExp.class, csNullLiteralExp);
		if (expression != null) {
			context.setType(expression, metaModelManager.getOclVoidType(), false);
		}
		return expression;
	}

	@Override
	public Element visitNumberLiteralExpCS(@NonNull NumberLiteralExpCS csNumberLiteralExp) {
		NumericLiteralExp expression = PivotUtil.getPivot(NumericLiteralExp.class, csNumberLiteralExp);
		if (expression instanceof UnlimitedNaturalLiteralExp) {
			context.setType(expression, metaModelManager.getUnlimitedNaturalType(), true);
		}
		else if (expression instanceof IntegerLiteralExp) {
			context.setType(expression, metaModelManager.getIntegerType(), true);
		}
		else if (expression != null){
			context.setType(expression, metaModelManager.getRealType(), true);
		}
		return expression;
	}

	@Override
	public Element visitOperatorCS(@NonNull OperatorCS object) {
		return null;
	}

	@Override
	public Element visitPrefixExpCS(@NonNull PrefixExpCS csPrefixExp) {
		UnaryOperatorCS csRoot = csPrefixExp.getOwnedOperator().get(0);
		if (csRoot == null) {
			return null;
		}
		if (csPrefixExp.eContainer() instanceof InfixExpCS) {
			// PrefixExpCS embedded in InfixExpCS is resolved as part of the Infix tree;		
		}
		else {
//			initializePrefixOperators(csPrefixExp, null);
			context.visitLeft2Right(OCLExpression.class, csRoot);		
		}
		OCLExpression pivotElement = PivotUtil.getPivot(OCLExpression.class, csRoot);
		if (pivotElement != null) {
			context.installPivotUsage(csPrefixExp, pivotElement);
		}
		return pivotElement;
	}

	@Override
	public Element visitSelfExpCS(@NonNull SelfExpCS csSelfExp) {	// FIXME Just use VariableExpCS
		VariableExp expression = PivotUtil.getPivot(VariableExp.class, csSelfExp);
		if (expression != null) {
			ElementCS parent = csSelfExp.getLogicalParent();
			if (parent != null) {
				@SuppressWarnings("null") @NonNull EReference eReference = PivotPackage.Literals.EXPRESSION_IN_OCL__CONTEXT_VARIABLE;
				EnvironmentView environmentView = new EnvironmentView(metaModelManager, eReference, Environment.SELF_VARIABLE_NAME);
				ScopeView baseScopeView = BaseScopeView.getScopeView(metaModelManager, parent, eReference);
				environmentView.computeLookups(baseScopeView);
				VariableDeclaration variableDeclaration = (VariableDeclaration) environmentView.getContent();
				if (variableDeclaration == null) {
					return context.addBadExpressionError(csSelfExp, "The context of 'self' is unspecified");
				}
				expression.setReferredVariable(variableDeclaration);
				context.setType(expression, variableDeclaration.getType(), true);
			}
		}
		return expression;
	}

	@Override
	public Element visitStringLiteralExpCS(@NonNull StringLiteralExpCS csStringLiteralExp) {
		StringLiteralExp pivotElement = PivotUtil.getPivot(StringLiteralExp.class, csStringLiteralExp);
		if (pivotElement != null) {
			context.setType(pivotElement, metaModelManager.getStringType(), true);
		}
		return pivotElement;
	}

	@Override
	public Element visitTupleLiteralExpCS(@NonNull TupleLiteralExpCS csTupleLiteralExp) {
		TupleLiteralExp expression = PivotUtil.getPivot(TupleLiteralExp.class, csTupleLiteralExp);	
		if (expression != null) {
			for (TupleLiteralPartCS csPart : csTupleLiteralExp.getOwnedParts()) {
				assert csPart != null;
				context.visitLeft2Right(TupleLiteralPart.class, csPart);
			}
			String tupleTypeName = "Tuple"; //ownedCollectionType.getName();
			List<TupleLiteralPart> parts = expression.getPart();
			assert parts != null;
			Type type = metaModelManager.getTupleType(tupleTypeName, parts, null);
			context.setType(expression, type, true);
		}
		return expression;
	}

	@Override
	public Element visitTupleLiteralPartCS(@NonNull TupleLiteralPartCS csTupleLiteralPart) {
		TupleLiteralPart pivotElement = PivotUtil.getPivot(TupleLiteralPart.class, csTupleLiteralPart);	
		if (pivotElement != null) {
			ExpCS csInitExpression = csTupleLiteralPart.getInitExpression();
			if (csInitExpression != null) {
				OCLExpression initExpression = context.visitLeft2Right(OCLExpression.class, csInitExpression);
				pivotElement.setInitExpression(initExpression);
				TypedRefCS csType = csTupleLiteralPart.getOwnedType();
				Type type = csType != null ? PivotUtil.getPivot(Type.class, csType) : initExpression.getType();
				context.setType(pivotElement, type, initExpression.isRequired());
			}
		}
		return pivotElement;
	}

	@Override
	public Element visitTypeLiteralExpCS(@NonNull TypeLiteralExpCS csTypeLiteralExp) {
		TypedRefCS csType = csTypeLiteralExp.getOwnedType();
//		context.visitInOrder(csType, null);
		Type type = PivotUtil.getPivot(Type.class, csType);
		return type != null ? resolveTypeExp(csTypeLiteralExp, type) : null;
	}

	@Override
	public Element visitUnaryOperatorCS(@NonNull UnaryOperatorCS csOperator) {
		OperationCallExp expression = context.refreshModelElement(OperationCallExp.class, PivotPackage.Literals.OPERATION_CALL_EXP, csOperator);
		String name = csOperator.getName();
		assert name != null;
		context.refreshName(expression, name);
		ExpCS csSource = csOperator.getSource();
		if (csSource != null) {
			OCLExpression source = context.visitLeft2Right(OCLExpression.class, csSource);
			if (source != null) {
				expression.setSource(source);
				Type sourceType = PivotUtil.getType(source);
				if (sourceType != null) {
					resolveOperationCall(expression, csOperator, new UnaryOperationFilter(sourceType));
				}
			}
		}
		return expression;
	}

	@Override
	public Element visitUnlimitedNaturalLiteralExpCS(@NonNull UnlimitedNaturalLiteralExpCS csUnlimitedNaturalLiteralExp) {
		UnlimitedNaturalLiteralExp expression = PivotUtil.getPivot(UnlimitedNaturalLiteralExp.class, csUnlimitedNaturalLiteralExp);
		if (expression != null) {
			context.setType(expression, metaModelManager.getUnlimitedNaturalType(), true);
		}
		return expression;
	}

	@Override
	public Element visitVariableCS(@NonNull VariableCS csVariable) {
		Variable variable = PivotUtil.getPivot(Variable.class, csVariable);
		if (variable != null) {
			OCLExpression initExpression = PivotUtil.getPivot(OCLExpression.class, csVariable.getInitExpression());
			if (initExpression != null) {
				Type initType = initExpression.getType();
				TypedRefCS csType = csVariable.getOwnedType();
				Type type;
				if (csType != null) {
					type = PivotUtil.getPivot(Type.class, csType);
				}
				else {
					type = initType;
					// FIXME deduction is more complex than this
				}
				if (metaModelManager.isUnderspecified(initType)) {
					initExpression.setType(type);
				}
				context.setType(variable, type, initExpression.isRequired());
			}
			variable.setInitExpression(initExpression);
		}
		return variable;
	}	
}
