/**
 * <copyright>
 *
 * Copyright (c) 2005, 2007 IBM Corporation 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:
 *   IBM - Initial API and implementation
 *
 * </copyright>
 *
 * $Id: ValidationVisitorImpl.java,v 1.12 2007/01/29 20:31:18 cdamus Exp $
 */

package org.eclipse.emf.ocl.expressions.impl;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ocl.expressions.AssociationClassCallExp;
import org.eclipse.emf.ocl.expressions.BooleanLiteralExp;
import org.eclipse.emf.ocl.expressions.CollectionItem;
import org.eclipse.emf.ocl.expressions.CollectionKind;
import org.eclipse.emf.ocl.expressions.CollectionLiteralExp;
import org.eclipse.emf.ocl.expressions.CollectionLiteralPart;
import org.eclipse.emf.ocl.expressions.CollectionRange;
import org.eclipse.emf.ocl.expressions.EnumLiteralExp;
import org.eclipse.emf.ocl.expressions.ExpressionsFactory;
import org.eclipse.emf.ocl.expressions.FeatureCallExp;
import org.eclipse.emf.ocl.expressions.IfExp;
import org.eclipse.emf.ocl.expressions.IntegerLiteralExp;
import org.eclipse.emf.ocl.expressions.InvalidLiteralExp;
import org.eclipse.emf.ocl.expressions.IterateExp;
import org.eclipse.emf.ocl.expressions.IteratorExp;
import org.eclipse.emf.ocl.expressions.LetExp;
import org.eclipse.emf.ocl.expressions.MessageExp;
import org.eclipse.emf.ocl.expressions.NullLiteralExp;
import org.eclipse.emf.ocl.expressions.OCLExpression;
import org.eclipse.emf.ocl.expressions.OperationCallExp;
import org.eclipse.emf.ocl.expressions.PropertyCallExp;
import org.eclipse.emf.ocl.expressions.RealLiteralExp;
import org.eclipse.emf.ocl.expressions.StateExp;
import org.eclipse.emf.ocl.expressions.StringLiteralExp;
import org.eclipse.emf.ocl.expressions.TupleLiteralExp;
import org.eclipse.emf.ocl.expressions.TupleLiteralPart;
import org.eclipse.emf.ocl.expressions.TypeExp;
import org.eclipse.emf.ocl.expressions.UnspecifiedValueExp;
import org.eclipse.emf.ocl.expressions.Variable;
import org.eclipse.emf.ocl.expressions.VariableExp;
import org.eclipse.emf.ocl.expressions.Visitor;
import org.eclipse.emf.ocl.expressions.util.AbstractVisitor;
import org.eclipse.emf.ocl.expressions.util.ExpressionsUtil;
import org.eclipse.emf.ocl.internal.OCLPlugin;
import org.eclipse.emf.ocl.parser.EcoreEnvironment;
import org.eclipse.emf.ocl.parser.Environment;
import org.eclipse.emf.ocl.types.BagType;
import org.eclipse.emf.ocl.types.CollectionType;
import org.eclipse.emf.ocl.types.OrderedSetType;
import org.eclipse.emf.ocl.types.PrimitiveBoolean;
import org.eclipse.emf.ocl.types.SequenceType;
import org.eclipse.emf.ocl.types.SetType;
import org.eclipse.emf.ocl.types.TupleType;
import org.eclipse.emf.ocl.types.TypeType;
import org.eclipse.emf.ocl.types.VoidType;
import org.eclipse.emf.ocl.types.impl.AnyTypeImpl;
import org.eclipse.emf.ocl.types.impl.TypeUtil;
import org.eclipse.emf.ocl.types.util.Types;
import org.eclipse.emf.ocl.uml.Constraint;
import org.eclipse.emf.ocl.uml.UMLPackage;
import org.eclipse.emf.ocl.utilities.ASTNode;
import org.eclipse.emf.ocl.utilities.PredefinedType;
import org.eclipse.ocl.internal.l10n.OCLMessages;

/**
 * @author Edith Schonberg (edith)
 * 
 * Checks the well-formedness rules for the expressions package
 */
public class ValidationVisitorImpl
	implements Visitor {

	private static Environment NULL_ENVIRONMENT = new NullEnvironment();
	
	private Environment environment = null;
	
	/**
	 * Obtains an instance of the validation visitor that assumes an Ecore
	 * environment, inferred from the context of the constraint being validated.
	 * 
	 * @return a validation visitor instance
	 */
	public static Visitor getInstance() {
		return new ValidationVisitorImpl(null);
	}
	
	/**
	 * Obtains an instance of the validation visitor that validates against the
	 * specified environment, which presumably was used in parsing the OCL in
	 * the first place.
	 * 
	 * @param environment an OCL environment
	 * 
	 * @return a validation visitor instance for the specified environment
	 */
	public static Visitor getInstance(Environment environment) {
		return new ValidationVisitorImpl(environment);
	}

	/**
	 * Default constructor.
	 * 
	 * @param environment the environment
	 */
	private ValidationVisitorImpl(Environment environment) {
		super();
		
		this.environment = environment;
	}
	
	/**
	 * Obtains the current environment, which may be inferred from the context
	 * of the constraint that we are validating.
	 * 
	 * @param node an AST node from which possibly to infer the environment.
	 *     If <code>null</code>, it will be assumed that we were initialized
	 *     with an environment
	 *     
	 * @return a suitable environment, or a default if no node was
	 *     provide for inference and we were not initialized with an explicit
	 *     environment
	 */
	protected Environment getEnvironment(ASTNode node) {
		Environment result = environment;
		
		if (result == null) {
			if (node != null) {
				result = createEcoreEnvironment(node);
			}
			
			if (result == null) {
				result = NULL_ENVIRONMENT;
			}
			
			environment = result;  // cache the result
		}
		
		return result;
	}
	
	/**
	 * Creates an Ecore environment from the context of an AST node.
	 * 
	 * @param node an AST node in the OCL constraint being validated
	 * 
	 * @return the appropriate environment
	 */
	private Environment createEcoreEnvironment(ASTNode node) {
		Environment result = null;
		
		Object context = null;
		Constraint constraint = (Constraint) ExpressionsUtil.containerOfType(
				UMLPackage.Literals.CONSTRAINT, node);
		
		if ((constraint != null) && !constraint.getConstrainedElement().isEmpty()) {
			context = constraint.getConstrainedElement().get(0);
			
			if (context instanceof EClassifier) {
				result = ExpressionsUtil.createClassifierContext(
						(EClassifier) context);
			} else if (context instanceof EOperation) {
				result = ExpressionsUtil.createOperationContext(
						(EOperation) context);
			} else if (context instanceof EStructuralFeature) {
				result = ExpressionsUtil.createPropertyContext(
						(EStructuralFeature) context);
			}
		}
		
		return result;
	}

	/**
	 * Callback for an OperationCallExp visit.
	 * 
	 * Well-formedness rule: All of the arguments must conform to the parameters
	 * of the referred operation. There must be exactly as many arguments as the
	 * referred operation has parameters.
	 * 
	 * @param oc
	 *            the operation call expression
	 * @return Boolean -- true if validated
	 */
	public Object visitOperationCallExp(OperationCallExp oc) {

		OCLExpression source = oc.getSource();
		EOperation oper = oc.getReferredOperation();
		int opcode = oc.getOperationCode();
		EList args = oc.getArgument();

		if (oper == null) {
			String message = OCLMessages.bind(
					OCLMessages.NullOperation_ERROR_,
					oc.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin
				.throwing(getClass(), "visitOperationCallExp", error);//$NON-NLS-1$
			throw error;
		}

		if (source == null) {
			String message = OCLMessages.bind(
					OCLMessages.NullSourceOperation_ERROR_,
					oc.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin
				.throwing(getClass(), "visitOperationCallExp", error);//$NON-NLS-1$
			throw error;
		}

		EClassifier sourceType = source.getType();
		int numArgs = args.size();
		String operName = oper.getName();

		for (int i = 0; i < numArgs; i++) {
			((OCLExpression) args.get(i)).accept(this);
		}
		
		visitFeatureCallExp(oc);
		
		if (opcode == PredefinedType.OCL_IS_NEW) {
			// oclIsNew() may only be used in postcondition constraints
			if (!ExpressionsUtil.isInPostcondition(oc)) {
				
				IllegalArgumentException error = new IllegalArgumentException(
						OCLMessages.OCLIsNewInPostcondition_ERROR_);
				OCLPlugin.throwing(getClass(),
					"visitOperationCallExp", error);//$NON-NLS-1$
				throw error;
			}
		}
		
		source.accept(this);

		// Check argument conformance.
		try {
			EOperation oper1 = getEnvironment(oc).lookupOperation(sourceType,
				operName, args);
			if (oper1 != oper) {
				String message = OCLMessages.bind(
						OCLMessages.IllegalOperation_ERROR_,
						oc.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitOperationCallExp", error);//$NON-NLS-1$
				throw error;
			}
			
			if (!getEnvironment(oc).isQuery(oper)) {
				String message = OCLMessages.bind(
						OCLMessages.NonQueryOperation_ERROR_,
						oper.getName());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitOperationCallExp", error);//$NON-NLS-1$
				throw error;
			}
			
			EClassifier resultType = null;

			if (sourceType instanceof PredefinedType) {
				PredefinedType pt = (PredefinedType) sourceType;
				
				if (opcode != pt.getOperationCodeFor(operName)) {
					String message = OCLMessages.bind(
							OCLMessages.IllegalOpcode_ERROR_,
							operName);
					IllegalArgumentException error = new IllegalArgumentException(
						message);
					OCLPlugin.throwing(getClass(),
						"visitOperationCallExp", error);//$NON-NLS-1$
					throw error;
				}
				
				resultType = pt.getResultTypeFor(sourceType, opcode, args);
				
				if (resultType == null) {
					// maybe this operation was an "extra" contribution by a
					//    custom environment implementation
					resultType = TypeUtil.getOCLType(oper);
				} else {
                    // be sure to compare apples to apples (the call expression's
                    //    type is an OCL type)
				    resultType = TypeUtil.getOCLType(resultType);
                }
			} else {
				// source is an EClass, an enumeration, or a user data type
				if (opcode != AnyTypeImpl.getOperationCode(operName)) {
					String message = OCLMessages.bind(
							OCLMessages.IllegalOpcode_ERROR_,
							operName);
					IllegalArgumentException error = new IllegalArgumentException(
						message);
					OCLPlugin.throwing(getClass(),
						"visitOperationCallExp", error);//$NON-NLS-1$
					throw error;
				}
				resultType = AnyTypeImpl
					.getResultType(sourceType, opcode, args);
				if (resultType == null) {
					resultType = TypeUtil.getOCLType(oper);
				}
			}
			if (TypeUtil.typeCompare(resultType, oc.getType()) != 0) {
				String message = OCLMessages.bind(
						OCLMessages.TypeConformanceOperation_ERROR_,
						oc.getType().toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitOperationCallExp", error);//$NON-NLS-1$
				throw error;
			}
		} catch (Exception e) {
			IllegalArgumentException error = new IllegalArgumentException(e
				.getMessage());
			OCLPlugin
				.throwing(getClass(), "visitOperationCallExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}

	/**
	 * Callback for an EnumLiteralExp visit. Well-formedness rule: The type of
	 * an enum Literal expression is the type of the referred literal.
	 * 
	 * @param el
	 *            the enumeration literal expresion
	 * @return Boolean -- true if validated
	 */
	public Object visitEnumLiteralExp(EnumLiteralExp el) {
		EEnumLiteral l = el.getReferredEnumLiteral();
		EClassifier type = el.getType();
		if (!(type instanceof EEnum) || l.getEEnum() != type) {
			String message = OCLMessages.bind(
					OCLMessages.IllegalEnumLiteral_ERROR_,
					el.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitEnumLiteralExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}

	/**
	 * Callback for a VariableExp visit. Well-formedness rule: The type of a
	 * VariableExp is the type of the Variable to which it refers.
	 * 
	 * @param v
	 *            the variable expression
	 * @return Boolean -- true if validated
	 */
	public Object visitVariableExp(VariableExp v) {
		// get the referred variable name
		Variable vd = v.getReferredVariable();

		if (vd == null || v.getType() == null || vd.getName() == null
			|| vd.getType() == null) {
			String message = OCLMessages.bind(
					OCLMessages.IncompleteVariableExp_ERROR_,
					v.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitVariableExp", error);//$NON-NLS-1$
			throw error;
		}
		vd.accept(this);
		if (TypeUtil.typeCompare(vd.getType(), v.getType()) != 0) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(OCLMessages.VariableTypeMismatch_ERROR_, vd.getName()));
			OCLPlugin.throwing(getClass(), "visitVariableExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}

	/**
	 * Callback for an PropertyCallExp visit. Well-formedness rule: The
	 * type of the PropertyCallExp is the type of the referred
	 * EStructuralFeature.
	 * 
	 * @param pc the property call expression
	 * @return Boolean -- true if validated
	 */
	public Object visitPropertyCallExp(PropertyCallExp pc) {
		EStructuralFeature property = pc.getReferredProperty();
		OCLExpression source = pc.getSource();
		EClassifier type = pc.getType();

		if (property == null) {
			String message = OCLMessages.bind(
					OCLMessages.NullProperty_ERROR_,
					pc.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(),
				"visitPropertyCallExp", error);//$NON-NLS-1$
			throw error;
		}
		
		if (source == null) {
			String message = OCLMessages.bind(
					OCLMessages.NullNavigationSource_ERROR_,
					pc.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(),
				"visitPropertyCallExp", error);//$NON-NLS-1$
			throw error;
		}
		if (type == null) {
			String message = OCLMessages.bind(
					OCLMessages.NullNavigationType_ERROR_,
					pc.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(),
				"visitPropertyCallExp", error);//$NON-NLS-1$
			throw error;
		}
		
		EList qualifiers = pc.getQualifier();
		if (!qualifiers.isEmpty()) {
			// navigation qualifiers must conform to expected qualifier types
			EList expectedQualifierTypes = getEnvironment(pc).getQualifiers(property);
			
			if (expectedQualifierTypes.size() != qualifiers.size()) {
				String message = OCLMessages.bind(
						OCLMessages.MismatchedQualifiers_ERROR_,
						pc.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitPropertyCallExp", error);//$NON-NLS-1$
				throw error;
			} else {
				Iterator eiter = expectedQualifierTypes.iterator();
				Iterator qiter = qualifiers.iterator();
				
				while (eiter.hasNext()) {
					EClassifier expectedType = TypeUtil.getOCLType(
							(ETypedElement) eiter.next());
					OCLExpression qualifier = (OCLExpression) qiter.next();
					
					EClassifier qualifierType = qualifier.getType();
					if ((TypeUtil.getRelationship(qualifierType, expectedType)
							& PredefinedType.SUBTYPE) == 0) {
						
						String message = OCLMessages.bind(
								OCLMessages.MismatchedQualifiers_ERROR_,
								pc.toString());
						IllegalArgumentException error = new IllegalArgumentException(
							message);
						OCLPlugin.throwing(getClass(),
							"visitPropertyCallExp", error);//$NON-NLS-1$
						throw error;
					}
				}
			}
		}
		
		visitFeatureCallExp(pc);
		
		source.accept(this);

		EClassifier refType = TypeUtil.getOCLType(property);
		
		if (!pc.getQualifier().isEmpty() && (refType instanceof CollectionType)) {
			// qualifying the navigation results in a non-collection
			//    type
			refType = ((CollectionType) refType).getElementType();
		}
		
		return Boolean.valueOf(TypeUtil.typeCompare(refType, type) == 0);
	}

	/**
	 * Callback for an AssociationClassCallExp visit. Well-formedness rules:
	 * <ul>
	 *   <li>the type of the AssociationClassCallExp is the type of the
	 *       referenced EReference</li>
	 *   <li>the referenced EReference is an AssociationClassEnd, and its
	 *       associationClass reference is not null</li>
	 * </ul>
	 * 
	 * @param ae
	 *            the association end expression
	 * @return Boolean -- true if validated
	 */
	public Object visitAssociationClassCallExp(AssociationClassCallExp ae) {
		EClass ref = ae.getReferredAssociationClass();
		OCLExpression source = ae.getSource();
		EClassifier type = ae.getType();

		if (ref == null) {
			String message = OCLMessages.bind(
					OCLMessages.MissingAssociationClass_ERROR_,
					ae.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(),
				"visitAssociationClassCallExp", error);//$NON-NLS-1$
			throw error;
		}
		
		if (source == null) {
			String message = OCLMessages.bind(
					OCLMessages.NullNavigationSource_ERROR_,
					ae.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(),
				"visitAssociationClassCallExp", error);//$NON-NLS-1$
			throw error;
		}
		EClassifier sourceType = source.getType();
		
		if (type == null) {
			String message = OCLMessages.bind(
					OCLMessages.NullNavigationType_ERROR_,
					ae.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(),
				"visitAssociationClassCallExp", error);//$NON-NLS-1$
			throw error;
		}
		
		if (type instanceof CollectionType) {
			type = ((CollectionType) type).getElementType();
		}
		
		if (ae.getNavigationSource() != null) {
			// navigation source must be an end of the association class
			EStructuralFeature end = ae.getNavigationSource();
			
			if (!(end instanceof EReference)
					|| (ref != getEnvironment(ae).getAssociationClass((EReference) end))
					|| (end != getEnvironment(ae).lookupProperty(sourceType, end.getName()))) {
				String message = OCLMessages.bind(
						OCLMessages.AssociationClassQualifierType_ERROR_,
						ae.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitAssociationClassCallExp", error);//$NON-NLS-1$
				throw error;
			}
		}
		
		visitFeatureCallExp(ae);
		
		source.accept(this);

		EClassifier refType = TypeUtil.getOCLType(ref);

		if (TypeUtil.typeCompare(refType, type) == 0)
			return Boolean.TRUE;
		return Boolean.FALSE;
	}

	/**
	 * Callback for a VariableDeclaration visit. Well-formedness rule: The type
	 * of the initExpression must conform to the type of the declared variable.
	 * 
	 * @param vd --
	 *            variable declaration
	 * @return Boolean -- true if validated
	 */
	public Object visitVariable(Variable vd) {
		String varName = vd.getName();
		if (varName == null) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.MissingNameInVariableDeclaration_ERROR_);
			OCLPlugin.throwing(getClass(),
				"visitVariableDeclaration", error);//$NON-NLS-1$
			throw error;
		}
		EClassifier type = vd.getType();
		OCLExpression init = vd.getInitExpression();

		if (init != null) {
			init.accept(this);
			if (TypeUtil.typeCompare(init.getType(), type) > 0) {
				IllegalArgumentException error = new IllegalArgumentException(
						OCLMessages.bind(
								OCLMessages.TypeConformanceInit_ERROR_,
								varName));
				OCLPlugin.throwing(getClass(),
					"visitVariableDeclaration", error);//$NON-NLS-1$
				throw error;
			}
		}
		return Boolean.TRUE;
	}

	/**
	 * Callback for an IfExp visit. Well-formedness Rule: The type of the
	 * condition must be Boolean. The type of the if expression is the common
	 * supertype of the then and else
	 * 
	 * @param i -
	 *            if expression
	 * @return Boolean -- true if validated
	 */
	public Object visitIfExp(IfExp i) {
		OCLExpression cond = i.getCondition();
		OCLExpression thenexp = i.getThenExpression();
		OCLExpression elseexp = i.getElseExpression();

		if (cond == null || thenexp == null | elseexp == null) {
			String message = OCLMessages.bind(
					OCLMessages.IncompleteIfExp_ERROR_,
					i.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitIfExp", error);//$NON-NLS-1$
			throw error;
		}
		cond.accept(this);
		thenexp.accept(this);
		elseexp.accept(this);
		if (cond.getType() != Types.OCL_BOOLEAN) {
			String message = OCLMessages.bind(
					OCLMessages.NonBooleanIfExp_ERROR_,
					cond.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitIfExp", error);//$NON-NLS-1$
			throw error;
		}
		EClassifier thenelsetype = null;
		try {
			thenelsetype = TypeUtil.commonSuperType(thenexp.getType(),
				elseexp.getType());
		} catch (Exception e) {
			throw new IllegalArgumentException(e.getMessage());
		}
		if (TypeUtil.typeCompare(i.getType(), thenelsetype) != 0) {
			String message = OCLMessages.bind(
					OCLMessages.TypeConformanceIfExp_ERROR_,
					i.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitIfExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}

	public Object visitMessageExp(MessageExp m) {
		if (m.getTarget() == null) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(
							OCLMessages.MissingMessageTarget_ERROR_,
							m.toString()));
			OCLPlugin.throwing(getClass(), "visitMessageExp", error);//$NON-NLS-1$
			throw error;
		}
		
		m.getTarget().accept(this);
		
		if (m.getCalledOperation() == null && m.getSentSignal() == null) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.UnrecognizedMessageType_ERROR_);
			OCLPlugin.throwing(getClass(), "visitMessageExp", error);//$NON-NLS-1$
			throw error;
		}
		if (m.getCalledOperation() != null && m.getSentSignal() != null) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.AmbiguousMessageType_ERROR_);
			OCLPlugin.throwing(getClass(), "visitMessageExp", error);//$NON-NLS-1$
			throw error;
		}
		
		EList parameters;
		
		if (m.getCalledOperation() != null) {
			EOperation operation = m.getCalledOperation().getOperation();
			
			if (operation == null) {
				IllegalArgumentException error = new IllegalArgumentException(
						OCLMessages.bind(
								OCLMessages.MissingOperationInCallAction_ERROR_,
								m.toString()));
				OCLPlugin.throwing(getClass(), "visitMessageExp", error);//$NON-NLS-1$
				throw error;
			}
			
			parameters = operation.getEParameters();
		} else {
			EClass signal = m.getSentSignal().getSignal();
			
			if (signal == null) {
				IllegalArgumentException error = new IllegalArgumentException(
						OCLMessages.bind(
								OCLMessages.MissingSignalInCallAction_ERROR_,
								m.toString()));
				OCLPlugin.throwing(getClass(), "visitMessageExp", error);//$NON-NLS-1$
				throw error;
			}
			
			parameters = TypeUtil.getProperties(signal);
		}
		
		EList arguments = m.getArgument();
		
		if (arguments.size() != parameters.size()) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(OCLMessages.MessageArgumentCount_ERROR_,
							getName(m.getType())));
			OCLPlugin.throwing(getClass(), "visitMessageExp", error);//$NON-NLS-1$
			throw error;
		}
		
		// check type conformance against operation/signal parameters
		Iterator paramsIter = parameters.iterator();
		Iterator argsIter = arguments.iterator();
		while (paramsIter.hasNext()) {
			ETypedElement param = (ETypedElement) paramsIter.next();
			OCLExpression arg = (OCLExpression) argsIter.next();
			
			if (TypeUtil.typeCompare(arg.getType(), TypeUtil.getOCLType(param)) > 0) {
				IllegalArgumentException error = new IllegalArgumentException(
						OCLMessages.bind(OCLMessages.MessageArgConformance_ERROR_,
							param.getName(), arg.toString()));
				OCLPlugin.throwing(getClass(), "visitMessageExp", error);//$NON-NLS-1$
				throw error;
			}
			
			// validate the argument
			arg.accept(this);
		}
		
		return Boolean.TRUE;
	}
	
	/**
	 * Callback for an UnspecifiedValueExp visit.
	 * 
	 * @param uv --
	 *            unspecified value expression
	 * @return Boolean -- true if validated
	 */
	public Object visitUnspecifiedValueExp(UnspecifiedValueExp uv) {
		// unspecified values need not declare a type (it can be OclVoid).
		//   The only restriction is that they can only be used in message expressions
		if (!(uv.eContainer() instanceof MessageExp)) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(
							OCLMessages.IllegalUnspecifiedValueExp_ERROR_,
							uv.toString()));
			OCLPlugin.throwing(getClass(), "visitUnspecifiedValueExp", error);//$NON-NLS-1$
			throw error;
		}
		
		return Boolean.TRUE;
	}
	
	/**
	 * Callback for a TypeExp visit.
	 */
	public Object visitTypeExp(TypeExp t) {
		if (!(t.getType() instanceof TypeType)) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(OCLMessages.TypeConformanceTypeExp_ERROR_,
							getName(t.getType())));
			OCLPlugin.throwing(getClass(),
				"visitTypeExp", error);//$NON-NLS-1$
			throw error;
		}
		
		if (t.getReferredType() == null) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(
							OCLMessages.TypeExpMissingType_ERROR_,
							t.toString()));
			OCLPlugin.throwing(getClass(),
				"visitTypeExp", error);//$NON-NLS-1$
			throw error;
		}
		
		return Boolean.TRUE;
	}

	/**
	 * Callback for an IntegerLiteralExp visit. Well-formedness rule: The type
	 * of an integer Literal expression is the type Integer
	 * 
	 * @param il -
	 *            integer literal expression
	 * @return Boolean -- true if validated
	 */
	public Object visitIntegerLiteralExp(IntegerLiteralExp il) {
		if (il.getType() != Types.OCL_INTEGER) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.TypeConformanceIntegerLiteral_ERROR_);
			OCLPlugin.throwing(getClass(),
				"visitIntegerLiteralExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}

	/**
	 * Callback for a RealLiteralExp visit. Well-formedness rule: The type of a
	 * real literal expression is the type Real.
	 * 
	 * @param rl --
	 *            real literal expression
	 * @return Boolean -- true if validated
	 */
	public Object visitRealLiteralExp(RealLiteralExp rl) {
		if (rl.getType() != Types.OCL_REAL) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.TypeConformanceRealLiteral_ERROR_);
			OCLPlugin.throwing(getClass(), "visitRealLiteralExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}

	/**
	 * Callback for a StringLiteralExp visit. Well-formedness rule: The type of
	 * a string literal expression is the type of the string.
	 * 
	 * @param sl --
	 *            string literal expression
	 * @return Boolean -- true if validated
	 */
	public Object visitStringLiteralExp(StringLiteralExp sl) {
		if (sl.getType() != Types.OCL_STRING) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.TypeConformanceStringLiteral_ERROR_);
			OCLPlugin
				.throwing(getClass(), "visitStringLiteralExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}

	/**
	 * Callback for a BooleanLiteralExp visit. Well-formedness rule: The type of
	 * a Boolean Literal expression is the type of the boolean.
	 * 
	 * @param bl -
	 *            boolean literal expression
	 * @return Boolean - true if validated
	 */
	public Object visitBooleanLiteralExp(BooleanLiteralExp bl) {
		if (bl.getType() != Types.OCL_BOOLEAN) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.TypeConformanceBooleanLiteral_ERROR_);
			OCLPlugin.throwing(getClass(),
				"visitBooleanLiteralExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}

	/**
	 * Callback for LetExp visit. Well-formedness rule: The type of the Let
	 * expression is the type of the in expression.
	 * 
	 * @param l --
	 *            let expression
	 * @return Boolean -- true if validated
	 */
	public Object visitLetExp(LetExp l) {
		Variable vd = l.getVariable();
		OCLExpression in = l.getIn();
		EClassifier type = l.getType();

		if (vd == null || in == null || type == null) {
			String message = OCLMessages.bind(
					OCLMessages.IncompleteLetExp_ERROR_,
					l.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitLetExp", error);//$NON-NLS-1$
			throw error;
		}

		vd.accept(this);
		in.accept(this);

		if (TypeUtil.typeCompare(type, in.getType()) != 0) {
			String message = OCLMessages.bind(
					OCLMessages.TypeConformanceLetExp_ERROR_,
					type, in.getType());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitLetExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}

	/**
	 * 
	 * Callback for an IterateExp visit. *Well-formedness rule: The type of the
	 * iterate is the type of the result variable. The type of the body
	 * expression must conform to the declared type of the result variable. *A
	 * result variable must have an init expression. *The type of a source
	 * expression must be a collection. *The loop variable has no init
	 * expression. *The type of the iterator variable must be the type of the
	 * elements of the *source collection.
	 * 
	 * @param ie -
	 *            iterate expression
	 * @return Boolean -- true if validated
	 */
	public Object visitIterateExp(IterateExp ie) {
		// get the variable declaration for the result
		Variable vd = ie.getResult();
		EClassifier type = ie.getType();
		OCLExpression body = ie.getBody();
		OCLExpression source = ie.getSource();
		EList iterators = ie.getIterator();

		if (vd == null || type == null || source == null || body == null
			|| iterators.isEmpty()) {
			String message = OCLMessages.bind(
					OCLMessages.IncompleteIterateExp_ERROR_,
					ie.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitIterateExp", error);//$NON-NLS-1$
			throw error;
		}

		int numIters = iterators.size();

		// Validate all of the iterate parts
		source.accept(this);
		vd.accept(this);
		body.accept(this);

		if (vd.getInitExpression() == null) {
			String message = OCLMessages.bind(
					OCLMessages.MissingInitIterateExp_ERROR_,
					ie.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitIterateExp", error);//$NON-NLS-1$
			throw error;
		}

		if (TypeUtil.typeCompare(type, vd.getType()) != 0) {
			String message = OCLMessages.bind(
					OCLMessages.TypeConformanceIterateExp_ERROR_,
					ie.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitIterateExp", error);//$NON-NLS-1$
			throw error;
		}
		if (TypeUtil.typeCompare(body.getType(), vd.getType()) > 0) {
			String message = OCLMessages.bind(
					OCLMessages.TypeConformanceIterateExpBody_ERROR_,
					ie.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitIterateExp", error);//$NON-NLS-1$
			throw error;
		}

		EClassifier sourceType = source.getType();
		if (!(sourceType instanceof CollectionType)) {
			String message = OCLMessages.bind(
					OCLMessages.IteratorSource_ERROR_,
					ie.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitIterateExp", error);//$NON-NLS-1$
			throw error;
		}

		for (int i = 0; i < numIters; i++) {
			Variable loopiter = (Variable) iterators
				.get(i);
			// Validate the iterator expressions
			loopiter.accept(this);
			if (loopiter.getInitExpression() != null) {
				String message = OCLMessages.bind(
						OCLMessages.IterateExpLoopVarInit_ERROR_,
						ie.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(), "visitIterateExp", error);//$NON-NLS-1$
				throw error;
			}
			if (TypeUtil.typeCompare(loopiter.getType(),
				((CollectionType) sourceType).getElementType()) != 0) {
				String message = OCLMessages.bind(
						OCLMessages.TypeConformanceIterateExpLoopVar_ERROR_,
						ie.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(), "visitIterateExp", error);//$NON-NLS-1$
				throw error;
			}
		}
		return Boolean.TRUE;
	}

	/**
	 * Callback for an IteratorExp visit. Well-formedness rule: If the iterator
	 * is "forall", "isUnique", "any", "one", or "exists", the type of the
	 * iterator must be Boolean. The result type of the collect operation on a
	 * sequence type is a sequence; the result type of collect on any other type
	 * is a bag. The select and reject iterators have the same type as its
	 * source. They type of the body of the select, reject, forall, exists must
	 * be boolean. The type of a source expression must be a collection. The
	 * loop variable has no init expression. The type of the iterator variable
	 * must be the type of the elements of the source collection.
	 * 
	 * @param ie --
	 *            iterator expression
	 * @return Boolean -- true if validated
	 */
	public Object visitIteratorExp(IteratorExp ie) {
		EClassifier type = ie.getType();
		OCLExpression body = ie.getBody();
		OCLExpression source = ie.getSource();
		EList iterators = ie.getIterator();
		String name = ie.getName();

		if (type == null || name == null || source == null || body == null
			|| iterators.isEmpty()) {
			String message = OCLMessages.bind(
					OCLMessages.IncompleteIteratorExp_ERROR_,
					ie.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitIteratorExp", error);//$NON-NLS-1$
			throw error;
		}

		int opcode = 0;
		if (source.getType() instanceof PredefinedType) {
			opcode = ((PredefinedType) source.getType()).getOperationCodeFor(name);
		}
		
		int numIters = iterators.size();

		// Validate all of the iterate parts
		source.accept(this);
		body.accept(this);

		switch (opcode) {
		case PredefinedType.FOR_ALL:
		case PredefinedType.EXISTS:
		case PredefinedType.IS_UNIQUE:
			if (type != Types.OCL_BOOLEAN) {
				String message = OCLMessages.bind(
						OCLMessages.TypeConformanceIteratorResult_ERROR_,
						ie.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(), "visitIteratorExp", error);//$NON-NLS-1$
				throw error;
			}
		}
		
		if (opcode == PredefinedType.COLLECT) {
			if (source.getType() instanceof SequenceType
				|| source.getType() instanceof OrderedSetType) {
				if (!(type instanceof SequenceType)) {
					String message = OCLMessages.bind(
							OCLMessages.TypeConformanceCollectSequence_ERROR_,
							ie.toString());
					IllegalArgumentException error = new IllegalArgumentException(
						message);
					OCLPlugin.throwing(getClass(),
						"visitIteratorExp", error);//$NON-NLS-1$
					throw error;
				}
			} else if (!(type instanceof BagType)) {
				String message = OCLMessages.bind(
						OCLMessages.TypeConformanceCollectBag_ERROR_,
						ie.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(), "visitIteratorExp", error);//$NON-NLS-1$
				throw error;
			}
		}
		
		switch (opcode) {
		case PredefinedType.SELECT:
		case PredefinedType.REJECT:
			if (TypeUtil.typeCompare(type, source.getType()) != 0) {
				String message = OCLMessages.bind(
						OCLMessages.TypeConformanceSelectReject_ERROR_,
						ie.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(), "visitIteratorExp", error);//$NON-NLS-1$
				throw error;
			}
		}

		switch (opcode) {
		case PredefinedType.SELECT:
		case PredefinedType.REJECT:
		case PredefinedType.FOR_ALL:
		case PredefinedType.ANY:
		case PredefinedType.EXISTS:
		case PredefinedType.ONE:
			if (body.getType() != Types.OCL_BOOLEAN) {
				String message = OCLMessages.bind(
						OCLMessages.TypeConformanceIteratorBodyBoolean_ERROR_,
						ie.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(), "visitIteratorExp", error);//$NON-NLS-1$
				throw error;
			}
		}

		EClassifier sourceType = source.getType();
		if (!(sourceType instanceof CollectionType)) {
			String message = OCLMessages.bind(
					OCLMessages.IteratorSource_ERROR_,
					ie.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(), "visitIteratorExp", error);//$NON-NLS-1$
			throw error;
		}
		
		if (opcode == PredefinedType.CLOSURE) {
			if (!(type instanceof SetType)) {
				String message = OCLMessages.bind(
					OCLMessages.TypeConformanceClosure_ERROR_,
					ie.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitIteratorExp", error);//$NON-NLS-1$
				throw error;
			}
			
			// recursive reference must be to a type conforming
			//   to the source, otherwise it isn't recursive
			
			// checked above that the source is a collection type
			EClassifier sourceElementType =
				((CollectionType) source.getType()).getElementType();
			EClassifier bodyType =
				((CollectionType) type).getElementType();
			
			if (TypeUtil.typeCompare(sourceElementType, bodyType) < 0) {
				String message = OCLMessages.bind(
						OCLMessages.ElementTypeConformanceClosure_ERROR_,
						getName(bodyType),
						getName(sourceElementType));
					IllegalArgumentException error = new IllegalArgumentException(
						message);
					OCLPlugin.throwing(getClass(),
						"visitIteratorExp", error);//$NON-NLS-1$
					throw error;
			}
		}

		for (int i = 0; i < numIters; i++) {
			Variable loopiter = (Variable) iterators
				.get(i);
			// Validate the iterator expressions
			loopiter.accept(this);
			if (loopiter.getInitExpression() != null) {
				String message = OCLMessages.bind(
						OCLMessages.IterateExpLoopVarInit_ERROR_,
						ie.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(), "visitIteratorExp", error);//$NON-NLS-1$
				throw error;
			}
			if (TypeUtil.typeCompare(loopiter.getType(),
				((CollectionType) sourceType).getElementType()) != 0) {
				String message = OCLMessages.bind(
						OCLMessages.TypeConformanceIteratorExpLoopVar_ERROR_,
						ie.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(), "visitIteratorExp", error);//$NON-NLS-1$
				throw error;
			}
		}

		return Boolean.TRUE;
	}

	/**
	 * Callback for a CollectionLiteralExp visit. Well-formedness rule: The type
	 * of a collection literal expression is determined by the collection kind
	 * selection, and the common supertype of all elements. The empty collection
	 * has a Classifier as element type.
	 * 
	 * @param cl --
	 *            collection literal expression
	 * @return Boolean -- true if validated
	 */
	public Object visitCollectionLiteralExp(CollectionLiteralExp cl) {

		CollectionKind kind = cl.getKind();
		EClassifier collectionType = cl.getType();
		if (collectionType == null
			|| !(collectionType instanceof CollectionType)) {
			String message = OCLMessages.bind(
					OCLMessages.TypeConformanceCollectionLiteralExp_ERROR_,
					cl.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(),
				"visitCollectionLiteralExp", error);//$NON-NLS-1$
			throw error;
		}

		if (kind == CollectionKind.SET_LITERAL) {
			if (!(collectionType instanceof SetType)) {
				String message = OCLMessages.bind(
						OCLMessages.TypeConformanceSetLiteral_ERROR_,
						cl.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitCollectionLiteralExp", error);//$NON-NLS-1$
				throw error;
			}
		} else if (kind == CollectionKind.ORDERED_SET_LITERAL) {
			if (!(collectionType instanceof OrderedSetType)) {
				String message = OCLMessages.bind(
						OCLMessages.TypeConformanceOrderedSetLiteral_ERROR_,
						cl.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitCollectionLiteralExp", error);//$NON-NLS-1$
				throw error;
			}
		} else if (kind == CollectionKind.BAG_LITERAL) {
			if (!(collectionType instanceof BagType)) {
				String message = OCLMessages.bind(
						OCLMessages.TypeConformanceBagLiteral_ERROR_,
						cl.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitCollectionLiteralExp", error);//$NON-NLS-1$
				throw error;
			}
		} else if (kind != CollectionKind.SEQUENCE_LITERAL
			|| !(collectionType instanceof SequenceType)) {
			String message = OCLMessages.bind(
					OCLMessages.TypeConformanceSequenceLiteral_ERROR_,
					cl.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(),
				"visitCollectionLiteralExp", error);//$NON-NLS-1$
			throw error;
		}

		List parts = cl.getPart();
		if (parts.isEmpty()) {
			if (((CollectionType) collectionType).getElementType() != Types.OCL_VOID) {
				String message = OCLMessages.bind(
						OCLMessages.TypeConformanceEmptyCollection_ERROR_,
						cl.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitCollectionLiteralExp", error);//$NON-NLS-1$
				throw error;
			} else
				return Boolean.TRUE;
		}

		EClassifier partsType = ((CollectionLiteralPart) parts.get(0))
			.getType();

		for (Iterator it = parts.iterator(); it.hasNext();) {
			CollectionLiteralPart part = (CollectionLiteralPart) it.next();

			if (part instanceof CollectionItem) {
				((CollectionItem) part).getItem().accept(this);
			} else {
				((CollectionRange) part).getFirst().accept(this);
				((CollectionRange) part).getLast().accept(this);
			}
			try {
				partsType = TypeUtil.commonSuperType(partsType, part
					.getType());
			} catch (Exception e) {
				throw new IllegalArgumentException(e.getMessage());
			}

		}
		if (TypeUtil.typeCompare(partsType,
			((CollectionType) collectionType).getElementType()) != 0) {
			String message = OCLMessages.bind(
					OCLMessages.TypeConformanceCollectionElementType_ERROR_,
					cl.toString());
			IllegalArgumentException error = new IllegalArgumentException(
				message);
			OCLPlugin.throwing(getClass(),
				"visitCollectionLiteralExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}

	/**
	 * Callback for a TupleLiteralExp visit.
	 * 
	 * Well-formedness rule: The type of a tuple literal is a TupleType the
	 * specified parts All tuple literal expression parts must have unique
	 * names. The type of each attribute in a tuple literal part must match the
	 * type of the initialization expression.
	 * 
	 * @param tl
	 *            tuple literal expression
	 * @return Boolean
	 */
	public Object visitTupleLiteralExp(TupleLiteralExp tl) {

		EClassifier type = tl.getType();
		if (!(type instanceof TupleType)) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(
							OCLMessages.TypeConformanceTupleLiteralExp_ERROR_,
							tl.toString()));
			OCLPlugin.throwing(getClass(), "visitTupleLiteralExp", error);//$NON-NLS-1$
			throw error;
		}

		EClass eclazz = (EClass) type;
		
		// The fields of the tuple are the properties of the EClass.

		EList tp = tl.getPart();
		if (tp.size() != eclazz.getEStructuralFeatures().size()) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(
							OCLMessages.TypeConformanceTupleLiteralExpParts_ERROR_,
							tl.toString()));
			OCLPlugin.throwing(getClass(), "visitTupleLiteralExp", error);//$NON-NLS-1$
			throw error;
		}

		Set names = new java.util.HashSet();
		
		// Match each property with a tuple part
		Iterator iter = tl.getPart().iterator();
		while (iter.hasNext()) {
			TupleLiteralPart part = (TupleLiteralPart) iter.next();
			String name = part.getName();
			EStructuralFeature property = eclazz.getEStructuralFeature(name);
			
			if (property == null) {
				String message = OCLMessages.bind(
						OCLMessages.TupleLiteralExpressionPart_ERROR_,
						name,
						tl.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitTupleLiteralExp", error);//$NON-NLS-1$
				throw error;
			}

			// Validate each TupleLiteralPart in the tuple literal
			// At the same time, check for unique names
			if (!names.add(name)) {
				String message = OCLMessages.bind(
						OCLMessages.TupleDuplicateName_ERROR_,
						name, tl.toString());
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitTupleLiteralExp", error);//$NON-NLS-1$
				throw error;
			}
			
			part.accept(this);
		}
		
		return Boolean.TRUE;
	}
	
	public Object visitTupleLiteralPart(TupleLiteralPart tp) {
		EStructuralFeature property = tp.getAttribute();
		
		if (property == null) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(
							OCLMessages.MissingPropertyInTupleLiteralPart_ERROR_,
							tp.getName(),
							tp.eContainer().toString()));
			OCLPlugin.throwing(getClass(),
				"visitTupleLiteralPart", error);//$NON-NLS-1$
			throw error;
		}
		
		EClassifier type = tp.getType();
		
		if (type == null) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(
							OCLMessages.MissingTypeInTupleLiteralPart_ERROR_,
							tp.getName(),
							tp.eContainer().toString()));
			OCLPlugin.throwing(getClass(),
				"visitTupleLiteralPart", error);//$NON-NLS-1$
			throw error;
		}
		
		// convert property type to OCL type because it may be an Ecore primitive
		//    such as EIntegerObject
		if (TypeUtil.typeCompare(TypeUtil.getOCLType(property), type) != 0) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(
							OCLMessages.TuplePartType_ERROR_,
							tp.getName(),
							tp.eContainer().toString()));
			OCLPlugin.throwing(getClass(),
				"visitTupleLiteralPart", error);//$NON-NLS-1$
			throw error;
		}
		
		OCLExpression init = tp.getValue();
		
		if (init != null) {
			init.accept(this);
			
			if (TypeUtil.typeCompare(init.getType(), type) > 0) {
				IllegalArgumentException error = new IllegalArgumentException(
						OCLMessages.TypeConformanceTuplePartValue_ERROR_);
				OCLPlugin.throwing(getClass(),
					"visitTupleLiteralPart", error);//$NON-NLS-1$
				throw error;
			}
		}
		
		return Boolean.TRUE;
	}
	
	public Object visitStateExp(StateExp s) {
		EObject state = s.getReferredState();
		
		if (state == null) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.bind(
							OCLMessages.MissingStateInStateExp_ERROR_,
							s.toString()));
			OCLPlugin.throwing(getClass(),
				"visitStateExp", error);//$NON-NLS-1$
			throw error;
		}
		
		return Boolean.TRUE;
	}
	
	/**
	 * Applies well-formedness rules to constraints.
	 * 
	 * @param constraint the constraint to validate
	 */
	public Object visitConstraint(Constraint constraint) {
		String stereo = constraint.getStereotype();

		EClassifier bodyType = constraint.getBody().getType();
		EClassifier operationType = null;
		EClassifier propertyType = null;
		String operationName = null;
		String propertyName = null;
		String classifierName = null;
		
		if (!constraint.getConstrainedElement().isEmpty()) {
			Object constrained = constraint.getConstrainedElement().get(0);
			
			if (constrained instanceof EOperation) {
				EOperation operation = (EOperation) constrained;
				operationName = operation.getName();
				
				if (operation.getEContainingClass() != null) {
					classifierName = operation.getEContainingClass().getName();
				}
				
				if (operation.getEType() != null) {
					operationType = TypeUtil.getOCLType(operation);
				}
			} else if (constrained instanceof EStructuralFeature) {
				EStructuralFeature property = (EStructuralFeature) constrained;
				propertyName = property.getName();
				
				if (property.getEContainingClass() != null) {
					classifierName = property.getEContainingClass().getName();
				}
				
				if (property.getEType() != null) {
					propertyType = TypeUtil.getOCLType(property);
				}
			} else if (constrained instanceof EClassifier) {
				classifierName = ((EClassifier) constrained).getName();
			}
		}
		
		if (operationType == null) {
			operationType = Types.OCL_VOID;
		}
		
		if (propertyType == null) {
			propertyType = Types.OCL_VOID;
		}
		
		if (Constraint.BODY.equals(stereo)
				|| Constraint.POSTCONDITION.equals(stereo)
				|| Constraint.PRECONDITION.equals(stereo)) {
			// operation constraints must be boolean-valued
			if (!(bodyType instanceof PrimitiveBoolean)) {
				String message = OCLMessages.bind(
						OCLMessages.OperationConstraintBoolean_ERROR_,
					operationName);
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitConstraint", error);//$NON-NLS-1$
				throw error;
			}
		} else if (Constraint.INVARIANT.equals(stereo)) {
			if (!(bodyType instanceof PrimitiveBoolean)) {
				// so must invariants, but they have a different kind of context
				String message = OCLMessages.bind(
						OCLMessages.InvariantConstraintBoolean_ERROR_,
						classifierName);
				IllegalArgumentException error = new IllegalArgumentException(
						message);
				OCLPlugin.throwing(getClass(),
					"visitConstraint", error);//$NON-NLS-1$
				throw error;
			}
		} else if (Constraint.DEFINITION.equals(stereo)) {
			// expression type must conform to feature type
			ETypedElement feature = null;
			if (constraint.getConstrainedElement().size() >= 2) {
				Object constrained = constraint.getConstrainedElement().get(1);
				if (constrained instanceof ETypedElement) {
					feature = (ETypedElement) constrained;
				}
			}
			
			if (feature == null) {
				String message = OCLMessages.bind(
						OCLMessages.DefinitionConstraintFeature_ERROR_,
						classifierName);
				IllegalArgumentException error = new IllegalArgumentException(
						message);
				OCLPlugin.throwing(getClass(),
					"visitConstraint", error);//$NON-NLS-1$
				throw error;
			}
			
			EClassifier featureType = TypeUtil.getOCLType(feature);
			
			if ((featureType == null)
					|| TypeUtil.typeCompare(bodyType, featureType) > 0) {
				
				String message = OCLMessages.bind(
						OCLMessages.DefinitionConstraintConformance_ERROR_,
						getName(bodyType),
						getName(featureType));
				IllegalArgumentException error = new IllegalArgumentException(
						message);
				OCLPlugin.throwing(getClass(),
					"visitConstraint", error);//$NON-NLS-1$
				throw error;
			}
		} else if (Constraint.INITIAL.equals(stereo) || Constraint.DERIVATION.equals(stereo)) {
			// expression type must conform to property type
			if (TypeUtil.typeCompare(bodyType, propertyType) > 0) {
				
				String message = OCLMessages.bind(
						OCLMessages.InitOrDerConstraintConformance_ERROR_,
						new Object[] {
								getName(bodyType),
								propertyName,
								getName(propertyType)});
				IllegalArgumentException error = new IllegalArgumentException(
						message);
				OCLPlugin.throwing(getClass(),
					"visitConstraint", error);//$NON-NLS-1$
				throw error;
			}
		}
		
		if (Constraint.BODY.equals(constraint.getStereotype())) {
			if (operationType instanceof VoidType) {
				String message = OCLMessages.bind(
						OCLMessages.BodyConditionNotAllowed_ERROR_,
					operationName);
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitConstraint", error);//$NON-NLS-1$
				throw error;
			}
			
			// the expression must be of the form result = <expr> or
			//    <expr> = result, where <expr> is some expression whose type
			//    conforms to the operation type.  However, this expression is
			//    allowed to be nested inside any number of lets for the user's
			//    convenience
			OCLExpression exp = constraint.getBody();
			while (exp instanceof LetExp) {
				exp = ((LetExp) exp).getIn();
			}
			OperationCallExp body = null;
			if (exp instanceof OperationCallExp) {
				body = (OperationCallExp) exp;
			}
			
			if ((body == null)
					|| (body.getOperationCode() != PredefinedType.EQUAL)
					|| (body.getArgument().size() != 1)) {
				String message = OCLMessages.bind(
						OCLMessages.BodyConditionForm_ERROR_,
					operationName);
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitConstraint", error);//$NON-NLS-1$
				throw error;
			}
			
			OCLExpression bodyExpr;
			
			if (isResultVariable(body.getSource(), operationType)) {
				bodyExpr = (OCLExpression) body.getArgument().get(0);
			} else if (isResultVariable(
					(OCLExpression) body.getArgument().get(0),
					operationType)) {
				bodyExpr = body.getSource();
			} else {
				String message = OCLMessages.bind(
						OCLMessages.BodyConditionForm_ERROR_,
					operationName);
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitConstraint", error);//$NON-NLS-1$
				throw error;
			}
			
			bodyType = bodyExpr.getType();
			
			if ((TypeUtil.getRelationship(bodyType, operationType) & PredefinedType.SUBTYPE) == 0) {
				String message = OCLMessages.bind(
						OCLMessages.BodyConditionConformance_ERROR_,
					new Object[] {
						operationName,
						getName(bodyType),
						getName(operationType)});
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitConstraint", error);//$NON-NLS-1$
				throw error;
			}
			
			// one last check:  does the "body" part of the condition include
			//    the result variable?  It must not
			if (findResultVariable(bodyExpr, operationType)) {
				String message = OCLMessages.bind(
						OCLMessages.BodyConditionForm_ERROR_,
					operationName);
				IllegalArgumentException error = new IllegalArgumentException(
					message);
				OCLPlugin.throwing(getClass(),
					"visitConstraint", error);//$NON-NLS-1$
				throw error;
			}
		}
		
		// check the body condition, itself, for well-formedness
		return constraint.getBody().accept(this);
	}
	
	/**
	 * Null-safe alternative to {@link ENamedElement#getName()}.
	 * 
	 * @param element a named element that may be <code>null</code>
	 * @return the element's name, or <code>null</code> if the element is <code>null</code>
	 */
	static String getName(ENamedElement element) {
		return (element == null)? null : element.getName();
	}
	
	/**
	 * Determines whether the specified expression is a reference to the
	 * special <code>result</code> variable of an operation body constraint.
	 * 
	 * @param expr an OCL expression
	 * @param expectedType the expected type of the result variable (i.e.,
	 *     the operation type
	 * 
	 * @return <code>true</code> if it is the result variable;
	 *     <code>false</code>, otherwise
	 */
	private static boolean isResultVariable(OCLExpression expr, EClassifier expectedType) {
		// the implicitly defined "result" variable always has the same type
		//    as the operation
		boolean result = (expr instanceof VariableExp);
		
		if (result) {
			try {
				result = TypeUtil.typeCompare(expr.getType(), expectedType) == 0;
			} catch (Exception e) {
				// get an exception on incompatible types.  This is expected
				result = false;
			}
		}
		
		if (result) {
			Variable var = ((VariableExp) expr).getReferredVariable();
			
			result = (var != null) && "result".equals(var.getName()); //$NON-NLS-1$
		}
		
		return result;
	}
	
	/**
	 * Queries whether the special <code>result</code> variable can be found
	 * anywhere in the specified OCL expression.
	 * 
	 * @param expr the expression to search
	 * @param expectedType the expected type of the result variable
	 * 
	 * @return <code>true</code> if it includes some reference to the result
	 *    variable; <code>false</code>, otherwise
	 */
	private static boolean findResultVariable(OCLExpression expr, final EClassifier expectedType) {
		class ResultFinder extends AbstractVisitor {
			boolean found = false;
			
			public Object visitVariableExp(VariableExp v) {
				if (isResultVariable(v, expectedType)) {
					found = true;
				}
				
				// no need to call super because this is a leaf expression
				return null;
			}
		}
		
		ResultFinder finder = new ResultFinder();
		expr.accept(finder);
		
		return finder.found;
	}
	
	/**
	 * Applies well-formedness rules for model property calls in general.
	 * This includes checking that "@pre" notation is only used in a
	 * postcondition constraint.
	 * 
	 * @param exp the model property call expression to validate
	 */
	private void visitFeatureCallExp(FeatureCallExp exp) {
		if (exp.isMarkedPre()) {
			// check for a postcondition constraint
			if (!ExpressionsUtil.isInPostcondition(exp)) {
				
				IllegalArgumentException error = new IllegalArgumentException(
						OCLMessages.AtPreInPostcondition_ERROR_);
				OCLPlugin.throwing(getClass(),
					"visitModelPropertyCallExp", error);//$NON-NLS-1$
				throw error;
			}
		}
	}

	public Object visitInvalidLiteralExp(InvalidLiteralExp il) {
		if (il.getType() != Types.INVALID) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.TypeConformanceInvalidLiteral_ERROR_);
			OCLPlugin.throwing(getClass(),
				"visitInvalidLiteralExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}

	public Object visitNullLiteralExp(NullLiteralExp il) {
		if (il.getType() != Types.OCL_VOID) {
			IllegalArgumentException error = new IllegalArgumentException(
					OCLMessages.TypeConformanceNullLiteral_ERROR_);
			OCLPlugin.throwing(getClass(),
				"visitNullLiteralExp", error);//$NON-NLS-1$
			throw error;
		}
		return Boolean.TRUE;
	}
	
	/**
	 * A default environment in the context of the OclAny type, which simply
	 * provides the default EcoreEnvironment algorithms for looking up features
	 * of classifiers, which usually just delegates to <code>TypeUtil</code>
	 * or <code>UMLTypeUtil</code>.  This environment is only used when no
	 * other environment is specified by the client or inferable from the
	 * expression's constraint.
	 *
	 * @author Christian W. Damus (cdamus)
	 */
	private static class NullEnvironment extends EcoreEnvironment {

		public NullEnvironment() {
			super(EcorePackage.eINSTANCE);
			
			Variable selfVar = ExpressionsFactory.eINSTANCE.createVariable();
			selfVar.setName("self"); //$NON-NLS-1$
			selfVar.setType(Types.OCL_ANY_TYPE);
			
			setSelfVariable(selfVar);
		}
	}
} // ValidationVisitorImpl

