/*******************************************************************************
 * 
 * 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:
 *     Borland Software Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.ast.parser;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.BasicEMap;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.m2m.internal.qvt.oml.QvtPlugin;
import org.eclipse.m2m.internal.qvt.oml.ast.binding.ASTBindingHelper;
import org.eclipse.m2m.internal.qvt.oml.ast.binding.ASTSyntheticNode;
import org.eclipse.m2m.internal.qvt.oml.ast.binding.ASTSyntheticNodeAccess;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QVTOEnvironment;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtEnvironmentBase;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalFileEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalModuleEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalStdLibrary;
import org.eclipse.m2m.internal.qvt.oml.compiler.QvtCompilerOptions;
import org.eclipse.m2m.internal.qvt.oml.cst.AssertExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.AssignStatementCS;
import org.eclipse.m2m.internal.qvt.oml.cst.BlockExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.BreakExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ClassifierDefCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ClassifierPropertyCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ComputeExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ConfigPropertyCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ConstructorCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ContextualPropertyCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ContinueExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.DictLiteralExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.DictLiteralPartCS;
import org.eclipse.m2m.internal.qvt.oml.cst.DictionaryTypeCS;
import org.eclipse.m2m.internal.qvt.oml.cst.DirectionKindEnum;
import org.eclipse.m2m.internal.qvt.oml.cst.ExpressionStatementCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ForExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ImperativeIterateExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ImperativeOperationCallExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ImportCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ImportKindEnum;
import org.eclipse.m2m.internal.qvt.oml.cst.InstantiationExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.LibraryCS;
import org.eclipse.m2m.internal.qvt.oml.cst.LibraryImportCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ListLiteralExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ListTypeCS;
import org.eclipse.m2m.internal.qvt.oml.cst.LocalPropertyCS;
import org.eclipse.m2m.internal.qvt.oml.cst.LogExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingBodyCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingCallExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingDeclarationCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingExtensionCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingExtensionKindCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingInitCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingMethodCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingModuleCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingQueryCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingRuleCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingSectionCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MappingSectionsCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ModelTypeCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ModulePropertyCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ModuleRefCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ModuleUsageCS;
import org.eclipse.m2m.internal.qvt.oml.cst.MultiplicityDefCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ObjectExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.OppositePropertyCS;
import org.eclipse.m2m.internal.qvt.oml.cst.PackageRefCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ParameterDeclarationCS;
import org.eclipse.m2m.internal.qvt.oml.cst.QualifierKindCS;
import org.eclipse.m2m.internal.qvt.oml.cst.RenameCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ResolveExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ResolveInExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.ReturnExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.SwitchAltExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.SwitchExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.TagCS;
import org.eclipse.m2m.internal.qvt.oml.cst.TransformationHeaderCS;
import org.eclipse.m2m.internal.qvt.oml.cst.TypeSpecCS;
import org.eclipse.m2m.internal.qvt.oml.cst.VariableInitializationCS;
import org.eclipse.m2m.internal.qvt.oml.cst.WhileExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.parser.AbstractQVTParser;
import org.eclipse.m2m.internal.qvt.oml.cst.temp.ErrorCallExpCS;
import org.eclipse.m2m.internal.qvt.oml.cst.temp.ScopedNameCS;
import org.eclipse.m2m.internal.qvt.oml.emf.util.mmregistry.EmfMmUtil;
import org.eclipse.m2m.internal.qvt.oml.emf.util.mmregistry.MetamodelRegistry;
import org.eclipse.m2m.internal.qvt.oml.expressions.Constructor;
import org.eclipse.m2m.internal.qvt.oml.expressions.ConstructorBody;
import org.eclipse.m2m.internal.qvt.oml.expressions.ContextualProperty;
import org.eclipse.m2m.internal.qvt.oml.expressions.DirectionKind;
import org.eclipse.m2m.internal.qvt.oml.expressions.EntryOperation;
import org.eclipse.m2m.internal.qvt.oml.expressions.ExpressionsFactory;
import org.eclipse.m2m.internal.qvt.oml.expressions.ExpressionsPackage;
import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeCallExp;
import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation;
import org.eclipse.m2m.internal.qvt.oml.expressions.ImportKind;
import org.eclipse.m2m.internal.qvt.oml.expressions.Library;
import org.eclipse.m2m.internal.qvt.oml.expressions.MappingBody;
import org.eclipse.m2m.internal.qvt.oml.expressions.MappingCallExp;
import org.eclipse.m2m.internal.qvt.oml.expressions.MappingOperation;
import org.eclipse.m2m.internal.qvt.oml.expressions.MappingParameter;
import org.eclipse.m2m.internal.qvt.oml.expressions.ModelParameter;
import org.eclipse.m2m.internal.qvt.oml.expressions.ModelType;
import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
import org.eclipse.m2m.internal.qvt.oml.expressions.ModuleImport;
import org.eclipse.m2m.internal.qvt.oml.expressions.ObjectExp;
import org.eclipse.m2m.internal.qvt.oml.expressions.OperationBody;
import org.eclipse.m2m.internal.qvt.oml.expressions.OperationalTransformation;
import org.eclipse.m2m.internal.qvt.oml.expressions.ResolveExp;
import org.eclipse.m2m.internal.qvt.oml.expressions.ResolveInExp;
import org.eclipse.m2m.internal.qvt.oml.expressions.VarParameter;
import org.eclipse.m2m.internal.qvt.oml.library.QvtResolveUtil;
import org.eclipse.m2m.internal.qvt.oml.stdlib.QVTUMLReflection;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.AltExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.AssertExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.AssignExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.BlockExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.BreakExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ComputeExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ContinueExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.DictLiteralExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.DictLiteralPart;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.DictionaryType;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ForExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ImperativeIterateExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ImperativeOCLFactory;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.InstantiationExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ListType;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.LogExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ReturnExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.SeverityKind;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.SwitchExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.VariableInitExp;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.WhileExp;
import org.eclipse.ocl.Environment;
import org.eclipse.ocl.SemanticException;
import org.eclipse.ocl.Environment.Internal;
import org.eclipse.ocl.cst.CSTFactory;
import org.eclipse.ocl.cst.CSTNode;
import org.eclipse.ocl.cst.CallExpCS;
import org.eclipse.ocl.cst.CollectionLiteralPartCS;
import org.eclipse.ocl.cst.CollectionTypeCS;
import org.eclipse.ocl.cst.DotOrArrowEnum;
import org.eclipse.ocl.cst.FeatureCallExpCS;
import org.eclipse.ocl.cst.IfExpCS;
import org.eclipse.ocl.cst.IteratorExpCS;
import org.eclipse.ocl.cst.LiteralExpCS;
import org.eclipse.ocl.cst.OCLExpressionCS;
import org.eclipse.ocl.cst.OperationCallExpCS;
import org.eclipse.ocl.cst.PathNameCS;
import org.eclipse.ocl.cst.PrimitiveTypeCS;
import org.eclipse.ocl.cst.SimpleNameCS;
import org.eclipse.ocl.cst.SimpleTypeEnum;
import org.eclipse.ocl.cst.StringLiteralExpCS;
import org.eclipse.ocl.cst.TupleTypeCS;
import org.eclipse.ocl.cst.TypeCS;
import org.eclipse.ocl.cst.VariableCS;
import org.eclipse.ocl.cst.VariableExpCS;
import org.eclipse.ocl.ecore.CallExp;
import org.eclipse.ocl.ecore.CallOperationAction;
import org.eclipse.ocl.ecore.Constraint;
import org.eclipse.ocl.ecore.EcoreFactory;
import org.eclipse.ocl.ecore.SendSignalAction;
import org.eclipse.ocl.expressions.BooleanLiteralExp;
import org.eclipse.ocl.expressions.CollectionKind;
import org.eclipse.ocl.expressions.CollectionLiteralExp;
import org.eclipse.ocl.expressions.CollectionLiteralPart;
import org.eclipse.ocl.expressions.FeatureCallExp;
import org.eclipse.ocl.expressions.IfExp;
import org.eclipse.ocl.expressions.IntegerLiteralExp;
import org.eclipse.ocl.expressions.InvalidLiteralExp;
import org.eclipse.ocl.expressions.IteratorExp;
import org.eclipse.ocl.expressions.NullLiteralExp;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.expressions.OperationCallExp;
import org.eclipse.ocl.expressions.PropertyCallExp;
import org.eclipse.ocl.expressions.RealLiteralExp;
import org.eclipse.ocl.expressions.StringLiteralExp;
import org.eclipse.ocl.expressions.TypeExp;
import org.eclipse.ocl.expressions.UnlimitedNaturalLiteralExp;
import org.eclipse.ocl.expressions.Variable;
import org.eclipse.ocl.expressions.VariableExp;
import org.eclipse.ocl.parser.AbstractOCLAnalyzer;
import org.eclipse.ocl.parser.OCLLexer;
import org.eclipse.ocl.parser.OCLParser;
import org.eclipse.ocl.types.BagType;
import org.eclipse.ocl.types.CollectionType;
import org.eclipse.ocl.types.OCLStandardLibrary;
import org.eclipse.ocl.types.OrderedSetType;
import org.eclipse.ocl.types.SequenceType;
import org.eclipse.ocl.types.SetType;
import org.eclipse.ocl.types.TypeType;
import org.eclipse.ocl.util.OCLStandardLibraryUtil;
import org.eclipse.ocl.util.OCLUtil;
import org.eclipse.ocl.util.TypeUtil;
import org.eclipse.ocl.utilities.ASTNode;
import org.eclipse.ocl.utilities.TypedElement;
import org.eclipse.ocl.utilities.UMLReflection;
import org.eclipse.osgi.util.NLS;


public class QvtOperationalVisitorCS
		extends AbstractOCLAnalyzer<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, 
							CallOperationAction, SendSignalAction, Constraint, EClass, EObject> { 	// FIXME - changed in M3.4 migration

    private final QvtCompilerOptions myCompilerOptions;    
    private Set<TypedElement<?>> myErrorNodes;
    
	/* TODO - 
	 * Groups all late resolve expression encountered during CST analysis for later validation.
	 * At the moment when resolve expression is visited it has not its container connect yet, which
	 * required for validation. Should be replaced by introducing a validation visitor.
	 */
    private List<ResolveExp> myLateResolveExps;
    
	public QvtOperationalVisitorCS(
			OCLLexer lexStream,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> environment, QvtCompilerOptions options) {
		super(new OCLParser(lexStream));
        myCompilerOptions = options;
	}
	
	public QvtOperationalVisitorCS(AbstractQVTParser parser, QvtCompilerOptions options) {
		super(parser);		
		myCompilerOptions = options;
	}
	
	public QvtCompilerOptions getCompilerOptions() {
        return myCompilerOptions;
    }
	
    @Override
    protected void initStartEndPositions(ASTNode astNode, CSTNode cstNode) {
        // FIXME - temp workaround after OCL 1.2 migration    	
    	astNode.setStartPosition(cstNode.getStartOffset());
    	astNode.setEndPosition(cstNode.getEndOffset());
    }
    
    protected InstantiationExp instantiationExpCS(InstantiationExpCS newCallExp, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
    		EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		InstantiationExp instantiationExp = ImperativeOCLFactory.eINSTANCE.createInstantiationExp();
		initStartEndPositions(instantiationExp, newCallExp);
		newCallExp.setAst(instantiationExp);

		if (env instanceof QvtOperationalEnv) {
			TypeSpecPair typeSpecCS = visitTypeSpecCS(newCallExp.getTypeSpecCS(), DirectionKind.OUT, (QvtOperationalEnv) env);
			instantiationExp.setType(typeSpecCS.myType);
			instantiationExp.setExtent(typeSpecCS.myExtent);
		}
		else {
			EClassifier instantiatedClass = typeCS(newCallExp.getTypeSpecCS().getTypeCS(), env);
			instantiationExp.setType(instantiatedClass);
		}

		boolean isTransformationInstantiation = false;
		if (instantiationExp.getType() instanceof EClass) {			
			instantiationExp.setInstantiatedClass((EClass) instantiationExp.getType());
			instantiationExp.setName(instantiationExp.getType().getName());
			isTransformationInstantiation = QvtOperationalStdLibrary.INSTANCE.getTransformationClass()
					.isSuperTypeOf(instantiationExp.getInstantiatedClass());
		}

		for (OCLExpressionCS nextArgCS : newCallExp.getArguments()) {
			OCLExpression<EClassifier> nextArgAST = oclExpressionCS(nextArgCS, env);
			if(nextArgAST != null) {
				instantiationExp.getArgument().add((org.eclipse.ocl.ecore.OCLExpression)nextArgAST);
			}
		}
		
		if (!isTransformationInstantiation && env instanceof QvtOperationalEnv) {
			EOperation lookupOperation = ((QvtOperationalEnv) env).lookupConstructorOperation(instantiationExp.getType(), instantiationExp.getName(), instantiationExp.getArgument());
			if (lookupOperation instanceof Constructor) {
				instantiationExp.eAdapters().add(new ConstructorOperationAdapter((Constructor) lookupOperation));
			}
		}
		
		return instantiationExp;
    }
	
	@Override
	protected EClassifier tupleTypeCS(TupleTypeCS tupleTypeCS, Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		EClassifier type = null;
		try {			
			type = super.tupleTypeCS(tupleTypeCS, env);
		} catch (Exception e) {
			// catch MDT OCL exception related to unresolved types used in Tuples, and report error
			String message = NLS.bind(ValidationMessages.UnknownClassifierType, QvtOperationalParserUtil.getStringRepresentation(tupleTypeCS), tupleTypeCS);
			QvtOperationalUtil.reportError(env, message, tupleTypeCS);
		}
		
		return type;
	}
	
	@Override
	protected EClassifier typeCS(TypeCS typeCS, Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		EClassifier type = super.typeCS(typeCS, env);
		if (type == null) {
			if (typeCS instanceof ListTypeCS) {
				type = listTypeCS((ListTypeCS) typeCS, env);
			} else if(typeCS instanceof DictionaryTypeCS) {
				type = dictionaryTypeCS((DictionaryTypeCS) typeCS, env);
			}
		}
		if(type == getOclVoid() && typeCS instanceof PrimitiveTypeCS == false) { 
			if(typeCS instanceof PathNameCS) {
				// check whether Void synonym was used
				PathNameCS pathNameCS = (PathNameCS) typeCS;
				if(QvtOperationalStdLibrary.INSTANCE.lookupClassifier(pathNameCS.getSequenceOfNames()) == getOclVoid()) {
					return type;
				}
			}
			// FIXME - workaround for migration to OCL 1.2 => non primitive type but
			// resolved as OclVoid in super impl. indicates actually a type unresolved by the fEnv.
			return null;
		}
		
		// MDT OCL does not check for nested type whether they are resolved
		// do it here if element type is null
		if(type instanceof CollectionType && typeCS instanceof CollectionTypeCS) {
			CollectionType<?, ?> collectionType = (CollectionType<?, ?>)type;			
			
			if(collectionType.getElementType() == null) {
				
				CollectionTypeCS collectionTypeCS = (CollectionTypeCS)typeCS;				
				QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.UnknownClassifierType, new Object[] {
						QvtOperationalParserUtil.getStringRepresentation(collectionTypeCS.getTypeCS())}),
						collectionTypeCS.getTypeCS());
			}
		}
		
		if(type != null) {
			if(myCompilerOptions.isGenerateCompletionData()) {
				// bind Module type only, for now  
				if(type instanceof Module) {				
					ASTBindingHelper.createCST2ASTBindingUnidirectional(typeCS, type);
				}
	        }
		}
		return type;
	}
	
	private EClassifier visitTypeCS(TypeCS typeCS, DirectionKind directionKind, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		EClassifier type = typeCS(typeCS, env);
		if (type == null) {
			// FIXME - M3.4 not needed, already reported above in #typeCS(typeCS, fEnv); 
			/*fEnv.reportError(NLS.bind(ValidationMessages.UnknownClassifierType, new Object[] {
					QvtOperationalParserUtil.getStringRepresentation(typeCS)}),
					typeCS); */	
		}
		return type;
	}
	
	@Override
	protected EOperation lookupOperation(CSTNode cstNode,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env,
			EClassifier owner, String name,
			List<? extends TypedElement<EClassifier>> args) {
		if ((cstNode instanceof SimpleNameCS)
				&& (cstNode.eContainer() instanceof ImperativeOperationCallExpCS) 
				&& (env instanceof QvtEnvironmentBase)) {
			QvtEnvironmentBase qvtEnvironmentBase = (QvtEnvironmentBase) env;
			
			ImperativeOperationCallExpCS imperativeOperationCallExpCS = (ImperativeOperationCallExpCS) cstNode.eContainer();
			SimpleNameCS moduleQualifier = imperativeOperationCallExpCS.getModule();
			String targetModuleName = (moduleQualifier == null) ? null : moduleQualifier.getValue();
			
			if(targetModuleName != null) {
				List<QvtEnvironmentBase> allExtendedEnvs;

				Module currentModule = qvtEnvironmentBase.getModuleContextType();
				if(currentModule != null && targetModuleName.equals(currentModule.getName())) {
					// the call is qualified by the calling module					
					allExtendedEnvs = Collections.singletonList(qvtEnvironmentBase);
				} else {
					// lookup in all modules within the extends hierarchy  
					allExtendedEnvs = new ArrayList<QvtEnvironmentBase>(qvtEnvironmentBase.getAllExtendedModules());
					
					for (QvtEnvironmentBase accessedEnv: qvtEnvironmentBase.getImportsByAccess()) {
						if(accessedEnv.getModuleContextType() instanceof Library) {
							allExtendedEnvs.add(accessedEnv);
						}
					}
				}

				EOperation resolvedOper = null;
				for (QvtEnvironmentBase nextExtenedModuleEnv : allExtendedEnvs) { 
					Module extendedModule = nextExtenedModuleEnv.getModuleContextType();
					if(extendedModule != null && targetModuleName.equals(extendedModule.getName())) {
						// TODO - should handle multiple ambiguous resolutions
						EClassifier actualOwner = (owner instanceof Module) ? extendedModule : owner;
						EOperation operation = nextExtenedModuleEnv.lookupOperation(actualOwner, name, args);
						if(operation != null) {
							Module owningModule = QvtOperationalParserUtil.getOwningModule(operation);
							if(extendedModule == owningModule) {
								resolvedOper = operation;
								break;
							}
						}
					}
				}

				cstNode.setAst(resolvedOper);
				return resolvedOper;
			}
		}
		return super.lookupOperation(cstNode, env, owner, name, args);
	}

	@Override
	protected Variable<EClassifier, EParameter> lookupImplicitSourceForOperation(
			CSTNode cstNode,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env,
			List<OCLExpression<EClassifier>> args, String operationName) {

		 Variable<EClassifier, EParameter> source = super.lookupImplicitSourceForOperation(cstNode, env, args, operationName);
		 if(source == null) {
			 	// FIXME - why is this done?, looks like a workaround for MDT OCL, 
			 	// it's a legal contract for the lookupXXX operation to return null
				source = EcoreFactory.eINSTANCE.createVariable();
				initASTMapping(env, source, cstNode);
		 }
		 return source;
	}

	private EClassifier visitTypeCSInModelType(TypeSpecCS typeSpecCS, ModelType modelType,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		EClassifier type = typeCS(typeSpecCS.getTypeCS(), env);
		if (type == null) {
			// FIXME - M3.4 not needed, already reported above in #typeCS(typeCS, fEnv); 
			/*fEnv.reportError(NLS.bind(ValidationMessages.UnknownClassifierType, new Object[] {
					QvtOperationalParserUtil.getStringRepresentation(typeSpecCS.getTypeCS())}),
					typeSpecCS.getTypeCS());*/
		}
		return type;
	}

    private static class TypeSpecPair {
        public EClassifier myType;
        public ModelParameter myExtent;
    }

	private ModelParameter lookupModelParameter(SimpleNameCS nameCS, DirectionKind directionKind, QvtOperationalEnv env) {
		QvtOperationalModuleEnv moduleEnv = getModuleContextEnv(env);
		ModelParameter modelParam = moduleEnv.lookupModelParameter(nameCS.getValue(), directionKind);
		if(modelParam == null) {		
			env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_extentWrongName,
					new Object[] { nameCS.getValue(), moduleEnv.getAllExtentNames(directionKind) }), nameCS);
		}
		
		return modelParam;
	}	
	
	private TypeSpecPair visitTypeSpecCS(TypeSpecCS typeSpecCS, DirectionKind directionKind,
			QvtOperationalEnv env)  {
		TypeSpecPair result = new TypeSpecPair();
		
		if (typeSpecCS.getSimpleNameCS() != null) {
			result.myExtent = lookupModelParameter(typeSpecCS.getSimpleNameCS(), directionKind, env);
			
			typeSpecCS.getSimpleNameCS().setAst(result.myExtent);
			
			if (result.myExtent != null && result.myExtent.getEType() instanceof ModelType) {
				result.myType = visitTypeCSInModelType(typeSpecCS, (ModelType) result.myExtent.getEType(), env);
				return result;
			}
		}

		result.myType = visitTypeCS(typeSpecCS.getTypeCS(), directionKind, env);

		typeSpecCS.setAst(result.myType);
		return result;
	}

	private String visitLiteralExpCS(StringLiteralExpCS stringLiteralExpCS, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env)
			throws SemanticException {
	    // stringLiteralExpCS() is not called directly for AST-CST binding creation done in literalExpCS()
		OCLExpression<EClassifier> literalExp = literalExpCS(stringLiteralExpCS, env);
		if (literalExp instanceof StringLiteralExp) {
			return ((StringLiteralExp<EClassifier>) literalExp).getStringSymbol();
		}
        return null;
	}
	
	@Override
	protected IfExp<EClassifier> ifExpCS(
			IfExpCS ifExpCS,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		// FIXME -
		IfExp<EClassifier> ifExp = super.ifExpCS(ifExpCS, env);
		return ifExp;
	}
	
	/**
	 * Produces AST Node from the given CST and performs validation on it.
	 */
	public OCLExpression<EClassifier> analyzeExpressionCS(OCLExpressionCS oclExpressionCS, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) throws SemanticException {
		OCLExpression<EClassifier> result = oclExpressionCS(oclExpressionCS, env);	
		validate(env);		
		return result;
	}

	@Override
	protected org.eclipse.ocl.ecore.OCLExpression oclExpressionCS(OCLExpressionCS oclExpressionCS,
	        Environment<EPackage, EClassifier, EOperation, EStructuralFeature, 
	        EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction,
	        Constraint, EClass, EObject> env) {
	    try {
            if (oclExpressionCS instanceof BlockExpCS) {
                return visitBlockExpCS((BlockExpCS) oclExpressionCS, env);
            }
            if (oclExpressionCS instanceof ComputeExpCS) {
                return visitComputeExpCS((ComputeExpCS) oclExpressionCS, env);
            }
	        if (oclExpressionCS instanceof WhileExpCS) {
	            return visitWhileExpCS((WhileExpCS) oclExpressionCS, env);
	        }
	        if (oclExpressionCS instanceof SwitchExpCS) {
	            return visitSwitchExpCS((SwitchExpCS) oclExpressionCS, env);
	        }
	        if (oclExpressionCS instanceof ObjectExpCS) {
                return visitObjectExpCS((ObjectExpCS) oclExpressionCS, toQVTOperationalEnv(env), true);
	        }
	        if (oclExpressionCS instanceof AssignStatementCS) {
	            return visitAssignStatementCS((AssignStatementCS) oclExpressionCS, env);
	        }
	        if (oclExpressionCS instanceof VariableInitializationCS) {
	            return variableInitializationCS((VariableInitializationCS) oclExpressionCS, env);
	        }
	        if (oclExpressionCS instanceof ExpressionStatementCS) {
	            return visitExpressionStatementCS((ExpressionStatementCS) oclExpressionCS, env);
	        }
	        if (oclExpressionCS instanceof ResolveInExpCS) {
	            return visitResolveInExpCS((ResolveInExpCS) oclExpressionCS, toQVTOperationalEnv(env));
	        }
	        if (oclExpressionCS instanceof ResolveExpCS) {
	            return visitResolveExpCS((ResolveExpCS) oclExpressionCS, toQVTOperationalEnv(env));
	        }
	        if(oclExpressionCS instanceof LogExpCS) {
	            return logExp((LogExpCS) oclExpressionCS, env);
	        }
	        if(oclExpressionCS instanceof AssertExpCS) {
	            return assertExp((AssertExpCS) oclExpressionCS, env);
	        }

            if (oclExpressionCS instanceof ForExpCS) {
                return visitForExp((ForExpCS) oclExpressionCS, env);
            }

            if (oclExpressionCS instanceof ImperativeIterateExpCS) {
	            return visitImperativeIterateExp((ImperativeIterateExpCS) oclExpressionCS, env);
	        }

	        if (oclExpressionCS instanceof ReturnExpCS) {
	            return visitReturnExpCS((ReturnExpCS) oclExpressionCS, env);
	        }
	        
	        if (oclExpressionCS instanceof BreakExpCS) {
	            return visitBreakExpCS((BreakExpCS) oclExpressionCS, env);
	        }
	        
	        if (oclExpressionCS instanceof ContinueExpCS) {
	            return visitContinueExpCS((ContinueExpCS) oclExpressionCS, env);
	        }
	        
	        if(oclExpressionCS instanceof InstantiationExpCS) {
	        	return instantiationExpCS((InstantiationExpCS)oclExpressionCS, env);
	        }
	        	
	        if (oclExpressionCS instanceof TypeCS) {
	            EClassifier type = typeCS((TypeCS) oclExpressionCS, env);
	            if (type == null) {
	                QvtOperationalUtil.reportError(env, NLS.bind(
	                		ValidationMessages.UnknownClassifierType,
	                        QvtOperationalUtil.getStringRepresentation((TypeCS) oclExpressionCS)), oclExpressionCS);
	            }
	            else {
	                TypeExp<EClassifier> typeExp = env.getOCLFactory().createTypeExp();
	                typeExp.setReferredType(type);
	                typeExp.setType(TypeUtil.resolveTypeType(env, type));
	                return (org.eclipse.ocl.ecore.TypeExp)typeExp;
	            }
	        }
	        else {
	        	org.eclipse.ocl.ecore.OCLExpression result = (org.eclipse.ocl.ecore.OCLExpression)super.oclExpressionCS(oclExpressionCS, env);

	    		if (oclExpressionCS instanceof OperationCallExpCS) {
	    			if (result instanceof OperationCallExp) {
		    			validateOperationCall((OperationCallExpCS) oclExpressionCS,
		    					(OperationCallExp<EClassifier, EOperation>) result, env);
	    			}
	    			if (result instanceof IteratorExp 
	    					&& ((IteratorExp<EClassifier, EOperation>) result).getBody() instanceof OperationCallExp) {
		    			validateOperationCall((OperationCallExpCS) oclExpressionCS,
		    					(OperationCallExp<EClassifier, EOperation>) ((IteratorExp<EClassifier, EOperation>) result).getBody(), 
		    					env);
	    			}
	    		}
	    		return result;
	        }
	    }
	    catch (NullPointerException ex) {
	        QvtPlugin.log(ex);
	        QvtOperationalUtil.reportError(env, ValidationMessages.QvtOperationalVisitorCS_oclParseNPE, oclExpressionCS);
	    }
	    catch (RuntimeException ex) {
	        //QvtPlugin.log(ex);
	    	QvtOperationalUtil.reportError(env, ValidationMessages.QvtOperationalVisitorCS_oclParseNPE, oclExpressionCS);
	    }
	    return (org.eclipse.ocl.ecore.OCLExpression)createDummyInvalidLiteralExp(env, oclExpressionCS);
	}
	
    private org.eclipse.ocl.ecore.OCLExpression visitContinueExpCS(
			ContinueExpCS continueExpCS,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {

		ContinueExp result = ImperativeOCLFactory.eINSTANCE.createContinueExp();
		initStartEndPositions(result, continueExpCS);
		
		return result;
	}

	private org.eclipse.ocl.ecore.OCLExpression visitBreakExpCS(
			BreakExpCS breakExpCS,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {

		BreakExp result = ImperativeOCLFactory.eINSTANCE.createBreakExp();
		initStartEndPositions(result, breakExpCS);
		
		return result;
	}

	@Override
    protected OCLExpression<EClassifier> literalExpCS(LiteralExpCS literalExpCS,
            Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	
    	OCLExpression<EClassifier> literalExp;    	
    	if (literalExpCS instanceof ListLiteralExpCS) {
    		literalExp = listLiteralExpCS((ListLiteralExpCS) literalExpCS, env);
    	} else if (literalExpCS instanceof DictLiteralExpCS) {
    		literalExp = dictionaryLiteralExp((DictLiteralExpCS)literalExpCS, env);
    	} else {
    		literalExp = super.literalExpCS(literalExpCS, env);
    	}
        // AST binding 
        if(myCompilerOptions.isGenerateCompletionData()) {
            ASTBindingHelper.createCST2ASTBinding(literalExpCS, literalExp);
        }
        //
        return literalExp;
    }
        
    protected AssertExp assertExp(AssertExpCS assertExpCS, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	AssertExp assertAST = ImperativeOCLFactory.eINSTANCE.createAssertExp();
    	assertAST.setStartPosition(assertExpCS.getStartOffset());
    	assertAST.setEndPosition(assertExpCS.getEndOffset());
    	    	
    	if(assertExpCS.getAssertion() != null) {
    		assertAST.setAssertion((org.eclipse.ocl.ecore.OCLExpression)oclExpressionCS(assertExpCS.getAssertion(), env));
    	}
    	
    	if(assertExpCS.getSeverity() != null) {
    		String severityCSVal = assertExpCS.getSeverity().getValue();
    		if(severityCSVal != null) {
    			SeverityKind actualSeverity = SeverityKind.get(severityCSVal);
    			if(actualSeverity != null) {
    				assertAST.setSeverity(actualSeverity);
    			} else {
    				CSTNode errorNode = assertExpCS.getSeverity();
    				QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.UknownSeverityKindError, severityCSVal), errorNode);
    			}
    		}
    	}
    	
    	if(assertExpCS.getLog() != null) {
    		assertAST.setLog(logExp(assertExpCS.getLog(), env));
    	}    	    	

    	validateAssertExp(assertAST, env);    	
    	return assertAST;
    }
    
    private void validateAssertExp(AssertExp assertExp, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	EClassifier boolType = env.getOCLStandardLibrary().getBoolean();
    	if(assertExp.getAssertion() == null || assertExp.getAssertion().getType() != boolType) {
    		ASTNode errNode = assertExp.getAssertion() != null ? assertExp.getAssertion() : assertExp;
    		QvtOperationalUtil.reportError(env, ValidationMessages.BooleanTypeAssertConditionError, 
    				errNode.getStartPosition(), errNode.getEndPosition());
    	}
    	
    	LogExp logExp = assertExp.getLog();
    	if(logExp != null) {
    		validateLogExp(logExp, env);    		
    	}
    }        
    
    private void validateLogExp(LogExp logExp, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	EList<OCLExpression<EClassifier>> allArgs = logExp.getArgument();
    	if(allArgs.isEmpty()) {
    		QvtOperationalUtil.reportError(env, ValidationMessages.MissingMessageLogExpArgumentError, logExp.getStartPosition(), logExp.getEndPosition());
    	}
    	
    	int pos = 1;
    	for (OCLExpression<EClassifier> arg : allArgs) {
    		switch (pos) {
			case 1:
				EClassifier stringType = env.getOCLStandardLibrary().getString();
				if(stringType != arg.getType()) {
					QvtOperationalUtil.reportError(env, ValidationMessages.StringTypeMessageLogArgumentError, arg.getStartPosition(), arg.getEndPosition());
				}
				break;
			case 2:
				// anything accepted here
				break;				
			case 3:
				EClassifier intType = env.getOCLStandardLibrary().getInteger();
				if(intType != arg.getType()) {
					QvtOperationalUtil.reportError(env, ValidationMessages.LogLevelNumberArgumentError, arg.getStartPosition(), arg.getEndPosition());
				}
				
				break;				

			default:
				QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.UnsupportedLogExpArgumentError, pos), arg.getStartPosition(), arg.getEndPosition());				
			}
    		pos++;
		}
    	
    	OCLExpression<EClassifier> condition = logExp.getCondition();
    	if(condition != null && condition.getType() != env.getOCLStandardLibrary().getBoolean()) {    		
    		QvtOperationalUtil.reportError(env, ValidationMessages.LogExpBooleanTypeConditionError, 
    				condition.getStartPosition(), condition.getEndPosition());
    	}
    }
        
    protected LogExp logExp(LogExpCS logExpCS, Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	
    	LogExp logAST = ImperativeOCLFactory.eINSTANCE.createLogExp();
    	logAST.setStartPosition(logExpCS.getStartOffset());
    	logAST.setEndPosition(logExpCS.getEndOffset());
    	
    	logAST.setName("log"); //$NON-NLS-1$
    	for (OCLExpressionCS argCS : logExpCS.getArguments() ) {
			OCLExpression<EClassifier> arg = this.oclExpressionCS(argCS, env);
			if(arg != null) {
				logAST.getArgument().add(arg);
			}
		}
    	
    	if(logExpCS.getCondition() != null) {
    		logAST.setCondition(oclExpressionCS(logExpCS.getCondition(), env));
    	}
    	
    	validateLogExp(logAST, env);   	
    	return logAST;
	}

    @Override
    protected Variable<EClassifier, EParameter> variableDeclarationCS(VariableCS variableDeclarationCS,
            Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env,
            boolean addToEnvironment) {
        Variable<EClassifier, EParameter> varDecl = super.variableDeclarationCS(variableDeclarationCS, env, addToEnvironment);
        if ((varDecl.getType() == null) && (varDecl.getInitExpression() != null)) {
            varDecl.setType(varDecl.getInitExpression().getType());
        }
        
        // AST binding 
        if(myCompilerOptions.isGenerateCompletionData()) {
        	ASTBindingHelper.createCST2ASTBinding(variableDeclarationCS, varDecl);
        }
        //
        return varDecl;
    }
	
    @Override
    protected OCLExpression<EClassifier> propertyCallExpCS(CallExpCS propertyCallExpCS, 
            Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env)
             {
        if (propertyCallExpCS instanceof ErrorCallExpCS) {
            OCLExpressionCS sourceExpCS = propertyCallExpCS.getSource();
            if (sourceExpCS != null) {
                if (propertyCallExpCS.getAccessor() == DotOrArrowEnum.ARROW_LITERAL) {
                    getCollectionSourceExpression(sourceExpCS, env);
                } else {
                    oclExpressionCS(sourceExpCS, env);
                }
            }
            return null;
        }
        OCLExpression<EClassifier> result = super.propertyCallExpCS(propertyCallExpCS, env);
        if(result != null) {
            // AST binding    
            if(myCompilerOptions.isGenerateCompletionData()) {          
            	createPropertyCallASTBinding(propertyCallExpCS, result, env);
            }
        }
        return result;
    }
    
    @Override
    protected OCLExpression<EClassifier> simpleNameCS(
    		SimpleNameCS simpleNameCS,
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env,
    		OCLExpression<EClassifier> source) {
    	
    	OCLExpression<EClassifier> result = customSimpleNameCS(simpleNameCS, env, source);

        // AST binding    	
        if(myCompilerOptions.isGenerateCompletionData()) {    	
            ASTBindingHelper.createCST2ASTBinding(simpleNameCS, result);
        }
    	//
    	
    	return result;
    }
    
	private OperationCallExp<EClassifier, EOperation> genNonContextualQualifiedOperationCall(
			OperationCallExpCS operationCallExpCS, PathNameCS sourceCS, QvtEnvironmentBase env) {

		EClassifier sourceType = lookupClassifier(sourceCS, env, sourceCS.getSequenceOfNames());
		sourceCS.setAst(sourceType);
		
		if (sourceType instanceof Module) {
			Module sourceModule = (Module) sourceType;			
			Variable<EClassifier, EParameter> sourceVar = QvtOperationalParserUtil.getThisVariable(sourceModule);
			if(sourceVar == null) {
				return null;
			}

			OCLExpression<EClassifier> sourceExpr = createVariableExp(env, sourceCS, sourceVar);
			EList<OCLExpressionCS> argsCS = operationCallExpCS.getArguments();
			List<OCLExpression<EClassifier>> args = new java.util.ArrayList<OCLExpression<EClassifier>>(argsCS.size());
			for (OCLExpressionCS arg : argsCS) {
				OCLExpression<EClassifier> argExpr = oclExpressionCS(arg, env);
				if (argExpr == null) {
					argExpr = createDummyInvalidLiteralExp(env, arg);
					initASTMapping(env, argExpr, arg);
				}
				args.add(argExpr);	
			}
			
			String rule = "genNonContextualQualifiedOperationCall"; //$NON-NLS-1$
			String name = operationCallExpCS.getSimpleNameCS().getValue();
			OperationCallExp<EClassifier, EOperation> result = genOperationCallExp(env, operationCallExpCS, rule, name, sourceExpr, sourceModule, args);
			
			if(result.getReferredOperation() != null) {
				boolean isValidModule = sourceModule instanceof Library ||
						env.getModuleContextType() == sourceModule ||
						QvtOperationalParserUtil.isExtendingEnv(env, sourceModule);
				if(!isValidModule) {
					String errMessage = NLS.bind(ValidationMessages.NoImplicitSourceForQualifiedCall, name);
					ERROR(operationCallExpCS.getSimpleNameCS(), rule, errMessage);
				}
			}
			
			if(result instanceof ImperativeCallExp) {
				((ImperativeCallExp) result).setIsVirtual(false);
			}
			return result; //$NON-NLS-1$
		}
		
		return null;
	}
	
    @Override
    protected OCLExpression<EClassifier> operationCallExpCS(
    		OperationCallExpCS operationCallExpCS,
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	
		if (operationCallExpCS.getSource() instanceof PathNameCS) {
			OCLExpressionCS sourceCS = operationCallExpCS.getSource();
			if (sourceCS instanceof PathNameCS && env instanceof QvtEnvironmentBase) {
				OperationCallExp<EClassifier, EOperation> result = genNonContextualQualifiedOperationCall(operationCallExpCS, (PathNameCS)sourceCS,(QvtEnvironmentBase) env);
				 if(result != null) {
					 return result;
				 }
			}
		}    	
    	
    	OCLExpression<EClassifier> result = super.operationCallExpCS(operationCallExpCS, env);
    	
    	if(result instanceof OperationCallExp) {
    	    OperationCallExp<EClassifier, EOperation> opCallExp = (org.eclipse.ocl.ecore.OperationCallExp) result;
    	    if(opCallExp.getReferredOperation() != null) {
    	    	EOperation referredOperation = opCallExp.getReferredOperation();
    	    	if(QvtOperationalParserUtil.isDeprecated(referredOperation)) {
	    	    	String message;
	    	    	String deprecatedByRef = QvtOperationalParserUtil.getDeprecatedBy(referredOperation);	    	    	
	    	    	
	    	    	if(deprecatedByRef != null) {
	    	    		message = NLS.bind(ValidationMessages.DeprecatedElementBy, 
	    	    				getFormatter().formatName(referredOperation), deprecatedByRef); 
	    	    	} else {
	    	    		message = NLS.bind(ValidationMessages.DeprecatedElement, getFormatter().formatName(referredOperation)); 
	    	    	}
	    	    	
	    	    	QvtOperationalUtil.reportWarning(env, message, operationCallExpCS);
    	    	}

    	    	if(QvtOperationalParserUtil.isUnsupported(referredOperation)) {
    	    		QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.UnsupportedElement, getFormatter().formatName(referredOperation)), operationCallExpCS);    	    		
    	    	}
    	    }
    	    
    	    OCLExpression<EClassifier> source = opCallExp.getSource();
            if (source != null) {
                if (isArrowAccessToCollection(operationCallExpCS, source)) {
                	// FIXME - use OCL TypeChecker::isStdLibOperation()
                    // Is it a standard operation like "select"?
                    // In other words, did lookupOperation() in genOperationCallExp() return something?
                    List<EOperation> operations = TypeUtil.getOperations(env, source.getType());
                    boolean isStdOperation = (operations != null) 
                            && (opCallExp.getReferredOperation() != null) 
                            && operations.contains(opCallExp.getReferredOperation());
                    if (!isStdOperation) {
                        result = createImplicitXCollect(source, opCallExp, env, operationCallExpCS);
                    }
                }
    	    }
            DeprecatedImplicitSourceCallHelper.validateCallExp(operationCallExpCS, opCallExp, env);
    	}
    	
    	return result;
    }
    
    @Override
    protected OperationCallExp<EClassifier, EOperation> genOperationCallExp(
            Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env,
            OperationCallExpCS operationCallExpCS, String rule,
            String operName, OCLExpression<EClassifier> source,
            EClassifier ownerType, List<OCLExpression<EClassifier>> args) {

    	EClassifier operationSourceType = ownerType;
        if (isArrowAccessToCollection(operationCallExpCS, source)
                && (lookupOperation(operationCallExpCS, env, ownerType, operName, args) == null)) {
            @SuppressWarnings("unchecked") //$NON-NLS-1$
            CollectionType<EClassifier, EOperation> sourceType = (CollectionType<EClassifier, EOperation>) ownerType;
            operationSourceType = sourceType.getElementType();
        }

		OperationCallExp<EClassifier, EOperation> result;

		// Performs method signature checking
		EOperation oper = lookupOperation(operationCallExpCS.getSimpleNameCS(), env,
				operationSourceType, operName, args);

		if(oper instanceof MappingOperation) {
			result = ExpressionsFactory.eINSTANCE.createMappingCallExp();
		} else if(oper instanceof ImperativeOperation) {
			result = ExpressionsFactory.eINSTANCE.createImperativeCallExp();	
		} else {
			result = oclFactory.createOperationCallExp();
		}
		
		initASTMapping(env, result, operationCallExpCS);
		result.setSource(source);
		

		// sometimes we use the resolved name in case the environment's look-up
		// supports aliasing
		String resolvedName = operName;

		if (oper == null) {
			String message;
			String operationString = operationString(env, operName, args);
			String operationSourceTypeString = (operationSourceType == null) ?
					null : uml.getName(operationSourceType);
			if (source.getType() == operationSourceType) {
				message = NLS.bind(
				ValidationMessages.QvtOperationalVisitorCS_OperationNotFound_ERROR_,
				operationString,
				operationSourceTypeString);
			} else {
				message = NLS.bind(
						ValidationMessages.QvtOperationalVisitorCS_OperationNotFoundForCollectionAndItsElement,
						new Object[] {operationString, uml.getName(source.getType()), operationSourceTypeString});
			}
			ERROR(operationCallExpCS, rule, message);
			result.setType(env.getOCLStandardLibrary().getOclVoid());
		} else {
			resolvedName = uml.getName(oper);
			TRACE(rule, resolvedName);
			result.setReferredOperation(oper);
		}

		// Set up arguments
		List<OCLExpression<EClassifier>> callargs = result.getArgument();
		if (args != null) {
			for (OCLExpression<EClassifier> arg : args) {
				if (arg == null) {
					ERROR(operationCallExpCS, rule, ValidationMessages.QvtOperationalVisitorCS_BadArg_ERROR_);
				} else {
					callargs.add(arg);
				}
			}
		}

		// Compute the result type, and perform conformance checking.
		if (oper != null) {
			EClassifier resultType = null;

			int opcode = 0;
			if (TypeUtil.isStandardLibraryFeature(env, operationSourceType, oper)) {
				// the operations defined intrinsically by the standard library
				// are the only ones that may have opcodes
				opcode = OCLStandardLibraryUtil.getOperationCode(resolvedName);
			} else if (TypeUtil.isOclAnyOperation(env, oper)) {
				// source is a user class, enumeration, or data type and the
				// operation is defined by OclAny, not the source type
				opcode = OCLStandardLibraryUtil
					.getOclAnyOperationCode(resolvedName);
			}

			result.setOperationCode(opcode);
			resultType = TypeUtil.getResultType(operationCallExpCS, env,
				ownerType, oper, args);
			if (resultType == null) {
				resultType = getOCLType(env, oper);
			}

			// resolve collection or tuple type against the cache in the
			// environment
			resultType = TypeUtil.resolveType(env, resultType);

			result.setType(resultType);
		}

		// setup the virtual call flag
		if(result instanceof ImperativeCallExp) {
			ImperativeCallExp imperativeCall = (ImperativeCallExp) result;				
			imperativeCall.setIsVirtual(true);
			// qualified call on a source object
			if(operationCallExpCS instanceof ImperativeOperationCallExpCS ) {
				ImperativeOperationCallExpCS imperativeCallCS = (ImperativeOperationCallExpCS) operationCallExpCS;
				if(imperativeCallCS.getModule() != null) {
					imperativeCall.setIsVirtual(false);
				}
			} else if(operationCallExpCS.getSource() instanceof PathNameCS) {
				// qualified call on by a module type (aka static call)				
				imperativeCall.setIsVirtual(false);
			}
		}
		
		return result;
	}

    /**
     * Creates an implicit <code>xcollect</code> iterator expression for a
     * property call on a collection-type source expression.
     * 
     * @param source the property call source expression
     * @param propertyCall the property call expression
     * @param fEnv the current environment
     * 
     * @return the xcollect expression
     * @throws TerminateException 
     */
    protected ImperativeIterateExp createImplicitXCollect(OCLExpression<EClassifier> source,
            FeatureCallExp<EClassifier> propertyCall,
            Environment<EPackage, EClassifier, EOperation, EStructuralFeature,
			EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint,
			EClass, EObject> env,
            CSTNode cstNode) {
        
        @SuppressWarnings("unchecked") //$NON-NLS-1$
        EClassifier sourceElementType = ((CollectionType<EClassifier, EOperation>) source.getType())
            .getElementType();
        
        ImperativeIterateExp result = ImperativeOCLFactory.eINSTANCE.createImperativeIterateExp();
        initASTMapping(env, result, cstNode);       
        Variable<EClassifier, EParameter> itervar =
            genVariableDeclaration(cstNode, "modelPropertyCallCS", env,//$NON-NLS-1$
                        null, sourceElementType, null, false, true, false);

        List<Variable<EClassifier, EParameter>> iters = result.getIterator();
        iters.add(itervar);
        result.setBody(propertyCall);
        result.setName("xcollect");//$NON-NLS-1$
        VariableExp<EClassifier, EParameter> vexp = oclFactory.createVariableExp();
        initASTMapping(env, vexp, cstNode);
        vexp.setType(itervar.getType());
        vexp.setReferredVariable(itervar);
        vexp.setName(itervar.getName());
        
        /* adjust the source variable for the body expression to be the
           newly generated implicit iterator variable */
        propertyCall.setSource(vexp);
        
        if (!(propertyCall instanceof OperationCallExp)) {
            // the overall start and end positions are the property positions
            propertyCall.setStartPosition(propertyCall.getPropertyStartPosition());
            propertyCall.setEndPosition(propertyCall.getPropertyEndPosition());
        }
        
        result.setSource(source);
        
        EClassifier bodyType = propertyCall.getType();
        
        if (source.getType() instanceof SequenceType ||
                source.getType() instanceof OrderedSetType) {
            EClassifier c = getCollectionType(
                    env,
                    CollectionKind.SEQUENCE_LITERAL,
                    bodyType);
            result.setType(c);
        } else {
            EClassifier c = getCollectionType(
                    env,
                    CollectionKind.BAG_LITERAL,
                    bodyType);
            result.setType(c);
        }
        
        env.deleteElement(itervar.getName());
        
        return result;
    }
    
    private boolean isArrowAccessToCollection(CallExpCS callExpCS, OCLExpression<EClassifier> source) {
        if (source == null) {
            return false;
        }
        return (callExpCS.getAccessor().getValue() == DotOrArrowEnum.ARROW) 
                && (source.getType() instanceof CollectionType);
    }
    
	@Override
    protected OCLExpression<EClassifier> variableExpCS(
            VariableExpCS variableExpCS,
            Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
        OCLExpression<EClassifier> result = super.variableExpCS(variableExpCS, env);
        
        if(result instanceof PropertyCallExp) {
        	DeprecatedImplicitSourceCallHelper.validateCallExp(variableExpCS, (PropertyCallExp<EClassifier, ?>)result, env);
        }
        
        // AST binding      
        if(myCompilerOptions.isGenerateCompletionData()) {      
            ASTBindingHelper.createCST2ASTBinding(variableExpCS, result);
        }
        //
        return result;
    }

    private org.eclipse.ocl.ecore.OCLExpression visitOclExpressionCS(OCLExpressionCS expressionCS, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	
    	org.eclipse.ocl.ecore.OCLExpression result = oclExpressionCS(expressionCS, env);
		if (expressionCS instanceof MappingCallExpCS) {
		    if (result instanceof OperationCallExp) {
		    	// FIXME - review this, seems to be useless as we create callexp according to referred operation		    	
		    	if(result instanceof MappingCallExp) {
		    		// keep 'virtual' attribute value
		    		return result;	
		    	}
		        MappingCallExp mappingCallExp = createMappingCallExp((MappingCallExpCS) expressionCS, result);
		        if (mappingCallExp != null) {
		            return mappingCallExp;
		        }
		    } else if (result instanceof IteratorExp) {
		        IteratorExp<EClassifier, EParameter> iteratorExp = (IteratorExp<EClassifier, EParameter>) result;
		        MappingCallExp mappingCallExp = createMappingCallExp((MappingCallExpCS) expressionCS, iteratorExp.getBody());
		        if (mappingCallExp != null) {
		            iteratorExp.setBody(mappingCallExp);
		            return (org.eclipse.ocl.ecore.OCLExpression)iteratorExp;
		        }
		    } else if (result instanceof ImperativeIterateExp) {
		        ImperativeIterateExp imperativeIterateExp = (ImperativeIterateExp) result;
		        MappingCallExp mappingCallExp = createMappingCallExp((MappingCallExpCS) expressionCS, imperativeIterateExp.getBody());
		        if (mappingCallExp != null) {
		            imperativeIterateExp.setBody(mappingCallExp);
		            return imperativeIterateExp;
		        }
		    }
		    // FIXME why this?
		    // should be processed more specifically, also unresolved operation error for a mapping call
		    // is sufficient, so we do not need yet another complaint 
		    QvtOperationalUtil.reportError(env, ValidationMessages.mappingOperationExpected, expressionCS);
			return null;
		}

		return result;
	}

    private org.eclipse.ocl.ecore.OCLExpression visitBlockExpCS(BlockExpCS expressionCS, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	
    	Collection<Variable<EClassifier, EParameter>> beginScopeVars = null;
    	if(expressionCS.eContainer() instanceof ImperativeOperation == false) {  
    		// variables defined in the scope of operation handled by environment scope		
    		beginScopeVars = env.getVariables();
    	}
    	
    	try {
    		return doVisitBlockExpCS(expressionCS, env);
    	} 
    	finally {
    		if(beginScopeVars != null) {
    			// remove variables of this scope when leaving it, only successfully added variables into fEnv
    			// in this block scope will be removed, so we can not remove outer scope 
    			// existing variables. 
    			// Note: nested block scopes have done their clean-up already so we remove
    			// only our stuff
    			Collection<Variable<EClassifier, EParameter>> endScopeVars = env.getVariables();
    			for (Variable<EClassifier, EParameter> nextVar : endScopeVars) {
    				// remove those new in the scope
    				if(!beginScopeVars.contains(nextVar)) {
    					env.deleteElement(nextVar.getName());
    				}
    			}
    		}
    	}
    }
    
    private org.eclipse.ocl.ecore.OCLExpression doVisitBlockExpCS(BlockExpCS expressionCS, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	
		BlockExp result = ImperativeOCLFactory.eINSTANCE.createBlockExp();
		result.setStartPosition(expressionCS.getStartOffset());
		result.setEndPosition(expressionCS.getEndOffset());
		result.setType(env.getOCLStandardLibrary().getOclVoid());

		for (OCLExpressionCS oclExpCS : expressionCS.getBodyExpressions()) {
			OCLExpression<EClassifier> bodyExp = visitOclExpressionCS(oclExpCS, env);
			if (bodyExp != null) {
    				result.getBody().add((org.eclipse.ocl.ecore.OCLExpression)bodyExp);
			}
		}
		
		return result;
    }
    
    private org.eclipse.ocl.ecore.OCLExpression visitComputeExpCS(ComputeExpCS computeExpCS, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	
        ComputeExp result = ImperativeOCLFactory.eINSTANCE.createComputeExp();
        result.setStartPosition(computeExpCS.getStartOffset());
        result.setEndPosition(computeExpCS.getEndOffset());
        
        Variable<EClassifier, EParameter> returnedElementExp = variableDeclarationCS(computeExpCS.getReturnedElement(), env, true);
        result.setReturnedElement((org.eclipse.ocl.ecore.Variable)returnedElementExp);
        result.setType(returnedElementExp.getType());
        
        OCLExpression<EClassifier> bodyExp = visitOclExpressionCS(computeExpCS.getBody(), env);
        result.setBody((org.eclipse.ocl.ecore.OCLExpression)bodyExp);
        
        env.deleteElement(returnedElementExp.getName());
        
        return result;
    }
    
    private org.eclipse.ocl.ecore.OCLExpression visitSwitchExpCS(SwitchExpCS switchExpCS, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	
		SwitchExp switchExp = ImperativeOCLFactory.eINSTANCE.createSwitchExp();
		switchExp.setStartPosition(switchExpCS.getStartOffset());
		switchExp.setEndPosition(switchExpCS.getEndOffset());
		
		List<EClassifier> allPartTypes = new ArrayList<EClassifier>();
		if (switchExpCS.getAlternativePart() != null) {
		    for (SwitchAltExpCS altExpCS : switchExpCS.getAlternativePart()) {
		    	AltExp altExp = visitSwitchAltExpCS(altExpCS, env);
		        switchExp.getAlternativePart().add((AltExp) altExp);
		        allPartTypes.add(altExp.getBody() != null ? altExp.getBody().getType() : null);
		    }
		}
		if (switchExpCS.getElsePart() != null) {
			org.eclipse.ocl.ecore.OCLExpression elsePart = visitOclExpressionCS(switchExpCS.getElsePart(), env);
		    switchExp.setElsePart(elsePart);
		    allPartTypes.add(elsePart.getType());
		}
		
		if (allPartTypes.isEmpty()) {
		    switchExp.setType(getOclVoid());
		}
		else if (allPartTypes.size() == 1) {
		    switchExp.setType(allPartTypes.get(0));
		}
		else {
			EClassifier type = null;
			for (int i = 0; i+1 < allPartTypes.size(); ++i) {
				type = TypeUtil.commonSuperType(switchExpCS, env,
						allPartTypes.get(i), allPartTypes.get(i+1));
				if (type == null) {
					break;
				}
			}
			switchExp.setType(type == null ? getOclVoid() : type);
		}
		
		return switchExp;
    }

	private AltExp visitSwitchAltExpCS(SwitchAltExpCS altExpCS, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		
	    AltExp altExp = ImperativeOCLFactory.eINSTANCE.createAltExp();
	    altExp.setStartPosition(altExpCS.getStartOffset());
	    altExp.setEndPosition(altExpCS.getEndOffset());
        
	    OCLExpression<EClassifier> condition = visitOclExpressionCS(altExpCS.getCondition(), env);
	    altExp.setCondition((org.eclipse.ocl.ecore.OCLExpression)condition);
	    OCLExpression<EClassifier> body = visitOclExpressionCS(altExpCS.getBody(), env);
	    altExp.setBody((org.eclipse.ocl.ecore.OCLExpression)body);
	    return altExp;
    }

    private org.eclipse.ocl.ecore.OCLExpression visitWhileExpCS(WhileExpCS whileCS, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		WhileExp whileExp = ImperativeOCLFactory.eINSTANCE.createWhileExp();
		org.eclipse.ocl.ecore.OCLExpression result = whileExp;
		
		whileExp.setStartPosition(whileCS.getStartOffset());
		whileExp.setEndPosition(whileCS.getEndOffset());
		
		String resultVarInEnv = null;
		// if result variable is declared, wrap WhileExp into ComputeExp
		if(whileCS.getResultVar() != null) {
	        ComputeExp embeddedComputeExp = ImperativeOCLFactory.eINSTANCE.createComputeExp();
	        result = embeddedComputeExp;
	        embeddedComputeExp.setStartPosition(whileCS.getStartOffset());
	        embeddedComputeExp.setEndPosition(whileCS.getEndOffset());
	        // define result variable in environment
			org.eclipse.ocl.ecore.Variable resultVar = (org.eclipse.ocl.ecore.Variable) 
					variableDeclarationCS(whileCS.getResultVar(), env, true);
	        // check if the variable was successfully added into environment			
			resultVarInEnv = (resultVar != null && env.lookup(resultVar.getName()) == resultVar) ? resultVar.getName() : null;
			
	        embeddedComputeExp.setReturnedElement(resultVar);
	        embeddedComputeExp.setType(resultVar.getType());
	        // actual body to execute is while expression itself
	        // we just define the result variable and its initial value
	        embeddedComputeExp.setBody(whileExp);	        	        			
	        embeddedComputeExp.setReturnedElement(resultVar);	        	        
	        // the wrapped while expression still need to return null, according to QVT specification
		}

		// while expression itself has  
		whileExp.setType(env.getOCLStandardLibrary().getOclVoid());
		
		// analyze the condition of while		
		org.eclipse.ocl.ecore.OCLExpression condExp = visitOclExpressionCS(whileCS.getCondition(), env);
		whileExp.setCondition(condExp);
		if(condExp != null) {
			EClassifier condType = condExp.getType();
			if(env.getOCLStandardLibrary().getBoolean() != condExp.getType()) {
				if(condType == null) {
					condType = env.getOCLStandardLibrary().getOclVoid();
				}
				String message = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_booleanTypeExpressionExpected, env.getUMLReflection().getName(condType));
				QvtOperationalUtil.reportError(env, message, whileCS.getCondition());
			}
		}

		// analyze the body of while
		whileExp.setBody(oclExpressionCS(whileCS.getBody(), env));
		
		// cleanup result variable in environment, if it was added
		if(resultVarInEnv != null) {
			env.deleteElement(resultVarInEnv);
		}
		
		return result;
	}
    
    private static MappingDeclarationCS findOwningMappingDeclarationCS(ObjectExpCS outExpCS) {
    	EObject eContainer = outExpCS.eContainer();
    	if (eContainer instanceof MappingBodyCS) {
    	    eContainer = eContainer.eContainer();
            if (eContainer instanceof MappingSectionsCS) {
                eContainer = eContainer.eContainer();
                if (eContainer instanceof MappingRuleCS) {
                    MappingRuleCS mappingCS = (MappingRuleCS) eContainer;
                    return mappingCS.getMappingDeclarationCS();
                }
            }
    	}
    	return null;
    }

    private ObjectExp visitObjectExpCS(ObjectExpCS outExpCS, QvtOperationalEnv env, boolean isValidationChecked) {
		MappingDeclarationCS topLevelInMapping = findOwningMappingDeclarationCS(outExpCS);		
		if(topLevelInMapping != null && topLevelInMapping.getResult().isEmpty() && topLevelInMapping.getContextType() == null) {
			//return null; FIXME - review this, ommitted to get better error reporting for AST
		}
		
		TypeSpecCS typeSpecCS = null;
		if (outExpCS.getTypeSpecCS() != null) {
			typeSpecCS = outExpCS.getTypeSpecCS();
		}

		ObjectExp objectExp = ExpressionsFactory.eINSTANCE.createObjectExp();
		objectExp.setStartPosition(outExpCS.getStartOffset());
		objectExp.setEndPosition(outExpCS.getEndOffset());
		
		if(typeSpecCS != null) {
			TypeSpecPair objectTypeSpec = visitTypeSpecCS(typeSpecCS, DirectionKind.OUT, env);
			
			objectExp.setType(objectTypeSpec.myType);
			if(objectTypeSpec.myType instanceof EClass) {
				// skip DataTypes as the instantiatedClass property expects Class
				// let's make AST validation to complain on missing class.
				// Note: Still can be derived from the referred object if specified explicitly
				objectExp.setInstantiatedClass((EClass)objectTypeSpec.myType);
			}
			objectExp.setExtent(objectTypeSpec.myExtent);
			
		} else if(topLevelInMapping != null) {
			// TODO - support multiple result parameters, for now take the first as the grammar does not allow this yet
			boolean isContextInOut = topLevelInMapping.getDirectionKindCS() != null ? 
					topLevelInMapping.getDirectionKindCS().getDirectionKind() == DirectionKindEnum.INOUT : false;
			
			assert env.getContextOperation() instanceof ImperativeOperation; 
			ImperativeOperation owningOperation = (ImperativeOperation)env.getContextOperation();

			if(owningOperation.getResult().isEmpty()) {
				if(isContextInOut && owningOperation.getContext() != null) {
					objectExp.setType(owningOperation.getContext().getEType());
				}
			}
		}

		SimpleNameCS referredObjNameCS = outExpCS.getSimpleNameCS();
		if(referredObjNameCS != null) {
			// a referred object has been explicitly specified
			String varName = referredObjNameCS.getValue();
			org.eclipse.ocl.ecore.Variable referredObject  = varName != null ? (org.eclipse.ocl.ecore.Variable)env.lookup(varName) : null;
			if(referredObject == null) {
				// variable not resolved
				env.reportError(NLS.bind(ValidationMessages.unresolvedNameError, varName), referredObjNameCS);
			} else {
				referredObjNameCS.setAst(referredObject);
				
				// TODO - implicit variables should follow multiplicity [1] referredObject and should always be created
				// for now, only explicit variables are recorded
				objectExp.setName(varName);
				objectExp.setReferredObject(referredObject);
			}
		}
		
		if(objectExp.getReferredObject() != null && objectExp.getType() == null) {
			objectExp.setType(objectExp.getReferredObject().getType());
		}
		
		if(objectExp.getType() instanceof EClass) {				
			objectExp.setInstantiatedClass((EClass)objectExp.getType());
		}		
		
		// try to derive extent from referred variable, if not retrieved from explicit TypeSpec yet
		if (objectExp.getExtent() == null) {
			Variable<EClassifier, EParameter> referredObject  = objectExp.getReferredObject();
			if(referredObject != null) {
				if(referredObject.getRepresentedParameter() instanceof MappingParameter) {			
					MappingParameter mappingPar = (MappingParameter) referredObject.getRepresentedParameter();
					objectExp.setExtent(mappingPar.getExtent());
				} 
			} 
			if (objectExp.getExtent() == null && objectExp.getType() != null) {
				QvtOperationalModuleEnv moduleEnv = getModuleContextEnv(env);				
				objectExp.setExtent(moduleEnv.resolveModelParameter(objectExp.getType(), DirectionKind.OUT));								
			}
		}
						

		Module module = env.getModuleContextType();
		
		if (objectExp.getExtent() == null && module != null && !getModelParameter(module).isEmpty()) {
			QvtOperationalModuleEnv moduleEnv = getModuleContextEnv(env);				
			boolean isInvalidForExtentResolve = false;
			if (objectExp.getReferredObject() == null) { 
				isInvalidForExtentResolve = (objectExp.getType() == null || !moduleEnv.isMayBelongToExtent(objectExp.getType()));
			}
			else {
				if (IntermediateClassFactory.isIntermediateClass(objectExp.getReferredObject().getType())) {
					isInvalidForExtentResolve = true;
				}
				else {
					isInvalidForExtentResolve = !QVTUMLReflection.isUserModelElement(objectExp.getReferredObject().getType());
				}
			}
			if(!isInvalidForExtentResolve) {
				env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_extentFailToInfer,
						QvtOperationalTypesUtil.getTypeFullName(objectExp.getType())),
						typeSpecCS != null ? typeSpecCS : outExpCS);
			}
		}
		
        ConstructorBody body = ExpressionsFactory.eINSTANCE.createConstructorBody();
        body.setStartPosition(outExpCS.getStartOffset());
        body.setEndPosition(outExpCS.getEndOffset());
        objectExp.setBody(body);

        QvtOperationalEnv tempEnv = env.getFactory().createEnvironment(env);
        org.eclipse.ocl.ecore.Variable elem = objectExp.getReferredObject();
        if (elem == null) { // new object creation
            elem = EcoreFactory.eINSTANCE.createVariable();
            elem.setType(objectExp.getType());
            objectExp.setReferredObject(elem);
			}
        String varName = (objectExp.getName() == null) ? env.generateTemporaryName() : objectExp.getName();
        objectExp.setName(varName);
        tempEnv.addImplicitVariableForProperties(varName, elem);
			
		for (OCLExpressionCS expCS : outExpCS.getExpressions()) {
            org.eclipse.ocl.ecore.OCLExpression exp = visitOclExpressionCS(expCS, tempEnv);
            if (exp != null) {
                body.getContent().add(exp);
            }
		}
			
        if(myCompilerOptions.isGenerateCompletionData()) {
            ASTBindingHelper.createCST2ASTBinding(outExpCS, objectExp, env);
			}

        if (isValidationChecked) {
            validateObjectExp(objectExp, outExpCS, env);
        }
        
        return objectExp;
        }
		
    
    
	public Module visitMappingModule(MappingModuleCS moduleCS, URI unitURI, QvtOperationalFileEnv env, ExternalUnitElementsProvider importResolver, ResourceSet resSet) throws SemanticException {        
        Module module = QvtOperationalParserUtil.createModule(moduleCS);        
		module.setStartPosition(moduleCS.getStartOffset());
		module.setEndPosition(moduleCS.getEndOffset());
        // AST binding
        if(myCompilerOptions.isGenerateCompletionData()) {
            ASTBindingHelper.createModuleBinding(moduleCS, module, env, unitURI);
        }
        //
		
		for (ModelTypeCS modelTypeCS : moduleCS.getMetamodels()) {
			ModelType modelType = visitModelTypeCS(modelTypeCS, env, module, resSet);
			if (modelType == null) {
				continue;
			}
			module.getEClassifiers().add(modelType);
			module.getUsedModelType().add(modelType);
			if (modelType.getName().length() > 0) {
				ModelType existingModelType = env.getModelType(Collections.singletonList(modelType.getName()));
				if(existingModelType == null) {
					env.registerModelType(modelType);
				} else {
					env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_modeltypeAlreadyDefined,
								new Object[] { modelType.getName() }),
								modelTypeCS.getIdentifierCS());
				}
			}
			else {
				env.registerModelType(modelType);
				env.reportWarning(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_modeltypeDeprecatedSyntax, new Object[] { }),
						modelTypeCS);
			}
		}
		
		visitTransformationHeaderCS(moduleCS.getHeaderCS(), env, module);
		
        env.setContextModule(module);
        
		visitIntermediateClassesCS(env, moduleCS, module);
		
		for (TagCS tagCS : moduleCS.getTags()) {
			visitTagCS(env, tagCS, module, env.getModuleContextType());
		}

		importsCS(moduleCS, module, env, importResolver);

		for (RenameCS renameCS : moduleCS.getRenamings()) {
			legacyRenameCS(renameCS, env);
		}
		
		createModuleProperties(module, moduleCS, env);
		
		HashMap<MappingMethodCS, ImperativeOperation> methodMap = new LinkedHashMap<MappingMethodCS, ImperativeOperation>(moduleCS.getMethods().size());
		
		// declare moduleAST operations as they are required to analyze rules' contents
		for (MappingMethodCS methodCS : moduleCS.getMethods()) {
			String name = ""; //$NON-NLS-1$			
			if(methodCS.getMappingDeclarationCS() != null) {
				SimpleNameCS methodNameCS = methodCS.getMappingDeclarationCS().getSimpleNameCS();
				if(methodNameCS != null) {
					name = methodNameCS.getValue(); //$NON-NLS-1$
				}
			}
			
			ImperativeOperation operation = null;
			if (methodCS instanceof ConstructorCS) {
				operation = ExpressionsFactory.eINSTANCE.createConstructor();
			}
			else if (methodCS instanceof MappingRuleCS) {
				operation = ExpressionsFactory.eINSTANCE.createMappingOperation();
			}
			else if (QvtOperationalEnv.MAIN.equals(name)) {
				operation = ExpressionsFactory.eINSTANCE.createEntryOperation();
			}
			else {
				operation = ExpressionsFactory.eINSTANCE.createHelper();
			}
			
			if (visitMappingDeclarationCS(methodCS, env, operation)) {
				ImperativeOperation imperativeOp = env.defineImperativeOperation(operation, methodCS instanceof MappingRuleCS, true);
				if (imperativeOp != null) {
					methodMap.put(methodCS, imperativeOp);
				}
			}
		}
		
		// Handle the case of legacy constructs which allows for signature-less 
		// transformation definition
		DeprecatedSignaturelessTransf.patchModule(module);			
		
		boolean moduleEntryFound = false;
		for (MappingMethodCS methodCS : methodMap.keySet()) {
			ImperativeOperation imperativeOp = methodMap.get(methodCS);
			if(imperativeOp == null) {
				continue;
			}
			
			visitMappingMethodCS(methodCS, env, imperativeOp);				
	        if(myCompilerOptions.isGenerateCompletionData()) {
				//ASTBindingHelper.createCST2ASTBinding(methodCS, imperativeOp, env);
			} 
			
			if ((!QvtOperationalEnv.MAIN.equals(imperativeOp.getName()) || 
					getModelParameter(env.getModuleContextType()).isEmpty()) == false) {
				checkMainMappingConformance(env, imperativeOp);
			}
			
			if (false == moduleCS instanceof LibraryCS
					&& QvtOperationalEnv.MAIN.equals(imperativeOp.getName())) {
				if (moduleEntryFound) {
					env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_entryPointShouldBeDeclOnce,
							QvtOperationalEnv.MAIN), methodCS);
				}
				moduleEntryFound = true;
			}
		}
		
		for (ModuleImport moduleImport : module.getModuleImport()) {
			for (EOperation operation : QvtOperationalParserUtil.getOwnedOperations(moduleImport.getImportedModule())) {
				if(operation instanceof MappingOperation) {
					MappingOperation mappingOperation = (MappingOperation) operation;
					env.registerMappingOperation(mappingOperation);
				}
			}
		}
		
		env.resolveResolveInExpInMappings();
		
		ImperativeOperation mainMethod = QvtOperationalParserUtil.getMainOperation(module);
		if(mainMethod instanceof EntryOperation) {
			module.setEntry((EntryOperation)mainMethod);
		}

		validate(env);

		return module;
	}
	
	/**
	 * Clears the state of this QVT analyzer.  
	 */
	public void clear() {
		if(myErrorNodes != null) {
			myErrorNodes.clear();
		}
	}

	private void visitTagCS(QvtOperationalEnv env, TagCS ownedTagCS, Module module, EClassifier tagContextType) throws SemanticException {
		String tagId = visitLiteralExpCS(ownedTagCS.getName(), env);
		
		String value = null;
		if (ownedTagCS.getOclExpressionCS() != null) {
			org.eclipse.ocl.ecore.OCLExpression oclExpression = visitOclExpressionCS(ownedTagCS.getOclExpressionCS(), env);
			if (oclExpression instanceof StringLiteralExp) {
				value = ((StringLiteralExp) oclExpression).getStringSymbol();
			}
		}
		
		EModelElement element = null;
		ScopedNameCS scopedNameCS = ownedTagCS.getScopedNameCS();
		TypeCS typeCS = scopedNameCS.getTypeCS();
		if (typeCS != null) {
			EClassifier owningType = visitTypeCS(typeCS, null, env);
			if (owningType != null && scopedNameCS.getName() != null) {
				element = env.lookupProperty(TypeUtil.resolveType(env, owningType), scopedNameCS.getName());				
			}
		}
		else if (scopedNameCS.getName() != null) {	
			element = env.lookupProperty(tagContextType, scopedNameCS.getName());
		}
		
		if (element == null) {
            QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.unresolvedNameError,
            		new Object[] { QvtOperationalParserUtil.getStringRepresentation(scopedNameCS) }),
            		scopedNameCS);
		}
		else {
			EAnnotation ownedTag = createTag(tagId, value, element);
			
			ASTSyntheticNode astNode = ASTSyntheticNodeAccess.createASTNode(ownedTag);
			astNode.setStartPosition(ownedTagCS.getStartOffset());
			astNode.setEndPosition(ownedTagCS.getEndOffset());
			
			module.getOwnedTag().add(ownedTag);
		}
	}

	private void visitIntermediateClassesCS(QvtOperationalFileEnv env, MappingModuleCS moduleCS, Module module) throws SemanticException {
		
		Map<String, EClass> createdIntermClasses = new LinkedHashMap<String, EClass>(moduleCS.getClassifierDefCS().size());
		final Map<EClass, CSTNode> cstIntermClassesMap = new LinkedHashMap<EClass, CSTNode>();
		for (ClassifierDefCS classifierDefCS : moduleCS.getClassifierDefCS()) {
			if (false == module instanceof OperationalTransformation) {
	            env.reportError(NLS.bind(ValidationMessages.IntermediateClassifierNotAllowed,
	            		new Object[] {}), classifierDefCS);
			}
			if (createdIntermClasses.containsKey(classifierDefCS.getSimpleNameCS().getValue())) {
	            env.reportError(NLS.bind(ValidationMessages.DuplicateClassifier,
	            		new Object[] { classifierDefCS.getSimpleNameCS().getValue() }), classifierDefCS.getSimpleNameCS());
				continue;
			}

			EClass eClassifier = IntermediateClassFactory.getFactory(module).createIntermediateClassifier();
			ASTSyntheticNode astNode = ASTSyntheticNodeAccess.createASTNode(eClassifier);
			astNode.setStartPosition(classifierDefCS.getStartOffset());
			astNode.setEndPosition(classifierDefCS.getEndOffset());
			if (myCompilerOptions.isGenerateCompletionData()) {
				ASTSyntheticNodeAccess.setCST(astNode, classifierDefCS);
			}
			
			eClassifier.setName(classifierDefCS.getSimpleNameCS().getValue());
			
			createdIntermClasses.put(eClassifier.getName(), eClassifier);
			cstIntermClassesMap.put(eClassifier, classifierDefCS.getSimpleNameCS());
		}

		if (!createdIntermClasses.isEmpty()) {
			IntermediateClassFactory.getFactory(module).registerModelType(env);
		}

		for (ClassifierDefCS classifierDefCS : moduleCS.getClassifierDefCS()) {
			String className = classifierDefCS.getSimpleNameCS().getValue();
			EClass rootClass = createdIntermClasses.get(className);			
			for (TypeCS typeCS : classifierDefCS.getExtends()) {
				
				if (typeCS instanceof PathNameCS && ((PathNameCS) typeCS).getSequenceOfNames().size() == 1) {
					EClass extClass = createdIntermClasses.get(((PathNameCS) typeCS).getSequenceOfNames().get(0));
					if (extClass != null) {
						typeCS.setAst(extClass);
						rootClass.getESuperTypes().add(extClass);
						continue;
					}
				}
				
				EClassifier extendType = visitTypeCS(typeCS, null, env);
				if (extendType == null) {
					// error reported by visitTypeCS(..)
					continue;
				}
				else if (!QVTUMLReflection.isUserModelElement(extendType)) {
					env.reportError(NLS.bind(ValidationMessages.InvalidClassifierForExtend,
							QvtOperationalTypesUtil.getTypeFullName(extendType)),
							typeCS);
				}
				else {
					rootClass.getESuperTypes().add((EClass) extendType);
				}
			}
		}

		Map<ClassifierPropertyCS, EStructuralFeature> createdProperties = new IdentityHashMap<ClassifierPropertyCS, EStructuralFeature>();
		for (ClassifierDefCS classifierDefCS : moduleCS.getClassifierDefCS()) {
			String className = classifierDefCS.getSimpleNameCS().getValue();
			if (!createdIntermClasses.containsKey(className)) {
				continue;
			}
			visitClassifierDefCS(classifierDefCS, createdIntermClasses.get(className), module, createdProperties, env);
		}
		for (ClassifierDefCS classifierDefCS : moduleCS.getClassifierDefCS()) {
			String className = classifierDefCS.getSimpleNameCS().getValue();
			if (!createdIntermClasses.containsKey(className)) {
				continue;
			}
			initClassifierDefCS(createdIntermClasses.get(className), module, createdProperties, env);
		}
		
		class CycleChecker {
			boolean checkClass(EClass cls) {
				myVisitedClasses.clear();
				return checkClassImpl(cls);
			}
			
			private boolean checkClassImpl(EClass cls) {
				myVisitedClasses.add(cls);
				for (EClass superCls : cls.getESuperTypes()) {
					// check only intermediate hierarchy
					if (!cstIntermClassesMap.containsKey(superCls)) {
						continue;
					}
					if (myVisitedClasses.contains(superCls)) {
						return false;
					}
					if (!checkClassImpl(superCls)) {
						return false;
					}
				}
				return true;
			}
			
			final Set<EClass> myVisitedClasses = new HashSet<EClass>(2);
		}
		
		CycleChecker cycleChecker = new CycleChecker();
		for (EClass nextClass : cstIntermClassesMap.keySet()) {
			if (!cycleChecker.checkClass(nextClass)) {
				env.reportError(NLS.bind(ValidationMessages.CycleInIntermHierarchy,
						QvtOperationalTypesUtil.getTypeFullName(nextClass)),
						cstIntermClassesMap.get(nextClass));
			}

			//nextClass.getESuperTypes().add(EcorePackage.Literals.ECLASS);
			
			Map<String, EStructuralFeature> ownFeatures = new HashMap<String, EStructuralFeature>(nextClass.getEStructuralFeatures().size());
			for (EStructuralFeature nextFeature : nextClass.getEStructuralFeatures()) {
				ownFeatures.put(nextFeature.getName(), nextFeature);
			}
			for (EStructuralFeature nextFeature : nextClass.getEAllStructuralFeatures()) {
				EStructuralFeature ownFeature = ownFeatures.get(nextFeature.getName());
				if (ownFeature != null && ownFeature != nextFeature) {
					env.reportError(NLS.bind(ValidationMessages.HidingProperty,
							nextFeature.getName()),
							cstIntermClassesMap.get(nextClass));
				}
			}
			
//			org.eclipse.emf.common.util.Diagnostic validate = new org.eclipse.emf.ecore.util.Diagnostician().validate(nextClass);
//			if (validate.getSeverity() != org.eclipse.emf.common.util.Diagnostic.OK) {
//				System.err.println(validate.getMessage());
//			}
		}
		
	}
	
	private EClass visitClassifierDefCS(ClassifierDefCS classifierDefCS, EClass eClassifier, Module module,
			Map<ClassifierPropertyCS, EStructuralFeature> createdProperties, QvtOperationalFileEnv env) throws SemanticException {

		class PropertyPair {
			final EStructuralFeature myEFeature;
			final ClassifierPropertyCS myPropCS;
			
			PropertyPair(EStructuralFeature eFeature, ClassifierPropertyCS propCS) {
				myEFeature = eFeature;
				myPropCS = propCS;
			}
		}

		Map<String, List<PropertyPair>> classifierProperties = new LinkedHashMap<String, List<PropertyPair>>(classifierDefCS.getProperties().size());

		// first pass for creation
		for (ClassifierPropertyCS propCS : classifierDefCS.getProperties()) {
			EStructuralFeature eFeature = visitClassifierPropertyCS(propCS, env);
			if (eFeature == null) {
				continue;
			}
			
			eClassifier.getEStructuralFeatures().add(eFeature);

			List<PropertyPair> properties = classifierProperties.get(eFeature.getName());
			if (properties == null) {
				properties = new ArrayList<PropertyPair>(2);
				classifierProperties.put(eFeature.getName(), properties);
			}
			properties.add(new PropertyPair(eFeature, propCS));
			
			createdProperties.put(propCS, eFeature);
		}
		
		for (String propName : classifierProperties.keySet()) {
			List<PropertyPair> properties = classifierProperties.get(propName);
			if (properties.size() == 1) {
				continue;
			}
			for (PropertyPair propPair : properties) {
				HiddenElementAdapter.markAsHidden(propPair.myEFeature);
	            env.reportError(NLS.bind(ValidationMessages.DuplicateProperty,
	            		new Object[] { eClassifier.getName() + '.' + propPair.myEFeature.getName() }), propPair.myPropCS.getSimpleNameCS());
			}
		}
		
		for (TagCS tagCS : classifierDefCS.getTags()) {
			visitTagCS(env, tagCS, module, eClassifier);
		}
		
		return eClassifier;
	}

	private void initClassifierDefCS(EClass eClassifier, Module module,
			Map<ClassifierPropertyCS, EStructuralFeature> createdProperties, QvtOperationalEnv env) throws SemanticException {

		// second pass for initialization parts and opposite properties
		for (ClassifierPropertyCS propCS : createdProperties.keySet()) {
			EStructuralFeature eFeature = createdProperties.get(propCS);
			if (eClassifier != eFeature.eContainer()) {
				continue;
			}
			
			initClassifierPropertyCS(propCS, eFeature, env);

			OCLExpression<EClassifier> initExp = QvtOperationalParserUtil.getInitExpression(eFeature);
			if (initExp != null) {
				IntermediateClassFactory.getFactory(module).addClassifierPropertyInit(eClassifier, eFeature, initExp);
			}
		}
	}

	private void initClassifierPropertyCS(ClassifierPropertyCS propCS, EStructuralFeature eFeature, QvtOperationalEnv env) {
		// handle initialization expression
		OCLExpression<EClassifier> initExpression = null;
		if (propCS.getOclExpressionCS() != null) {
			initExpression = visitOclExpressionCS(propCS.getOclExpressionCS(), env);
			QvtOperationalParserUtil.setInitExpression(eFeature, initExpression);			
		}
		
		if (eFeature.getEType() == null && initExpression != null) {
			eFeature.setEType(initExpression.getType());
		}
		
		if (initExpression != null) {
			EClassifier realType = initExpression.getType();
			EClassifier declaredType = env.getUMLReflection().getOCLType(eFeature);
			if (!QvtOperationalParserUtil.isAssignableToFrom(env, declaredType, realType)) {
				env.reportError(NLS.bind(ValidationMessages.TypeMismatchError,
						new Object[] { QvtOperationalTypesUtil.getTypeFullName(declaredType), QvtOperationalTypesUtil.getTypeFullName(realType) }),
						propCS.getStartOffset(), propCS.getEndOffset());
			}
		}
		
		// handle opposite property
		OppositePropertyCS oppositeCS = propCS.getOpposite();
		if (oppositeCS != null) {
			if (eFeature instanceof EReference) {

				if (oppositeCS.getMultiplicity() != null) {
					visitMultiplicityDefCS(oppositeCS.getMultiplicity(), env);
				}
				
				if (oppositeCS.getSimpleNameCS() != null) {
					String oppositeName = oppositeCS.getSimpleNameCS().getValue();
					EReference oppositeRef = null;
					EClassifier eFeatureType = eFeature.getEType();
					if (eFeatureType instanceof EClass) {
						for (EReference nextRef : ((EClass) eFeatureType).getEAllReferences()) {
							if (oppositeName.equals(nextRef.getName())) {
								oppositeRef = nextRef;
								break;
							}							
						}
						
						if (oppositeRef != null) {
							((EReference) eFeature).setEOpposite(oppositeRef);
						}
						else {
				            env.reportError(NLS.bind(ValidationMessages.IntermClassifier_invalideOppositeName,
				            		new Object[] { oppositeName, QvtOperationalTypesUtil.getTypeFullName(eFeatureType) }),
				            		oppositeCS.getSimpleNameCS());
						}
					}
					else {
			            env.reportError(NLS.bind(ValidationMessages.IntermClassifier_invalideOppositeType,
			            		new Object[] { QvtOperationalTypesUtil.getTypeFullName(eFeatureType) }), oppositeCS);
					}
				}
			}
			else {
	            env.reportError(NLS.bind(ValidationMessages.IntermClassifier_oppositeOnlyForReferences,
	            		new Object[] { }), oppositeCS);
			}
		}
	}

	private EStructuralFeature visitClassifierPropertyCS(ClassifierPropertyCS propCS, QvtOperationalEnv env) {
		EClassifier propertyEType = null;
		if (propCS.getTypeCS() != null) {
			propertyEType = visitTypeCS(propCS.getTypeCS(), null, env);
		}

		EStructuralFeature eFeature = createESFeature(propertyEType);
		eFeature.setName(propCS.getSimpleNameCS().getValue());		
		eFeature.setEType(propertyEType);

		ASTSyntheticNode astNode = ASTSyntheticNodeAccess.createASTNode(eFeature);
		astNode.setStartPosition(propCS.getStartOffset());
		astNode.setEndPosition(propCS.getEndOffset());
		
		// handle stereotype qualifiers
		Set<String> handledStereotypes = new HashSet<String>(2);
		for (SimpleNameCS nameCS : propCS.getStereotypeQualifiers()) {
			String qualifName = nameCS.getValue();
			if ("id".equals(qualifName)) { //$NON-NLS-1$
				if (eFeature instanceof EAttribute) {
					((EAttribute) eFeature).setID(true);
				}
				else {
		            env.reportError(NLS.bind(ValidationMessages.IntermClassifier_unapplicableStereotypeQualifier,
		            		new Object[] { qualifName }), nameCS);
				}
			}
			else {
	            env.reportWarning(NLS.bind(ValidationMessages.IntermClassifier_unknownStereotypeQualifier,
	            		new Object[] { qualifName }), nameCS);
			}

			if (handledStereotypes.contains(qualifName)) {
	            env.reportWarning(NLS.bind(ValidationMessages.IntermClassifier_duplicatedStereotypeQualifier,
	            		new Object[] { qualifName }), nameCS);
			}
			handledStereotypes.add(qualifName);
		}
		
		// handle feature keys
		SimpleNameCS staticNameCS = null, composesNameCS = null;
		Set<String> handledFeatureKeys = new HashSet<String>(2);
		for (SimpleNameCS nameCS : propCS.getFeatureKeys()) {
			String keyName = nameCS.getValue();
			if ("composes".equals(keyName)) { //$NON-NLS-1$
				if (eFeature instanceof EReference) {
					((EReference) eFeature).setContainment(true);
				}
				else {
		            env.reportError(NLS.bind(ValidationMessages.IntermClassifier_referenceOnlyFeatureKey,
		            		new Object[] { keyName }), nameCS);
				}
				composesNameCS = nameCS;
			}
			else if ("references".equals(keyName)) { //$NON-NLS-1$
				if (eFeature instanceof EReference) {
					((EReference) eFeature).setContainment(false);
				}
				else {
		            env.reportError(NLS.bind(ValidationMessages.IntermClassifier_referenceOnlyFeatureKey,
		            		new Object[] { keyName }), nameCS);
				}
			}
			else if ("readonly".equals(keyName)) { //$NON-NLS-1$
				eFeature.setChangeable(false);
			}
			else if ("derived".equals(keyName)) { //$NON-NLS-1$
	            env.reportWarning(NLS.bind(ValidationMessages.IntermClassifier_unsupportedFeatureKey,
	            		new Object[] { keyName }), nameCS);
			}
			else if ("static".equals(keyName)) { //$NON-NLS-1$
				IntermediateClassFactory.markFeatureAsStatic(eFeature);
				staticNameCS = nameCS;
			}

			if (handledFeatureKeys.contains(keyName)) {
	            env.reportWarning(NLS.bind(ValidationMessages.IntermClassifier_duplicatedFeatureKey,
	            		new Object[] { keyName }), nameCS);
			}
			handledFeatureKeys.add(keyName);
		}
		
		if (composesNameCS != null && staticNameCS != null) {
            env.reportError(NLS.bind(ValidationMessages.IntermClassifier_incompatibleFeatureKeys,
            		new Object[] { composesNameCS.getValue(), staticNameCS.getValue() }), composesNameCS);
            env.reportError(NLS.bind(ValidationMessages.IntermClassifier_incompatibleFeatureKeys,
            		new Object[] { composesNameCS.getValue(), staticNameCS.getValue() }), staticNameCS);
		}
		
		if (propCS.getMultiplicity() != null) {
			MultiplicityDef multiplcityDef = visitMultiplicityDefCS(propCS.getMultiplicity(), env);
			eFeature.setLowerBound(multiplcityDef.lower);
			eFeature.setUpperBound(multiplcityDef.upper);
		}
		
		eFeature.setOrdered(propCS.isIsOrdered());

		return eFeature;
	}
	
	private static class MultiplicityDef {
		public int lower = 0;
		public int upper = 1;
	}
	
	private MultiplicityDef visitMultiplicityDefCS(MultiplicityDefCS multiplicityCS, QvtOperationalEnv env) {
		MultiplicityDef multiplicityDef = new MultiplicityDef();

		try {
			multiplicityDef.lower = Integer.valueOf(multiplicityCS.getLowerBound().getSymbol());
			if ("*".equals(multiplicityCS.getUpperBound().getSymbol())) { //$NON-NLS-1$
				multiplicityDef.upper = -1;
			}
			else {
				multiplicityDef.upper = Integer.valueOf(multiplicityCS.getUpperBound().getSymbol());
			}
			
			// check UML constraints [7.3.32]
			if (multiplicityDef.lower < 0) {
				throw new NumberFormatException(ValidationMessages.IntermClassifier_multiplicityInvalidLowerBound);
			}
			if (multiplicityDef.upper >= 0 && multiplicityDef.lower > multiplicityDef.upper) {
				throw new NumberFormatException(ValidationMessages.IntermClassifier_multiplicityInvalidRange);
			}
			if (multiplicityDef.upper == 0 && multiplicityDef.lower == 0) {
				throw new NumberFormatException(ValidationMessages.IntermClassifier_multiplicityEmptyRange);
			}
		}
		catch (NumberFormatException ex) {
            env.reportError(ex.getLocalizedMessage(), multiplicityCS);
			// default multiplicity from specification [8.4.6]
            multiplicityDef = new MultiplicityDef();
		}
		
		return multiplicityDef;
	}
	
	private void importsCS(MappingModuleCS parsedModuleCS, Module module, QvtOperationalFileEnv env, ExternalUnitElementsProvider importResolver) {
		
		EList<ModuleUsageCS> moduleUsages = parsedModuleCS.getHeaderCS().getModuleUsages();		
		boolean hasModuleUsage = !moduleUsages.isEmpty();
	    EMap<String, List<QvtOperationalModuleEnv>> importMap = new BasicEMap<String, List<QvtOperationalModuleEnv>>(5);
	    
		for (ImportCS nextImportedCS : parsedModuleCS.getImports()) {			
			if(nextImportedCS.getPathNameCS() == null) {
				// nothing meaningful to represent in AST
				continue;
			}

			String unitQualifiedName = QvtOperationalParserUtil.getStringRepresentation(nextImportedCS.getPathNameCS(), "."); //$NON-NLS-1$			
			EList<String> importedUnitQName = nextImportedCS.getPathNameCS().getSequenceOfNames();
			List<QvtOperationalModuleEnv> moduleEnvironments = importResolver.getModules(importedUnitQName);
			
			if(moduleEnvironments != null && !moduleEnvironments.isEmpty()) {
				for (QvtOperationalModuleEnv nextImportedEnv : moduleEnvironments) {
					URI sourceURI = getSourceURI(nextImportedEnv);
					nextImportedCS.setAst(sourceURI);
					nextImportedCS.getPathNameCS().setAst(sourceURI);
					
					Module importedModule = nextImportedEnv.getModuleContextType();
					if(importedModule == null) {
						// nothing to import in, no module was successfully parsed
						continue;
					}
					
					// process imports here only in case of the legacy implicit import by extension, 
					// otherwise pass the responsibility to module usage analysis						
					if(!hasModuleUsage) {						
						if(!env.getImportsByExtends().contains(nextImportedEnv)) {
							// we might have duplicates in imports, so avoid exceptions in environments
							env.addImplicitExtendsImport(nextImportedEnv);
						}
																					
						ModuleImport moduleImport = ExpressionsFactory.eINSTANCE.createModuleImport();					
						moduleImport.setImportedModule(importedModule);
						moduleImport.setKind(ImportKind.EXTENSION);
						moduleImport.setStartPosition(nextImportedCS.getStartOffset());
						moduleImport.setEndPosition(nextImportedCS.getEndOffset());
												
						module.getModuleImport().add(moduleImport);
						
						if(module instanceof OperationalTransformation && importedModule  instanceof OperationalTransformation) {
							validateImportedSignature(env, (OperationalTransformation) module, (OperationalTransformation) importedModule, moduleImport);
						}					
						
						if(myCompilerOptions.isGenerateCompletionData()) {
							ASTBindingHelper.createCST2ASTBinding(nextImportedCS, moduleImport);
						}
					}
				}
				
				importMap.put(unitQualifiedName, moduleEnvironments);				
				
				// report legacy library import statements
				if(nextImportedCS instanceof LibraryImportCS) {
					// warn about specific library import deprecation
					env.reportWarning(NLS.bind(ValidationMessages.DeprecatedLibraryImportStatement, new Object[] { unitQualifiedName }), nextImportedCS.getPathNameCS());
				}
			}
		}
		
		for (ModuleUsageCS nextModuleUsage : moduleUsages) {
	    	moduleUsageCS(nextModuleUsage, module, env, importMap);
		}
	}

	private void moduleUsageCS(ModuleUsageCS moduleUsageCS, Module module, QvtOperationalModuleEnv env, EMap<String, List<QvtOperationalModuleEnv>> importMap) {
    	EList<ModuleRefCS> moduleRefs = moduleUsageCS.getModuleRefs();
    	for (ModuleRefCS moduleRefCS : moduleRefs) {
    		List<QvtOperationalModuleEnv> resolvedModuleEnvs = new ArrayList<QvtOperationalModuleEnv>(2);
    		
    		PathNameCS modulePathNameCS = moduleRefCS.getPathNameCS();
    		if(modulePathNameCS == null) {
    			// should already have reported error CST parse error
    			continue;
    		}
    		
    		EList<String> qname = modulePathNameCS.getSequenceOfNames();    		
    		if(qname.size() == 1) {
    			String moduleName = qname.get(0);
    			for (String unitQName : importMap.keySet()) {
    				List<QvtOperationalModuleEnv> moduleEnvs = importMap.get(unitQName);
    				
    				for (QvtOperationalModuleEnv nextModuleEnv : moduleEnvs) {
						Module nextImportedModule = nextModuleEnv.getModuleContextType();
					
						if(nextImportedModule != null && moduleName.equals(nextImportedModule.getName())) {
							List<ModelType> refereceSignatureModelTypes = new ArrayList<ModelType>(5);							
							EList<ParameterDeclarationCS> signatureParams = moduleRefCS.getParameters();
							if(signatureParams.isEmpty()) {
								// be tolerant, we are not specific about the model types, select only by name
								resolvedModuleEnvs.add(nextModuleEnv);
								continue;
							}
							
							for (ParameterDeclarationCS nextParamCS : signatureParams) {
								TypeSpecCS nextTypeCS = nextParamCS.getTypeSpecCS();
								if(nextTypeCS != null && nextTypeCS.getTypeCS() instanceof PathNameCS) {
									PathNameCS modelTypeCS = (PathNameCS) nextTypeCS.getTypeCS();
 									EClassifier modelType = env.getModelType(modelTypeCS.getSequenceOfNames());
 									if(modelType instanceof ModelType) {
 										refereceSignatureModelTypes.add((ModelType) modelType);
 									}
								}
							}

							List<ModelType> importedSignatureTypes;
							if(nextImportedModule instanceof OperationalTransformation) {
								OperationalTransformation ot = (OperationalTransformation) nextImportedModule;
								importedSignatureTypes = QvtOperationalUtil.collectValidModelParamaterTypes(ot);
							} else {
								// the only place where a library can declare its signature
								importedSignatureTypes = nextImportedModule.getUsedModelType();								
							}
							
							if(refereceSignatureModelTypes.size() == importedSignatureTypes.size()) {
								boolean compatible = true;
								for (int i = 0; i < refereceSignatureModelTypes.size(); i++) {
									if(!QvtOperationalUtil.isCompatibleModelType(
										refereceSignatureModelTypes.get(i), importedSignatureTypes.get(i))) {
										compatible = false;
										break;
									}
								}
								
								if(compatible) {
									resolvedModuleEnvs.add(nextModuleEnv);
								}
							}
						}
					}
				}
    		}
    		    		
    		int matchCount = resolvedModuleEnvs.size();
			switch(matchCount) {			
			case 1:
        		QvtOperationalModuleEnv importedModuleEnv = resolvedModuleEnvs.get(0);    			
    			Module importedModule = importedModuleEnv.getModuleContextType();
    			
				ImportKindEnum importKindCS = moduleUsageCS.getImportKind();
				ImportKind kind = importKindCS == ImportKindEnum.ACCESS ? ImportKind.ACCESS : ImportKind.EXTENSION;
    			
				env.addImport(kind, importedModuleEnv);
								
				ModuleImport moduleImport = ExpressionsFactory.eINSTANCE.createModuleImport();					
				moduleImport.setImportedModule(importedModule);
				moduleImport.setKind(kind);

				moduleImport.setStartPosition(moduleUsageCS.getStartOffset());
				moduleImport.setEndPosition(moduleUsageCS.getEndOffset());
    			modulePathNameCS.setAst(importedModule);
				
				if(kind == ImportKind.EXTENSION) {
					if(module instanceof OperationalTransformation && importedModule  instanceof OperationalTransformation) {
						validateImportedSignature(env, (OperationalTransformation) module, (OperationalTransformation) importedModule, moduleImport);
					}					
				}
				
				module.getModuleImport().add(moduleImport);
				break;
			case 0:
    			String message = NLS.bind(ValidationMessages.UnresolvedModuleReference, 
    					QvtOperationalParserUtil.getStringRepresentation(modulePathNameCS)); //$NON-NLS-1$
    			env.reportError(message, moduleRefCS);
    			break;
    		default:
    			env.reportError(NLS.bind(ValidationMessages.AmbiguousModuleReference, 
    					QvtOperationalParserUtil.getStringRepresentation(modulePathNameCS)), moduleRefCS);
    		}
		}		
	}	
	
	private void createModuleProperties(Module module, MappingModuleCS moduleCS, QvtOperationalFileEnv env) throws SemanticException {
		
		for (ModulePropertyCS propCS : moduleCS.getProperties()) {
			EStructuralFeature prop = visitModulePropertyCS(propCS, env);
			if (prop == null) {
				continue;
			}

			EStructuralFeature eFeature = null;
			if (propCS instanceof ContextualPropertyCS) {
				EClass ctxType = ((ContextualProperty) prop).getContext();
				if (ctxType != null && env.lookupProperty(ctxType, prop.getName()) != null) {
					// need to check now for duplicates, as MDT OCL lookup now returns the most specific 
					// redefinition [244886], so further checking lookup might not reach the original valid feature
					// being redefined (thus no collision would be detectable)
					HiddenElementAdapter.markAsHidden(prop);
				}
				if (module instanceof OperationalTransformation) {
					((OperationalTransformation) module).getIntermediateProperty().add(prop);
				}
				else {
		            env.reportError(NLS.bind(ValidationMessages.IntermediatePropertyNotAllowed, new Object[] {}), propCS);
				}
				eFeature = prop;
				// using AST-CST map as this mapping is not optional but always required
				env.getASTNodeToCSTNodeMap().put(prop, propCS); 
			} else {
				//eFeature = env.getUMLReflection().createProperty(prop.getName(), prop.getEType());
				eFeature = prop;				
				//QvtOperationalParserUtil.addLocalPropertyAST(eFeature, prop);				
		        if (env.lookupProperty(module, prop.getName()) != null) {
		        	HiddenElementAdapter.markAsHidden(eFeature);
		            env.reportError(NLS.bind(ValidationMessages.ModulePropertyAlreadyDefined, new Object[] { prop.getName() }), propCS.getSimpleNameCS());
		        }
				
				if (propCS instanceof ConfigPropertyCS) {
					module.getConfigProperty().add(eFeature);
				} 
			}
			
			module.getEStructuralFeatures().add(eFeature);						
		}

		if (module instanceof OperationalTransformation) {
			IntermediatePropertyHierarchy intermPropDefHierarchy = ((OperationalTransformation) module).getIntermediateProperty().isEmpty() ? null : new IntermediatePropertyHierarchy(module, env);				
			for (EStructuralFeature prop : ((OperationalTransformation) module).getIntermediateProperty()) {			
				if (prop instanceof ContextualProperty) {
					ContextualProperty ctxProperty = (ContextualProperty) prop;				
					EClass ctxType = ctxProperty.getContext();
					EStructuralFeature lookupProperty = ctxType != null ? env.lookupProperty(ctxType, prop.getName()) : null;
					
					boolean isAlreadyDefined = (lookupProperty != null && lookupProperty != ctxProperty) |
											HiddenElementAdapter.isMarkedAsHidden(ctxProperty);				
					if(isAlreadyDefined || intermPropDefHierarchy.hasHierarchyClashes(ctxProperty)) {
						HiddenElementAdapter.markAsHidden(ctxProperty);											
						String message = NLS.bind(ValidationMessages.IntermediatePropertyAlreadyDefined, prop.getName());
						
						int startPos = ctxProperty.getStartPosition();
						int endPos = ctxProperty.getEndPosition();
						CSTNode cstNode = QvtOperationalParserUtil.getPropertyProblemNode(prop, env);
						if(cstNode != null) {
							startPos = cstNode.getStartOffset();
							endPos = cstNode.getEndOffset();
						}
						env.reportError(message, startPos, endPos);
					}				
				}
			}
		}
	}
 
	protected void visitTransformationHeaderCS(TransformationHeaderCS headerCS,
			QvtOperationalFileEnv env, Module module) {
		if (!headerCS.getQualifiers().isEmpty()) {
			env.reportWarning(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_transfQualifiersNotSupported,
					new Object[] { }), 
					headerCS.getQualifiers().get(0).getStartOffset(),
					headerCS.getQualifiers().get(headerCS.getQualifiers().size()-1).getEndOffset());
		}
		
		if(!QvtOperationalParserUtil.hasSimpleName(headerCS)) {
			env.reportError(NLS.bind(ValidationMessages.moduleNameMustBeSimpleIdentifierError, new Object[] { 
					QvtOperationalParserUtil.getMappingModuleQualifiedName(headerCS) }), headerCS.getPathNameCS());
		}		
		
        String unitSimpleName = QvtOperationalParserUtil.getMappingModuleSimpleName(headerCS);
        
		module.setName(unitSimpleName);
		module.setNsPrefix(unitSimpleName);
		
		if (module instanceof OperationalTransformation) {
		    visitOperationalTransformationSignature(headerCS, env, (OperationalTransformation) module);
		} else if (module instanceof Library) {
            visitLibrarySignature(headerCS, env, (Library) module);
		} else {
		    throw new RuntimeException("Unknown module type: " + module); //$NON-NLS-1$
		}
		
		if (headerCS.getTransformationRefineCS() != null) {
			env.reportWarning(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_transfRefineNotSupported,
					new Object[] { }), headerCS.getTransformationRefineCS());
		}
		if (!headerCS.getModuleUsages().isEmpty()) {
// supported now			
//			env.reportWarning(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_transfUsagesNotSupported,
//					new Object[] { }), 
//					headerCS.getModuleUsages().get(0).getStartOffset(),
//					headerCS.getModuleUsages().get(headerCS.getModuleUsages().size()-1).getEndOffset());
		}		
	}

    protected void visitOperationalTransformationSignature(TransformationHeaderCS headerCS,
            QvtOperationalFileEnv env, OperationalTransformation module) {
        Set<String> paramNames = new LinkedHashSet<String>();
        for (ParameterDeclarationCS paramCS : headerCS.getParameters()) {
            EClassifier type = null;
            TypeCS paramTypeCS = (paramCS.getTypeSpecCS() != null) ? paramCS.getTypeSpecCS().getTypeCS() : null;
            boolean isSimpleName = false;
            if (paramTypeCS instanceof PathNameCS) {
                PathNameCS typePathNameCS = (PathNameCS) paramTypeCS;
                isSimpleName = typePathNameCS.getSequenceOfNames().size() == 1;
                type = env.getModelType(typePathNameCS.getSequenceOfNames());
                paramTypeCS.setAst(type);
            }
            if (type == null || !isSimpleName) {
                env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_transfParamWrongType,
                        new Object[] { }), paramTypeCS);
            }

            ModelParameter varParam = ExpressionsFactory.eINSTANCE.createModelParameter();
            paramCS.setAst(varParam);
            
            varParam.setRepresentedParameter(varParam);
            varParam.setStartPosition(paramCS.getStartOffset());
            varParam.setEndPosition(paramCS.getEndOffset());
            
            SimpleNameCS paramNameCS = paramCS.getSimpleNameCS();
			if(paramNameCS != null) {
                varParam.setName(paramNameCS.getValue());
                paramNameCS.setAst(varParam);
            } else {
                varParam.setName(""); //$NON-NLS-1$
            }
            varParam.setEType(type);
            DirectionKindEnum directionKind = paramCS.getDirectionKind();
            if (directionKind == DirectionKindEnum.DEFAULT) {
                directionKind = DirectionKindEnum.IN;
            }
            varParam.setKind((DirectionKind) ExpressionsFactory.eINSTANCE.createFromString(
                    ExpressionsPackage.eINSTANCE.getDirectionKind(), directionKind.getLiteral()));

            if (paramNames.contains(varParam.getName())) {
                env.reportError(NLS.bind(ValidationMessages.SameParamName, new Object[] { varParam.getName() }),
                        (paramNameCS == null || paramNameCS.getValue().length() == 0) ? paramCS : paramNameCS);
            }
            paramNames.add(varParam.getName());
            
            module.getModelParameter().add(varParam);
            
            if(myCompilerOptions.isGenerateCompletionData()) {
                ASTBindingHelper.createCST2ASTBinding(paramCS, varParam);
            }           
        }
    }

    private void visitLibrarySignature(TransformationHeaderCS headerCS,
            QvtOperationalFileEnv env, Library module) {
        Set<ModelType> usedModelTypes = new HashSet<ModelType>(); 
        for (ParameterDeclarationCS paramCS : headerCS.getParameters()) {
            TypeCS paramTypeCS = (paramCS.getTypeSpecCS() != null) ? paramCS.getTypeSpecCS().getTypeCS() : null;
            if ((paramCS.getTypeSpecCS() != null) && (paramCS.getTypeSpecCS().getSimpleNameCS() != null)) {
                env.reportError(ValidationMessages.QvtOperationalVisitorCS_LibrarySignatureErrorModelExtentSpecified, paramCS.getTypeSpecCS().getSimpleNameCS());
            }
            if ((paramCS.getDirectionKind() != null) && (paramCS.getDirectionKind() != DirectionKindEnum.DEFAULT)) {
                env.reportError(ValidationMessages.QvtOperationalVisitorCS_LibrarySignatureErrorDirectionKindSpecified, paramCS);
            }
            if (paramCS.getSimpleNameCS() != null) {
                env.reportError(ValidationMessages.QvtOperationalVisitorCS_LibrarySignatureErrorParameterNameSpecified, paramCS);
            }
            ModelType modelType = null;
            if (paramTypeCS instanceof PathNameCS) {
                PathNameCS typePathNameCS = (PathNameCS) paramTypeCS;
                if (typePathNameCS.getSequenceOfNames().size() == 1) {
                    modelType = env.getModelType(typePathNameCS.getSequenceOfNames());
                    if (modelType != null && !usedModelTypes.add(modelType)) {
                        env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_LibrarySignatureErrorDuplicateModelType, 
                                new Object[] { typePathNameCS.getSequenceOfNames().get(0) }), paramCS);
                    }
                }
            }
            if (modelType == null) {
                env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_transfParamWrongType,
                        new Object[] { }), paramCS);
            } else if (!module.getUsedModelType().contains(modelType)) {
                module.getUsedModelType().add(modelType); // Normally, all used model types are
                                                          // already present in the Library AST node
            }
        }
    }
    
    protected ModelType visitModelTypeCS(ModelTypeCS modelTypeCS, QvtOperationalFileEnv env,
			Module module, ResourceSet resolutionRS) throws SemanticException {
		if (modelTypeCS == null) {
			return null;
		}

		SimpleNameCS identifierCS = modelTypeCS.getIdentifierCS();
		ModelType modelType = QvtOperationalStdLibrary.INSTANCE.createModel(identifierCS != null ? identifierCS.getValue() : null);
		identifierCS.setAst(modelType);
		
		module.getEClassifiers().add(modelType);
		if(myCompilerOptions.isGenerateCompletionData()) {
			ASTBindingHelper.createCST2ASTBinding(modelTypeCS, modelType);
		}
		
		modelType.setStartPosition(modelTypeCS.getStartOffset());
		modelType.setEndPosition(modelTypeCS.getEndOffset());
		
		if (modelTypeCS.getComplianceKindCS() != null) {
			String complianceKind = visitLiteralExpCS(modelTypeCS.getComplianceKindCS(), env);
			if (complianceKind != null && complianceKind.length() > 0 && !QvtOperationalEnv.METAMODEL_COMPLIANCE_KIND_STRICT.equals(complianceKind)) {
				env.reportWarning(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_unsupportedMetamodelComplianceKind,
						new Object[] { complianceKind }), modelTypeCS.getComplianceKindCS());
			}
			modelType.setConformanceKind(complianceKind);
		}
		
		for (int i = 0, n = modelTypeCS.getPackageRefs().size(); i < n; ++i) {
			PackageRefCS packageRefCS = modelTypeCS.getPackageRefs().get(i);

			EPackage resolvedMetamodel = null;

			StringLiteralExpCS uriCS = packageRefCS.getUriCS();
			if (uriCS != null) {
				String metamodelUri = visitLiteralExpCS(uriCS, env);
				resolvedMetamodel = resolveMetamodel(env, metamodelUri, Collections.<String>emptyList(), uriCS, resolutionRS);
				uriCS.setAst(resolvedMetamodel);
			}
			
			PathNameCS pathNameCS = packageRefCS.getPathNameCS();
			if (pathNameCS != null && !pathNameCS.getSequenceOfNames().isEmpty()) {
				String metamodelName = QvtOperationalParserUtil.getStringRepresentation(
						pathNameCS, QvtOperationalTypesUtil.TYPE_NAME_SEPARATOR); 

				if (resolvedMetamodel == null) {
					resolvedMetamodel = resolveMetamodel(env, null, pathNameCS.getSequenceOfNames(), pathNameCS, resolutionRS);
				}
				else {
					resolvedMetamodel = checkMetamodelPath(env, resolvedMetamodel, pathNameCS, metamodelName);
				}
				
				pathNameCS.setAst(resolvedMetamodel);
			}
			
			if (resolvedMetamodel != null) {
				validateMetamodel(env, resolvedMetamodel, modelType, module, packageRefCS);				
				modelType.getMetamodel().add(resolvedMetamodel);
				
				for (++i; i < n; ++i) {
					packageRefCS = modelTypeCS.getPackageRefs().get(i);
					env.reportWarning(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_metamodelSinglePackageRefSupported,
							new Object[] { }), packageRefCS);
				}
				break;
			}
		}
		
		if (!modelTypeCS.getWhereStatements().isEmpty()) {
			int startOffset = modelTypeCS.getWhereStatements().get(0).getStartOffset();
			int endOffset = modelTypeCS.getWhereStatements().get(modelTypeCS.getWhereStatements().size()-1).getEndOffset();
			env.reportWarning(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_metamodelConditionsNotSupported,
					new Object[] { }), startOffset, endOffset);
		}
		
		if (modelType.getMetamodel().isEmpty()) {
			return null;
		}
		return modelType;
	}

	private EPackage checkMetamodelPath(QvtOperationalFileEnv env, EPackage resolvedMetamodel,
			PathNameCS pathNameCS, String metamodelName) {

		EList<String> path = pathNameCS.getSequenceOfNames();
		// lookup nested package started from package specified by URI
		EPackage localPackage = EmfMmUtil.lookupPackage(resolvedMetamodel, path);
		if (localPackage != null) {
			return localPackage;			
		}
		
		// lookup nested package started from root package of package specified by URI
		EPackage rootMetamodel = resolvedMetamodel;
		while (true) {
			if (rootMetamodel.getESuperPackage() == null) {
				break;
			}
			rootMetamodel = rootMetamodel.getESuperPackage();
		}
		
		if (rootMetamodel != resolvedMetamodel) {
			localPackage = EmfMmUtil.lookupPackage(rootMetamodel, path);
			
			boolean isContainedBy = false;
			EPackage curPkg = localPackage;
			while (curPkg != null) {
				if (curPkg == resolvedMetamodel) {
					isContainedBy = true;
					break;
				}
				curPkg = curPkg.getESuperPackage();
			}

			if (localPackage != null && isContainedBy) {
				return localPackage;			
			}
		}

		env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_metamodelPackageRefInconsistent,
				new Object[] { metamodelName }), pathNameCS);
		
		return null;		
	}

	private void validateMetamodel(QvtOperationalFileEnv env, EPackage resolvedMetamodel,
			ModelType modelType, Module module, CSTNode cstNode) throws SemanticException {

		String metamodelName = (resolvedMetamodel.getNsURI() == null ? resolvedMetamodel.getName() : resolvedMetamodel.getNsURI());
		List<EPackage> metamodels = modelType.getMetamodel();
		if (metamodels.contains(resolvedMetamodel)) {
			env.reportWarning(NLS.bind(ValidationMessages.DuplicateMetamodelImport,
					new Object[] { metamodelName }), cstNode);
		}
		if (module.getUsedModelType().contains(resolvedMetamodel)) {
			env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_metamodelAlreadyUsed,
					new Object[] { metamodelName }), cstNode);
		}		
	}
	
	private EPackage resolveMetamodel(QvtOperationalFileEnv env, String metamodelUri, List<String> packagePath,
			CSTNode cstNode, ResourceSet resolutionRS) throws SemanticException {
		EPackage resolvedMetamodel = null;
		String metamodelName = (packagePath.isEmpty() ? metamodelUri : packagePath.toString());
		try {
			MetamodelRegistry metamodelRegistry = env.getKernel().getMetamodelRegistry(env.getFile());
			
			List<EPackage> registerMetamodels = MetamodelResolutionHelper.registerMetamodel(
					env, metamodelUri, packagePath, resolutionRS, 
					metamodelRegistry, myCompilerOptions);
			
			if (registerMetamodels.isEmpty()) {
				env.reportError(NLS.bind(ValidationMessages.failedToResolveMetamodelError,
						new Object[] { metamodelName }), cstNode);
			}
			else {
				resolvedMetamodel = registerMetamodels.get(0);
			}
			
			if (registerMetamodels.size() > 1) {
				List<String> uriList = new ArrayList<String>(registerMetamodels.size());
				for (EPackage pack : registerMetamodels) {
					uriList.add(pack.getNsURI());					
				}
				env.reportWarning(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_metamodelNameAmbiguous,
						new Object[] { metamodelName, uriList }), cstNode);
			}
		} catch (RuntimeException e) {
			QvtPlugin.log(e);
			env.reportError(NLS.bind(ValidationMessages.failedToResolveMetamodelError,
					new Object[] { metamodelName }), cstNode);
		}
		
		return resolvedMetamodel;
	}
	
	protected EAnnotation legacyRenameCS(RenameCS renameCS, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) throws SemanticException {
		
		String message = ValidationMessages.DeprecatedRenameStatement;
		QvtOperationalUtil.reportWarning(env, message, renameCS.getStartOffset(), renameCS.getEndOffset());
		
		
		String originalName = visitLiteralExpCS(renameCS.getOriginalName(), env);
		String newName = renameCS.getSimpleNameCS().getValue();
		return renameProperty(renameCS.getTypeCS(), renameCS.getOriginalName(), originalName, renameCS.getSimpleNameCS(), newName, env);
	}

	private EAnnotation renameProperty(TypeCS typeCS, CSTNode oringinalPropertyCS, String originalName, CSTNode newNameCS, String newName,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) throws SemanticException {
		
		EClassifier type = visitTypeCS(typeCS, null, env);
		if (type == null) {
			return null;
		}
 
		EStructuralFeature originalProperty = env.lookupProperty(type, originalName);
		if (originalProperty == null) {
			QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.noPropertyInTypeError, originalName, 
					QvtOperationalTypesUtil.getTypeFullName(type)), oringinalPropertyCS);
			return null;
		}
		
		EStructuralFeature newProperty = env.lookupProperty(type, newName);
		if (newProperty != null) {
			QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.propertyAlreadyExistsInTypeError, newName,
			        QvtOperationalTypesUtil.getTypeFullName(type)), newNameCS);
			return null;
		}

		EAnnotation aliasTag = createTag(QvtOperationalEnv.TAG_ALIAS, newName, originalProperty);
		// FIXME - we should required QVT specific requirement env in this operation argument
		if(env instanceof QvtOperationalEnv) {
			QvtOperationalModuleEnv moduleEnv = getModuleContextEnv((QvtOperationalEnv) env);
			if(moduleEnv.getModuleContextType() != null) {
				moduleEnv.getModuleContextType().getOwnedTag().add(aliasTag);
			}
		}

		return aliasTag;
	}

	private List<org.eclipse.ocl.ecore.OCLExpression> visitMappingSectionCS(MappingSectionCS mappingSectionCS,
			QvtOperationalEnv env) throws SemanticException {
		List<org.eclipse.ocl.ecore.OCLExpression> statements = new ArrayList<org.eclipse.ocl.ecore.OCLExpression>(mappingSectionCS
				.getStatements().size());
		for (OCLExpressionCS statementCS : mappingSectionCS.getStatements()) {
			if (statementCS == null) {
				continue;
			}
			org.eclipse.ocl.ecore.OCLExpression statement = visitOclExpressionCS(statementCS, env);
			if (statement != null) {
				statements.add(statement);
			}
		}
		return statements;
	}

	protected void visitMappingMethodCS(MappingMethodCS methodCS, QvtOperationalEnv env, ImperativeOperation declaredOperation)
			throws SemanticException {
		methodCS.setAst(declaredOperation);
		
		if (methodCS instanceof ConstructorCS) {
			visitConstructorCS((ConstructorCS) methodCS, env, declaredOperation);
		}
		else if (methodCS instanceof MappingRuleCS) {
			visitMappingRuleCS((MappingRuleCS) methodCS, env, (MappingOperation)declaredOperation);
		}
		else {
			visitMappingQueryCS((MappingQueryCS) methodCS, env, declaredOperation);
		}

		// process operation qualifiers
		EList<QualifierKindCS> qualifiersCS = (methodCS.getMappingDeclarationCS() == null) ? null 
		        : methodCS.getMappingDeclarationCS().getQualifiers();
		
		if(declaredOperation instanceof MappingOperation) {
		    if (qualifiersCS != null) {
	            for (QualifierKindCS nextQualifierCS : qualifiersCS) {
	                if(nextQualifierCS != QualifierKindCS.ABSTRACT) {
	                    // only 'abstract' qualifier for mapping is currently supported 
	                    String errMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_unsupportedQualifierOnOperation, 
	                            nextQualifierCS.getName(), QvtOperationalParserUtil.getMappingStringRepresentation(methodCS));
	                    env.reportError(errMessage, QvtOperationalParserUtil.getImperativeOperationProblemNode(methodCS));
	                } else {
	                    QvtOperationalParserUtil.markAsAbstractMappingOperation((MappingOperation) declaredOperation);
	                }
	            }
		    }
		}
		
		Collection<QualifierKindCS> qualifierDups = QvtOperationalParserUtil.selectDuplicateQualifiers(qualifiersCS);
		for(QualifierKindCS duplicate : qualifierDups) {
			String errMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_duplicateQualifierOnOperation, 
					duplicate.getName(), QvtOperationalParserUtil.getMappingStringRepresentation(methodCS));			
			env.reportError(errMessage, QvtOperationalParserUtil.getImperativeOperationProblemNode(methodCS));
		}
	}

	private void visitConstructorCS(ConstructorCS methodCS, QvtOperationalEnv env, ImperativeOperation constructor) throws SemanticException {
		constructor.setEndPosition(methodCS.getEndOffset());

		if (constructor.getContext() == null) {
			env.reportError(ValidationMessages.ContextlessConstructor, methodCS.getMappingDeclarationCS());
		}
		else {
			if (!constructor.getContext().getEType().getName().equals(constructor.getName())) {
				env.reportError(ValidationMessages.ConstructorNameMismatch, methodCS.getMappingDeclarationCS());
			}
		}
		
		QvtOperationalEnv newEnv = env.getFactory().createOperationContext(env, constructor);
		newEnv.deleteElement(Environment.SELF_VARIABLE_NAME);
		
		VarParameter varResult = ExpressionsFactory.eINSTANCE.createVarParameter();
		varResult.setName(Environment.RESULT_VARIABLE_NAME);
		if (constructor.getContext() != null) {
			varResult.setEType(constructor.getContext().getEType());
		}
		varResult.setKind(DirectionKind.OUT);		
		varResult.setRepresentedParameter(varResult);
		newEnv.addElement(varResult.getName(), varResult, false);
		
        if(myCompilerOptions.isGenerateCompletionData()) {          
            ASTBindingHelper.createCST2ASTBinding(methodCS, constructor, newEnv);
        }

		OperationBody body = ExpressionsFactory.eINSTANCE.createConstructorBody();
		constructor.setBody(body);
		body.setStartPosition(methodCS.getMappingDeclarationCS().getEndOffset());
		body.setEndPosition(methodCS.getEndOffset());
        
        List<org.eclipse.ocl.ecore.OCLExpression> expressions = new ArrayList<org.eclipse.ocl.ecore.OCLExpression>(methodCS.getExpressions().size());
		for (OCLExpressionCS exprCS : methodCS.getExpressions()) {
			if (exprCS == null) {
				continue;
			}
			org.eclipse.ocl.ecore.OCLExpression expr = visitOclExpressionCS(exprCS, newEnv);
			if (expr != null) {
				expressions.add(expr);
			}
		}

		body.getContent().addAll(expressions);

		// adjust implicit variables for serialization
		consolidateImplicitVariables(newEnv);
		//
	}

	private ImperativeOperation visitMappingRuleCS(MappingRuleCS methodCS, QvtOperationalEnv env, final MappingOperation operation)
			throws SemanticException {
		env.registerMappingOperation(operation);
		operation.setEndPosition(methodCS.getEndOffset());

		if (QvtOperationalParserUtil.isContextual(operation) && operation.getContext().getKind() == DirectionKind.OUT) {
			env.reportError(ValidationMessages.ContextParamMustBeInOrInout, methodCS.getMappingDeclarationCS()
					.getDirectionKindCS());
		}

		QvtOperationalEnv newEnv = env.getFactory().createOperationContext(env, operation);		
        if(myCompilerOptions.isGenerateCompletionData()) {          
            ASTBindingHelper.createCST2ASTBinding(methodCS, operation, newEnv);
        }        

		org.eclipse.ocl.ecore.OCLExpression guard;
		if (methodCS.getGuard() != null) {
			guard = visitOclExpressionCS(methodCS.getGuard(), newEnv);
			if (guard != null) {
				EClassifier guardType = guard.getType();
				if (guardType != newEnv.getOCLStandardLibrary().getBoolean()) {
					newEnv.reportError(NLS.bind(ValidationMessages.mappingGuardNotBooleanError,
							new Object[] { QvtOperationalTypesUtil.getTypeFullName(guardType) }), methodCS.getGuard());
					guard = null;
				}
			}
		} else {
			guard = null;
		}

		List<org.eclipse.ocl.ecore.OCLExpression> inits = Collections.emptyList();
		if ((methodCS.getMappingBody() != null) && (methodCS.getMappingBody().getMappingInitCS() != null)) {
			inits = visitMappingSectionCS(methodCS.getMappingBody().getMappingInitCS(), newEnv);
		}

		MappingBody body = null;
		MappingBodyCS mappingBodyCS = (methodCS.getMappingBody() == null) ? null : methodCS.getMappingBody().getMappingBodyCS();
		if (mappingBodyCS != null) {
            body = visitMappingBodyCS(mappingBodyCS, newEnv, methodCS);
			if (body != null) {
				EClassifier returnType = operation.getEType();
				EClassifier bodyType = (body.getContent().size() == 1
						&& body.getContent().get(0) instanceof ObjectExp ? body.getContent().get(0).getType()
						: null);
                // TODO : Rewrite this when re-implementing ObjectExp
				if (bodyType != null && !QvtOperationalParserUtil.isAssignableToFrom(env, bodyType, returnType)) {
					/* checked by validation
					newEnv.reportError(NLS.bind(ValidationMessages.bodyTypeNotCompatibleWithReturnTypeError,
							new Object[] { QvtOperationalTypesUtil.getTypeFullName(bodyType), QvtOperationalTypesUtil.getTypeFullName(returnType) }),
						methodCS.getMappingDeclarationCS());
						*/
				}
			}
		} else {
			body = ExpressionsFactory.eINSTANCE.createMappingBody();
			body.setStartPosition(mappingBodyCS == null ? methodCS.getStartOffset() : mappingBodyCS.getStartOffset());			
			body.setEndPosition(mappingBodyCS == null ? methodCS.getEndOffset() : mappingBodyCS.getEndOffset());			
		}

		List<org.eclipse.ocl.ecore.OCLExpression> ends = Collections.emptyList();
		if ((methodCS.getMappingBody() != null) && (methodCS.getMappingBody().getMappingEndCS() != null)) {
			ends = visitMappingSectionCS(methodCS.getMappingBody().getMappingEndCS(), newEnv);
		}

		if (guard != null) {
			operation.getWhen().add(guard);
		}
		operation.setBody(body);
				
		if (body != null) {
			body.getInitSection().addAll(inits);
			body.getEndSection().addAll(ends);
		}

		checkAbstractOutParamsInitialized(operation.getResult(), methodCS, env);

		processMappingExtensions(methodCS, operation, env);
		
		// adjust implicit variables for serialization
		consolidateImplicitVariables(newEnv);
		//		
		return operation;
	}

	private static void consolidateImplicitVariables(QvtOperationalEnv newEnv) {
		EOperation eOperation = newEnv.getContextOperation();
		OperationBody body = null;
		if(eOperation instanceof ImperativeOperation) {
			body = ((ImperativeOperation)eOperation).getBody();
		}
		
		if(body == null) {
			return;
		}
		for (Variable<EClassifier, EParameter> var : newEnv.getImplicitVariables()) {
			if(var.eContainer() == null) {
				body.getVariable().add((org.eclipse.ocl.ecore.Variable)var);
			}			
		}
		for (Variable<EClassifier, EParameter> var : newEnv.getVariables()) {
			if(var.eContainer() == null) {
				body.getVariable().add((org.eclipse.ocl.ecore.Variable)var);
			}			
		}		
	}

	private void visitMappingQueryCS(MappingQueryCS methodCS, QvtOperationalEnv env, ImperativeOperation helper)
			throws SemanticException {
		helper.setEndPosition(methodCS.getEndOffset());

		if (QvtOperationalParserUtil.isContextual(helper) && helper.getContext().getKind() != DirectionKind.IN) {
			env.reportError(ValidationMessages.ContextParamMustBeIn, methodCS.getMappingDeclarationCS()
					.getSimpleNameCS());
		}

		QvtOperationalEnv newEnv = env.getFactory().createOperationContext(env, helper);
		//newEnv.defineOperationParameters(helper);

        if(myCompilerOptions.isGenerateCompletionData()) {          
            ASTBindingHelper.createCST2ASTBinding(methodCS, helper, newEnv);
        }

		OperationBody body = ExpressionsFactory.eINSTANCE.createOperationBody();
		helper.setBody(body);
		// FIXME - use CST info to set the flag
		//helper.setIsQuery(true);				
		body.setStartPosition(methodCS.getMappingDeclarationCS().getEndOffset());
		body.setEndPosition(methodCS.getEndOffset());
        
        List<org.eclipse.ocl.ecore.OCLExpression> expressions = new ArrayList<org.eclipse.ocl.ecore.OCLExpression>();
		for (OCLExpressionCS exprCS : methodCS.getExpressions()) {
			if (exprCS == null) {
				continue;
			}
			org.eclipse.ocl.ecore.OCLExpression expr = visitOclExpressionCS(exprCS, newEnv);
			if (expr != null) {
				expressions.add(expr);
			}
		}

		body.getContent().addAll(expressions);

		if (helper.getResult().size() <= 1) {
			EClassifier returnType = (helper.getResult().isEmpty() ? helper.getEType() : helper.getResult().get(0).getEType());
			EClassifier helperType = body.getContent().isEmpty() == false ? body.getContent().get(body.getContent().size() - 1).getType() : null;
			if (QvtOperationalEnv.MAIN.equals(helper.getName()) 
					&& (returnType == null || returnType == env.getOCLStandardLibrary().getOclVoid())) {
				// OK
			}
			else  if (helperType != null && !QvtOperationalParserUtil.isAssignableToFrom(env, returnType, helperType)) {
				env.reportError(NLS.bind(ValidationMessages.bodyTypeNotCompatibleWithReturnTypeError, new Object[] {
				        QvtOperationalTypesUtil.getTypeFullName(helperType), 
				        QvtOperationalTypesUtil.getTypeFullName(returnType) 
					}), 
					methodCS.getMappingDeclarationCS());
			}
			
			// adjust implicit variables for serialization
			consolidateImplicitVariables(newEnv);
			//
		}
		
		// add warning if single expression in non-simple body definition does not use return expression
		// as only during CST analysis we know that non-simple body variant is used
		// => query foo() : String = 'foo'; 
 		if(!methodCS.isIsSimpleDefinition() && helper.getResult().size() == 1 && body != null) {
 			EList<org.eclipse.ocl.ecore.OCLExpression> contents = body.getContent(); 			
 			if(contents.size() == 1 && contents.get(0) instanceof ReturnExp == false) {
 				env.reportWarning(ValidationMessages.useReturnExpForOperationResult, methodCS.getMappingDeclarationCS()); 				
 			}
		}		
	}
	
	/**
	 * TODO - make a common resolution operation, reusable in for ResolveInExp too. 
	 */
	private List<EOperation> resolveMappingOperationReference(ScopedNameCS identifierCS, QvtOperationalEnv env) {
		List<EOperation> result = Collections.emptyList();
		
		TypeCS typeCS = identifierCS.getTypeCS();
		EClassifier owningType = null;		
		if(typeCS != null) {
			owningType = visitTypeCS(typeCS, null, env);
			if(owningType != null && identifierCS.getName() != null) {
				result = env.lookupMappingOperations(TypeUtil.resolveType(env, owningType), identifierCS.getName());				
			}
		} else if(identifierCS.getName() != null) {	
			// TODO - review why lookup does not return MappingOperation type collection
			owningType = env.getModuleContextType();
			result = env.lookupMappingOperations(owningType, identifierCS.getName());
		}
		// filter out inherited mappings
		if(!result.isEmpty()) {
			List<EOperation> ownerLocalOpers = new ArrayList<EOperation>(result.size());
	        for (EOperation operation : result) {
	            EClassifier owner = env.getUMLReflection().getOwningClassifier(operation);
	            if ((typeCS == null && owner == null) || (TypeUtil.resolveType(env, owner) == owningType)) {
	                ownerLocalOpers.add(operation);
	            }	            
	        }
	        result = ownerLocalOpers;
		} 
		// validate the result
		if(result.isEmpty()) {
			if(owningType != null) {
				// unresolved type reported above by visiTypeCS(...)
				String errMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_unresolvedMappingOperationReference,
						QvtOperationalParserUtil.getStringRepresentation(identifierCS));
				env.reportError(errMessage, identifierCS);
			}
		} else if(result.size() > 1) {
			String errMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_ambiguousMappingOperationReference, 
					QvtOperationalParserUtil.getStringRepresentation(identifierCS));
			env.reportError(errMessage, identifierCS);			
		}
		
		return result;
	}
	
	private void processMappingExtensions(MappingRuleCS mappingCS, MappingOperation operation, QvtOperationalEnv env) {
		if((mappingCS.getMappingDeclarationCS() != null) && !mappingCS.getMappingDeclarationCS().getMappingExtension().isEmpty()) {
			for (MappingExtensionCS extensionCS : mappingCS.getMappingDeclarationCS().getMappingExtension()) {
				MappingExtensionKindCS kind = extensionCS.getKind();
				
				for (ScopedNameCS identifierCS : extensionCS.getMappingIdentifiers()) {
					List<EOperation> mappings = resolveMappingOperationReference(identifierCS, env);
					if(mappings.size() == 1) {
						boolean isAdded = false;
						MappingOperation extendedMapping = (MappingOperation)mappings.get(0);
						if(kind == MappingExtensionKindCS.INHERITS) {
							isAdded = operation.getInherited().add(extendedMapping);
							MappingExtensionHelper.bind2SourceElement(operation, identifierCS, kind);
						} 
						else if(kind == MappingExtensionKindCS.MERGES) {
							isAdded = operation.getMerged().add(extendedMapping);
							MappingExtensionHelper.bind2SourceElement(operation, identifierCS, kind);							
						} 
						else if(kind == MappingExtensionKindCS.DISJUNCTS) {
							isAdded = operation.getDisjunct().add(extendedMapping);
							MappingExtensionHelper.bind2SourceElement(operation, identifierCS, kind);							
						}

						if(!isAdded) {
							// Note: duplicates checked here as the mapping AST is {unique, ordered}
							env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_duplicateMappingRereferenceInExtensionKind, 
								kind.getName(), QvtOperationalParserUtil.getStringRepresentation(identifierCS)), 
								identifierCS);
						}

						if(getCompilerOptions().isGenerateCompletionData()) {
							ASTBindingHelper.createCST2ASTBinding(identifierCS, extendedMapping, false, null);
						}
					}
				}
			}
		}
	}
	
	protected boolean visitMappingDeclarationCS(MappingMethodCS mappingMethodCS, QvtOperationalModuleEnv env, ImperativeOperation operation) throws SemanticException {
	    MappingDeclarationCS mappingDeclarationCS = mappingMethodCS.getMappingDeclarationCS();
		if (mappingDeclarationCS == null) {
			return false;
		}
		
		operation.setIsBlackbox(mappingMethodCS.isBlackBox());
		operation.setStartPosition(mappingDeclarationCS.getStartOffset());
		operation.setEndPosition(mappingDeclarationCS.getEndOffset());
		operation.setName(mappingDeclarationCS.getSimpleNameCS().getValue());		

		DirectionKind contextDirection = DirectionKind.IN;
		if ((mappingDeclarationCS.getDirectionKindCS() != null) && (mappingDeclarationCS.getDirectionKindCS().getDirectionKind() != DirectionKindEnum.DEFAULT)) {
			contextDirection = (DirectionKind) ExpressionsFactory.eINSTANCE.createFromString(
					ExpressionsPackage.eINSTANCE.getDirectionKind(), mappingDeclarationCS.getDirectionKindCS()
							.getDirectionKind().getLiteral());
		}

		TypeCS contextTypeCS = mappingDeclarationCS.getContextType();
		EClassifier contextType;
		if (contextTypeCS != null) {
			contextType = visitTypeCS(contextTypeCS, contextDirection, env);
			if (contextType == null) {
				contextType = env.getModuleContextType();
			}
		} else {
			contextType = env.getModuleContextType();
		}

		boolean isEntryPoint = QvtOperationalEnv.MAIN.equals(mappingDeclarationCS.getSimpleNameCS().getValue());
		boolean isMapping = ExpressionsPackage.eINSTANCE.getMappingOperation().getClassifierID() == 
							operation.eClass().getClassifierID();
		boolean createMappingParams = isEntryPoint || isMapping;
		
		List<EParameter> params = operation.getEParameters();
		for (ParameterDeclarationCS paramCS : mappingDeclarationCS.getParameters()) {
			VarParameter param = visitParameterDeclarationCS(paramCS, createMappingParams, env, isEntryPoint);
			if (param == null) {
				return false;
			}

			params.add(param);
		}
				
		if (contextTypeCS != null) {
			MappingParameter mappingParam = createMappingParams ? ExpressionsFactory.eINSTANCE.createMappingParameter() : null;
			VarParameter varContext = createMappingParams ? mappingParam : ExpressionsFactory.eINSTANCE.createVarParameter();
			
			varContext.setRepresentedParameter(varContext);
			varContext.setName(Environment.SELF_VARIABLE_NAME);
			varContext.setStartPosition(contextTypeCS.getStartOffset());
			varContext.setEndPosition(contextTypeCS.getEndOffset());
			
			varContext.setEType(contextType);
			varContext.setKind(contextDirection);
			if(mappingParam != null) {
				if (mappingParam.getExtent() == null) {
					mappingParam.setExtent(env.resolveModelParameter(contextType, varContext.getKind()));
				}
			}
		
			operation.setContext(varContext);
		}		
		
		EList<ParameterDeclarationCS> resultParams = mappingDeclarationCS.getResult();
		for(ParameterDeclarationCS nextResultParamCS : resultParams) {
			TypeSpecPair nextResultTypeSpec = visitTypeSpecCS(nextResultParamCS.getTypeSpecCS(), DirectionKind.OUT, env);
			if (nextResultTypeSpec.myType == null) {
				nextResultTypeSpec.myType = env.getOCLStandardLibrary().getOclVoid();
			}
			
			VarParameter varResult = createMappingResultParam(nextResultParamCS, createMappingParams, nextResultTypeSpec, env);
			if(resultParams.size() == 1) {
				varResult.setName(Environment.RESULT_VARIABLE_NAME);
				if(nextResultParamCS.getSimpleNameCS() != null) {
					String message = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_resultParamNameNotAllowed, nextResultParamCS.getSimpleNameCS().getValue());
					env.reportError(message, nextResultParamCS.getSimpleNameCS());
				}
				
				if(nextResultParamCS.isSetDirectionKind()) {
					env.reportError(ValidationMessages.QvtOperationalVisitorCS_resultParamNameDirectionNotAllowed, nextResultParamCS);
				}
			}
			operation.getResult().add(varResult);
			
			if (isEntryPoint) {
				env.reportWarning(ValidationMessages.QvtOperationalVisitorCS_entryPointReturnDeprecated,
						nextResultParamCS.getTypeSpecCS());
			}
	
		}
		
		// set operation return type
		if(resultParams.isEmpty()) {
			// no result parameter should exist
			operation.setEType(env.getOCLStandardLibrary().getOclVoid());
		} else if(resultParams.size() > 1) {
			// create extra tuple-type the result type
			operation.setEType(createResultTupleType(operation, env));
		} else {
			operation.setEType(operation.getResult().get(0).getEType());
		}

		return true;
	}

	private EClassifier createResultTupleType(ImperativeOperation operation, QvtOperationalEnv env) {
		EList<VarParameter> resultParams = operation.getResult();
		assert resultParams.size() > 1;
		
		List<Variable<EClassifier, EParameter>> parts = new ArrayList<Variable<EClassifier,EParameter>>(resultParams.size());		
		for(VarParameter resultParam : resultParams) {
			Variable<EClassifier, EParameter> var = oclFactory.createVariable();
			uml.setName(var, resultParam.getName());
			uml.setType(var, resultParam.getEType());
			
			parts.add(var);
		}		
		return env.getTypeResolver().resolve((EClassifier)env.getOCLFactory().createTupleType(parts));
	}
		
	private VarParameter createMappingResultParam(ParameterDeclarationCS paramCS, boolean createMappingParam, TypeSpecPair typeSpec, QvtOperationalEnv env) {
		MappingParameter mappingParam = createMappingParam ? ExpressionsFactory.eINSTANCE.createMappingParameter() : null;
		VarParameter varResult = createMappingParam ? mappingParam : ExpressionsFactory.eINSTANCE.createVarParameter();
		varResult.setStartPosition(paramCS.getStartOffset());
		varResult.setEndPosition(paramCS.getEndOffset());
		
		SimpleNameCS simpleNameCS = paramCS.getSimpleNameCS();
		if(simpleNameCS != null) {
			simpleNameCS.setAst(varResult);
			varResult.setName(simpleNameCS.getValue());
		} 
		
		if(varResult.getName() == null){
			varResult.setName(""); //$NON-NLS-1$
		}
		
		varResult.setEType(typeSpec.myType);
		varResult.setKind(DirectionKind.OUT);		
		
		if(mappingParam != null) {
			mappingParam.setExtent(typeSpec.myExtent);
			if (mappingParam.getExtent() == null) {
				QvtOperationalModuleEnv moduleEnv = getModuleContextEnv(env);
				mappingParam.setExtent(moduleEnv.resolveModelParameter(typeSpec.myType, varResult.getKind()));
			}
		}
		
		if(getCompilerOptions().isGenerateCompletionData()) {
			ASTBindingHelper.createCST2ASTBinding(paramCS, varResult);
		}
		
		varResult.setRepresentedParameter(varResult);
		
		paramCS.setAst(varResult);		
		
		return varResult;
	}

	@SuppressWarnings("unchecked")
	private org.eclipse.ocl.ecore.OCLExpression visitAssignStatementCS(AssignStatementCS expressionCS, 
	        Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
	        EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {

	    OCLExpressionCS lValueCS = expressionCS.getLValueCS();
	    if ((lValueCS instanceof OperationCallExpCS)
	    		|| !(lValueCS instanceof VariableExpCS) && !(lValueCS instanceof FeatureCallExpCS)) {
	        QvtOperationalUtil.reportError(env, ValidationMessages.notAnLValueError, lValueCS);
	        return null;
	    }

	    org.eclipse.ocl.ecore.OCLExpression rightExpr = visitOclExpressionCS(expressionCS.getOclExpressionCS(), env);
	    if (rightExpr == null) {
	        return null;
	    }

	    org.eclipse.ocl.ecore.OCLExpression lValue = oclExpressionCS(lValueCS, env);
	    if (lValue instanceof VariableExp<?, ?>) {
	    	VariableExp<EClassifier, EParameter> variableExp = (VariableExp<EClassifier, EParameter>) lValue;
		    String referredVariableName = variableExp.getName();
		    if (Environment.SELF_VARIABLE_NAME.equals(referredVariableName)) {
		        QvtOperationalUtil.reportError(env, ValidationMessages.CantAssignToSelf, lValueCS);
		        return null;
		    }


		    if (QvtOperationalEnv.THIS.equals(referredVariableName)) {
		        QvtOperationalUtil.reportError(env, ValidationMessages.CantAssignToThis, lValueCS);
		        return null;
		    }
		    Variable<EClassifier, EParameter> variable = variableExp.getReferredVariable();
	        if (variable == null) { // We mustn't be here. Must have been detected by OCL
	            QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.unresolvedNameError, new Object[] { referredVariableName }),
	                    lValueCS);
	            return null;
	        }
	        QvtOperationalParserUtil.validateVariableModification(variable, lValueCS, null, env, true);         
	        QvtOperationalParserUtil.validateAssignment(false, variable.getName(), variable.getType(), rightExpr.getType(),
	        		expressionCS.isIncremental(), lValueCS, env);
	    } else if (lValue instanceof PropertyCallExp<?, ?>) {
	        PropertyCallExp<EClassifier, EStructuralFeature> propertyCallExp = (PropertyCallExp<EClassifier, EStructuralFeature>) lValue;
	        EStructuralFeature property = propertyCallExp.getReferredProperty();
	        if (property == null) { // We mustn't be here. This case is to be handled below
	            QvtOperationalUtil.reportError(env, ValidationMessages.invalidPropertyReferenceError, lValueCS);
	            return null;
	        } else {
	            if (!property.isChangeable()) {
	                QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.ReadOnlyProperty, property.getName()), lValueCS);
	            } else {
	                OCLExpression<EClassifier> source = propertyCallExp.getSource();
	                if (source instanceof VariableExp) {
	                    VariableExp<EClassifier, EParameter> sourceExp = (VariableExp<EClassifier, EParameter>) source;
	                    Variable<EClassifier, EParameter> sourceVariable = sourceExp.getReferredVariable();
	                    QvtOperationalParserUtil.validateVariableModification(sourceVariable, lValueCS, property, env, false);
	                }
	                QvtOperationalParserUtil.validateAssignment(true, property.getName(), env.getUMLReflection().getOCLType(property),
	                		rightExpr.getType(), expressionCS.isIncremental(), lValueCS, env);
	            }
	        }
	    } else {
	        // TODO: This code is to be transferred to the AST validator
	        if ((lValue != null) && !(lValue instanceof InvalidLiteralExp)) { // to avoid induced errors on unresolved variables
	            QvtOperationalUtil.reportError(env, ValidationMessages.notAnLValueError, lValueCS);
	            return null;
	        }
	    }

	    AssignExp result = ImperativeOCLFactory.eINSTANCE.createAssignExp();
	    result.setStartPosition(expressionCS.getStartOffset());
	    result.setEndPosition(expressionCS.getEndOffset());
	    result.getValue().add(rightExpr);
	    result.setIsReset(!expressionCS.isIncremental());
	    result.setLeft(lValue);
	    if (lValue != null) {
	    	result.setType(lValue.getType());
	    }
	    return result;
	}
	
    private VarParameter visitParameterDeclarationCS(ParameterDeclarationCS paramCS, boolean createMappingParam, 
			QvtOperationalModuleEnv env, boolean isOutAllowed) throws SemanticException {
		DirectionKindEnum directionKindEnum = paramCS.getDirectionKind();
		if (directionKindEnum == DirectionKindEnum.DEFAULT) {
		    directionKindEnum = DirectionKindEnum.IN;
		}
        DirectionKind directionKind = (DirectionKind) ExpressionsFactory.eINSTANCE.createFromString(
				ExpressionsPackage.eINSTANCE.getDirectionKind(), directionKindEnum.getLiteral());
		TypeSpecPair typeSpec = visitTypeSpecCS(paramCS.getTypeSpecCS(), directionKind, env);
		if (typeSpec.myType == null) {
			typeSpec.myType = env.getOCLStandardLibrary().getOclVoid();
		}

		MappingParameter mappingParam = createMappingParam ? ExpressionsFactory.eINSTANCE.createMappingParameter() : null;
		VarParameter varParam = createMappingParam ? mappingParam : ExpressionsFactory.eINSTANCE.createVarParameter();
		varParam.setRepresentedParameter(varParam);
		varParam.setStartPosition(paramCS.getStartOffset());
		varParam.setEndPosition(paramCS.getEndOffset());
		
		SimpleNameCS paramNameCS = paramCS.getSimpleNameCS();
		if(paramNameCS != null) {
			paramNameCS.setAst(varParam);
			varParam.setName(paramNameCS.getValue());
		} else {
			varParam.setName(""); //$NON-NLS-1$
		}
		varParam.setEType(typeSpec.myType);
		varParam.setKind(directionKind);		

		if(mappingParam != null) {
			mappingParam.setExtent(typeSpec.myExtent);
			if (mappingParam.getExtent() == null) {
				mappingParam.setExtent(env.resolveModelParameter(typeSpec.myType, directionKind));
				if (mappingParam.getExtent() == null && directionKind == DirectionKind.OUT) {
					env.reportError(ValidationMessages.OutParamWithoutExtent, paramCS);
				}
			}
		}
		
		if (!isOutAllowed && varParam.getKind() == DirectionKind.OUT) {
			env.reportError(ValidationMessages.OutParamsNotSupported, paramCS);
		}

        // AST binding
        if(myCompilerOptions.isGenerateCompletionData()) {		
			ASTBindingHelper.createCST2ASTBinding(paramCS, varParam);
        }
		//
		
        paramCS.setAst(varParam);
        
		return varParam;
	}

	protected VariableInitExp variableInitializationCS(VariableInitializationCS varInitCS, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {

		boolean hasExplicitInitExpression = varInitCS.getOclExpressionCS() != null;
		boolean hasDeclType = varInitCS.getTypeCS() != null;
		String varName = varInitCS.getSimpleNameCS().getValue();		
		
		VariableInitExp result = ImperativeOCLFactory.eINSTANCE.createVariableInitExp();
		result.setStartPosition(varInitCS.getStartOffset());
		result.setEndPosition(varInitCS.getEndOffset());		
		
		result.setName(varName);
		result.setWithResult(varInitCS.isWithResult());
		
		org.eclipse.ocl.ecore.Variable referredVar = EcoreFactory.eINSTANCE.createVariable();
		result.setReferredVariable(referredVar);
		
		referredVar.setName(varName);
		
		EClassifier declaredType = null;		
		EClassifier derivedInitType = null;		
		if (hasDeclType) {
			// Note: visiting typeCS reports a type resolution issue  
			declaredType = visitTypeCS(varInitCS.getTypeCS(), null, env);
		}
		
		if(hasExplicitInitExpression) {
			org.eclipse.ocl.ecore.OCLExpression exp = visitOclExpressionCS(varInitCS.getOclExpressionCS(), env);
		    referredVar.setInitExpression(exp);
		    if(exp != null) {
		    	derivedInitType = referredVar.getInitExpression().getType();
		    }
		}

		referredVar.setType(declaredType != null ? declaredType : derivedInitType);
		result.setType(referredVar.getType());
		
		if (!hasExplicitInitExpression && declaredType != null) {
			// FIXME - should not be initialized at AST level but at evaluation level			
	    	org.eclipse.ocl.ecore.OCLExpression defaultInitializationValue = createDefaultInitializationValue(declaredType, env);
	        if (defaultInitializationValue == null) {
	            NullLiteralExp<EClassifier> nullLiteralExp = oclFactory.createNullLiteralExp();
	            nullLiteralExp.setType(getOclVoid());
	            defaultInitializationValue = (org.eclipse.ocl.ecore.NullLiteralExp)nullLiteralExp;
	        }
	        
	        referredVar.setInitExpression(defaultInitializationValue);
		}
				
		OCLExpression<EClassifier> initExpression = referredVar.getInitExpression();		
		if (declaredType != null && derivedInitType != null) {
			if(!QvtOperationalParserUtil.isAssignableToFrom(env, declaredType, derivedInitType)) {
				QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.TypeMismatchError, new Object[] { 
							QvtOperationalTypesUtil.getTypeFullName(declaredType),  
							QvtOperationalTypesUtil.getTypeFullName(derivedInitType) 
				}), initExpression.getStartPosition(), initExpression.getEndPosition());
			}
		}
		
		if (env.lookupLocal(varName) != null) {
			QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.NameAlreadyDefinedError, 
					new Object[] { varName }), result.getStartPosition(), result.getEndPosition());
		} else {
			env.addElement(referredVar.getName(), referredVar, true);
		}			
		
        // AST binding
        if(myCompilerOptions.isGenerateCompletionData()) {
			if(result.getName() != null) {
				Variable<EClassifier, EParameter> envVar = env.lookupLocal(result.getName());
				if(envVar != null) {
					ASTBindingHelper.createCST2ASTBinding(varInitCS, envVar);
				}	        
			}
        }
		//		
        
        varInitCS.setAst(result);
		
		return result;
	}
			
	private ReturnExp visitReturnExpCS(ReturnExpCS returnExpCS, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		
		ReturnExp result = ImperativeOCLFactory.eINSTANCE.createReturnExp();
		initStartEndPositions(result, returnExpCS);
		if(returnExpCS.getValue() != null) {
			org.eclipse.ocl.ecore.OCLExpression value = oclExpressionCS(returnExpCS.getValue(), env);
			result.setValue(value);
			if(value != null) {
				result.setType(value.getType());
			}
		}
		
		if(result.getType() == null) {
			result.setType(env.getOCLStandardLibrary().getOclVoid());
		}
		
		return result;
	}
	
    private MappingBody visitMappingBodyCS(MappingBodyCS mappingBodyCS, QvtOperationalEnv env, MappingMethodCS mappingRuleCS)
			throws SemanticException {

		MappingBody body = ExpressionsFactory.eINSTANCE.createMappingBody();
		body.setStartPosition(mappingBodyCS.getStartOffset());
		body.setEndPosition(mappingBodyCS.getEndOffset());
		
        //Spec 07-07-07: 8.2.1.19 MappingBody
        //The rule for interpreting a body in which there is no population keyword is as follows:
        //(1) If the mapping operation defines a unique result, the list of expressions in the body is the list of expressions of the -
        //unique - implicit object expression (see ObjectExp) contained by the population section.
        //(2) If the mapping operation defines more than one result, the list of expressions in the body is the list of expressions of
        //the population section.
        if (!mappingBodyCS.isHasPopulationKeyword()) {
            MappingDeclarationCS mappingDeclarationCS = mappingRuleCS.getMappingDeclarationCS();
            if (mappingDeclarationCS != null) {
                boolean isUniqueResult = mappingDeclarationCS.getResult().size() == 1; 
                boolean isImplicitContext = mappingDeclarationCS.getResult().isEmpty() 
                && (mappingDeclarationCS.getContextType() != null)
                && (mappingDeclarationCS.getDirectionKindCS() != null)
                && (mappingDeclarationCS.getDirectionKindCS().getDirectionKind() == DirectionKindEnum.INOUT);
                if (isUniqueResult || isImplicitContext) {
                	ObjectExpCS implicitObjectExpCS = org.eclipse.m2m.internal.qvt.oml.cst.CSTFactory.eINSTANCE.createObjectExpCS();
                    implicitObjectExpCS.setIsImplicit(true);

                    SimpleNameCS resultVar = CSTFactory.eINSTANCE.createSimpleNameCS();
                    String implicitVarName = isUniqueResult ? Environment.RESULT_VARIABLE_NAME : Environment.SELF_VARIABLE_NAME; 
                    resultVar.setValue(implicitVarName);

                    implicitObjectExpCS.setSimpleNameCS(resultVar);
                    implicitObjectExpCS.setStartOffset(mappingBodyCS.getStartOffset());
                    implicitObjectExpCS.setEndOffset(mappingBodyCS.getEndOffset());

                    implicitObjectExpCS.getExpressions().addAll(mappingBodyCS.getStatements());
                    mappingBodyCS.getStatements().add(implicitObjectExpCS);

                    ObjectExp objectExp = visitObjectExpCS(implicitObjectExpCS, env, false);
                    body.getContent().add(objectExp);
                    return body;
				}
			}
		}
        List<org.eclipse.ocl.ecore.OCLExpression> expressions = visitMappingSectionCS(mappingBodyCS, env);
        body.getContent().addAll(expressions);
		
		return body;
	}

	private int getStartOffset(ASTNode astNode, CSTNode cstNodeOpt) {
		if(cstNodeOpt != null) {
			return cstNodeOpt.getStartOffset();
		}
		return astNode.getStartPosition();
	}
	
	private int getEndOffset(ASTNode astNode, CSTNode cstNodeOpt) {
		if(cstNodeOpt != null) {
			return cstNodeOpt.getEndOffset();
		}
		return astNode.getEndPosition();
	}	
	
	private void validateObjectExp(ObjectExp objectExp, ObjectExpCS objectExpCS, QvtOperationalEnv env) {
		EClass derivedInstantiatedClass = objectExp.getInstantiatedClass();		
		Variable<EClassifier, EParameter> referredObject  = objectExp.getReferredObject();
		if(derivedInstantiatedClass == null && (referredObject != null && QVTUMLReflection.isUserModelElement(referredObject.getType()))) {
			derivedInstantiatedClass = (EClass)referredObject.getType();
		}
		
        if((derivedInstantiatedClass == null) || !QVTUMLReflection.isUserModelElement(derivedInstantiatedClass)) {
			CSTNode problemCS = null;
			if(objectExpCS != null) {
                problemCS = objectExpCS.getTypeSpecCS();
                if(problemCS == null) {
                    problemCS = objectExpCS.getSimpleNameCS();
				}
				if(problemCS == null) {
                    problemCS = objectExpCS;
				}
			}

			int startOffs = getStartOffset(objectExp, problemCS);
			int endOffs = getEndOffset(objectExp, problemCS);
			if(referredObject != null)	{ 
				if(referredObject.getType() != null && (referredObject.getType() instanceof CollectionType == false)) { 
					// we failed to figure out the class but type is available, let's report it's classifier only 
					env.reportError(NLS.bind(ValidationMessages.nonModelTypeError,
							QvtOperationalParserUtil.safeGetQualifiedName(env, referredObject.getType())), startOffs, endOffs);
				}
			}
		}
				 
		// check for the type conformance only if instantiatedClass class was explicitly set
		if(referredObject != null) {
			if(objectExp.getType() != null) {				
				CSTNode problemCS = null;
				if(objectExpCS != null) {
					problemCS = objectExpCS.getSimpleNameCS();
					if(problemCS == null) {
						problemCS = objectExpCS.getTypeSpecCS() != null ? objectExpCS.getTypeSpecCS() : objectExpCS;						
					}
				}
				
				EClassifier referredType = referredObject.getType();
				EClassifier actualType = objectExp.getType();
				// Note : invalid AST might have type node missing, so just check, a problem would be reported by variable validation
				if(referredType != null && (TypeUtil.getRelationship(env, actualType, referredType) & UMLReflection.SAME_TYPE) == 0) {				
					String actualTypeName = QvtOperationalParserUtil.safeGetQualifiedName(env, actualType);
					String referredTypeName = QvtOperationalParserUtil.safeGetQualifiedName(env, referredType);
					String errorMessage = NLS.bind(ValidationMessages.QvtOperationalVisitorCS_instatiatedTypeDoesNotConformToReferredType,  
							actualTypeName, referredTypeName);
	
					env.reportError(errorMessage, getStartOffset(objectExp, problemCS), getEndOffset(objectExp, problemCS));
				}
				
				if(referredObject.getRepresentedParameter() instanceof MappingParameter) {
					MappingParameter mappingPar = (MappingParameter) referredObject.getRepresentedParameter();
					if(mappingPar.getKind() == DirectionKind.IN) {
						env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_canNotModifyINParameter, referredObject.getName()), problemCS);
					}
				}
			}
		} else if(derivedInstantiatedClass != null && (derivedInstantiatedClass.isAbstract() || derivedInstantiatedClass.isInterface())) {			
			// always creates a new instance, ensure non-abstract type. 
			String typeName = QvtOperationalParserUtil.safeGetQualifiedName(env, derivedInstantiatedClass);
			env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_canNotInstantiateAbstractType, typeName), objectExpCS);
		}
	}

	private org.eclipse.ocl.ecore.OCLExpression visitExpressionStatementCS(ExpressionStatementCS expressionCS, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		
		return visitOclExpressionCS(expressionCS.getOclExpressionCS(), env);
	}

	private static EStructuralFeature createESFeature(EClassifier type) {
		if(type instanceof EClass) {
			return org.eclipse.emf.ecore.EcoreFactory.eINSTANCE.createEReference();
		}
		return org.eclipse.emf.ecore.EcoreFactory.eINSTANCE.createEAttribute();
	}
	
	private EStructuralFeature visitConfigPropertyCS(ConfigPropertyCS propCS, QvtOperationalFileEnv env) {
		SimpleNameCS simpleNameCS = propCS.getSimpleNameCS();
		String name = simpleNameCS != null ? simpleNameCS.getValue() : ""; //$NON-NLS-1$

		EClassifier type = null;
		if (propCS.getTypeCS() != null) {
			type = visitTypeCS(propCS.getTypeCS(), null, env);
			if (type != null) {
				if (!QvtOperationalUtil.isCreateFromStringSupported(type)) {
					env.reportError(NLS.bind(ValidationMessages.ConfigPropertyTypeUnsupported, new Object[] { type
							.getName() }), propCS.getTypeCS());
				}
			}
		} else {
			env.reportError(NLS.bind(ValidationMessages.ConfigPropertyMustHaveType,
					new Object[] { name }), simpleNameCS != null ? simpleNameCS : propCS);
		}

		EStructuralFeature feature = createESFeature(type);
		simpleNameCS.setAst(feature);
		
		feature.setName(name);
		feature.setEType(type);

		ASTSyntheticNode astNode = ASTSyntheticNodeAccess.createASTNode(feature);
		astNode.setStartPosition(propCS.getStartOffset());
		astNode.setEndPosition(propCS.getEndOffset());

		return feature;
	}

	private EStructuralFeature visitLocalPropertyCS(LocalPropertyCS propCS, QvtOperationalEnv env) {
		EClassifier type = null;
		if (propCS.getTypeCS() != null) {
			type = visitTypeCS(propCS.getTypeCS(), null, env);
		}

		EStructuralFeature prop = createESFeature(type);
		SimpleNameCS simpleNameCS = propCS.getSimpleNameCS();
		simpleNameCS.setAst(prop);
		
		prop.setName(simpleNameCS.getValue());		
		prop.setEType(type);

		ASTSyntheticNode astNode = ASTSyntheticNodeAccess.createASTNode(prop);
		astNode.setStartPosition(propCS.getStartOffset());
		astNode.setEndPosition(propCS.getEndOffset());
		
		OCLExpression<EClassifier> exp = null;
		if (propCS.getOclExpressionCS() != null) {
			exp = visitOclExpressionCS(propCS.getOclExpressionCS(), env);
			QvtOperationalParserUtil.setInitExpression(prop, exp);			
		}
		
		if (prop.getEType() == null && exp != null) {
			prop.setEType(exp.getType());
		}
		
		if(exp != null) {
			EClassifier realType = exp.getType();
			EClassifier declaredType = prop.getEType();
			if (!QvtOperationalParserUtil.isAssignableToFrom(env, declaredType, realType)) {
				env.reportError(NLS.bind(ValidationMessages.TypeMismatchError,
						new Object[] { QvtOperationalTypesUtil.getTypeFullName(declaredType), QvtOperationalTypesUtil.getTypeFullName(realType) }),
						astNode.getStartPosition(), astNode.getEndPosition());
			}
		}

		return prop;
	}

	private ContextualProperty visitContextualPropertyCS(ContextualPropertyCS propCS, QvtOperationalFileEnv env) {
		ContextualProperty prop = ExpressionsFactory.eINSTANCE.createContextualProperty();
		prop.setStartPosition(propCS.getStartOffset());
		prop.setEndPosition(propCS.getEndOffset());
		
		ScopedNameCS scopedNameCS = propCS.getScopedNameCS();
		scopedNameCS.setAst(prop);
		prop.setName(scopedNameCS.getName());

		EClassifier type = null;
		if (propCS.getTypeCS() != null) {
			type = visitTypeCS(propCS.getTypeCS(), null, env);
			if (type == null) {
				return prop;
			}
		}		

		org.eclipse.ocl.ecore.OCLExpression exp = null;
		if (propCS.getOclExpressionCS() != null) {
			env.reportWarning(NLS.bind(ValidationMessages.IntermediatePropertiesInitNotSupported,
						new Object[] { }), propCS.getOclExpressionCS());			
			exp = visitOclExpressionCS(propCS.getOclExpressionCS(), env);
		}
		
		if (type == null && exp != null) {
			type = exp.getType();
		}
		if (type == null) {
			return null;
		}
		
		prop.setEType(type);
		prop.setInitExpression(exp);
		
		if (exp != null) {
			EClassifier realType = exp.getType();
			EClassifier declaredType = prop.getEType();
			if (!QvtOperationalParserUtil.isAssignableToFrom(env, declaredType, realType)) {
				env.reportError(NLS.bind(ValidationMessages.TypeMismatchError,
						new Object[] { QvtOperationalTypesUtil.getTypeFullName(declaredType), QvtOperationalTypesUtil.getTypeFullName(realType) }),
						prop.getStartPosition(), prop.getEndPosition());
			}
		}
		
		EClassifier contextType = visitTypeCS(scopedNameCS.getTypeCS(), null, env);
		if (contextType != null) {
			if(contextType instanceof EClass) {
				prop.setContext((EClass)contextType);
			} else {
				env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_ContextualPropertyTypeIsNotClass, 
								new Object[] { prop.getName() }), scopedNameCS.getTypeCS());
			}
		}
		else {
			env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_ContextualPropertyTypeIsMissed, 
					new Object[] { }), scopedNameCS);
		}
		
		return prop;
	}
		
	protected EStructuralFeature visitModulePropertyCS(ModulePropertyCS propCS, QvtOperationalFileEnv env) {
		EStructuralFeature result = null;		
		if (propCS instanceof ConfigPropertyCS) {
			result = visitConfigPropertyCS((ConfigPropertyCS) propCS, env);
		}
		else if (propCS instanceof LocalPropertyCS) {
			result = visitLocalPropertyCS((LocalPropertyCS) propCS, env);
		}
		else if (propCS instanceof ContextualPropertyCS) {
			result = visitContextualPropertyCS((ContextualPropertyCS) propCS, env);
		}
		else {
			assert false : "Unexpected CS class: " + propCS; //$NON-NLS-1$
		}
		
        // AST binding
        if (myCompilerOptions.isGenerateCompletionData()) {
        	propCS.setAst(result);

        	if(result instanceof ASTNode) {
        		ASTBindingHelper.createCST2ASTBinding(propCS, (ASTNode)result, env);
        	} else if (result != null) {
        		ASTSyntheticNode astNode = ASTSyntheticNodeAccess.getASTNode(result); 
        		ASTSyntheticNodeAccess.setCST(astNode, propCS);
        	}
        }
		//
		return result;
	}

    private org.eclipse.ocl.ecore.OCLExpression visitResolveExpCS(ResolveExpCS resolveExpCS, QvtOperationalEnv env) {
        ResolveExp resolveExp = populateResolveExp(resolveExpCS, env, ExpressionsFactory.eINSTANCE.createResolveExp());
        if (resolveExp.getSource() == null) {
            env.reportError(NLS.bind(ValidationMessages.ResolveExpMustHaveASource, new Object[] { }), resolveExpCS);
        }
        
        DeprecatedImplicitSourceCallHelper.validateCallExp(resolveExpCS, resolveExp, env);
        
        return resolveExp;
    }
    
    private void validateResolveExp(ResolveExp  resolveExp, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	if(resolveExp.isIsDeferred()) {    	
    		if(!QvtResolveUtil.isSuppportedAsDeferredAssigned(resolveExp)) {
    			int startPos = (resolveExp.getSource() != null) ? resolveExp.getSource().getEndPosition() : resolveExp.getStartPosition(); 
    			QvtOperationalUtil.reportWarning(env, ValidationMessages.lateResolveNotUsedInDeferredAssignment, startPos, resolveExp.getEndPosition());
    		}
		}
    }
        
    private org.eclipse.ocl.ecore.OCLExpression visitResolveInExpCS(ResolveInExpCS resolveInExpCS, QvtOperationalEnv env) {
        ResolveInExp resolveInExp = ExpressionsFactory.eINSTANCE.createResolveInExp();
        TypeCS contextTypeCS = resolveInExpCS.getInMappingType();
        EClassifier eClassifier = (contextTypeCS == null) ? null : visitTypeCS(contextTypeCS, null, env); // mapping context type
        eClassifier = eClassifier != null ? eClassifier : env.getModuleContextType();
        String mappingName = resolveInExpCS.getInMappingName().getValue();
        List<EOperation> rawMappingOperations = env.lookupMappingOperations(eClassifier, mappingName);
        List<EOperation> mappingOperations = new ArrayList<EOperation>();
        
        for (EOperation operation : rawMappingOperations) {
            EClassifier owner = env.getUMLReflection().getOwningClassifier(operation);
            if (((contextTypeCS == null) && (owner == null))
                    || (TypeUtil.resolveType(env, owner) == eClassifier)) {
                mappingOperations.add(operation);
            }
        }
        if (mappingOperations.size() == 1) {
            env.registerResolveInExp(resolveInExp, eClassifier, mappingName);
        } else {
            String mappingFQName = (eClassifier == null) ? "" : eClassifier.getName() + QvtOperationalTypesUtil.TYPE_NAME_SEPARATOR; //$NON-NLS-1$
            mappingFQName += mappingName;
            if (mappingOperations.size() == 0) {
                env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_ResolveInMappingNotFound, new Object[] {
                        mappingFQName}), resolveInExpCS.getInMappingName() != null ? resolveInExpCS.getInMappingName() : resolveInExpCS);
            } else if (mappingOperations.size() > 1) {
                env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_ambiguousMappingOperationReference, 
                		new Object[] { mappingFQName }), resolveInExpCS.getInMappingName());
                env.registerResolveInExp(resolveInExp, eClassifier, mappingName);
            }
        }
        
        ResolveExp result = populateResolveExp(resolveInExpCS, env, resolveInExp);
        //        DeprecatedImplicitSourceCallHelper.validateCallExp(resolveInExpCS, result, env);
        return result;
    }
    
    private ResolveExp populateResolveExp(ResolveExpCS resolveExpCS, QvtOperationalEnv env, ResolveExp resolveExp) {
        // AST binding
        if(myCompilerOptions.isGenerateCompletionData()) {      
            ASTBindingHelper.createCST2ASTBinding(resolveExpCS, resolveExp, env);
        }
        //
        if (resolveExpCS.getSource() != null) {
            OCLExpression<EClassifier> sourceExp = visitOclExpressionCS(resolveExpCS.getSource(), env);
            resolveExp.setSource(sourceExp);
        } else {
            //            // lookup for implicit source
            //            Variable<EClassifier,EParameter> implicitSource = env.lookupImplicitSourceForResolveExp();
            //            if (implicitSource != null) {
            //                VariableExp<EClassifier,EParameter> vexp = org.eclipse.ocl.expressions.ExpressionsFactory.eINSTANCE.createVariableExp();
            //                
            //                vexp.setType(implicitSource.getType());
            //                vexp.setReferredVariable(implicitSource);
            //                vexp.setName(implicitSource.getName());
            //                
            //                resolveExp.setSource(vexp);
            //            }
        }
        resolveExp.setOne(resolveExpCS.isOne());
        resolveExp.setIsInverse(resolveExpCS.isIsInverse());
        resolveExp.setIsDeferred(resolveExpCS.isIsDeferred());
        
        VariableCS targetVarCS = resolveExpCS.getTarget();
		if (targetVarCS != null) { // at least type is defined
            org.eclipse.ocl.ecore.Variable variable = EcoreFactory.eINSTANCE.createVariable();
            targetVarCS.setAst(variable);
            
            EClassifier type = visitTypeCS(targetVarCS.getTypeCS(), null, env);
            variable.setType(type);
            
            boolean isTargetVarClashing = false;
            String targetVarName = targetVarCS.getName();
            if (targetVarName != null) {
        		if (env.lookupLocal(targetVarName) != null) {
        			isTargetVarClashing = true;
        			
        			env.reportError(NLS.bind(ValidationMessages.NameAlreadyDefinedError, new Object[] { targetVarName }),
        					targetVarCS.getStartOffset(), targetVarCS.getEndOffset());
        		}
    			variable.setName(targetVarName);
            }
            resolveExp.setTarget(variable);
            
            // AST binding
            if(myCompilerOptions.isGenerateCompletionData()) {      
                ASTBindingHelper.createCST2ASTBinding(targetVarCS, variable, env);
            }
            //
            
            if (resolveExp.isOne()) {
                resolveExp.setType(type);
            } else {
        		EClassifier resolveType = (EClassifier) env.getOCLFactory().createSequenceType(type);
                resolveExp.setType(TypeUtil.resolveType(env, resolveType));
            }
            if (resolveExpCS.getCondition() != null) {
                if (!isTargetVarClashing && variable.getName() != null) {                	
                	env.addElement(variable.getName(), variable, true);
                }
                org.eclipse.ocl.ecore.OCLExpression condExp = visitOclExpressionCS(resolveExpCS.getCondition(), env);
                resolveExp.setCondition(condExp);                
                
                if (!isTargetVarClashing && variable.getName() != null) {
                    env.deleteElement(variable.getName());
                    // ensure to bind back to the ResolveExp container
                    resolveExp.setTarget(variable);
                }
            }
        } else {
            if (resolveExp.isOne()) {
                resolveExp.setType(env.getOCLStandardLibrary().getOclAny());
            } else {
        		EClassifier resolveType = (EClassifier) env.getOCLFactory().createSequenceType(env.getOCLStandardLibrary().getOclAny());
                resolveExp.setType(TypeUtil.resolveType(env, resolveType));
            }
        }
        resolveExp.setStartPosition(resolveExpCS.getStartOffset());
        resolveExp.setEndPosition(resolveExpCS.getEndOffset());
        
    	if(resolveExpCS.isIsDeferred()) {
    		addLateResolve(resolveExp);
    	}
        
		OCLExpression<EClassifier> condition = resolveExp.getCondition();
		if(condition != null) {
			EClassifier condType = condition.getType();
			if(env.getOCLStandardLibrary().getBoolean() != condType) {
				env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_booleanTypeExpressionExpected, 
						env.getUMLReflection().getName(condType)), condition.getStartPosition(), condition.getEndPosition());
			}
		}    	
    	
        return resolveExp;
    }

    private org.eclipse.ocl.ecore.OCLExpression visitForExp(ForExpCS forExpCS, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	
        OCLExpression<EClassifier> source =
            getCollectionSourceExpression(forExpCS.getSource(), env);
        if (!(source.getType() instanceof CollectionType)) {
            return (org.eclipse.ocl.ecore.OCLExpression)createDummyInvalidLiteralExp();
        }
        String name = forExpCS.getSimpleNameCS().getValue();

        ForExp astNode = ImperativeOCLFactory.eINSTANCE.createForExp();
        initASTMapping(env, astNode, forExpCS);
        astNode.setName(name);
        astNode.setStartPosition(forExpCS.getStartOffset());
        astNode.setEndPosition(forExpCS.getEndOffset());
        astNode.setType(env.getOCLStandardLibrary().getOclVoid());

        EList<Variable<EClassifier, EParameter>> iterators = astNode.getIterator();
        @SuppressWarnings("unchecked")
        CollectionType<EClassifier, EOperation> sourceCollectionType = (CollectionType<EClassifier, EOperation>) source.getType();
        Variable<EClassifier, EParameter> vdcl = null;
        if (forExpCS.getVariable1() != null) {
            vdcl = variableDeclarationCS(forExpCS.getVariable1(), env, true);
            vdcl.setType(sourceCollectionType.getElementType());
            iterators.add(vdcl);
        }
        
        Variable<EClassifier, EParameter> vdcl1 = null;
        if (forExpCS.getVariable2() != null) {
            vdcl1 = variableDeclarationCS(forExpCS.getVariable2(), env, true);
            vdcl1.setType(sourceCollectionType.getElementType());
            iterators.add(vdcl1);
        }
        
        if (forExpCS.getCondition() != null) { 
            OCLExpression<EClassifier> conditionExp = oclExpressionCS(forExpCS.getCondition(), env);
            astNode.setCondition((org.eclipse.ocl.ecore.OCLExpression)conditionExp);
        }
        
        if (forExpCS.getBody() != null) {
            OCLExpression<EClassifier> bodyExp = oclExpressionCS(forExpCS.getBody(), env);
            astNode.setBody(bodyExp);
        }
        
        astNode.setSource(source);
        
        if (vdcl != null) {
            env.deleteElement(vdcl.getName());
        }
        if (vdcl1 != null) {
            env.deleteElement(vdcl1.getName());
        }

        return astNode;
    }
    
    private org.eclipse.ocl.ecore.OCLExpression visitImperativeIterateExp(ImperativeIterateExpCS imperativeIterateExpCS, 
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
    	
        OCLExpression<EClassifier> source =
            getCollectionSourceExpression(imperativeIterateExpCS.getSource(), env);
        if (!(source.getType() instanceof CollectionType)) {
            return (org.eclipse.ocl.ecore.OCLExpression)createDummyInvalidLiteralExp();
        }
        String name = imperativeIterateExpCS.getSimpleNameCS().getValue();

        Variable<EClassifier, EParameter> vdcl = null;
        Variable<EClassifier, EParameter> vdcl1 = null;
        List<Variable<EClassifier, EParameter>> iterators = null;
    
        ImperativeIterateExp astNode;
        @SuppressWarnings("unchecked")
        CollectionType<EClassifier, EOperation> sourceCollectionType = (CollectionType<EClassifier, EOperation>) source.getType();
        
        if (imperativeIterateExpCS.getVariable1() != null) {
            vdcl = variableDeclarationCS(imperativeIterateExpCS.getVariable1(), env, true);
                
            astNode = ImperativeOCLFactory.eINSTANCE.createImperativeIterateExp();
            initASTMapping(env, astNode, imperativeIterateExpCS);
            astNode.setName(name);
            iterators = astNode.getIterator();  
            if (vdcl.getType() == null) {
                vdcl.setType(sourceCollectionType.getElementType());
            }
            iterators.add(vdcl);
            
            if (imperativeIterateExpCS.getVariable2() != null) {
                vdcl1 = variableDeclarationCS(imperativeIterateExpCS.getVariable2(), env, true);
                
                if (vdcl1.getType() == null) {
                    vdcl1.setType(sourceCollectionType.getElementType());
                }
                iterators.add(vdcl1);
            }
        } else  {
            astNode = ImperativeOCLFactory.eINSTANCE.createImperativeIterateExp();
            initASTMapping(env, astNode, imperativeIterateExpCS);
            astNode.setName(name);
            iterators = astNode.getIterator();  
            // Synthesize the iterator expression.
            vdcl = genVariableDeclaration(imperativeIterateExpCS, "visitImperativeIterateExp", env, null, //$NON-NLS-1$
                sourceCollectionType.getElementType(), null, false, true, false);
            iterators.add(vdcl);
        }
        
        TRACE("visitImperativeIterateExp: ", name);//$NON-NLS-1$
        
        EClassifier resultElementType = null;

        if (name.equals("xselect") || name.equals("selectOne")) {//$NON-NLS-1$ //$NON-NLS-2$
            resultElementType = sourceCollectionType.getElementType();
        } else {
            // Body may be defined explicitly - then it is the collectselect(One) shorthand or xcollect/collectOne.
            // It may be contained it the target variable - then it is the full notation of collectselect(One).
            if (imperativeIterateExpCS.getBody() != null) {
                OCLExpression<EClassifier> bodyExp = oclExpressionCS(imperativeIterateExpCS.getBody(), env);
                astNode.setBody(bodyExp);
                if (((imperativeIterateExpCS.getTarget() == null) || (imperativeIterateExpCS.getTarget().getInitExpression() == null))
                        && (name.equals("collectselect") || name.equals("collectselectOne"))) { //$NON-NLS-1$ //$NON-NLS-2$
                    // This is the case with collectselect(One) shorthand
                    // list->prop[res| res.startswith("_")];
                    // equivalent to
                    // list->collectselect(i;res = i.prop | res.startswith("_"))
                    if (!isInnermostIteratorRelated(vdcl, bodyExp)) {
                    	QvtOperationalUtil.reportError(env, NLS.bind(ValidationMessages.QvtOperationalVisitorCS_FeatureNotFoundForType,
                                new Object[] {QvtOperationalTypesUtil.getTypeFullName(vdcl.getType())}),
                                imperativeIterateExpCS.getBody());
                    }
                    if (imperativeIterateExpCS.getTarget() == null) {
                        Variable<EClassifier, EParameter> targetVdcl = genVariableDeclaration(imperativeIterateExpCS, "visitImperativeIterateExp", env, null, //$NON-NLS-1$
                                bodyExp.getType(), null, false, true, false);
                        astNode.setTarget((org.eclipse.ocl.ecore.Variable)targetVdcl);
                    }
                }
            } 
            if (imperativeIterateExpCS.getTarget() != null) {
                Variable<EClassifier, EParameter> targetVdcl = variableDeclarationCS(imperativeIterateExpCS.getTarget(), env, true);
                if (targetVdcl.getInitExpression() != null) {
                    astNode.setBody(targetVdcl.getInitExpression()); // the body is transferred from the target variable due to containment
                }
                astNode.setTarget((org.eclipse.ocl.ecore.Variable)targetVdcl);
            }
            if (astNode.getBody() != null) {
                resultElementType = astNode.getBody().getType();
                if ((astNode.getTarget() != null) && (astNode.getTarget().getType() == null)) {
                    astNode.getTarget().setType(resultElementType);
                }
            }
        }
        
        if (imperativeIterateExpCS.getCondition() != null) { 
        	org.eclipse.ocl.ecore.OCLExpression conditionExp = oclExpressionCS(imperativeIterateExpCS.getCondition(), env);
            astNode.setCondition(conditionExp);
            if (conditionExp instanceof TypeExp<?>) {
                TypeExp<EClassifier> typedCondition = (TypeExp<EClassifier>) conditionExp;
                EClassifier rawTypeType = TypeUtil.resolveType(env, typedCondition.getType());
                if (rawTypeType instanceof TypeType) {
                    @SuppressWarnings("unchecked")
                    TypeType<EClassifier, EOperation> typeType = (TypeType<EClassifier, EOperation>) rawTypeType;
                    resultElementType = typeType.getReferredType();
                }
            } else if ((conditionExp != null) && (conditionExp.getType() != getBoolean())) {
            	QvtOperationalUtil.reportError(env, ValidationMessages.QvtOperationalVisitorCS_WrongImperativeIteratorConditionType, 
                        conditionExp.getStartPosition(), conditionExp.getEndPosition());
            }
        }
        
        if (astNode.getTarget() != null) {
            env.deleteElement(astNode.getTarget().getName());
        }

        if (name.equals("selectOne") || name.equals("collectOne") || name.equals("collectselectOne")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            astNode.setType(resultElementType);        
        } else if (name.equals("xselect")) { //$NON-NLS-1$
            EClassifier resultCollectionType = getCollectionType(env, sourceCollectionType.getKind(), resultElementType);
            astNode.setType(resultCollectionType);        
        } else { // xcollect and collectselect
            EClassifier resultCollectionType = ((sourceCollectionType instanceof SetType) || (sourceCollectionType instanceof BagType)) ?
                    getCollectionType(env, CollectionKind.BAG_LITERAL, resultElementType)
                    : getCollectionType(env, CollectionKind.SEQUENCE_LITERAL, resultElementType);
            astNode.setType(resultCollectionType);        
        }

        astNode.setSource(source);
        
        env.deleteElement(vdcl.getName());
        if (vdcl1 != null) {
            env.deleteElement(vdcl1.getName());
        }
		// ensure AST containment tree
        astNode.getIterator().addAll(iterators);
        
        initStartEndPositions(astNode, imperativeIterateExpCS);
        return astNode;
    }
    
    private boolean isInnermostIteratorRelated(Variable<EClassifier, EParameter> vdcl, OCLExpression<EClassifier> bodyExp) {
        if (bodyExp instanceof CallExp) {
            CallExp bodyCallExp = (CallExp) bodyExp;
            if (bodyCallExp.getSource() instanceof VariableExp) {
                VariableExp<EClassifier, EParameter> sourceExp = (VariableExp<EClassifier, EParameter>) bodyCallExp.getSource();
                return sourceExp.getReferredVariable() == vdcl;
            }
            return false;
        }
        return true; // might be switch exp, for example
    }

	private MappingCallExp createMappingCallExp(MappingCallExpCS expressionCS, OCLExpression<EClassifier> result) {
		if (result instanceof OperationCallExp) {
			OperationCallExp<EClassifier, EOperation> operationCallExp = (OperationCallExp<EClassifier, EOperation>) result;
			EOperation operation = operationCallExp.getReferredOperation();
			if (QvtOperationalUtil.isMappingOperation(operation)) {
				MappingCallExp mappingCallExp = ExpressionsFactory.eINSTANCE.createMappingCallExp();
				mappingCallExp.setStartPosition(operationCallExp.getStartPosition());
				mappingCallExp.setEndPosition(operationCallExp.getEndPosition());
				mappingCallExp.getArgument().addAll(operationCallExp.getArgument());
				mappingCallExp.setReferredOperation(operation);
				mappingCallExp.setSource(operationCallExp.getSource());
				mappingCallExp.setType(operationCallExp.getType());
				mappingCallExp.setIsStrict(expressionCS.isStrict());
				
				mappingCallExp.setPropertyStartPosition(operationCallExp.getPropertyStartPosition());
				mappingCallExp.setPropertyEndPosition(operationCallExp.getPropertyEndPosition());				
				
				return mappingCallExp;
			}
		}
		return null;
	}

	private void validateOperationCall(OperationCallExpCS opCallCS, OperationCallExp<EClassifier, EOperation> operationCallExp, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		
		if (QvtOperationalParserUtil.isTypeCast(operationCallExp.getReferredOperation())) {
			if (operationCallExp.getSource() != null && operationCallExp.getArgument().size() == 1) {
				EClassifier sourceType = operationCallExp.getSource().getType();
				EClassifier argumentType = ((OCLExpression<EClassifier>) operationCallExp.getArgument().get(0))
						.getType();
				if (argumentType instanceof TypeType
						&& QvtOperationalParserUtil.isIncorrectCast(sourceType,
								((TypeType<EClassifier, EOperation>) argumentType).getReferredType())) {
					QvtOperationalUtil.reportWarning(env, ValidationMessages.incorrectCastWarning, opCallCS);
				}
			}
		}
		if (QvtOperationalUtil.isMappingOperation(operationCallExp.getReferredOperation())) {
			if (false == opCallCS instanceof MappingCallExpCS) {
				QvtOperationalUtil.reportWarning(env, NLS.bind(ValidationMessages.QvtOperationalVisitorCS_mapKeywordNotUsed,
						operationCallExp.getReferredOperation().getName()), opCallCS);
			}
		}
	}

	
	private void validateImportedSignature(QvtOperationalEnv env, OperationalTransformation module, OperationalTransformation importedModule, ASTNode astNode) {
		Set<ModelParameter> processedParams = new HashSet<ModelParameter>();
		Set<ModelParameter> consideredParams = new HashSet<ModelParameter>();
		for (ModelParameter importedParam : importedModule.getModelParameter()) {
			for (ModelParameter param : module.getModelParameter()) {
				if (consideredParams.contains(param)) {
					continue;
				}
				if (QvtOperationalUtil.isModelParamEqual(param, importedParam, true)) {
					consideredParams.add(param);
					processedParams.add(importedParam);
					break;
				}
			}
		}

		for (ModelParameter importedParam : importedModule.getModelParameter()) {
			if (processedParams.contains(importedParam)) {
				continue;
			}
			boolean isCorrespondanceFound = false;
			for (ModelParameter param : module.getModelParameter()) {
				if (consideredParams.contains(param)) {
					continue;
				}
				if (QvtOperationalUtil.isModelParamEqual(param, importedParam, false)) {
					consideredParams.add(param);
					isCorrespondanceFound = true;
					break;
				}
			}
			if (!isCorrespondanceFound) {
				env.reportWarning(
						NLS.bind(ValidationMessages.QvtOperationalVisitorCS_incompatibleTransfSignature, importedModule.getName()),
						astNode.getStartPosition(), astNode.getEndPosition());
				return;
			}
		}
	}

	private void checkMainMappingConformance(QvtOperationalEnv env, ImperativeOperation operation) {
		Set<ModelParameter> usedExtent = new HashSet<ModelParameter>(operation.getEParameters().size());
		for (EParameter param : operation.getEParameters()) {
			MappingParameter varParam = (MappingParameter) param;
			if (usedExtent.contains(varParam.getExtent())) {
                env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_extentDuplicateUse, null),  
                		varParam.getStartPosition(), varParam.getEndPosition());
			}
			if (varParam.getKind() != DirectionKind.OUT) {
				usedExtent.add(varParam.getExtent());
			}
			
			if (varParam.getExtent() == null) {
				if(varParam.getKind() != DirectionKind.IN) {
					env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_extentFailToInfer,
							QvtOperationalTypesUtil.getTypeFullName(varParam.getEType())),  
							varParam.getStartPosition(), varParam.getEndPosition());
				}
			}
			else if (varParam.getExtent().getKind() == DirectionKind.IN) {
				if (varParam.getKind() != DirectionKind.IN) {
	                env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_extentDirectionMismatch, null),  
	                		varParam.getStartPosition(), varParam.getEndPosition());
				}
			}
			else if (varParam.getExtent().getKind() == DirectionKind.OUT) {
				if (varParam.getKind() != DirectionKind.OUT) {
	                env.reportError(NLS.bind(ValidationMessages.QvtOperationalVisitorCS_extentDirectionMismatch, null),  
	                		varParam.getStartPosition(), varParam.getEndPosition());
				}
			}
		}
	}

    private void checkAbstractOutParamsInitialized(EList<VarParameter> result, MappingRuleCS methodCS, QvtOperationalEnv env) {
        for (VarParameter varParameter : result) {
            EClassifier type = varParameter.getEType();
            if (type instanceof EClass) {
                EClass eClass = (EClass) type;
                if (!QvtOperationalUtil.isInstantiable(eClass)) {
                    MappingInitCS init = (methodCS.getMappingBody() == null) ? null : methodCS.getMappingBody().getMappingInitCS();
                    if (init != null) {
                        // TODO: The check could be more accurate
                        return;
                    }
                    if((methodCS.getMappingDeclarationCS() != null) && !(methodCS.getMappingDeclarationCS().getQualifiers().contains(QualifierKindCS.ABSTRACT))) {
                    	boolean hasDisjunct = false;
                    	for (MappingExtensionCS extensionCS : methodCS.getMappingDeclarationCS().getMappingExtension()) {
							if(extensionCS.getKind() == MappingExtensionKindCS.DISJUNCTS) {
								hasDisjunct = true;
								break;
							}
						}
                    	if(!hasDisjunct) {
                    		env.reportError(ValidationMessages.QvtOperationalVisitorCS_AbstractTypesNotInitialized, methodCS);
                    	}
                    }
                }
            }
        }
    }
    
//	private boolean validateInitializedValueCS(VariableInitializationCS varInitCS, VariableInitExp result, 
//			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
//			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
//		
//		result.setName(varInitCS.getSimpleNameCS().getValue());
//
//		EClassifier type;
//		if (varInitCS.getTypeCS() != null) {
//			type = visitTypeCS(varInitCS.getTypeCS(), null, env);
//			if (type == null) {
//				return false;
//			}
//		} else {
//			type = null;
//		}
//
//		if (varInitCS.getOclExpressionCS() == null) {
//		    if (type == null) {
//		        return false;
//		    } else {
//		    	org.eclipse.ocl.ecore.OCLExpression defaultInitializationValue = createDefaultInitializationValue(type, env);
//		        if (defaultInitializationValue == null) {
//		            NullLiteralExp<EClassifier> nullLiteralExp = oclFactory.createNullLiteralExp();
//		            nullLiteralExp.setType(getOclVoid());
//		            defaultInitializationValue = (org.eclipse.ocl.ecore.NullLiteralExp)nullLiteralExp;
//		        }
//		        result.setValue(defaultInitializationValue);
//		    }
//		} else {
//	        org.eclipse.ocl.ecore.OCLExpression exp = visitOclExpressionCS(varInitCS.getOclExpressionCS(), env);
//	        if (exp == null) {
//	            return false;
//	        }
//	        result.setValue(exp);
//		}
//		result.setType(type);
//		return true;
//	}

	// FIXME - should not be initialized at AST level but at evaluation level
	private org.eclipse.ocl.ecore.OCLExpression createDefaultInitializationValue(EClassifier type, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
        // 8.2.2.10 VariableInitExp
        // A variable may not declare an initialization value. In this case a default value is assumed (an empty collection for a collection,
        // zero for any numeric type, the empty string for a string and null for all other elements.
        // A. Igdalov: Spec says nothing about Booleans and OclInvalid. Abstract collections (Collection, opposed to Bags, OrderedSets, etc.) are also neglected.
        // Thus, this implementation assigns false to Booleans, Invalid to OclInvalids and nulls to abstract collections.
	    if (type instanceof org.eclipse.ocl.ecore.CollectionType) {
            org.eclipse.ocl.ecore.CollectionType collectionType = (org.eclipse.ocl.ecore.CollectionType) type;
            CollectionKind kind = collectionType.getKind();
            if (CollectionKind.COLLECTION_LITERAL == kind) {
                return null;
            }
            CollectionLiteralExp<EClassifier> collectionLiteralExp = oclFactory.createCollectionLiteralExp();
            collectionLiteralExp.setKind(kind);
            EClassifier resultType = getCollectionType(env, kind, collectionType.getElementType());
            collectionLiteralExp.setType(resultType);
            return (org.eclipse.ocl.ecore.CollectionLiteralExp)collectionLiteralExp;
        } else {
            EClassifier resolvedType = env.getTypeResolver().resolve(type);
            OCLStandardLibrary<EClassifier> oclStdLib = getStandardLibrary();
            if (resolvedType == oclStdLib.getBoolean()) {
                BooleanLiteralExp<EClassifier> booleanLiteralExp = oclFactory.createBooleanLiteralExp();
                booleanLiteralExp.setBooleanSymbol(Boolean.FALSE);
                booleanLiteralExp.setType(oclStdLib.getBoolean());
                return (org.eclipse.ocl.ecore.BooleanLiteralExp)booleanLiteralExp;
            } else if (resolvedType == oclStdLib.getInteger()) {
                IntegerLiteralExp<EClassifier> integerLiteralExp = oclFactory.createIntegerLiteralExp();
                integerLiteralExp.setIntegerSymbol(0);
                integerLiteralExp.setType(oclStdLib.getInteger());
                return (org.eclipse.ocl.ecore.IntegerLiteralExp)integerLiteralExp;
            } else if (resolvedType == oclStdLib.getReal()) {
                RealLiteralExp<EClassifier> realLiteralExp = oclFactory.createRealLiteralExp();
                realLiteralExp.setRealSymbol(0.0);
                realLiteralExp.setType(oclStdLib.getReal());
                return (org.eclipse.ocl.ecore.RealLiteralExp) realLiteralExp;
            } else if (resolvedType == oclStdLib.getUnlimitedNatural()) {
                UnlimitedNaturalLiteralExp<EClassifier> unlimitedNaturalLiteralExp = oclFactory.createUnlimitedNaturalLiteralExp();
                unlimitedNaturalLiteralExp.setIntegerSymbol(0);
                unlimitedNaturalLiteralExp.setType(oclStdLib.getUnlimitedNatural());
                return (org.eclipse.ocl.ecore.UnlimitedNaturalLiteralExp)unlimitedNaturalLiteralExp;
            } else if (resolvedType == oclStdLib.getInvalid()) {
                InvalidLiteralExp<EClassifier> invalidLiteralExp = oclFactory.createInvalidLiteralExp();
                invalidLiteralExp.setType(oclStdLib.getInvalid());
                return (org.eclipse.ocl.ecore.InvalidLiteralExp)invalidLiteralExp;
            } else if (resolvedType == oclStdLib.getString()) {
                org.eclipse.ocl.expressions.StringLiteralExp<EClassifier> stringLiteralExp = oclFactory.createStringLiteralExp();
                stringLiteralExp.setStringSymbol(""); //$NON-NLS-1$
                stringLiteralExp.setType(oclStdLib.getString());
                return (org.eclipse.ocl.ecore.StringLiteralExp) stringLiteralExp;
            }
        }
	    return null;
	}
		
	private void addLateResolve(ResolveExp resolve) {
		assert resolve.isIsDeferred();
		if(myLateResolveExps == null) {
			myLateResolveExps = new LinkedList<ResolveExp>();
		}
		myLateResolveExps.add(resolve);
	}
	
	private List<ResolveExp> getAllLateResolves() {
		return myLateResolveExps != null ? myLateResolveExps : Collections.<ResolveExp>emptyList();
	}

	private void validate(Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, 
			EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		for (ResolveExp lateResolve : getAllLateResolves()) {
			validateResolveExp(lateResolve, env);
		}
	}
	
	/**
	 * SimpleNameCS
	 * @param simpleNameCS the <code>SimpleNameCS</code> <code>CSTNode</code>
	 * @param fEnv the OCL environment
	 * @param source the source of the <code>SimpleNameCS</code>
	 * @return the parsed <code>OCLExpression</code> 
	 */
	private OCLExpression<EClassifier> customSimpleNameCS(
    		SimpleNameCS simpleNameCS,
    		Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env,
    		OCLExpression<EClassifier> source) {

		if ((source != null) && isErrorNode(source)) {
			// don't attempt to parse navigation from an unparseable source
			return source; // return the same unparseable token
		}
		
		String simpleName = null;		
		EClassifier classifier = null;

		/* A name can be a variable defined by a Variable declaration, the special
		  variable "self", an attribute or a reference to another object.
		  If the source is not null, then the last token was a "." or "->"
		  The source is used to establish the navigation.
		  If no type is provided, then either the name is a the use of a variable,
		  or there is an implicit variable declaration (self or an iterator)
		  that is the source.		  		   
		 */
		switch (simpleNameCS.getType().getValue()) {
			case SimpleTypeEnum.SELF:
			case SimpleTypeEnum.KEYWORD:
			case SimpleTypeEnum.IDENTIFIER:
				simpleName = simpleNameCS.getValue();
				break;
			case SimpleTypeEnum.INTEGER:
			case SimpleTypeEnum.STRING:
			case SimpleTypeEnum.REAL:
			case SimpleTypeEnum.BOOLEAN:
			case SimpleTypeEnum.OCL_ANY:
			case SimpleTypeEnum.OCL_VOID:
			case SimpleTypeEnum.INVALID:
			case SimpleTypeEnum.OCL_MESSAGE:
				// if we have a source, then this is a feature call
				if (source == null) {
					classifier = primitiveTypeCS(simpleNameCS.getType(), env);
					simpleName = uml.getName(classifier);
				}
				break;
		}

					
		/*
		 * The source may be a collection type (for example, in self.children.name, children
		 * may be a set.)_  In this case, we have to get the element type of children, so
		 * that the attribute name can be found.
		 * The source type can also be a tuple type. In this case, we need to get the 
		 * EClass of the tuple.
		 * 
		 */ 
		EClassifier sourceElementType = null;
		if (source != null) {
			sourceElementType = source.getType();
			if (sourceElementType instanceof CollectionType) {
				@SuppressWarnings("unchecked")
				CollectionType<EClassifier, EOperation> ct = (CollectionType<EClassifier, EOperation>) sourceElementType;
				
				sourceElementType = ct.getElementType();
			} 
		}
		
		// cascaded alternatives for a simpleNameCS
		OCLExpression<EClassifier> astNode = simpleTypeName(simpleNameCS, env, source,
			classifier, simpleName);
		if (astNode == null) {
			astNode = simpleVariableName(simpleNameCS, env, source, simpleName);
		}
		if (astNode == null) {
			astNode = simplePropertyName(simpleNameCS, env, source,
				sourceElementType, simpleName);
		}
		if (astNode == null) {
			astNode = simpleAssociationClassName(simpleNameCS, env, source,
				sourceElementType, simpleName);
		}
		if (astNode == null) {
			astNode = simpleUndefinedName(simpleNameCS, env, source, simpleName);
		}
		
		// FIXME - we should ask MDT OCL for a support to handle this in a better way
		/*
		 * If the source type is a collection, then need there is an implicit COLLECT 
		 * or imperative COLLECT operator.
		 */
		if ((source != null) && (source.getType() instanceof CollectionType)
				&& (astNode instanceof FeatureCallExp)) {
		    CallExpCS callExpCS = (CallExpCS) simpleNameCS.eContainer();
		    FeatureCallExp<EClassifier> featureCallExp = (FeatureCallExp<EClassifier>) astNode;
		    astNode = isArrowAccessToCollection(callExpCS, source) ?
		            createImplicitXCollect(source, featureCallExp, env, simpleNameCS)
		            : createImplicitCollect(source, featureCallExp, env, simpleNameCS);
		}

		return astNode;
	}	

	protected EClassifier listTypeCS(ListTypeCS listTypeCS,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {

		TypeCS elementTypeCS = listTypeCS.getTypeCS();
		EClassifier elementType = typeCS(elementTypeCS, env);
		elementTypeCS.setAst(elementType);
		
		ListType result = getListType(elementType, env);
		if(result == null) {
			return env.getOCLStandardLibrary().getOclVoid();
		}
		
		
		CollectionType<EClassifier, EOperation> astNode = (CollectionType<EClassifier, EOperation>) result;
		initTypePositions(astNode, elementTypeCS);
		
		listTypeCS.setAst(result);		
		return result;
	}
	
	protected CollectionLiteralExp<EClassifier> listLiteralExpCS(ListLiteralExpCS listLiteralExpCS,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {

		CollectionLiteralExp<EClassifier> astNode = oclFactory.createCollectionLiteralExp();

		EClassifier elementType = null;

		initASTMapping(env, astNode, listLiteralExpCS);
		astNode.setKind(CollectionKind.SEQUENCE_LITERAL);
		
		EList<CollectionLiteralPart<EClassifier>> collectionParts = astNode.getPart();

		EList<CollectionLiteralPartCS> collectionLiteralPartsCS = listLiteralExpCS
			.getCollectionLiteralParts();

		if (!collectionLiteralPartsCS.isEmpty()) {
			Iterator<CollectionLiteralPartCS> i = collectionLiteralPartsCS
				.iterator();

			CollectionLiteralPartCS colPart = i.next();
			CollectionLiteralPart<EClassifier> collectionLiteralPartExp = collectionLiteralPartCS(colPart, env);
			collectionParts.add(collectionLiteralPartExp);
			elementType = collectionLiteralPartExp.getType();

			if (isErrorNode(collectionLiteralPartExp)) {
				// propagate error stigma to the collection literal
				markAsErrorNode(astNode);
			}

			while (i.hasNext()) {
				collectionLiteralPartExp = collectionLiteralPartCS(i.next(),
					env);

				EClassifier type1 = collectionLiteralPartExp.getType();
				elementType = getCommonSuperType(colPart,
					"collectionLiteralExpCS", env, elementType, type1); //$NON-NLS-1$
				collectionParts.add(collectionLiteralPartExp);

				if (isErrorNode(collectionLiteralPartExp)) {
					// propagate error stigma to the collection literal
					markAsErrorNode(astNode);
				}
			}
		}
		
		if (elementType == null) {
			elementType = env.getOCLStandardLibrary().getOclVoid();
		}
		
		EClassifier resultType = getListType(elementType, env);
		if(resultType == null) {
			resultType = env.getOCLStandardLibrary().getOclVoid();
		}
		
		astNode.setType(resultType);
		
		listLiteralExpCS.setAst(astNode);

		return astNode;
	}
	
	protected EClassifier dictionaryTypeCS(DictionaryTypeCS dictTypeCS,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {

		TypeCS keyTypeCS = dictTypeCS.getKey();		
		EClassifier keyType = typeCS(keyTypeCS, env);
		keyTypeCS.setAst(keyType);

		TypeCS valueTypeCS = dictTypeCS.getValue();
		EClassifier valueType = typeCS(valueTypeCS, env);
		valueTypeCS.setAst(valueType);

		DictionaryType result = getDictionaryType(keyType, valueType, env);
		if(result == null) {
			return env.getOCLStandardLibrary().getOclVoid();
		}
				
		initTypePositions((CollectionType<EClassifier, EOperation>) result, keyTypeCS);		
		dictTypeCS.setAst(result);		
		return result;
	}	
	
	/**
	 * Remark: Null argument safe operation
	 */
	protected DictionaryType getDictionaryType(EClassifier keyType, EClassifier valueType, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		if(env instanceof QVTOEnvironment && keyType != null && valueType != null) {
			QVTOEnvironment qvtEnv = (QVTOEnvironment) env;
			return qvtEnv.getTypeResolver().resolveDictionaryType(keyType, valueType);
		}
		return null;
	}

	/**
	 * Remark: Null argument safe operation
	 */	
	protected ListType getListType(EClassifier elementType, 
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		if(env instanceof QVTOEnvironment && elementType != null) {
			QVTOEnvironment qvtEnv = (QVTOEnvironment) env;
			return qvtEnv.getTypeResolver().resolveListType(elementType);
		}
		return null;
	}	
	
	protected DictLiteralExp dictionaryLiteralExp(DictLiteralExpCS dictLiteralExpCS,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		DictLiteralExp result = ImperativeOCLFactory.eINSTANCE.createDictLiteralExp();		
		
		for (DictLiteralPartCS nextPartCS : dictLiteralExpCS.getParts()) {			
			DictLiteralPart literalPartAST = dictionaryLiteralPart(nextPartCS, env);
			result.getPart().add(literalPartAST);			
		}		

		EClassifier commonKeyType = null;
		EClassifier commonnValueType = null;
		boolean commonSuperTypeError = false;
		
		for (DictLiteralPart literalPartAST : result.getPart()) {
			EClassifier nextKeyType = literalPartAST.getKey() != null ? literalPartAST.getKey().getType() : null;
			EClassifier nextValueType = literalPartAST.getValue() != null ? literalPartAST.getValue().getType() : null;

			if(nextKeyType != null && nextValueType != null) {
				if(commonKeyType != null && commonnValueType != null) {
					commonKeyType = TypeUtil.commonSuperType(dictLiteralExpCS, env, nextKeyType, commonKeyType);
					if(commonKeyType != null) {
						commonnValueType = TypeUtil.commonSuperType(dictLiteralExpCS, env, nextValueType, commonnValueType);
					}
				} else {
					// first iteration, take the first types
					commonKeyType = nextKeyType;
					commonnValueType = nextValueType; 
				}
			} 
			
			commonSuperTypeError = commonKeyType == null || commonnValueType == null;
			if(commonSuperTypeError) {
				break;
			}
		}

		EClassifier resultType = getDictionaryType(commonKeyType, commonnValueType, env);
		if(resultType == null) {
			resultType = env.getOCLStandardLibrary().getOclVoid();
		}
		
		result.setType(resultType);		
		
		initStartEndPositions(result, dictLiteralExpCS);		
		dictLiteralExpCS.setAst(result);		
		return result;
	}
	
	protected DictLiteralPart dictionaryLiteralPart(DictLiteralPartCS dictLiteralPartCS,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		
		DictLiteralPart result = ImperativeOCLFactory.eINSTANCE.createDictLiteralPart();	
		result.setKey((org.eclipse.ocl.ecore.OCLExpression)oclExpressionCS(dictLiteralPartCS.getKey(), env));
		result.setValue((org.eclipse.ocl.ecore.OCLExpression)oclExpressionCS(dictLiteralPartCS.getValue(), env));
		dictLiteralPartCS.setAst(result);		
		return result;
	}

	@Override
	protected boolean isErrorNode(TypedElement<EClassifier> expr) {
		if(myErrorNodes == null) {
			return false;
		}

		return myErrorNodes.contains(expr);
	}

	@Override
	protected void markAsErrorNode(TypedElement<EClassifier> expr) {
		if(myErrorNodes == null) {
			myErrorNodes = new java.util.HashSet<TypedElement<?>>();			
		}
		myErrorNodes.add(expr);
	}
	
	private static void createPropertyCallASTBinding(
			CallExpCS propertyCallExpCS,
			OCLExpression<EClassifier> result,
			Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) {
		ASTNode boundAST = result;
		CSTNode boundCST = propertyCallExpCS;            	
		if(result instanceof IteratorExp) {
			@SuppressWarnings("unchecked")			
			IteratorExp<EClassifier, EParameter> itExpAST = (IteratorExp<EClassifier, EParameter>) result;
			if(propertyCallExpCS instanceof IteratorExpCS) {
				IteratorExpCS itExpCST = (IteratorExpCS) propertyCallExpCS;
				if(itExpCST.getBody() != null) {
					boundCST = itExpCST.getBody();
				}
			}            		
			if(itExpAST.getBody() instanceof FeatureCallExp) {
				boundAST = (FeatureCallExp<EClassifier>) itExpAST.getBody();
			}
		} else if(result instanceof ImperativeIterateExp) {
			ImperativeIterateExp impIterExpAST = (ImperativeIterateExp) result;
			if(propertyCallExpCS instanceof ImperativeIterateExpCS) {
				ImperativeIterateExpCS itExpCST = (ImperativeIterateExpCS) propertyCallExpCS;
				if(itExpCST.getBody() != null) {
					boundCST = itExpCST.getBody();
				}
			}
			if(impIterExpAST.getBody() instanceof FeatureCallExp) {
				boundAST = (FeatureCallExp<EClassifier>) impIterExpAST.getBody();
			}			
		}
		ASTBindingHelper.createCST2ASTBinding(boundCST, boundAST, env);
	}

	private static List<ModelParameter> getModelParameter(Module module) {
		if(module instanceof OperationalTransformation) {
			OperationalTransformation operationalTransformation = (OperationalTransformation) module;
			return operationalTransformation.getModelParameter();
		}
		return Collections.emptyList();
	}
	
	private static QvtOperationalModuleEnv getModuleContextEnv(QvtOperationalEnv env) {
		Internal<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> 
			nextParent = env;
		while(nextParent != null) {
			if(nextParent instanceof QvtOperationalModuleEnv) {
				return (QvtOperationalModuleEnv) nextParent;
			}
			nextParent = nextParent.getInternalParent();
		}
		
		return null;
	}
	
	private static QvtOperationalEnv toQVTOperationalEnv(Environment<EPackage, EClassifier, 
			EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, 
			CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env) throws IllegalArgumentException {
		
		QvtOperationalEnv adapter = OCLUtil.getAdapter(env, QvtOperationalEnv.class);
		if(adapter == null) {
			throw new IllegalArgumentException("QVTOperationalEnv is required"); //$NON-NLS-1$
		}
		
		return adapter;
	}
	
	private static EAnnotation createTag(String tagId, String value, EModelElement element) {		
		EAnnotation annotation = org.eclipse.emf.ecore.EcoreFactory.eINSTANCE.createEAnnotation();
		annotation.getDetails().put(tagId, value);
		annotation.getReferences().add(element);
		return annotation;
	}
	
	private static URI getSourceURI(QvtOperationalModuleEnv env) {
		if(env instanceof QvtOperationalFileEnv) {
			QvtOperationalFileEnv fileEnv = (QvtOperationalFileEnv) env;
			return fileEnv.getFile();
		}
		return null;
	}
}