[422933] Push results to current evaluation environment
diff --git a/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMEvaluationVisitor.java b/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMEvaluationVisitor.java
index a84b06f..04ffbf0 100644
--- a/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMEvaluationVisitor.java
+++ b/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMEvaluationVisitor.java
@@ -127,18 +127,18 @@
 	}
 
 	@Override
-	protected Object postVisit(@NonNull Visitable visitable, @Nullable Element preState, @Nullable Object result) {
+	protected Object postVisit(@NonNull Visitable visitable, @Nullable Element parentElement, @Nullable Object result) {
 		Element element = (Element)visitable;
 		if (VMVirtualMachine.POST_VISIT.isActive()) {
 			VMVirtualMachine.POST_VISIT.println("[" + Thread.currentThread().getName() + "] " + element.eClass().getName() + ": " + element.toString() + " => " + result);
 		}
-		setCurrentEnvInstructionPointer(preState);
+		setCurrentEnvInstructionPointer(parentElement);
 		IVMEvaluationEnvironment<?> evalEnv = getEvaluationEnvironment();
-		postVisit(evalEnv, element, preState);
+		postVisit(evalEnv, element, result, parentElement);
 		return result;
 	}
 
-	protected abstract void postVisit(@NonNull IVMEvaluationEnvironment<?> evalEnv, @NonNull Element element, @Nullable Element preState);
+	protected abstract void postVisit(@NonNull IVMEvaluationEnvironment<?> evalEnv, @NonNull Element element, @Nullable Object result, @Nullable Element parentElement);
 
 	@Override
 	protected @Nullable Element preVisit(@NonNull Visitable visitable) {
diff --git a/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMNestedEvaluationEnvironment.java b/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMNestedEvaluationEnvironment.java
index 18f350c..eae6d8e 100644
--- a/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMNestedEvaluationEnvironment.java
+++ b/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMNestedEvaluationEnvironment.java
@@ -12,17 +12,20 @@
 package org.eclipse.qvtd.debug.evaluator;
 
 import java.util.Map;
+import java.util.Stack;
 
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.ocl.examples.debug.vm.UnitLocation;
 import org.eclipse.ocl.examples.debug.vm.core.VMDebugCore;
+import org.eclipse.ocl.examples.debug.vm.evaluator.IVMEvaluationEnvironment;
 import org.eclipse.ocl.examples.debug.vm.utils.ASTBindingHelper;
 import org.eclipse.ocl.examples.debug.vm.utils.VMRuntimeException;
 import org.eclipse.ocl.examples.debug.vm.utils.VMStackTraceBuilder;
 import org.eclipse.ocl.examples.pivot.Element;
 import org.eclipse.ocl.examples.pivot.NamedElement;
+import org.eclipse.ocl.examples.pivot.Variable;
 import org.eclipse.qvtd.pivot.qvtbase.Transformation;
 import org.eclipse.qvtd.pivot.qvtimperative.evaluation.QVTiNestedEvaluationEnvironment;
 
@@ -32,6 +35,7 @@
 	private @NonNull NamedElement myOperation;
     private final int myStackDepth;
 	private final long id;
+	private final @NonNull Stack<StepperEntry> stepperStack = new Stack<StepperEntry>();
     
 	public QVTiVMNestedEvaluationEnvironment(@NonNull IQVTiVMEvaluationEnvironment evaluationEnvironment, long id, @NonNull NamedElement operation) {
 		super(evaluationEnvironment);
@@ -100,6 +104,11 @@
 	}
 
 	@Override
+	@NonNull public Variable getPCVariable() {
+		return getRootEvaluationEnvironment().getPCVariable();
+	}
+
+	@Override
 	public @Nullable IQVTiVMEvaluationEnvironment getParentEvaluationEnvironment() {
 		return (IQVTiVMEvaluationEnvironment) super.getParentEvaluationEnvironment();
 	}
@@ -109,6 +118,11 @@
 		return (QVTiVMRootEvaluationEnvironment) rootEvaluationEnvironment;
 	}
 
+	@Override
+	public @NonNull Stack<IVMEvaluationEnvironment.StepperEntry> getStepperStack() {
+		return stepperStack;
+	}
+
 	public boolean isDeferredExecution() {
 		return getRootEvaluationEnvironment().isDeferredExecution();
 	}
diff --git a/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMNestedEvaluationVisitor.java b/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMNestedEvaluationVisitor.java
index 84a821d..6ccc43f 100644
--- a/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMNestedEvaluationVisitor.java
+++ b/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMNestedEvaluationVisitor.java
@@ -48,8 +48,8 @@
 		return root;
 	}
 
-	protected void postVisit(@NonNull IVMEvaluationEnvironment<?> evalEnv, @NonNull Element element, @Nullable Element preState) {
-		root.postVisit(evalEnv, element, preState);
+	protected void postVisit(@NonNull IVMEvaluationEnvironment<?> evalEnv, @NonNull Element element, @Nullable Object result, @Nullable Element parentElement) {
+		root.postVisit(evalEnv, element, result, parentElement);
 	}
 
 	protected @Nullable Element preVisit(@NonNull IVMEvaluationEnvironment<?> evalEnv, @NonNull Element element) {
diff --git a/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMRootEvaluationEnvironment.java b/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMRootEvaluationEnvironment.java
index e5ba43f..426028d 100644
--- a/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMRootEvaluationEnvironment.java
+++ b/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMRootEvaluationEnvironment.java
@@ -15,6 +15,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Stack;
 
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.jdt.annotation.NonNull;
@@ -24,8 +25,12 @@
 import org.eclipse.ocl.examples.debug.vm.utils.ASTBindingHelper;
 import org.eclipse.ocl.examples.debug.vm.utils.VMRuntimeException;
 import org.eclipse.ocl.examples.debug.vm.utils.VMStackTraceBuilder;
+import org.eclipse.ocl.examples.domain.utilities.DomainUtil;
 import org.eclipse.ocl.examples.pivot.Element;
 import org.eclipse.ocl.examples.pivot.NamedElement;
+import org.eclipse.ocl.examples.pivot.PivotFactory;
+import org.eclipse.ocl.examples.pivot.PivotPackage;
+import org.eclipse.ocl.examples.pivot.Variable;
 import org.eclipse.ocl.examples.pivot.manager.MetaModelManager;
 import org.eclipse.qvtd.debug.core.QVTiDebugCore;
 import org.eclipse.qvtd.pivot.qvtbase.Transformation;
@@ -44,11 +49,17 @@
 //    private Trace myTraces;
 	private @NonNull Element myCurrentIP;
 	private final long id;
+	private final @NonNull Variable pcVariable;
+	private final @NonNull Stack<StepperEntry> stepperStack = new Stack<StepperEntry>();
 
     public QVTiVMRootEvaluationEnvironment(@NonNull MetaModelManager metaModelManager, @NonNull QVTiModelManager modelManager, @NonNull Transformation transformation, long id) {
 		super(metaModelManager, modelManager, transformation);
 		myCurrentIP = transformation;
 		this.id = id;
+		pcVariable = DomainUtil.nonNullEMF(PivotFactory.eINSTANCE.createVariable());
+		pcVariable.setName("$pc");
+		String typeName = DomainUtil.nonNullEMF(PivotPackage.Literals.OCL_EXPRESSION.getName());
+		pcVariable.setType(metaModelManager.getPivotType(typeName));
 	}
 
 	@Override
@@ -143,10 +154,20 @@
 	}
 
 	@Override
+	@NonNull public Variable getPCVariable() {
+		return pcVariable;
+	}
+
+	@Override
 	public @NonNull QVTiVMRootEvaluationEnvironment getRootEvaluationEnvironment() {
 		return this;
 	}
 
+	@Override
+	public @NonNull Stack<org.eclipse.ocl.examples.debug.vm.evaluator.IVMEvaluationEnvironment.StepperEntry> getStepperStack() {
+		return stepperStack;
+	}
+
     @Override
 	public boolean isDeferredExecution() {
 		return myIsDeferedExecution;
@@ -189,7 +210,7 @@
 			saveThrownException(exception);
 			exception.setStackVMTrace(new VMStackTraceBuilder(this).buildStackTrace());
 		} catch (Exception e) {
-			getDebugCore().error("Failed to build QVT stack trace", e); //$NON-NLS-1$
+			getDebugCore().error("Failed to build VM stack trace", e); //$NON-NLS-1$
 		}
 		
 		throw exception;
diff --git a/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMRootEvaluationVisitor.java b/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMRootEvaluationVisitor.java
index ecf0a23..120d2b4 100644
--- a/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMRootEvaluationVisitor.java
+++ b/plugins/org.eclipse.qvtd.debug/src/org/eclipse/qvtd/debug/evaluator/QVTiVMRootEvaluationVisitor.java
@@ -28,10 +28,10 @@
 import org.eclipse.ocl.examples.debug.vm.VMVirtualMachine;
 import org.eclipse.ocl.examples.debug.vm.data.VMStackFrameData;
 import org.eclipse.ocl.examples.debug.vm.data.VMSuspension;
-import org.eclipse.ocl.examples.debug.vm.evaluator.IVMRootEvaluationVisitor;
 import org.eclipse.ocl.examples.debug.vm.evaluator.IStepper;
 import org.eclipse.ocl.examples.debug.vm.evaluator.IStepperVisitor;
 import org.eclipse.ocl.examples.debug.vm.evaluator.IVMEvaluationEnvironment;
+import org.eclipse.ocl.examples.debug.vm.evaluator.IVMRootEvaluationVisitor;
 import org.eclipse.ocl.examples.debug.vm.event.VMResumeEvent;
 import org.eclipse.ocl.examples.debug.vm.event.VMStartEvent;
 import org.eclipse.ocl.examples.debug.vm.event.VMSuspendEvent;
@@ -46,6 +46,8 @@
 import org.eclipse.ocl.examples.domain.utilities.DomainUtil;
 import org.eclipse.ocl.examples.pivot.Element;
 import org.eclipse.ocl.examples.pivot.LoopExp;
+import org.eclipse.ocl.examples.pivot.NamedElement;
+import org.eclipse.ocl.examples.pivot.OCLExpression;
 import org.eclipse.qvtd.debug.core.QVTiDebugCore;
 import org.eclipse.qvtd.debug.stepper.QVTiStepperVisitor;
 import org.eclipse.qvtd.debug.vm.QVTiVMVirtualMachine;
@@ -55,12 +57,11 @@
 {
 	private final @NonNull IVMDebuggerShell fDebugShell;
 	private final @NonNull VMBreakpointManager fBPM;
-	private UnitLocation fCurrentLocation;
+	private @NonNull UnitLocation fCurrentLocation;
 	private final @NonNull IterateBreakpointHelper fIterateBPHelper;
 //	private final List<UnitLocation> fLocationStack;
 	private @NonNull VMSuspension fCurrentStepMode;
 	private @NonNull Stack<QVTiVMEvaluationVisitor> visitorStack = new Stack<QVTiVMEvaluationVisitor>();
-	private final @NonNull Stack<IStepper> stepperStack = new Stack<IStepper>();
 
 	public QVTiVMRootEvaluationVisitor(@NonNull QVTiVMEnvironment env, @NonNull IQVTiVMEvaluationEnvironment evalEnv, @NonNull IVMDebuggerShell shell) {
 		super(new QVTiVMEvaluationVisitorImpl(env, evalEnv));
@@ -70,12 +71,13 @@
 //		fLocationStack = new ArrayList<UnitLocation>();
 		fCurrentStepMode = VMSuspension.UNSPECIFIED;
 		pushVisitor(this);
-		fCurrentLocation = null; //getCurrentLocation();
+		fCurrentLocation = getCurrentLocation();
 	}
 
 	@Override
 	protected @Nullable Object badVisit(@NonNull IVMEvaluationEnvironment<?> evalEnv,
 			@NonNull Element element, Object preState, @NonNull Throwable e) {
+		Stack<IVMEvaluationEnvironment.StepperEntry> stepperStack = evalEnv.getStepperStack();
 		if (!stepperStack.isEmpty()) {
 			stepperStack.pop();
 		}
@@ -109,7 +111,8 @@
 		}
 		if (request instanceof VMResumeRequest) {
 			VMResumeRequest resumeRequest = (VMResumeRequest) request;
-			fCurrentLocation = getCurrentLocation();
+//			fCurrentLocation = getCurrentLocation();
+//			fCurrentLocation = fCurrentStepMode == VMSuspension.STEP_INTO ? null : getCurrentLocation();
 			fCurrentStepMode = resumeRequest.suspension;
 			if (fCurrentStepMode == VMSuspension.UNSPECIFIED) {
 				fIterateBPHelper.removeAllIterateBreakpoints();
@@ -154,10 +157,15 @@
 	
 	private @NonNull String getMainModuleName() {
 		CompiledUnit mainUnit = fBPM.getUnitManager().getMainUnit();
-		if (mainUnit.getModules().isEmpty()) {
+		List<NamedElement> modules = mainUnit.getModules();
+		if (modules.isEmpty()) {
 			return "<null>"; //$NON-NLS-1$
 		}
-		return DomainUtil.nonNullState(mainUnit.getModules().get(0).getName());
+		String name = modules.get(0).getName();
+		if (name == null) {
+			return "<null>"; //$NON-NLS-1$
+		}
+		return DomainUtil.nonNullState(name);
 	}
 
 	public @NonNull QVTiVMRootEvaluationVisitor getRootEvaluationVisitor() {
@@ -169,7 +177,7 @@
 		return QVTiStepperVisitor.INSTANCE;
 	}
 
-	protected void handleLocationChanged(@NonNull Element  element, UnitLocation location, boolean isElementEnd) {
+	protected void handleLocationChanged(@NonNull Element element, @NonNull UnitLocation location, boolean isElementEnd) {
 		if (VMVirtualMachine.LOCATION.isActive()) {
 			VMVirtualMachine.LOCATION.println("[" + Thread.currentThread().getName() + "] " + element.eClass().getName() + ": " + element.toString() + " @ " + location + " " + (isElementEnd ? "start" : "end"));
 		}
@@ -184,30 +192,24 @@
 //			validbreakpointlocator.isBreakpointableElementEnd(element))) {
 //			return;
 //		}
-		
-		if (fCurrentStepMode == VMSuspension.STEP_OVER) {
-			if (location.getStackDepth() <= fCurrentLocation.getStackDepth()
-					&& (!location.isTheSameLine(fCurrentLocation)
-						/*|| repeatedInIterator(location, fCurrentLocation)*/ )) {
-				fCurrentLocation = null;
-				suspendAndWaitForResume(location, fCurrentStepMode);
-				return;
-			}
+		boolean doSuspendAndResume = false;
+		if (fCurrentStepMode == VMSuspension.STEP_INTO) {
+			doSuspendAndResume = true;
 		}
-		else if (fCurrentStepMode == VMSuspension.STEP_INTO) {
-			if (!location.isTheSameLocation(fCurrentLocation) /*|| repeatedInIterator(location, fCurrentLocation)*/) {
-				fCurrentLocation = null;
-				suspendAndWaitForResume(location, fCurrentStepMode);
-				return;
+		else if (fCurrentStepMode == VMSuspension.STEP_OVER) {
+			if (isSmallerStackDepth(location) || isNewLine(location) /*|| repeatedInIterator(location, fCurrentLocation)*/ ) {
+				doSuspendAndResume = true;
 			}
 		}
 		else if (fCurrentStepMode == VMSuspension.STEP_RETURN) {
-			if (location.getStackDepth() < fCurrentLocation.getStackDepth()) {
-				fCurrentLocation = null;
-				suspendAndWaitForResume(location, fCurrentStepMode);
-				return;
+			if (isSmallerStackDepth(location)) {
+				doSuspendAndResume = true;
 			}
 		}
+		if (doSuspendAndResume) {
+			suspendAndWaitForResume(location, fCurrentStepMode);
+			return;
+		}
 
 		// check if we trigger a registered breakpoint
 		for (VMBreakpoint breakpoint : fBPM.getBreakpoints(element)) {	// FIXME Use Adapters to avoid potentially long loop
@@ -260,6 +262,34 @@
 		
 	}
 
+	/**
+	 * Return true if a call (stack push) has occurred on location wrt the last displayed location.
+	 */
+	protected boolean isLargerStackDepth(@NonNull UnitLocation location) {
+		return location.getStackDepth() > fCurrentLocation.getStackDepth();
+	}
+
+	/**
+	 * Return true if a line change has occurred on location wrt the last displayed location.
+	 */
+	protected boolean isNewLine(@NonNull UnitLocation location) {
+		return !location.isTheSameLine(fCurrentLocation);
+	}
+
+	/**
+	 * Return true if a position change has occurred on location wrrt the last displayed location.
+	 */
+	protected boolean isNewLocation(@NonNull UnitLocation location) {
+		return !location.isTheSameLocation(fCurrentLocation);
+	}
+
+	/**
+	 * Return true if a return (stack pop) has occurred on location wrt the last displayed location.
+	 */
+	protected boolean isSmallerStackDepth(@NonNull UnitLocation location) {
+		return location.getStackDepth() < fCurrentLocation.getStackDepth();
+	}
+
 	private @NonNull UnitLocation newLocalLocation(@NonNull IVMEvaluationEnvironment<?> evalEnv, @NonNull Element node, int startPosition, int endPosition) {
 		return new UnitLocation(startPosition, endPosition, evalEnv, node);
 	}
@@ -278,20 +308,27 @@
 //		}
 	}
 
-	protected void postVisit(@NonNull IVMEvaluationEnvironment<?> evalEnv, @NonNull Element element, @Nullable Element preState) {
+	protected void postVisit(@NonNull IVMEvaluationEnvironment<?> evalEnv, @NonNull Element element, @Nullable Object result, @Nullable Element parentElement) {
+		Stack<IVMEvaluationEnvironment.StepperEntry> stepperStack = evalEnv.getStepperStack();
 		if (stepperStack.isEmpty()) {
 			return;
 		}
-		stepperStack.pop();
+		IVMEvaluationEnvironment.StepperEntry childStepperEntry = stepperStack.pop();
+		childStepperEntry.popFrom(evalEnv);
 		if (stepperStack.isEmpty()) {
 			return;
 		}
-		IStepper parentStepper = stepperStack.peek();
-		Element postElement = parentStepper.isPostStoppable(this, element, preState);
+		IVMEvaluationEnvironment.StepperEntry parentStepperEntry = stepperStack.peek();
+		if (element instanceof OCLExpression) {		// NB not REalizedVariable
+			parentStepperEntry.pushTo(evalEnv, (OCLExpression) element, result);
+		}
+		IStepper parentStepper = parentStepperEntry.stepper;
+		Element postElement = parentStepper.isPostStoppable(this, element, parentElement);
 		if (postElement != null) {
-			UnitLocation unitLocation = parentStepper.createUnitLocation(evalEnv, postElement);
-			setCurrentLocation(postElement, unitLocation, false);
-			processDebugRequest(unitLocation);
+				UnitLocation unitLocation = parentStepper.createUnitLocation(evalEnv, postElement);
+				setCurrentLocation(postElement, unitLocation, false);
+				processDebugRequest(unitLocation);
+//			}
 		}
 /*		if (element instanceof Transformation) {
 			// 
@@ -318,8 +355,7 @@
 	public void preIterate(@NonNull LoopExp loopExp) {
 		UnitLocation topLocation = getCurrentLocation();
 		boolean skipIterate = (fCurrentStepMode == VMSuspension.UNSPECIFIED)
-				|| ((fCurrentStepMode == VMSuspension.STEP_OVER) && 
-					(topLocation.getStackDepth() > fCurrentLocation.getStackDepth()));
+				|| ((fCurrentStepMode == VMSuspension.STEP_OVER) && isLargerStackDepth(topLocation));
 
 		if (!skipIterate) {
 			/*return*/ fIterateBPHelper.stepIterateElement(loopExp, topLocation);
@@ -327,8 +363,9 @@
 	}
 
 	protected @Nullable Element preVisit(@NonNull IVMEvaluationEnvironment<?> evalEnv, @NonNull Element element) {
+		Stack<IVMEvaluationEnvironment.StepperEntry> stepperStack = evalEnv.getStepperStack();
 		IStepper stepper = getStepperVisitor().getStepper(element);
-		stepperStack.push(stepper);
+		stepperStack.push(new IVMEvaluationEnvironment.StepperEntry(stepper, element));
 		if (stepper.isPreStoppable(this, element)) {
 			UnitLocation unitLocation = stepper.createUnitLocation(evalEnv, element);
 			setCurrentLocation(element, unitLocation, false);
@@ -432,6 +469,7 @@
 	}
 	
 	private void suspendAndWaitForResume(@NonNull UnitLocation location, @NonNull VMSuspendEvent suspendEvent) {		
+		fCurrentLocation = location;
 		try {			
 			VMSuspendEvent vmSuspend = suspendEvent;