/*******************************************************************************
 * Copyright (c) 2013 E.D.Willink and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *   E.D.Willink - Initial API and implementation
 *******************************************************************************/
package org.eclipse.qvtd.codegen.qvti.java;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.codegen.analyzer.NameManager;
import org.eclipse.ocl.examples.codegen.cgmodel.CGElementId;
import org.eclipse.ocl.examples.codegen.cgmodel.CGExecutorProperty;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIterator;
import org.eclipse.ocl.examples.codegen.cgmodel.CGOperation;
import org.eclipse.ocl.examples.codegen.cgmodel.CGPackage;
import org.eclipse.ocl.examples.codegen.cgmodel.CGParameter;
import org.eclipse.ocl.examples.codegen.cgmodel.CGTypeId;
import org.eclipse.ocl.examples.codegen.cgmodel.CGValuedElement;
import org.eclipse.ocl.examples.codegen.cgmodel.CGVariable;
import org.eclipse.ocl.examples.codegen.generator.TypeDescriptor;
import org.eclipse.ocl.examples.codegen.java.CG2JavaVisitor;
import org.eclipse.ocl.examples.codegen.java.JavaConstants;
import org.eclipse.ocl.examples.codegen.java.JavaLocalContext;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.Parameter;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.evaluation.Evaluator;
import org.eclipse.ocl.pivot.ids.ClassId;
import org.eclipse.ocl.pivot.ids.CollectionTypeId;
import org.eclipse.ocl.pivot.ids.ElementId;
import org.eclipse.ocl.pivot.ids.PropertyId;
import org.eclipse.ocl.pivot.ids.TypeId;
import org.eclipse.ocl.pivot.internal.manager.MetamodelManager;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.NameUtil;
import org.eclipse.ocl.pivot.utilities.ValueUtil;
import org.eclipse.qvtd.codegen.qvti.analyzer.QVTiAnalyzer;
import org.eclipse.qvtd.codegen.qvticgmodel.CGEcorePropertyAssignment;
import org.eclipse.qvtd.codegen.qvticgmodel.CGEcoreRealizedVariable;
import org.eclipse.qvtd.codegen.qvticgmodel.CGFunction;
import org.eclipse.qvtd.codegen.qvticgmodel.CGFunctionCallExp;
import org.eclipse.qvtd.codegen.qvticgmodel.CGFunctionParameter;
import org.eclipse.qvtd.codegen.qvticgmodel.CGGuardVariable;
import org.eclipse.qvtd.codegen.qvticgmodel.CGMapping;
import org.eclipse.qvtd.codegen.qvticgmodel.CGMappingCall;
import org.eclipse.qvtd.codegen.qvticgmodel.CGMappingCallBinding;
import org.eclipse.qvtd.codegen.qvticgmodel.CGMappingExp;
import org.eclipse.qvtd.codegen.qvticgmodel.CGMappingLoop;
import org.eclipse.qvtd.codegen.qvticgmodel.CGMiddlePropertyAssignment;
import org.eclipse.qvtd.codegen.qvticgmodel.CGMiddlePropertyCallExp;
import org.eclipse.qvtd.codegen.qvticgmodel.CGPredicate;
import org.eclipse.qvtd.codegen.qvticgmodel.CGPropertyAssignment;
import org.eclipse.qvtd.codegen.qvticgmodel.CGRealizedVariable;
import org.eclipse.qvtd.codegen.qvticgmodel.CGSequence;
import org.eclipse.qvtd.codegen.qvticgmodel.CGTransformation;
import org.eclipse.qvtd.codegen.qvticgmodel.CGTypedModel;
import org.eclipse.qvtd.codegen.qvticgmodel.CGVariablePredicate;
import org.eclipse.qvtd.codegen.qvticgmodel.util.QVTiCGModelVisitor;
import org.eclipse.qvtd.pivot.qvtbase.Transformation;
import org.eclipse.qvtd.pivot.qvtbase.evaluation.AbstractTransformationExecutor;
import org.eclipse.qvtd.pivot.qvtcorebase.Area;
import org.eclipse.qvtd.pivot.qvtcorebase.Assignment;
import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern;
import org.eclipse.qvtd.pivot.qvtcorebase.PropertyAssignment;
import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable;
import org.eclipse.qvtd.pivot.qvtcorebase.utilities.QVTcoreBaseUtil;
import org.eclipse.qvtd.pivot.qvtimperative.Mapping;
import org.eclipse.qvtd.pivot.qvtimperative.MappingCall;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiTransformationAnalysis;
import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeUtil;

/**
 * A QVTiCG2JavaVisitor supports generation of Java code from an optimized QVTi CG transformation tree.
 */
public class QVTiCG2JavaVisitor extends CG2JavaVisitor<QVTiCodeGenerator> implements QVTiCGModelVisitor<Boolean>
{
	protected class MyTransformationAnalysis extends QVTiTransformationAnalysis
	{
		protected final @NonNull String classIndex2classIdName;
		protected final @NonNull String classIndex2allClassIndexesName;
		protected final @NonNull String classIndex2objectsName;
		protected final @NonNull String modelObjectsName;
		
		protected MyTransformationAnalysis(@NonNull MetamodelManager metamodelManager, @NonNull CGTransformation cgTransformation) {
			super(metamodelManager);
			@SuppressWarnings("null")@NonNull Transformation transformation = (Transformation) cgTransformation.getAst();
			analyzeTransformation(transformation);
			NameManager nameManager = getGlobalContext().getNameManager();
			classIndex2classIdName = nameManager.getGlobalSymbolName(null, "classIndex2classId");
			classIndex2allClassIndexesName = nameManager.getGlobalSymbolName(null, "classIndex2allClassIndexes");
			classIndex2objectsName = "classIndex2objects"; // nameManager.getGlobalSymbolName(null, "classIndex2objects");
			modelObjectsName = "modelObjects"; // nameManager.getGlobalSymbolName(null, "modelObjects");
		}

		public @NonNull String getClassIndex2classIdName() {
			return classIndex2classIdName;
		}

		public @NonNull String getClassIndex2allClassIndexesName() {
			return classIndex2allClassIndexesName;
		}

		public @NonNull String getClassIndex2objectsName() {
			return classIndex2objectsName;
		}

		public @NonNull String getModelObjectsName() {
			return modelObjectsName;
		}
	}

	protected final @NonNull QVTiAnalyzer analyzer;
	protected final @NonNull CGPackage cgPackage;
	protected final @Nullable List<CGValuedElement> sortedGlobals;
	private MyTransformationAnalysis transformationAnalysis = null;
	
	public QVTiCG2JavaVisitor(@NonNull QVTiCodeGenerator codeGenerator, @NonNull CGPackage cgPackage,
			@Nullable List<CGValuedElement> sortedGlobals) {
		super(codeGenerator);
		this.analyzer = codeGenerator.getAnalyzer();
		this.cgPackage = cgPackage;
		this.sortedGlobals = sortedGlobals;
	}

	protected void appendModelIndex(@Nullable CGTypedModel cgTypedModel) {
		if (cgTypedModel == null) {
			js.append("-1/*null*/");
		}
		else {
			js.append(cgTypedModel.getModelIndex() + "/*" + cgTypedModel.getName() + "*/");
		}
	}

	protected void doAddRealization(@NonNull CGRealizedVariable cgRealizedVariable) {
		RealizedVariable pRealizedVariable = (RealizedVariable)cgRealizedVariable.getAst();
		Area pArea = QVTcoreBaseUtil.getContainingArea(pRealizedVariable);
		if (pArea != null) {
			BottomPattern pBottomPattern = pArea.getBottomPattern();
			if (pBottomPattern != null) {
				for (Assignment pAssignment : pBottomPattern.getAssignment()) {
					if (pAssignment instanceof PropertyAssignment) {
						Property pProperty = ((PropertyAssignment)pAssignment).getTargetProperty();
						if (pProperty != null) {
							Property pOppositeProperty = pProperty.getOpposite();
							if ((pOppositeProperty != null) && pOppositeProperty.isComposite()) {
// FIXME must check for null asssignment and correct target								return;
							}
						}
					}
				}
			}
		}
		CGTypedModel cgTypedModel = cgRealizedVariable.getTypedModel();
		//
		js.append(transformationAnalysis.getModelObjectsName());
		js.append("[");
		appendModelIndex(cgTypedModel);
		js.append("].add(");
		js.appendValueName(cgRealizedVariable);
		js.append(");\n");
		if (transformationAnalysis != null) {
			TypeId typeId = pRealizedVariable.getTypeId();
			if (typeId instanceof ClassId) {
				Integer classIndex = transformationAnalysis.getAllInstancesClassIndex((ClassId)typeId);
				if (classIndex != null) {
					js.append(transformationAnalysis.getClassIndex2objectsName());
					js.append("[");
					js.append(classIndex + "/*" + typeId.getDisplayName() + "*/");
					js.append("].add(");
					js.appendValueName(cgRealizedVariable);
					js.append(");\n");
				}
			}
		}
	}

	protected String[] doAllInstances() {
//		Set<org.eclipse.ocl.pivot.Class> allInstancesClasses = transformationAnalysis.getAllInstancesClasses();
		Map<ClassId, Integer> allInstancesClassId2classIndex = transformationAnalysis.getAllInstancesClassId2classIndex();
		if (allInstancesClassId2classIndex.size() > 0) {
			Map<ClassId, List<ClassId>> instancesClassAnalysis = transformationAnalysis.getInstancesClassAnalysis(transformationAnalysis.getAllInstancesClasses());
			//
			// Populate a mapping from instancesClass to linear index.
			//
//			Map<org.eclipse.ocl.pivot.Class, Integer> instancesClass2index = new HashMap<org.eclipse.ocl.pivot.Class, Integer>(instancesClassAnalysis.size());
			ClassId[] classIndex2classId = new ClassId[allInstancesClassId2classIndex.size()];
//			Collections.sort(sortedList, NameUtil.NameableComparator.INSTANCE);
			for (ClassId classId : allInstancesClassId2classIndex.keySet()) {
				classIndex2classId[allInstancesClassId2classIndex.get(classId)] = classId;
			}
			//
			//	Emit the ClassId array
			//
			js.append("/*\n");
			js.append(" * Array of the ClassIds of each class for which allInstances() may be invoked. Array index is the ClassIndex.\n");
			js.append(" */\n");
			js.append("private static final ");
			js.appendIsRequired(true);
			js.append(" ");
			js.appendClassReference(ClassId.class);
			js.append("[] ");
			js.append(transformationAnalysis.getClassIndex2classIdName());
			js.append(" = new ");
			js.appendClassReference(ClassId.class);
			js.append("[]{\n");
			js.pushIndentation(null);
			for (int i = 0; i < classIndex2classId.length; i++) {
				@SuppressWarnings("null")@NonNull ClassId instancesClassId = classIndex2classId[i];
				CGTypeId cgTypeId = getCodeGenerator().getAnalyzer().getTypeId(instancesClassId);
				js.appendValueName(cgTypeId);
				if ((i+1) < classIndex2classId.length) {
					js.append(",");
				}
				js.append("\t\t// " + i + " => " + instancesClassId.getDisplayName() + "\n");
			}
			js.popIndentation();
			js.append("};\n");
			//
			//	Emit the classIndex2allClassIndexes array of arrays
			//
			js.append("/*\n");
			js.append(" * Mapping from each ClassIndex to all the ClassIndexes to which an object of the outer index\n");
			js.append(" * may contribute results to an allInstances() invocation.\n");
			js.append(" * Non trivial inner arrays arise when one ClassId is a derivation of another and so an\n");
			js.append(" * instance of the derived classId contributes to derived and inherited ClassIndexes.\n");
			js.append(" */\n");
			js.append("private final static ");
			js.appendIsRequired(true);
			js.append(" ");
			js.appendClassReference(int.class);
			js.append("[][] ");
			js.append(transformationAnalysis.getClassIndex2allClassIndexesName());
			js.append(" = new ");
			js.appendClassReference(int.class);
			js.append("[][] {\n");
			js.pushIndentation(null);
			for (int i = 0; i < classIndex2classId.length; i++) {
				ClassId instancesClassId = classIndex2classId[i];
				List<ClassId> superInstancesClassIds = instancesClassAnalysis.get(instancesClassId);
				js.append("{");
				boolean isFirst = true;
				for (ClassId superInstancesClassId : superInstancesClassIds) {
					if (!isFirst) {
						js.append(",");
					}
					js.append("" + allInstancesClassId2classIndex.get(superInstancesClassId));
					isFirst = false;
				}
				js.append("}");
				if ((i+1) < classIndex2classId.length) {
					js.append(",");
				}
				js.append("\t\t// " + i + " : ");
				js.append(instancesClassId.getDisplayName());
				js.append(" -> {");
				isFirst = true;
				for (ClassId superInstancesClassId : superInstancesClassIds) {
					if (!isFirst) {
						js.append(",");
					}
					js.append(superInstancesClassId.getDisplayName());
					isFirst = false;
				}
				js.append("}\n");
			}
			js.popIndentation();
			js.append("};\n");
			return new String[]{ transformationAnalysis.getClassIndex2classIdName(), transformationAnalysis.getClassIndex2allClassIndexesName()};
		}
		return null;
    }

	protected void doConstructor(@NonNull CGTransformation cgTransformation, @Nullable String oppositeName, @Nullable String[] allInstancesNames) {
//		String evaluatorName = ((QVTiGlobalContext)globalContext).getEvaluatorParameter().getName();
		String evaluatorName = JavaConstants.EVALUATOR_NAME;
		String className = cgTransformation.getName();
		//
		js.append("public " + className + "(final ");
		js.appendIsRequired(true);
		js.append(" ");
		js.appendClassReference(Evaluator.class);
		js.append(" " + evaluatorName + ") {\n");
		js.pushIndentation(null);		
		js.append("super(" + evaluatorName + ", new String[] {");
		boolean isFirst = true;
		for (CGTypedModel cgTypedModel : cgTransformation.getTypedModels()) {
			if (!isFirst) {
				js.append(", ");
			}
			String name = cgTypedModel.getName();
			js.appendString(name != null ? name : "");
			isFirst = false;
		}
		js.append("}");
		if (oppositeName != null) {
			js.append(", ");
			js.append(oppositeName);
		}
		else {
			js.append(", null");
		}
		if (allInstancesNames != null) {
			js.append(", ");
			js.append(allInstancesNames[0]);
			js.append(", ");
			js.append(allInstancesNames[1]);
		}
		else {
			js.append(", null, null");
		}
		js.append(");\n");
		js.popIndentation();
		js.append("}\n");
	}
    
	protected void doMiddleOppositeCaches() {
		Map<Property, String> toMiddleProperties = getGlobalContext().getToMiddleProperties();
		if (toMiddleProperties != null) {
			js.append("\n/* Outer-to-Middle Property navigation caches */\n");
			Map<String, Property> key2property = new HashMap<String, Property>();
			for (Map.Entry<Property, String> entry : toMiddleProperties.entrySet()) {
				key2property.put(entry.getValue(), entry.getKey());
			}
			List<String> sortedKeys = new ArrayList<String>(key2property.keySet());
			Collections.sort(sortedKeys);
			for (String key : sortedKeys) {
				Property property = key2property.get(key);
				TypeDescriptor outerTypeDescriptor = context.getBoxedDescriptor(property.getOwningClass().getTypeId());
				TypeDescriptor middleTypeDescriptor = context.getBoxedDescriptor(property.getType().getTypeId());
				js.append("protected final ");
				js.appendIsRequired(true);
				js.append(" ");
				js.appendClassReference(Map.class, false, middleTypeDescriptor, outerTypeDescriptor);
				js.append(" ");
				js.append(key);
				js.append(" = new ");
				js.appendClassReference(HashMap.class, false, middleTypeDescriptor, outerTypeDescriptor);
				js.append("();\n");
			}
		}
    }
    
	protected @Nullable String doOppositeCaches() {
		Map<Property, Integer> opposites = transformationAnalysis.getOpposites();
		if (opposites.size() <= 0) {
			return null;
		}
		NameManager nameManager = getGlobalContext().getNameManager();
		List<Property> sortedList = new ArrayList<Property>();
		for (Map.Entry<Property, Integer> entry : opposites.entrySet()) {
			sortedList.set(entry.getValue().intValue(), entry.getKey());
		}
		//
		//	Emit the ClassId array
		//
		js.append("/*\n");
		js.append(" * Array of the PropertyIds of each Property for which unnavigable opposite property navigation may occur.\n");
		js.append(" */\n");
		String oppositeIndex2propertyIdName = nameManager.getGlobalSymbolName(null, "oppositeIndex2propertyId");
		js.append("private static final ");
		js.appendIsRequired(true);
		js.append(" ");
		js.appendClassReference(PropertyId.class);
		js.append("[] ");
		js.append(oppositeIndex2propertyIdName);
		js.append(" = new ");
		js.appendClassReference(ClassId.class);
		js.append("[]{\n");
		js.pushIndentation(null);
		for (int i = 0; i < sortedList.size(); i++) {
			Property property = sortedList.get(i);
			CGElementId cgPropertyId = getCodeGenerator().getAnalyzer().getElementId(property.getPropertyId());
			js.appendValueName(cgPropertyId);
			if ((i+1) < sortedList.size()) {
				js.append(",");
			}
			js.append("\t\t// " + i + " => " + property.getName() + "\n");
		}
		js.popIndentation();
		js.append("};\n");
		return oppositeIndex2propertyIdName;
    }

	protected void doRun(@NonNull CGTransformation cgTransformation) {
		CGMapping cgRootMapping = NameUtil.getNameable(cgTransformation.getMappings(), QVTimperativeUtil.ROOT_MAPPING_NAME);
		if (cgRootMapping == null) {
        	throw new IllegalStateException("Transformation " + cgTransformation.getName() + " has no root mapping");
		}
/*		List<CGGuardVariable> cgFreeVariables = cgRootMapping.getFreeVariables();
		NameManager nameManager = globalContext.getNameManager();
		Map<CGParameter, String> listNames = new HashMap<CGParameter, String>();
		for (CGGuardVariable cgFreeVariable : cgFreeVariables) {
			String nameHint = "LIST_" + cgFreeVariable.getValueName();
			String listName = nameManager.getGlobalSymbolName(null, nameHint);
			listNames.put(cgFreeVariable, listName);
		} */
		//
		js.append("public boolean run() {\n");
		js.pushIndentation(null);
/*		for (@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
			TypeDescriptor typeDescriptor = context.getTypeDescriptor(cgFreeVariable);
			EClassifier eClassifier = ClassUtil.nonNullState(typeDescriptor.getEClassifier());
			String qualifiedPackageInterfaceName = genModelHelper.getQualifiedPackageInterfaceName(eClassifier.getEPackage());
			String classifierLiteralName = genModelHelper.getLiteralName(eClassifier);
			String nameHint = "ECLASS_" + cgFreeVariable.getValueName();
			String eClassName = nameManager.getGlobalSymbolName(null, nameHint);
			//
			js.append("final ");
			js.appendClassReference(EClass.class);
			js.append(" ");
			js.append(eClassName);
			js.append(" = ");
			js.appendClassReference(qualifiedPackageInterfaceName);
			js.append(".Literals." + classifierLiteralName);
			js.append(";\n");
			//
			js.append("assert ");
			js.append(eClassName);
			js.append(" != null;\n");
			//
			js.appendClassReference(List.class, true, typeDescriptor);
			js.append(" ");
			js.append(listNames.get(cgFreeVariable));
			js.append(" = getObjectsByType(");
			js.appendClassReference(typeDescriptor);
			js.append(".class, ");
			appendModelIndex(cgFreeVariable.getTypedModel());
			js.append(", ");
			js.append(eClassName);
			js.append(");\n");
		}
		for (CGGuardVariable cgFreeVariable : cgFreeVariables) {
			js.append("for (");
//			if (cgFreeVariable.isNonNull()) {
//				js.append("@SuppressWarnings(\"null\")@NonNull ");
//			}
			js.appendClassReference(cgFreeVariable);
			js.append(" ");
			js.appendValueName(cgFreeVariable);
			js.append(" : ");
			js.append(listNames.get(cgFreeVariable));
			js.append(") {\n");
			js.pushIndentation(null);
			js.append("if (");
			js.appendValueName(cgFreeVariable);
			js.append(" != null) {\n");
			js.pushIndentation(null);
		} */
		js.append("return ");
		js.append(cgRootMapping.getName());
		js.append("(");
/*		boolean isFirst = true;
		for (CGGuardVariable cgFreeVariable : cgFreeVariables) {
			if (!isFirst) {
				js.append(", ");
			}
			js.appendValueName(cgFreeVariable);
			isFirst = false;
		} */
		js.append(");\n");
/*		for (@SuppressWarnings("unused") CGGuardVariable cgFreeVariable : cgFreeVariables) {
			js.popIndentation();
			js.append("}\n");
			js.popIndentation();
			js.append("}\n");
		} */
//		js.append("return true;\n");
		js.popIndentation();		
		js.append("}\n");
	}

	protected @NonNull QVTiGlobalContext getGlobalContext() {
		return (QVTiGlobalContext) globalContext;
	}

	protected @Nullable TypeDescriptor needsTypeCheck(@NonNull CGMappingCallBinding cgMappingCallBinding) {
		CGValuedElement value = cgMappingCallBinding.getValue();
		TypeDescriptor argumentTypeDescriptor = context.getTypeDescriptor(cgMappingCallBinding);
		TypeId pivotTypeId = value.getASTypeId();
		if (pivotTypeId instanceof CollectionTypeId) {
			pivotTypeId = ((CollectionTypeId)pivotTypeId).getElementTypeId();
		}
		TypeDescriptor iteratorTypeDescriptor = context.getBoxedDescriptor(ClassUtil.nonNullState(pivotTypeId));
		if (argumentTypeDescriptor.isAssignableFrom(iteratorTypeDescriptor)) {
			return null;
		}
		else {
			return argumentTypeDescriptor;
		}
	}

	@Override
	public @NonNull Boolean visitCGEcorePropertyAssignment(@NonNull CGEcorePropertyAssignment cgPropertyAssignment) {
//		Property pivotProperty = cgPropertyCallExp.getReferredProperty();
//		CGTypeId cgTypeId = analyzer.getTypeId(pivotProperty.getOwningType().getTypeId());
//		JavaTypeDescriptor requiredTypeDescriptor = context.getJavaTypeDescriptor(cgTypeId, false);
		EStructuralFeature eStructuralFeature = ClassUtil.nonNullModel(cgPropertyAssignment.getEStructuralFeature());
		CGValuedElement cgSlot = getExpression(cgPropertyAssignment.getSlotValue());
		CGValuedElement cgInit = getExpression(cgPropertyAssignment.getInitValue());
//		Class<?> requiredJavaClass = requiredTypeDescriptor.getJavaClass();
//		Method leastDerivedMethod = requiredJavaClass != null ? getLeastDerivedMethod(requiredJavaClass, getAccessor) : null;
//		Class<?> unboxedSourceClass = leastDerivedMethod != null ? leastDerivedMethod.getDeclaringClass() : requiredJavaClass;
		//
		if (!js.appendLocalStatements(cgSlot)) {
			return false;
		}
		if (!js.appendLocalStatements(cgInit)) {
			return false;
		}
		//
		if (eStructuralFeature.isMany()) {
			String getAccessor = genModelHelper.getGetAccessor(eStructuralFeature);
			//
			js.appendValueName(cgSlot);
			js.append(".");
			js.append(getAccessor);
			js.append("().addAll(");
			js.appendValueName(cgInit);
			js.append(");\n");
		}
		else {
			String setAccessor = genModelHelper.getSetAccessor(eStructuralFeature);
			//
		js.appendValueName(cgSlot);
		js.append(".");
		js.append(setAccessor);
		js.append("(");
		js.appendValueName(cgInit);
		js.append(");\n");
		}
		return true;
	}

	@Override
	public @NonNull Boolean visitCGEcoreRealizedVariable(@NonNull CGEcoreRealizedVariable cgRealizedVariable) {
		EClassifier eClassifier = cgRealizedVariable.getEClassifier();
		EPackage ePackage = eClassifier.getEPackage();			
		String createMethodName = "create" + eClassifier.getName();
		String javaClass;
		if (ePackage != null) {
			Class<?> factoryClass = genModelHelper.getEcoreFactoryClass(ePackage);
			if (factoryClass != null) {
				javaClass = factoryClass.getName();
				Method factoryMethod = context.getLeastDerivedMethod(factoryClass, createMethodName);
				if (factoryMethod != null) {
					if (context.getIsNonNull(factoryMethod) == Boolean.TRUE) {
						cgRealizedVariable.setNonNull();
					};
				}
			}
			else {
				javaClass = genModelHelper.getQualifiedFactoryInterfaceName(ePackage);
			}
		}
		else {
			javaClass = null;
		}
		//
		js.appendDeclaration(cgRealizedVariable);
		js.append(" = ");
		js.appendClassReference(javaClass);
//		js.appendReferenceTo(localContext.getExecutorType(cgRealizedVariable.getPivotTypeId()));
		js.append(".eINSTANCE.");
		js.append(createMethodName);
		js.append("();\n");
		//
		js.append("assert ");
		js.appendValueName(cgRealizedVariable);
		js.append(" != null;\n");
		//
		doAddRealization(cgRealizedVariable);
		return true;
	}

	@Override
	public @NonNull Boolean visitCGFunction(@NonNull CGFunction cgFunction) {
		JavaLocalContext<?> localContext2 = globalContext.getLocalContext(cgFunction);
		if (localContext2 != null) {
			localContext = localContext2;
			try {
				List<CGParameter> cgParameters = cgFunction.getParameters();
				CGValuedElement body = getExpression(cgFunction.getBody());
				//
				js.append("protected ");
				js.appendIsRequired(cgFunction.isRequired());
		//		js.append(" ");
		//		js.appendIsCaught(!cgOperation.isInvalid(), cgOperation.isInvalid());
				js.append(" ");
				ElementId elementId = cgFunction.getTypeId().getElementId();
				if (elementId != null) {
					TypeDescriptor javaTypeDescriptor = context.getUnboxedDescriptor(elementId);
					js.appendClassReference(javaTypeDescriptor);
				}
				js.append(" ");
				js.append(cgFunction.getName());
				js.append("(");
				boolean isFirst = true;
				for (@SuppressWarnings("null")@NonNull CGParameter cgParameter : cgParameters) {
					if (!isFirst) {
						js.append(", ");
					}
					js.appendDeclaration(cgParameter);
					isFirst = false;
				}
				js.append(") {\n");
				js.pushIndentation(null);
//					js.appendCastParameters(localContext2, cgParameters);
//					JavaDependencyVisitor dependencyVisitor = new JavaDependencyVisitor(localContext2, null);
//					dependencyVisitor.visit(body);
//					dependencyVisitor.visitAll(localContext2.getLocalVariables());
//					Iterable<CGValuedElement> sortedDependencies = dependencyVisitor.getSortedDependencies();
//					for (CGValuedElement cgElement : sortedDependencies) {
//						if (!cgElement.isInlined() && cgElement.isConstant() && !cgElement.isGlobal()) {
//							cgElement.accept(this);
//						}
//					}
					// FIXME merge locals into AST as LetExps.
					if (cgFunction.getBody() != null) {
						if (!js.appendLocalStatements(body)) {
							return false;
						}
						js.append("return ");
						js.appendValueName(body);
						js.append(";\n");
					}
					else {
						TypeId asTypeId = cgFunction.getASTypeId();
						if (asTypeId == TypeId.STRING) {			// FIXME Fudge for body-less functions
							js.append("return \"\";\n");
						}
						else if (asTypeId == TypeId.REAL) {			// FIXME Fudge for body-less functions
							js.append("return 0;\n");
						}
						else if (asTypeId == TypeId.INTEGER) {			// FIXME Fudge for body-less functions
							js.append("return 0;\n");
						}
						else if (asTypeId instanceof CollectionTypeId) {			// FIXME Fudge for body-less functions
							if (js.isUseNullAnnotations()) {
								js.append("@SuppressWarnings(\"null\")");
								js.appendIsRequired(true);
								js.append(" ");
							}
							if (elementId != null) {
								TypeDescriptor javaTypeDescriptor = context.getUnboxedDescriptor(elementId);
								js.appendClassReference(javaTypeDescriptor);
							}
							js.append(" emptyList = ");
							js.appendClassReference(Collections.class);
							js.append(".emptyList();\n");
							js.append("return emptyList;\n");
						}
						else {			// FIXME Fudge for body-less functions
							js.append("return \"\";\n");
						}
					}
				js.popIndentation();
				js.append("}\n");
			}
			finally {
				localContext = null;
			}
		}
		return true;
	}

	@Override
	public @NonNull Boolean visitCGFunctionCallExp(@NonNull CGFunctionCallExp cgFunctionCallExp) {
		Operation pOperation = cgFunctionCallExp.getReferredOperation();
		List<CGValuedElement> cgArguments = cgFunctionCallExp.getArguments();
		List<Parameter> pParameters = pOperation.getOwnedParameters();
		//
		for (@SuppressWarnings("null")@NonNull CGValuedElement cgArgument : cgArguments) {
			CGValuedElement argument = getExpression(cgArgument);
			if (!js.appendLocalStatements(argument)) {
				return false;
			}
		}
		//
		js.appendDeclaration(cgFunctionCallExp);
		js.append(" = ");
		js.append(cgFunctionCallExp.getFunction().getName());
		js.append("(");
		int iMax = Math.min(pParameters.size(), cgArguments.size());
		for (int i = 0; i < iMax; i++) {
			if (i > 0) {
				js.append(", ");
			}
			CGValuedElement cgArgument = cgArguments.get(i);
			CGValuedElement argument = getExpression(cgArgument);
			Parameter pParameter = pParameters.get(i);
//			CGTypeId cgParameterTypeId = analyzer.getTypeId(pParameter.getTypeId());
			TypeDescriptor parameterTypeDescriptor = context.getUnboxedDescriptor(pParameter.getTypeId());
			js.appendReferenceTo(parameterTypeDescriptor, argument);
		}
		js.append(");\n");
		return true;
	}

	@Override
	public @NonNull Boolean visitCGFunctionParameter(@NonNull CGFunctionParameter object) {
		return visitCGParameter(object);
	}

	@Override
	public @NonNull Boolean visitCGGuardVariable(@NonNull CGGuardVariable object) {
		return visitCGParameter(object);
	}

	@Override
	public @NonNull Boolean visitCGMapping(@NonNull CGMapping cgMapping) {
//		if ("associationToForeignKeyLM".equals(cgMapping.getName())) {
//			System.out.println("Got it");
//		}
		JavaLocalContext<?> localContext2 = globalContext.getLocalContext(cgMapping);
		if (localContext2 != null) {
			localContext = localContext2;
			try {
				String eName = globalContext.getEName();
				CGValuedElement cgBody = cgMapping.getBody();
				List<CGGuardVariable> cgFreeVariables = cgMapping.getFreeVariables();
				//
				js.appendCommentWithOCL(null, cgMapping.getAst());
				js.append("protected boolean " + cgMapping.getName() + "(");
				boolean isFirst = true;
				for (@SuppressWarnings("null")@NonNull CGGuardVariable cgFreeVariable : cgFreeVariables) {
					if (!isFirst) {
						js.append(", ");
					}
					js.appendDeclaration(cgFreeVariable);
					isFirst = false;
				}
				js.append(") {\n");
				js.pushIndentation(null);
					if (cgBody.isNonInvalid()) {
						js.append("// predicates\n");
						cgBody.accept(this);
						js.append("return true;\n");
					}
					else {
						js.append("try {\n");
						js.pushIndentation(null);
							js.append("// predicates\n");
							cgBody.accept(this);
							js.append("return true;\n");
						js.popIndentation();
						js.append("}\n");
						js.append("catch (");
						js.appendClassReference(Exception.class);
						js.append(" " + eName + ") {\n");
						js.pushIndentation(null);
							js.append("return false;\n");
						js.popIndentation();
						js.append("}\n");
					}
				js.popIndentation();
				js.append("}\n");
			}
			finally {
				localContext = null;
			}
		}
		return true;
	}

	@Override
	public @NonNull Boolean visitCGMappingCall(@NonNull CGMappingCall cgMappingCall) {
		MappingCall pMappingCall = (MappingCall) cgMappingCall.getAst();
		Mapping pReferredMapping = pMappingCall.getReferredMapping();
		if (pReferredMapping == null) {
			return true;
		}
		CGMapping cgReferredMapping = analyzer.getMapping(pReferredMapping);
		if (cgReferredMapping == null) {
			return true;
		}
		List<CGMappingCallBinding> cgMappingCallBindings = cgMappingCall.getMappingCallBindings();
		for (@SuppressWarnings("null")@NonNull CGMappingCallBinding cgMappingCallBinding : cgMappingCallBindings) {
			CGValuedElement value = cgMappingCallBinding.getValue();
			if (value != null) {
				if (!js.appendLocalStatements(value)) {
					return false;
				}
			}
		}
		//
		//	Set loopVariable non-null if it needs to be type-checked and cast to a narrower type.
		//
		for (@SuppressWarnings("null")@NonNull CGMappingCallBinding cgMappingCallBinding : cgMappingCallBindings) {
			TypeDescriptor checkedType = needsTypeCheck(cgMappingCallBinding);
			if (checkedType != null) {
				js.append("if (");
				js.appendValueName(cgMappingCallBinding.getValue());
				js.append(" instanceof ");
				js.appendClassReference(checkedType);
				js.append(") {\n");
				js.pushIndentation(null);
			}
		}
		//
		//	Emit the mapping call.
		//
		js.append(cgReferredMapping.getName() + "(");
		boolean isFirst = true;
		for (@SuppressWarnings("null")@NonNull CGMappingCallBinding cgMappingCallBinding : cgMappingCallBindings) {
			if (!isFirst) {
				js.append(", ");
			}
			TypeDescriptor checkedType = needsTypeCheck(cgMappingCallBinding);
			if (checkedType != null) {
				js.append("(");
				js.appendClassReference(checkedType);
				js.append(")");
			}
			js.appendValueName(cgMappingCallBinding.getValue());
			isFirst = false;
		}
		js.append(");\n");
		//
		//	End the type check.
		//
		for (@SuppressWarnings("null")@NonNull CGMappingCallBinding cgMappingCallBinding : cgMappingCallBindings) {
			TypeDescriptor checkedType = needsTypeCheck(cgMappingCallBinding);
			if (checkedType != null) {
				js.popIndentation();
				js.append("}\n");
			}
		}
		return true;
	}

	@Override
	public @NonNull Boolean visitCGMappingCallBinding(@NonNull CGMappingCallBinding object) {
		return true;
	}

	@Override
	public @NonNull Boolean visitCGMappingExp(@NonNull CGMappingExp cgMappingExp) {
		assert cgMappingExp.getPredicates().isEmpty();		// Get rewritten during JavaPre pass
		js.append("// creations\n");
		for (CGValuedElement cgRealizedVariable : cgMappingExp.getRealizedVariables()) {
			cgRealizedVariable.accept(this);
		}
		js.append("// assignments\n");
		for (CGPropertyAssignment cgAssignment : cgMappingExp.getAssignments()) {
			cgAssignment.accept(this);
		}
		js.append("// mapping statements\n");
		CGValuedElement body = cgMappingExp.getBody();
		if (body != null) {
			body.accept(this);
		}
		return true;
	}

	@Override
	public @NonNull Boolean visitCGMappingLoop(@NonNull CGMappingLoop cgMappingLoop) {
		CGValuedElement source = getExpression(cgMappingLoop.getSource());
		CGIterator iterator = cgMappingLoop.getIterators().get(0);
//		accumulatorName = getSymbolName(null, init.getValueName());
		if (!js.appendLocalStatements(source)) {
			return false;
		}
//		js.appendLocalStatements(iterator);
//		js.appendDeclaration(iterator);
//		js.append(" = ");
//		js.appendValueName(iterator.getInit());
		js.append(";\n");
		js.append("for (");
//		if (iterator.isNonNull()) {
//			js.append("@SuppressWarnings(\"null\")@NonNull ");
//		}
		js.appendClassReference(iterator);
		js.append(" ");
		js.appendValueName(iterator);
		js.append(" : ");
		js.appendValueName(source);
		js.append(") {\n");
		js.pushIndentation(null);
		js.append("if (");
		js.appendValueName(iterator);
		js.append(" != null) {\n");
		js.pushIndentation(null);
			cgMappingLoop.getBody().accept(this);
		js.popIndentation();
		js.append("}\n");
		js.popIndentation();
		js.append("}\n");
		return true;
	}

	@Override
	public @NonNull Boolean visitCGMiddlePropertyAssignment(@NonNull CGMiddlePropertyAssignment cgMiddlePropertyAssignment) {
		visitCGEcorePropertyAssignment(cgMiddlePropertyAssignment);
		Property pReferredProperty = ClassUtil.nonNullModel(cgMiddlePropertyAssignment.getReferredProperty());
		assert !pReferredProperty.isImplicit();
		CGValuedElement slotValue = cgMiddlePropertyAssignment.getSlotValue();
		CGValuedElement initValue = cgMiddlePropertyAssignment.getInitValue();
		if ((slotValue != null) && (initValue != null)) {
			Map<Property, String> toMiddleProperties = getGlobalContext().getToMiddleProperties();
			if (toMiddleProperties != null) {
				String cacheName = toMiddleProperties.get(pReferredProperty);
				if (cacheName != null) {
					js.append(cacheName);
					js.append(".put(");
					js.appendValueName(initValue);
					js.append(", ");
					js.appendValueName(slotValue);
					js.append(");\n");
				}
			}
		}
		return true;
	}

	@Override
	public @NonNull Boolean visitCGMiddlePropertyCallExp(@NonNull CGMiddlePropertyCallExp cgPropertyCallExp) {
		Property pivotProperty = cgPropertyCallExp.getReferredProperty();
		assert !pivotProperty.isImplicit();
		CGValuedElement source = getExpression(cgPropertyCallExp.getSource());
		//
		if (!js.appendLocalStatements(source)) {
			return false;
		}
		//
		js.appendDeclaration(cgPropertyCallExp);
		js.append(" = ");
		Map<Property, String> toMiddleProperties = getGlobalContext().getToMiddleProperties();
		if (toMiddleProperties != null) {
			String cacheName = toMiddleProperties.get(pivotProperty);
			if (cacheName != null) {
				js.appendClassReference(ClassUtil.class);
				js.append(".nonNullState (");
				js.append(cacheName);
				js.append(".get(");
				js.appendValueName(source);
				js.append("))");
			}
			js.append(";\n");
		}
		return true;
	}

	@Override
	public @NonNull Boolean visitCGPredicate(@NonNull CGPredicate cgPredicate) {
		boolean booleanCondition = false;
		CGValuedElement cgConditionExpression = cgPredicate.getConditionExpression();
		if (cgConditionExpression != null) {
			booleanCondition = js.is_boolean(cgConditionExpression);
			if (!js.appendLocalStatements(cgConditionExpression)) {
				return false;
			}
		}
		js.append("if (");
		if (booleanCondition) {
			js.append("!");
			js.appendValueName(cgConditionExpression);
		}
		else {
			js.appendValueName(cgConditionExpression);
			js.append(" != ");
			js.appendClassReference(ValueUtil.class);
			js.append(".TRUE_VALUE");
		}
		js.append(") {\n");
		js.pushIndentation(null);
		js.append("return false;\n");
		js.popIndentation();
		js.append("}\n");
		cgPredicate.getThenExpression().accept(this);
		return true;
	}

	@Override
	public @NonNull Boolean visitCGPropertyAssignment(@NonNull CGPropertyAssignment cgPropertyAssignment) {
		CGExecutorProperty cgExecutorProperty = cgPropertyAssignment.getExecutorProperty();
		CGValuedElement slotValue = cgPropertyAssignment.getSlotValue();
		CGValuedElement initValue = cgPropertyAssignment.getInitValue();
		if ((slotValue != null) && (initValue != null)) {
			if (!js.appendLocalStatements(slotValue)) {
				return false;
			}
			if (!js.appendLocalStatements(initValue)) {
				return false;
			}
			js.appendReferenceTo(cgExecutorProperty);
			js.append(".initValue(");
			js.appendValueName(slotValue);
			js.append(", ");
			js.appendValueName(initValue);
			js.append(");\n");
		}
		return true;
	}

	@Override
	public @NonNull Boolean visitCGRealizedVariable(@NonNull CGRealizedVariable cgRealizedVariable) {
		TypeId typeId = cgRealizedVariable.getASTypeId();
		if (typeId != null) {
			js.appendDeclaration(cgRealizedVariable);
			js.append(" = ");
			js.appendReferenceTo(cgRealizedVariable.getExecutorType());
			js.append(".createInstance();\n");
		}
		//
		doAddRealization(cgRealizedVariable);
		return true;
	}

	@Override
	public @Nullable Boolean visitCGSequence(@NonNull CGSequence cgSequence) {
		for (CGValuedElement cgStatement : cgSequence.getStatements()) {
			cgStatement.accept(this);
		}
		return true;
	}

	@Override
	public @NonNull Boolean visitCGTransformation(@NonNull CGTransformation cgTransformation) {		
		transformationAnalysis = new MyTransformationAnalysis(getMetamodelManager(), cgTransformation);
		String className = cgTransformation.getName();
		js.append("/**\n");
		js.append(" * The " + className + " transformation:\n");
		js.append(" * <p>\n");
		js.append(" * Construct with an evaluator\n");
		js.append(" * <br>\n");
		js.append(" * Populate each input model with {@link addRootObjects(String,List)}\n");
		js.append(" * <br>\n");
		js.append(" * {@link run()}\n");
		js.append(" * <br>\n");
		js.append(" * Extract each output model with {@link getRootObjects(String)}\n");
		js.append(" */\n");
		js.append("@SuppressWarnings(\"nls\")\n");
		js.append("public class " + className + " extends ");
		js.appendClassReference(AbstractTransformationExecutor.class);
		js.append("\n");
		js.append("{\n");
		js.pushIndentation(null);
		if (sortedGlobals != null) {
			for (CGValuedElement cgElement : sortedGlobals) {
				assert cgElement.isGlobal();
				cgElement.accept(this);
			}
		}
		doMiddleOppositeCaches();
		js.append("\n");
		String oppositeName = doOppositeCaches();
		js.append("\n");
		String[] allInstancesNames = doAllInstances();
		js.append("\n");
		doConstructor(cgTransformation, oppositeName, allInstancesNames);
		js.append("\n");
		doRun(cgTransformation);
		for (CGOperation cgOperation : cgTransformation.getOperations()) {
			js.append("\n");
			cgOperation.accept(this);
		}
		for (CGMapping cgMapping : cgTransformation.getMappings()) {
			js.append("\n");
			cgMapping.accept(this);
		}
		js.popIndentation();
		js.append("}\n");
		transformationAnalysis = null;
		return true;
	}

	@Override
	public @NonNull Boolean visitCGTypedModel(@NonNull CGTypedModel object) {
		return true;
	}

	@Override
	public @NonNull Boolean visitCGVariablePredicate(@NonNull CGVariablePredicate cgVariablePredicate) {
		CGValuedElement cgConditionExpression = ClassUtil.nonNullState(cgVariablePredicate.getConditionExpression());
		CGVariable cgPredicateVariable = ClassUtil.nonNullState(cgVariablePredicate.getPredicateVariable());
		TypeDescriptor sourceTypeDescriptor = context.getTypeDescriptor(cgConditionExpression);
		TypeDescriptor targetTypeDescriptor = context.getTypeDescriptor(cgPredicateVariable);
		if (!js.appendLocalStatements(cgConditionExpression)) {
			return false;
		}
		if (targetTypeDescriptor.isAssignableFrom(sourceTypeDescriptor)) {
			js.appendDeclaration(cgPredicateVariable);
			js.append(" = ");
			js.appendReferenceTo(cgConditionExpression);
			js.append(";\n");
		}
		else {
			js.append("if (!(");
			js.appendValueName(cgConditionExpression);
			js.append(" instanceof ");
			js.appendClassReference(targetTypeDescriptor);
			js.append(")) {\n");
			js.pushIndentation(null);
			js.append("return false;\n");
			js.popIndentation();
			js.append("}\n");
			js.appendDeclaration(cgPredicateVariable);
			js.append(" = ");
			js.appendReferenceTo(targetTypeDescriptor, cgConditionExpression);
			js.append(";\n");
		}
		cgVariablePredicate.getThenExpression().accept(this);
		return true;
	}
}
