/*******************************************************************************
 * Copyright (c) 2015, 2020 Willink Transformations and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *     E.D.Willink - initial API and implementation
 ******************************************************************************/
package org.eclipse.qvtd.pivot.qvtimperative.evaluation;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CallExp;
import org.eclipse.ocl.pivot.Model;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.NavigationCallExp;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.OppositePropertyCallExp;
import org.eclipse.ocl.pivot.Parameter;
import org.eclipse.ocl.pivot.PivotFactory;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.PropertyCallExp;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.VariableDeclaration;
import org.eclipse.ocl.pivot.evaluation.AbstractModelManager;
import org.eclipse.ocl.pivot.evaluation.EvaluationEnvironment;
import org.eclipse.ocl.pivot.evaluation.EvaluationVisitor;
import org.eclipse.ocl.pivot.evaluation.Executor;
import org.eclipse.ocl.pivot.evaluation.ModelManager;
import org.eclipse.ocl.pivot.ids.IdResolver;
import org.eclipse.ocl.pivot.internal.complete.StandardLibraryInternal;
import org.eclipse.ocl.pivot.internal.evaluation.AbstractExecutor;
import org.eclipse.ocl.pivot.internal.messages.PivotMessagesInternal;
import org.eclipse.ocl.pivot.labels.ILabelGenerator;
import org.eclipse.ocl.pivot.library.AbstractOperation;
import org.eclipse.ocl.pivot.resource.ASResource;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.LabelUtil;
import org.eclipse.ocl.pivot.utilities.NameUtil;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.pivot.utilities.ValueUtil;
import org.eclipse.ocl.pivot.values.InvalidValueException;
import org.eclipse.ocl.pivot.values.NullValue;
import org.eclipse.qvtd.pivot.qvtbase.Function;
import org.eclipse.qvtd.pivot.qvtbase.Transformation;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder;
import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil;
import org.eclipse.qvtd.pivot.qvtimperative.AppendParameter;
import org.eclipse.qvtd.pivot.qvtimperative.AppendParameterBinding;
import org.eclipse.qvtd.pivot.qvtimperative.EntryPoint;
import org.eclipse.qvtd.pivot.qvtimperative.GuardParameter;
import org.eclipse.qvtd.pivot.qvtimperative.GuardParameterBinding;
import org.eclipse.qvtd.pivot.qvtimperative.ImperativeTransformation;
import org.eclipse.qvtd.pivot.qvtimperative.LoopParameterBinding;
import org.eclipse.qvtd.pivot.qvtimperative.Mapping;
import org.eclipse.qvtd.pivot.qvtimperative.MappingCall;
import org.eclipse.qvtd.pivot.qvtimperative.MappingParameter;
import org.eclipse.qvtd.pivot.qvtimperative.MappingParameterBinding;
import org.eclipse.qvtd.pivot.qvtimperative.NewStatement;
import org.eclipse.qvtd.pivot.qvtimperative.NewStatementPart;
import org.eclipse.qvtd.pivot.qvtimperative.ObservableStatement;
import org.eclipse.qvtd.pivot.qvtimperative.SetStatement;
import org.eclipse.qvtd.pivot.qvtimperative.SimpleParameterBinding;
import org.eclipse.qvtd.pivot.qvtimperative.SpeculateStatement;
import org.eclipse.qvtd.pivot.qvtimperative.Statement;
import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiModelsManager.QVTiTypedModelInstance;
import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeUtil;
import org.eclipse.qvtd.runtime.evaluation.AbstractComputation;
import org.eclipse.qvtd.runtime.evaluation.AbstractInvocation;
import org.eclipse.qvtd.runtime.evaluation.AbstractTransformer;
import org.eclipse.qvtd.runtime.evaluation.Computation;
import org.eclipse.qvtd.runtime.evaluation.Connection;
import org.eclipse.qvtd.runtime.evaluation.Interval;
import org.eclipse.qvtd.runtime.evaluation.Invocation;
import org.eclipse.qvtd.runtime.evaluation.InvocationFailedException;
import org.eclipse.qvtd.runtime.evaluation.InvocationConstructor;
import org.eclipse.qvtd.runtime.evaluation.InvocationManager;
import org.eclipse.qvtd.runtime.evaluation.ModeFactory;
import org.eclipse.qvtd.runtime.evaluation.ObjectManager;
import org.eclipse.qvtd.runtime.evaluation.SlotState;
import org.eclipse.qvtd.runtime.evaluation.SlotState.Speculating;
import org.eclipse.qvtd.runtime.evaluation.TransformationExecutor;
import org.eclipse.qvtd.runtime.evaluation.Transformer;
import org.eclipse.qvtd.runtime.evaluation.TypedModelInstance;
import org.eclipse.qvtd.runtime.internal.evaluation.AbstractComputationConstructor;
import org.eclipse.qvtd.runtime.internal.evaluation.AbstractInvocationConstructor;
import org.eclipse.qvtd.runtime.internal.evaluation.IncrementalInvocationManager;
import org.eclipse.qvtd.runtime.internal.evaluation.IncrementalObjectManager;
import org.eclipse.qvtd.runtime.internal.evaluation.LazyInvocationManager;
import org.eclipse.qvtd.runtime.internal.evaluation.LazyObjectManager;

/**
 * BasicQVTiExecutor provides the functionality for interpreted transformation execution.
 *
 * NB The API is a bit different to the CGed exector for which distict complete Java code exists for each possible entry point.
 * It is therefore possible to delay choosing the entry point until run(). In contrrast this interpreted executor conditions one of the
 * AS ImperativeTransformation EntryPoints which must be selected, albeit as default at construction time.
 */
public class BasicQVTiExecutor extends AbstractExecutor implements QVTiExecutor, TransformationExecutor
{
	/**
	 * The run-time API version.
	 *
	 * @noreference this is solely for development usage.
	 */
	public static int RUN_TIME_EVALUATOR_API_VERSION = Transformer.RUN_TIME_EVALUATOR_API_VERSION_1_1_0_2;

	public enum Mode {
		LAZY,						// EvaluationStatus is created lazily where necessary
		INCREMENTAL,				// EvaluationStatus is created for all mapping elements
		REPAIR						// EvaluationStatus is updated for all mapping elements
	};

	public static class InterpretedInvocationConstructor extends AbstractInvocationConstructor.Incremental
	{
		private static @NonNull Interval createInterval(@NonNull InvocationManager invocationManager, Mapping asMapping) {
			Integer firstPass = asMapping.getFirstPass();
			if (firstPass != null) {
				return invocationManager.lazyCreateInterval(firstPass);
			}
			else {
				return invocationManager.createInterval();			// Legacy no-pass-numbers support
			}
		}

		protected final @NonNull BasicQVTiExecutor executor;
		protected final @NonNull MappingCall mappingCall;
		protected final @NonNull EvaluationVisitor undecoratedVisitor;

		public InterpretedInvocationConstructor(@NonNull BasicQVTiExecutor executor, @NonNull Mapping asMapping,
				@NonNull MappingCall mappingCall, @NonNull EvaluationVisitor undecoratedVisitor) {
			super(executor.getInvocationManager(), QVTimperativeUtil.getName(asMapping), createInterval(executor.getInvocationManager(), asMapping));
			this.executor = executor;
			this.mappingCall = mappingCall;
			this.undecoratedVisitor = undecoratedVisitor;
		}

		//	@Override
		//	public @NonNull ModeFactory getModeFactory() {
		//		return ModeFactory.NON_INCREMENTAL;
		//	}

		@Override
		public @NonNull Invocation newInstance(int invocationHashCode, @NonNull Object @NonNull [] theseValues) {
			return new InterpretedInvocation(this, invocationHashCode, theseValues);
		}

		private Object internalExecuteInvocation(@NonNull InterpretedInvocation invocation, @NonNull Object @NonNull [] theseValues) {
			return executor.internalExecuteInvocation(invocation, theseValues, mappingCall, undecoratedVisitor);
		}
	}

	public static class InterpretedInvocation extends AbstractInvocation.Incremental
	{
		protected final @NonNull Object @NonNull [] theseValues;

		public InterpretedInvocation(@NonNull InterpretedInvocationConstructor constructor, int invocationHashCode, @NonNull Object @NonNull [] theseValues) {
			super(constructor, invocationHashCode);
			int iMax = theseValues.length;
			this.theseValues = new @NonNull Object[iMax];
			for (int i = 0; i < iMax; i++) {
				this.theseValues[i] = theseValues[i];
			}
		}

		@Override
		public boolean execute() throws InvocationFailedException {
			Object returnStatus = ((InterpretedInvocationConstructor)constructor).internalExecuteInvocation(this, theseValues);
			return returnStatus == ValueUtil.TRUE_VALUE;
		}

		@Override
		public @NonNull Object getBoundValue(int index) {
			return theseValues[index];
		}

		@Override
		public int getBoundValues() {
			return theseValues.length;
		}

		@Override
		public boolean isEqual(@NonNull IdResolver idResolver, @NonNull Object @NonNull [] thoseValues) {
			int iMax = thoseValues.length;
			if (iMax != theseValues.length) {
				return false;
			}
			for (int i = 0; i < iMax; i++) {
				if (!idResolver.oclEquals(theseValues[i], thoseValues[i])) {
					return false;
				}
			}
			return true;
		}
	}

	protected class NewStatementOperation extends AbstractOperation
	{
		private final boolean isContained;

		public NewStatementOperation(boolean isContained) {
			this.isContained = isContained;
		}

		@Override
		public @Nullable Object basicEvaluate(@NonNull Executor executor, @NonNull TypedElement caller, @Nullable Object @NonNull [] sourceAndArgumentValues) {
			NewStatement iNewStatement = (NewStatement) caller;
			@SuppressWarnings("null")
			org.eclipse.ocl.pivot.@NonNull Class iClass = (org.eclipse.ocl.pivot.@NonNull Class)sourceAndArgumentValues[0];
			EObject element = iClass.createInstance();
			List<NewStatementPart> iNewStatementParts = iNewStatement.getOwnedParts();
			for (int i = 0; i < iNewStatementParts.size(); i++) {
				NewStatementPart iNewStatementPart = iNewStatementParts.get(i);
				Property iProperty = iNewStatementPart.getReferredProperty();
				Object value = sourceAndArgumentValues[i+1];
				EStructuralFeature eFeature = (EStructuralFeature)iProperty.getESObject();
				element.eSet(eFeature, value);
			}
			TypedModel typedModel = iNewStatement.getReferredTypedModel();
			assert typedModel != null;
			QVTiTypedModelInstance typedModelInstance = modelsManager.getTypedModelInstance(typedModel);
			typedModelInstance.add(element, isContained);
			return element;
		}

		@Override
		public @Nullable Object dispatch(@NonNull Executor executor, @NonNull OperationCallExp callExp, @Nullable Object sourceValue) {
			throw new UnsupportedOperationException();
		}
	}

	/**
	 * Model2ModelsManager supports OCL's global single model domain accesses by redirecting to QVTi's multiple models manager..
	 */
	private class Model2ModelsManager extends AbstractModelManager implements ModelManager.ModelManagerExtension2
	{
		@Override
		public @NonNull Set<@NonNull ? extends Object> get(org.eclipse.ocl.pivot.@NonNull Class type) {
			return modelsManager.get(type);
		}

		@Override
		public @NonNull Iterable<@NonNull Object> getOpposite(@NonNull Property target2sourceProperty, @NonNull Object sourceObject) {
			return modelsManager.getOpposite(target2sourceProperty, sourceObject);
		}
	}

	protected final boolean debugExceptions = AbstractTransformer.EXCEPTIONS.isActive();
	protected final boolean debugInvocations = AbstractTransformer.INVOCATIONS.isActive();
	protected final @NonNull EntryPoint entryPoint;
	protected final @NonNull ModeFactory modeFactory;
	protected final @NonNull ImperativeTransformation transformation;
	protected final @NonNull EntryPointsAnalysis entryPointsAnalysis;
	protected final @NonNull EntryPointAnalysis entryPointAnalysis;
	protected final @NonNull InvocationManager invocationManager;
	protected final @NonNull ObjectManager objectManager;
	protected final @NonNull QVTiModelsManager modelsManager;
	private final @NonNull Map<@NonNull Mapping, @NonNull Interval> mapping2interval = new HashMap<>();
	private @Nullable EObject transformationExecution = null;
	private @Nullable ModelManager model2ModelsManager = null;
	private @Nullable Map<@NonNull Property, @Nullable Property> compileTimeProperty2runtimeProperty = null;
	private @Nullable NewStatementOperation containedNewStatementOperation = null;
	private @Nullable NewStatementOperation notContainedNewStatementOperation = null;
	private Invocation.@Nullable Incremental currentInvocation = null;
	private @Nullable Map<@NonNull Mapping, @NonNull InvocationConstructor> mapping2invocationConstructor = null;
	private @Nullable Map<@NonNull Operation, Computation.@NonNull Constructor> operation2computationConstructor = null;

	public BasicQVTiExecutor(@NonNull QVTiEnvironmentFactory environmentFactory, @NonNull ImperativeTransformation transformation, @NonNull ModeFactory modeFactory) {
		this(environmentFactory, QVTimperativeUtil.getDefaultEntryPoint(transformation), modeFactory);
	}

	public BasicQVTiExecutor(@NonNull QVTiEnvironmentFactory environmentFactory, @NonNull EntryPoint entryPoint, @NonNull ModeFactory modeFactory) {
		super(environmentFactory);
		this.entryPoint = entryPoint;
		this.modeFactory = modeFactory;
		this.transformation = QVTimperativeUtil.getContainingTransformation(entryPoint);
		this.entryPointsAnalysis = environmentFactory.createEntryPointsAnalysis(transformation);
		entryPointsAnalysis.analyzeTransformation();
		this.entryPointAnalysis = entryPointsAnalysis.getEntryPointAnalysis(entryPoint);
		if (modeFactory.isLazy()) {
			this.invocationManager = new LazyInvocationManager(this);
			this.objectManager = new LazyObjectManager((LazyInvocationManager)invocationManager);
		}
		else {
			this.invocationManager = new IncrementalInvocationManager(this);
			this.objectManager = new IncrementalObjectManager((IncrementalInvocationManager)invocationManager);
		}
		objectManager.addSpeculatedEAttributes(entryPointAnalysis.getSpeculatedEAttributes());
		this.modelsManager = environmentFactory.createModelsManager(entryPointAnalysis);
		Interval rootInterval = invocationManager.getRootInterval();
		//		ModeFactory modeFactory = ModeFactory.NON_INCREMENTAL;// getModeFactory();
		for (@NonNull TypedModelInstance model : modelsManager.getTypedModelInstances()) {
			model.initConnections(rootInterval, modeFactory);
		}
	}

	@Override
	public @Nullable Resource addInputURI(@NonNull String modelName, @NonNull URI modelURI) {
		return modelsManager.addInputURI(modelName, modelURI);
	}

	@Override
	public @NonNull Resource addOutputURI(@NonNull String modelName, @NonNull URI modelURI) {
		return modelsManager.addOutputURI(modelName, modelURI);
	}

	@Override
	public void checkModels() throws CoreException {
		StringBuilder s = null;
		ResourceSet resourceSet = environmentFactory.getResourceSet();
		for (Resource resource : resourceSet.getResources()) {
			String messages = PivotUtil.formatResourceDiagnostics(resource.getErrors(), "Errors in " + resource.getURI().toString(), "\n");
			if (messages != null) {
				if (s == null) {
					s = new StringBuilder();
				}
				s.append(messages);
			}
		}
		if (s != null) {
			IStatus status = new Status(IStatus.ERROR, "getPluginId()", s.toString());
			throw new CoreException(status);
		}
	}

	@Override
	protected EvaluationVisitor.@NonNull EvaluationVisitorExtension createEvaluationVisitor() {
		IQVTiEvaluationVisitor visitor = new QVTiEvaluationVisitor(this);
		if (environmentFactory.isEvaluationTracingEnabled()) {
			// decorate the evaluation visitor with tracing support
			visitor = new QVTiTracingEvaluationVisitor(visitor);
			//	        ((QVTiTracingEvaluationVisitor)visitor).setVerboseLevel(QVTiTracingEvaluationVisitor.VERBOSE_LEVEL_HIGH);
		}
		return visitor;
	}

	public @NonNull String createGraph(@NonNull GraphStringBuilder s) {
		Execution2GraphVisitor execution2GraphVisitor = new Execution2GraphVisitor(s);
		invocationManager.accept(execution2GraphVisitor);
		objectManager.accept(execution2GraphVisitor);
		String string = execution2GraphVisitor.toString();
		assert string != null;
		return string;
	}

	/**
	 * Return (and if necessary create) the cached NewStatement creation.
	 * @param isContained
	 */
	protected @NonNull EObject createInstance(@NonNull NewStatement iNewStatement, @NonNull EvaluationVisitor undecoratedVisitor, boolean isContained) {
		NewStatementOperation newStatementOperation;
		if (isContained) {
			newStatementOperation = containedNewStatementOperation;
			if (newStatementOperation == null) {
				newStatementOperation = containedNewStatementOperation = new NewStatementOperation(true);
			}
		}
		else {
			newStatementOperation = notContainedNewStatementOperation;
			if (newStatementOperation == null) {
				newStatementOperation = notContainedNewStatementOperation = new NewStatementOperation(false);
			}
		}
		List<NewStatementPart> iNewStatementParts = iNewStatement.getOwnedParts();
		int iMax = iNewStatementParts.size();
		@Nullable Object @NonNull [] sourceAndArgumentValues = new @Nullable Object[iMax+1];
		sourceAndArgumentValues[0] = iNewStatement.getType();
		for (int i = 0 ; i < iMax; i++) {
			NewStatementPart iNewStatementPart = iNewStatementParts.get(i);
			assert iNewStatementPart != null;
			sourceAndArgumentValues[i+1] = iNewStatementPart.getOwnedExpression().accept(undecoratedVisitor);
		}
		@NonNull EObject element = (@NonNull EObject) getCachedEvaluationResult(newStatementOperation, iNewStatement, sourceAndArgumentValues);
		return element;
	}

	@Override
	protected EvaluationEnvironment.@NonNull EvaluationEnvironmentExtension createNestedEvaluationEnvironment(EvaluationEnvironment.@NonNull EvaluationEnvironmentExtension evaluationEnvironment, @NonNull NamedElement executableObject, @Nullable Object caller) {
		if (evaluationEnvironment instanceof QVTiEvaluationEnvironment) {
			return new QVTiNestedEvaluationEnvironment((QVTiEvaluationEnvironment) evaluationEnvironment, executableObject, caller);
		}
		else{
			return super.createNestedEvaluationEnvironment(evaluationEnvironment, executableObject, caller);
		}
	}

	@Override
	protected EvaluationEnvironment.@NonNull EvaluationEnvironmentExtension createRootEvaluationEnvironment(@NonNull NamedElement executableObject) {
		if (executableObject instanceof Transformation) {
			return new QVTiRootEvaluationEnvironment(this, (Transformation) executableObject);
		}
		else {
			return super.createRootEvaluationEnvironment(executableObject);
		}
	}

	@Override
	public void dispose() {
		modelsManager.dispose();
		super.dispose();
	}

	@Override
	public Boolean execute() {
		modelsManager.analyzeInputResources();
		initializeEvaluationEnvironment(transformation);
		getRootEvaluationEnvironment();
		StandardLibraryInternal standardLibrary = environmentFactory.getStandardLibrary();
		VariableDeclaration ownedContext = QVTbaseUtil.getContextVariable(standardLibrary, transformation);
		//		add(ownedContext, modelsManager.getTransformationInstance(transformation));
		add(ownedContext, getTransformationExecution());
		for (@NonNull TypedModel typedModel : QVTimperativeUtil.getModelParameters(transformation)) {
			if (!typedModel.isIsPrimitive() && !typedModel.isIsThis() && !typedModel.isIsTrace()) {
				ownedContext = QVTbaseUtil.getContextVariable(standardLibrary, typedModel);
				add(ownedContext, modelsManager.getTypedModelInstance(typedModel));
			}
		}
		return executeInternal();
	}

	@Override
	public Boolean execute(@Nullable String targetName) throws Exception {
		if (targetName == null) {
			return execute();
		}
		throw new UnsupportedOperationException("targetName must be specified using initTargetName");
	}

	protected Boolean executeInternal() {
		return (Boolean) getEvaluationVisitor().visit(transformation);
	}

	@Override
	public @NonNull QVTiEnvironmentFactory getEnvironmentFactory() {
		return (QVTiEnvironmentFactory) super.getEnvironmentFactory();
	}

	@Override
	public @NonNull QVTiEvaluationEnvironment getEvaluationEnvironment() {
		return (QVTiEvaluationEnvironment) super.getEvaluationEnvironment();
	}

	@Override
	public @NonNull Interval getInterval(@NonNull Mapping asMapping) {
		Interval interval = mapping2interval.get(asMapping);
		return ClassUtil.nonNullState(interval);
	}

	@Override
	public @NonNull InvocationConstructor getInvocationConstructor(@NonNull MappingCall mappingCall, @NonNull EvaluationVisitor undecoratedVisitor) {
		Mapping asMapping = ClassUtil.nonNullState(mappingCall.getReferredMapping());
		Map<@NonNull Mapping, @NonNull InvocationConstructor> mapping2invocationConstructor2 = mapping2invocationConstructor;
		if (mapping2invocationConstructor2 == null) {
			mapping2invocationConstructor = mapping2invocationConstructor2 = new HashMap<>();
		}
		InvocationConstructor invocationConstructor = mapping2invocationConstructor2.get(asMapping);
		if (invocationConstructor == null) {
			invocationConstructor = new InterpretedInvocationConstructor(this, asMapping, mappingCall, undecoratedVisitor);
			mapping2invocationConstructor2.put(asMapping, invocationConstructor);
		}
		return invocationConstructor;
	}

	@Override
	public @NonNull InvocationManager getInvocationManager() {
		return invocationManager;
	}

	/**
	 * Gets the named TypedModel.
	 */
	@Override
	public @Nullable Resource getModel(@NonNull String name) {
		TypedModel typedModel = getTypedModel(name);
		return modelsManager.getModel(typedModel);
	}

	@Override
	public @NonNull ModelManager getModelManager() {
		ModelManager model2ModelsManager2 = model2ModelsManager;
		if (model2ModelsManager2 == null) {
			model2ModelsManager2 = model2ModelsManager = new Model2ModelsManager();
		}
		return model2ModelsManager2;
	}

	@Override
	public @NonNull QVTiModelsManager getModelsManager() {
		return modelsManager;
	}

	//	public @NonNull Collection<@NonNull EObject> getRootEObjects(@NonNull String name) {
	//		return modelsManager.getRootEObjects(getTypedModel(name));
	//	}

	public @NonNull ImperativeTransformation getTransformation() {
		return transformation;
	}

	@Override
	public @Nullable EObject getTransformationExecution() {
		if (transformationExecution == null) {
			org.eclipse.ocl.pivot.Class runtimeContextClass = QVTimperativeUtil.getRuntimeContextClass(transformation);
			EObject contextEObject = runtimeContextClass.getESObject();
			if (contextEObject instanceof EClass) {
				EClass contextEClass = (EClass) contextEObject;
				EFactory eFactory = contextEClass.getEPackage().getEFactoryInstance();
				transformationExecution = eFactory.create(contextEClass);
			}
			Map<@NonNull Property, @Nullable Property> compileTimeProperty2runtimeProperty2 = compileTimeProperty2runtimeProperty = new HashMap<>();
			org.eclipse.ocl.pivot.Class compileTimeContextClass = QVTimperativeUtil.getCompileTimeContextClass(transformation);
			for (@NonNull Property compileTimeProperty : PivotUtil.getOwnedProperties(compileTimeContextClass)) {
				if (!compileTimeProperty.isIsDerived() && !compileTimeProperty.isIsTransient() && !compileTimeProperty.isIsVolatile() && (compileTimeProperty.getOpposite() == null)) {
					Property runtimeProperty = NameUtil.getNameable(runtimeContextClass.getOwnedProperties(), compileTimeProperty.getName());
					compileTimeProperty2runtimeProperty2.put(compileTimeProperty, runtimeProperty);
				}
			}
		}
		return transformationExecution;
	}

	protected @Nullable Property getTransformationExecutionProperty(@NonNull Property compileTimeProperty) {
		return compileTimeProperty2runtimeProperty != null ? compileTimeProperty2runtimeProperty.get(compileTimeProperty) : null;
	}

	@Override
	public @NonNull Transformer getTransformer() {
		throw new UnsupportedOperationException("Transformer API not implemented by interpreted executor");
	}

	public @NonNull TypedModel getTypedModel(@NonNull String name) {
		TypedModel typedModel = NameUtil.getNameable(QVTimperativeUtil.getModelParameters(transformation), name);
		if (typedModel == null) {
			//			if (QVTbaseUtil.TRACE_TYPED_MODEL_NAME.equals(name)) {
			//				typedModel = NameUtil.getNameable(QVTimperativeUtil.getOwnedTypedModels(transformation), QVTscheduleConstants.MIDDLE_DOMAIN_NAME);		// FIXME unify name
			//			}
			//			if (typedModel == null) {
			throw new IllegalStateException("Unknown TypedModel '" + name + "'");
			//			}
		}
		return typedModel;
	}

	@Override
	public int getTypedModelIndex(@NonNull String targetModelName) {
		int index = 0;
		for (@NonNull TypedModel typedModel : QVTimperativeUtil.getModelParameters(transformation)) {
			if (targetModelName.equals(typedModel.getName())) {
				return index;
			}
			index++;
		}
		return -1;
	}

	@Override
	public @NonNull TypedModelInstance getTypedModelInstance(@NonNull String modelName) {
		return modelsManager.getTypedModelInstance(modelName);
	}

	@Override
	public @Nullable Object internalExecuteFunctionCallExp(@NonNull OperationCallExp operationCallExp,
			@NonNull Function asFunction, @Nullable Object @NonNull [] boxedSourceAndArgumentValues) {
		Map<@NonNull Operation, Computation.@NonNull Constructor> operation2computationConstructor2 = operation2computationConstructor;
		if (operation2computationConstructor2 == null) {
			operation2computationConstructor = operation2computationConstructor2 = new HashMap<>();
		}
		Computation.Constructor computationConstructor = operation2computationConstructor2.get(asFunction);
		if (computationConstructor == null) {
			computationConstructor = new AbstractComputationConstructor(idResolver)
			{
				@Override
				public @NonNull Computation newInstance(@Nullable Object @NonNull [] theseValues) {
					Computation.Incremental computation = new AbstractComputation.Incremental(PivotUtil.getName(asFunction))
					{
						protected Object result = internalExecuteFunctionCallExpNested(operationCallExp, asFunction, theseValues);

						@Override
						public @Nullable Object getResult() {
							return result;
						}

						@Override
						public boolean isEqual(@NonNull IdResolver idResolver, @Nullable Object @NonNull [] thoseValues) {
							int iMax = thoseValues.length;
							if (iMax != theseValues.length) {
								return false;
							}
							for (int i = 0; i < iMax; i++) {
								if (!idResolver.oclEquals(theseValues[i], thoseValues[i])) {
									return false;
								}
							}
							return true;
						}

						@Override
						public String toString() {
							return operationCallExp.getReferredOperation().getName() + "@" + Integer.toHexString(System.identityHashCode(this));
						}
					};
					return computation;
				}
			};
			operation2computationConstructor2.put(asFunction, computationConstructor);
		}
		Computation computation = computationConstructor.getUniqueComputation(boxedSourceAndArgumentValues);
		return computation.getResult();
	}

	protected @Nullable Object internalExecuteFunctionCallExpNested(@NonNull OperationCallExp operationCallExp,
			@NonNull Function referredFunction, @Nullable Object @NonNull [] boxedSourceAndArgumentValues) {
		//		PivotUtil.checkExpression(expressionInOCL);
		EvaluationEnvironment nestedEvaluationEnvironment = pushEvaluationEnvironment(referredFunction, (TypedElement)operationCallExp);
		//		nestedEvaluationEnvironment.add(ClassUtil.nonNullModel(expressionInOCL.getOwnedContext()), sourceValue);
		List<Parameter> parameters = referredFunction.getOwnedParameters();
		if (!parameters.isEmpty()) {
			for (int i = 0; i < parameters.size(); i++) {
				Object value = boxedSourceAndArgumentValues[i+1];
				nestedEvaluationEnvironment.add(ClassUtil.nonNullModel(parameters.get(i)), value);
			}
		}
		try {
			OCLExpression bodyExpression = referredFunction.getQueryExpression();
			assert bodyExpression != null;
			Object result = evaluate(bodyExpression);
			assert !(result instanceof NullValue);
			return result;
		}
		catch (InvalidValueException e) {
			throw e;
		}
		catch (Exception e) {
			// This is a backstop. Library operations should catch their own exceptions
			//  and produce a better reason as a result.
			throw new InvalidValueException(e, PivotMessagesInternal.FailedToEvaluate_ERROR_, referredFunction, ILabelGenerator.Registry.INSTANCE.labelFor(null), operationCallExp);
		}
		finally {
			popEvaluationEnvironment();
		}
	}

	private Object internalExecuteInvocation(@NonNull InterpretedInvocation invocation, @NonNull Object @NonNull [] theseValues, @NonNull MappingCall mappingCall, @NonNull EvaluationVisitor undecoratedVisitor) {
		currentInvocation = invocation;
		try {
			return internalExecuteMappingCallInternal(mappingCall, theseValues, undecoratedVisitor);
		}
		finally {
			currentInvocation = null;
		}
	}

	@Override
	public @Nullable Object internalExecuteMappingCall(@NonNull MappingCall mappingCall, @NonNull Object @NonNull [] boundValues, @NonNull EvaluationVisitor undecoratedVisitor) {
		Mapping asMapping = ClassUtil.nonNullState(mappingCall.getReferredMapping());
		if (modeFactory.isLazy()) {
			if (!entryPointAnalysis.isHazardous(asMapping)) {
				return internalExecuteMappingCallInternal(mappingCall, boundValues, undecoratedVisitor);
			}
		}
		InvocationConstructor invocationConstructor = getInvocationConstructor(mappingCall, undecoratedVisitor);
		invocationConstructor.invoke(boundValues);
		return null;
	}

	protected @Nullable Object internalExecuteMappingCallInternal(@NonNull MappingCall mappingCall, @NonNull Object @NonNull [] boundValues, @NonNull EvaluationVisitor undecoratedVisitor) {
		Mapping calledMapping = mappingCall.getReferredMapping();
		if (calledMapping != null) {
			pushEvaluationEnvironment(calledMapping, mappingCall);
			try {
				int index = 0;
				for (@NonNull MappingParameterBinding binding : QVTimperativeUtil.getOwnedMappingParameterBindings(mappingCall)) {
					MappingParameter boundVariable = ClassUtil.nonNullState(binding.getBoundVariable());
					Object boundValue = boundValues[index++];
					if (binding instanceof AppendParameterBinding) {	// FIXME visit the bindings
						if (!replace(boundVariable, boundValue, false)) {
							return false;
						}
					}
					else if (binding instanceof GuardParameterBinding) {
						//						if (boundValue instanceof Connection) {
						//							boundValue = ((Connection)boundValue).
						//						}
						if (!replace(boundVariable, boundValue, ((GuardParameterBinding)binding).isIsCheck())) {
							return false;
						}
					}
					else if (binding instanceof LoopParameterBinding) {
						if (!replace(boundVariable, boundValue, ((LoopParameterBinding)binding).isIsCheck())) {
							return false;
						}
					}
					else if (binding instanceof SimpleParameterBinding) {
						if (!replace(boundVariable, boundValue, ((SimpleParameterBinding)binding).isIsCheck())) {
							return false;
						}
					}
					else {
						assert false;
					}
				}
				calledMapping.accept(undecoratedVisitor);
			}
			finally {
				popEvaluationEnvironment();
			}
		}
		return true;
	}

	@Override
	public @Nullable Object internalExecuteMapping(@NonNull Mapping mapping, @NonNull EvaluationVisitor undecoratedVisitor) {
		boolean success = false;
		boolean isSpeculation = false;
		try {
			for (Statement statement : mapping.getOwnedStatements()) {
				Object result = statement.accept(undecoratedVisitor);
				if (result != Boolean.TRUE) {
					return success;
				}
			}
			success = true;
			return success;
		}
		catch (InvocationFailedException e) {
			isSpeculation = e.isSpeculation;
			throw e;
		}
		catch (Throwable e) {
			// Mapping failures are just mappings that never happened.
			if (debugExceptions) {
				AbstractTransformer.EXCEPTIONS.println("Execution failure in " + mapping.getName() + " : " + e);
			}
			throw e;
			//			return success;
		}
		finally {
			if (!isSpeculation) {
				for (@NonNull MappingParameter mappingParameter : QVTimperativeUtil.getOwnedMappingParameters(mapping)) {
					if (mappingParameter instanceof GuardParameter) {
						Property successProperty = ((GuardParameter)mappingParameter).getSuccessProperty();
						if (successProperty != null) {
							Object guardVariable = getValueOf(mappingParameter);
							if (guardVariable != null) {
								successProperty.initValue(guardVariable, success);
							}
						}
					}
				}
			}
		}
	}

	@Override
	public @Nullable Object internalExecuteNavigationCallExp(@NonNull NavigationCallExp navigationCallExp, @NonNull Property referredProperty, @Nullable Object sourceValue) {
		if (sourceValue == transformationExecution) {
			Property transformationExecutionProperty = getTransformationExecutionProperty(referredProperty);
			if (transformationExecutionProperty != null) {
				referredProperty = transformationExecutionProperty;
			}
		}
		if (referredProperty.isIsImplicit()) {
			QVTiModelsManager modelManager = getModelsManager();
			Integer cacheIndex = entryPointAnalysis.getCacheIndex((OppositePropertyCallExp) navigationCallExp);
			if (cacheIndex != null) {
				if (sourceValue != null) {
					return modelManager.getUnnavigableOpposite(cacheIndex, sourceValue);
				}
				else {
					throw new InvalidValueException("Failed to evaluate '" + referredProperty + "'", sourceValue, navigationCallExp);
				}
			}
		}
		Mapping asMapping = QVTimperativeUtil.basicGetContainingMapping(navigationCallExp);
		Object ecoreValue;
		//		if ((asMapping != null) && transformationAnalysis.isHazardousRead(asMapping, navigationCallExp)) {		// null within queries
		if ((asMapping != null) && isHazardous2(navigationCallExp)) {		// null within queries
			//			assert false; 		// Should use an AccessStatement
			//			assert sourceValue != null;
			if (sourceValue == null) {
				throw new InvalidValueException("Null source for '" + referredProperty + "'", sourceValue, navigationCallExp);
			}
			boolean isOpposite = false;
			EStructuralFeature eFeature = (EStructuralFeature)referredProperty.getESObject();
			if (eFeature == null) {
				assert referredProperty.isIsImplicit();
				isOpposite = true;
				eFeature = (EStructuralFeature)referredProperty.getOpposite().getESObject();
			}
			objectManager.getting(sourceValue, eFeature, isOpposite);
			ecoreValue = internalExecuteNavigationCallExpInternal(navigationCallExp, referredProperty, sourceValue);
			if (debugInvocations) {
				AbstractTransformer.INVOCATIONS.println("got " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + LabelUtil.getLabel(sourceValue) + " = " + LabelUtil.getLabel(ecoreValue));
			}
		}
		else {
			ecoreValue = internalExecuteNavigationCallExpInternal(navigationCallExp, referredProperty, sourceValue);
		}
		if (!modeFactory.isLazy()) {
			Invocation.Incremental currentInvocation2 = currentInvocation;
			if (currentInvocation2 != null) {			// Null at root
				assert sourceValue != null;
				EStructuralFeature eFeature = (EStructuralFeature)referredProperty.getESObject();
				assert currentInvocation2 != null;
				objectManager.got(currentInvocation2, sourceValue, eFeature, ecoreValue);
			}
		}
		return ecoreValue;
	}

	protected @Nullable Object internalExecuteNavigationCallExpInternal(@NonNull NavigationCallExp navigationCallExp,
			@NonNull Property referredProperty, @Nullable Object sourceValue) {
		return super.internalExecuteNavigationCallExp(navigationCallExp, referredProperty, sourceValue);
	}

	@Override
	public @Nullable Object internalExecuteNewStatement(@NonNull NewStatement iNewStatement, @NonNull EvaluationVisitor undecoratedVisitor) {

		boolean isContained = false;		// FIXME compute containment guarantee
		OCLExpression ownedExpression = iNewStatement.getOwnedExpression();
		List<NewStatementPart> ownedParts = iNewStatement.getOwnedParts();
		Object result;
		if (ownedExpression != null) {
			assert ownedParts.isEmpty();
			Object initValue = ownedExpression.accept(undecoratedVisitor);
			getEvaluationEnvironment().add(iNewStatement, initValue);
			replace(iNewStatement, initValue);
			TypedModel typedModel = iNewStatement.getReferredTypedModel();
			assert typedModel != null;
			EObject ecoreValue = (EObject) getIdResolver().ecoreValueOf(null, initValue);
			assert ecoreValue != null;
			modelsManager.getTypedModelInstance(typedModel).add(ecoreValue, isContained);
			result = ecoreValue;
		}
		else {
			// Realized variables are in the mapping's target bottom pattern
			// and create elements in the target model. The realized variables
			// are being visited for each binding of variable in the mapping.
			Type type = iNewStatement.getType();
			if (!(type instanceof org.eclipse.ocl.pivot.Class)) {
				result = null;
			}
			else {
				TypedModel typedModel = iNewStatement.getReferredTypedModel();
				assert typedModel != null;
				org.eclipse.ocl.pivot.Class iClass = (org.eclipse.ocl.pivot.Class)type;
				if (iClass.isIsAbstract()) {
					Mapping asMapping = QVTimperativeUtil.getContainingMapping(iNewStatement);
					throw new IllegalStateException("Attempted to create instance of abstract '" + iClass.getName() + "' in " + asMapping.getName());
				}
				EObject element;
				if (ownedParts.isEmpty()) {
					element = iClass.createInstance();
					QVTiTypedModelInstance typedModelInstance = modelsManager.getTypedModelInstance(typedModel);
					typedModelInstance.add(element, isContained);
				}
				else {
					element = createInstance(iNewStatement, undecoratedVisitor, isContained);
				}
				// Add the realize variable binding to the environment
				if (!replace(iNewStatement, element, false)) {
					result = null;
				}
				else {
					result =element;
				}
			}
		}
		if ((result != null) && modeFactory.isIncremental()) {
			Invocation.Incremental currentInvocation2 = currentInvocation;
			assert currentInvocation2 != null;
			objectManager.created(currentInvocation2, result);
			/*			DomainUsage domainUsage = getEvaluationEnvironment().getUsageFor(realizedVariable);
			ClassStatus classStatus = statusManager.getClassStatus(domainUsage, realizedVariable.getType(), (EObject)element);
			MappingStatus mappingStatus = findMappingStatus();
			assert mappingStatus != null;
			mappingStatus.getOutputs().add(classStatus); */
		}
		return result;
	}

	@Override
	public void internalExecuteSetStatement(@NonNull SetStatement setStatement, @NonNull Object sourceObject, @Nullable Object ecoreValue) {
		Property targetProperty = QVTimperativeUtil.getTargetProperty(setStatement);
		boolean isPartial = setStatement.isIsPartial();
		if (isPartial) {		// FIXME add Property.addValue() API
			//	assert ValueUtil.isEcore(ecoreValue);
			EStructuralFeature eTarget = (EStructuralFeature)targetProperty.getESObject();
			EStructuralFeature eFeature = eTarget;
			List<Object> eObjects = (List<Object>) ((EObject)sourceObject).eGet(eFeature);
			eObjects.add(ecoreValue);
		}
		else {
			targetProperty.initValue(sourceObject, ecoreValue);
		}
		Integer cacheIndex = entryPointsAnalysis.getCacheIndex(setStatement);
		if (cacheIndex != null) {
			modelsManager.setUnnavigableOpposite(cacheIndex, sourceObject, ecoreValue);
		}
		if (modeFactory.isLazy()) {
			if (setStatement.isIsNotify()) {
				assert targetProperty != null;
				EStructuralFeature eFeature = (EStructuralFeature)targetProperty.getESObject();
				objectManager.assigned(sourceObject, eFeature, ecoreValue, isPartial);
			}
		}
		else {
			assert targetProperty != null;
			EStructuralFeature eFeature = (EStructuralFeature)targetProperty.getESObject();
			Invocation.Incremental currentInvocation2 = currentInvocation;
			assert currentInvocation2 != null;
			objectManager.assigned(currentInvocation2, sourceObject, eFeature, ecoreValue, isPartial);
		}
	}

	@Override
	public @Nullable Boolean internalExecuteSpeculateStatement(@NonNull SpeculateStatement speculateStatement) {
		Mapping iMapping = QVTimperativeUtil.getContainingMapping(speculateStatement);
		for (@NonNull MappingParameter iMappingParameter : QVTimperativeUtil.getOwnedMappingParameters(iMapping)) {
			if (iMappingParameter instanceof GuardParameter) {
				Object thisParameter = getValueOf(iMappingParameter);
				assert thisParameter != null;
				Property successProperty = ((GuardParameter)iMappingParameter).getSuccessProperty();
				if (successProperty != null) {	// Should be exactly one, but may be nested loop handles a trace merge
					EAttribute eAttribute = (EAttribute) successProperty.getESObject();
					assert eAttribute != null;
					Speculating outputSpeculatingSlotState = objectManager.getSpeculatingSlotState(thisParameter, eAttribute);
					Boolean outputStatus = outputSpeculatingSlotState.getSpeculationStatus();
					if (outputStatus != Boolean.TRUE) {
						if (outputStatus == Boolean.FALSE) {
							outputSpeculatingSlotState.setSpeculated(false);
							//	outputSpeculatingSlotState.assigned(thisParameter, eAttribute, Boolean.FALSE, false);
							return Boolean.FALSE;
						}
						boolean needsSpeculation = false;
						for (@NonNull OCLExpression iExpression : QVTimperativeUtil.getOwnedExpressions(speculateStatement)) {
							if (iExpression instanceof PropertyCallExp) {
								PropertyCallExp iCallExpression = (PropertyCallExp)iExpression;
								OCLExpression sourceExpression = QVTimperativeUtil.getOwnedSource(iCallExpression);
								Object sourceObject = evaluate(sourceExpression);
								if (sourceObject != null) {
									Property accessProperty = QVTimperativeUtil.getReferredProperty(iCallExpression);
									EAttribute accessAttribute = (EAttribute) accessProperty.getESObject();
									assert accessAttribute != null;
									//									SlotState.Speculating inputSpeculatingSlotState = getSpeculatingSlotState(objectManager, outputSpeculatingSlotState, sourceObject, accessAttribute);
									SlotState.Speculating inputSpeculatingSlotState = objectManager.getSpeculatingSlotState(sourceObject, accessAttribute);
									Boolean inputStatus = inputSpeculatingSlotState.getSpeculationStatus();
									if (inputStatus != Boolean.TRUE) {
										if (inputStatus == Boolean.FALSE) {
											outputSpeculatingSlotState.setSpeculated(false);
											//	outputSpeculatingSlotState.assigned(thisParameter, eAttribute, Boolean.FALSE, false);
											return Boolean.FALSE;
										}
										needsSpeculation = true;
										outputSpeculatingSlotState.addInput(inputSpeculatingSlotState);
									}
								}
								else if (sourceExpression.isIsRequired()) {
									throw new InvalidValueException("null expression for speculated property source");
								}
							}
						}
						if (needsSpeculation) {
							throw new InvocationFailedException(outputSpeculatingSlotState, true);
						}
					}
					//	else {
					//	outputSpeculatingSlotState.setStatus(Boolean.TRUE);	// redundant ??
					//	outputSpeculatingSlotState.assigned(thisParameter, eAttribute, Boolean.TRUE, false);
					//	}
				}
			}
		}
		return Boolean.TRUE;
	}

	@Override
	public @Nullable Object internalExecuteTransformation(@NonNull ImperativeTransformation transformation, @NonNull EvaluationVisitor undecoratedVisitor) {
		CallExp callExp = PivotFactory.eINSTANCE.createOperationCallExp();		// FIXME TransformationCallExp
		pushEvaluationEnvironment(entryPoint, (TypedElement)callExp);
		try {
			Interval rootInterval = getInvocationManager().getRootInterval();
			mapping2interval.put(entryPoint, rootInterval);
			Iterable<@NonNull TypedModel> inputTypedModels = QVTimperativeUtil.getInputTypedModels(entryPoint);
			for (@NonNull MappingParameter mappingParameter : QVTimperativeUtil.getOwnedMappingParameters(entryPoint)) {
				if (mappingParameter instanceof AppendParameter) {
					org.eclipse.ocl.pivot.Class type = QVTimperativeUtil.getClassType(mappingParameter);
					org.eclipse.ocl.pivot.Package asPackage = PivotUtil.getContainingPackage(type);
					assert asPackage != null;
					TypedModelInstance modelInstance = null;
					for (@NonNull TypedModel asTypedModel : inputTypedModels) {
						if (asTypedModel.getUsedPackage().contains(asPackage)) {
							assert modelInstance == null;
							modelInstance = modelsManager.getTypedModelInstance(asTypedModel);
							assert modelInstance != null;
						}
					}
					Connection connection = rootInterval.createConnection(QVTimperativeUtil.getName(mappingParameter), type.getTypeId(), false, ModeFactory.NON_INCREMENTAL);
					if (modelInstance != null) {
						Iterable<@NonNull ? extends Object> objectsOfKind = modelInstance.getObjectsOfKind(type);
						for (@NonNull Object object : objectsOfKind) {
							connection.appendElement(object);
						}
					}
					getEvaluationEnvironment().add(mappingParameter, connection);
				}
			}
			entryPoint.accept(undecoratedVisitor);			// Use an outer InvocationConstructor?
			getInvocationManager().flush();
		}
		finally {
			popEvaluationEnvironment();
		}
		return true;
	}

	private boolean isHazardous2(@NonNull NavigationCallExp asNavigationCallExp) {
		for (EObject eObject = asNavigationCallExp; eObject != null; eObject = eObject.eContainer()) {
			if (eObject instanceof ObservableStatement) {
				List<Property> observedProperties = ((ObservableStatement)eObject).getObservedProperties();
				Property navigatedProperty = PivotUtil.getReferredProperty(asNavigationCallExp);
				return observedProperties.contains(navigatedProperty);
			}
		}
		return false;
	}

	@Override
	public void replace(@NonNull TypedElement asVariable, @Nullable Object value) {
		if (value == null) {
			if (asVariable.isIsRequired()) {
				throw new InvalidValueException("Attempted to assign null value to " + asVariable);
			}
		}
		super.replace(asVariable, value);
	}

	@Override
	public boolean replace(@NonNull TypedElement asVariable, @Nullable Object value, boolean checkType) {
		if (value == null) {
			if (asVariable.isIsRequired()) {
				//				throw new InvalidValueException("Attempted to assign null value to " + asVariable);
				return false;
			}
		}
		else if (checkType) {
			Type valueType = getIdResolver().getDynamicTypeOf(value);
			//			Type valueType2 = getIdResolver().getStaticTypeOf(value);
			//			Type valueType = valueType1;
			Type variableType = ClassUtil.nonNullState(asVariable.getType());
			if (!valueType.conformsTo(getStandardLibrary(), variableType)) {
				//				throw new InvalidValueException("Attempted to assign incompatible value to " + asVariable);
				return false;
			}
		}
		super.replace(asVariable, value);
		return true;
	}

	@Override
	public void saveModels(@Nullable Map<?, ?> saveOptions) throws IOException {
		modelsManager.saveModels(saveOptions);
	}

	@Override
	public void saveOutput(@NonNull String modelName, @NonNull URI uri) {
		Resource outputResource = ClassUtil.nonNullState(environmentFactory.getResourceSet().createResource(uri));
		TypedModelInstance typedModelInstance = getTypedModelInstance(modelName);
		typedModelInstance.addOutputResource(outputResource);
	}

	public void saveTransformation(URI saveURI, Map<?,?> options) throws IOException {
		XMLResource resource = (XMLResource) transformation.eResource();
		//    	new AS2ID().assignIds(resource.getResourceSet());
		if (saveURI != null) {
			resource.setURI(saveURI);
		}
		((ASResource)resource).setSaveable(true);
		resource.save(options);
	}

	@Override
	public void setContextualProperty(@NonNull String propertyName, Object value) {
		EObject transformationExecution = getTransformationExecution();
		if (transformationExecution == null) {
			throw new IllegalArgumentException("No contextual instance available");
		}
		EClass txEClass = transformationExecution.eClass();
		EStructuralFeature eStructuralFeature = txEClass.getEStructuralFeature(propertyName);
		if (eStructuralFeature == null) {
			throw new IllegalArgumentException("No '" + propertyName + "' contextual property in '" + txEClass.getName());
		}
		transformationExecution.eSet(eStructuralFeature, value);
	}

	public void setExternalURI(@NonNull String name, @NonNull URI modelURI) throws IOException {
		TypedModel typedModel = getTypedModel(name);
		Resource resource = modelsManager.getModel(typedModel);
		if (resource != null) {
			for (EObject eObject : resource.getContents()) {
				if (eObject instanceof Model) {
					((Model)eObject).setExternalURI(modelURI.toString());
				}
			}
		}
	}

	@Override
	public void setSuppressFailureDiagnosis(boolean suppressFailureDiagnosis) {}
}
