Bug 153913 step over action becomes disabled
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
index 02217f5..9e9a45c 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
@@ -150,11 +150,12 @@
 	 */
 	private List fCurrentBreakpoints = new ArrayList(2);
 	/**
-	 * Whether this thread is currently performing
+	 * State for whether this thread is currently performing
 	 * an evaluation. An evaluation may involve a series
-	 * of method invocations.
+	 * of method invocations. Non-negative when performing 
+	 * an evaluation.
 	 */
-	private boolean fIsPerformingEvaluation= false;
+	private int fEvaluationDetail = -1;
 	private IEvaluationRunnable fEvaluationRunnable;
 	
 	/**
@@ -363,21 +364,21 @@
 	 * @see IStep#canStepInto()
 	 */
 	public boolean canStepInto() {
-		return canStep();
+		return isStepEnabled();
 	}
 
 	/**
 	 * @see IStep#canStepOver()
 	 */
 	public boolean canStepOver() {
-		return canStep();
+		return isStepEnabled();
 	}
 
 	/**
 	 * @see IStep#canStepReturn()
 	 */
 	public boolean canStepReturn() {
-		return canStep();
+		return isStepEnabled();
 	}
 
 	/**
@@ -399,6 +400,18 @@
 			return false;
 		}
 	}
+	
+	/**
+	 * Returns whether the step action should be enabled for this
+	 * thread. This check "lies" a little based on the implicit
+	 * evaluation state of the thread to avoid disabling the step
+	 * action during an implicit evaluation.
+	 * 
+	 * @return whether the step action should be enabled for this thread.
+	 */
+	protected boolean isStepEnabled() {
+		return canStep() || fEvaluationDetail == DebugEvent.EVALUATION_IMPLICIT;
+	}	
 
 	/**
 	 * Determines and sets whether this thread represents a system thread.
@@ -501,7 +514,7 @@
 					fStackFrames.add(0, new JDIStackFrame(this, (StackFrame) frames.get(i), depth));
 					depth++;
 				}
-				int numToRebind = Math.min(newSize, oldSize); // number of frames to attempt to rebind
+				int numToRebind = Math.min(newSize, oldSize); // number of frames to attempt to re-bind
 				int offset = newSize - 1;
 				for (depth = 0; depth < numToRebind; depth++) {
 					JDIStackFrame oldFrame = (JDIStackFrame) fStackFrames.get(offset);
@@ -626,7 +639,7 @@
 			requestFailed(JDIDebugModelMessages.JDIThread_Evaluation_failed___thread_not_suspended, null, IJavaThread.ERR_THREAD_NOT_SUSPENDED); 
 		}
 		
-		fIsPerformingEvaluation = true;
+		fEvaluationDetail = evaluationDetail;
 		fEvaluationRunnable= evaluation;
 		fHonorBreakpoints= hitBreakpoints;
 		fireResumeEvent(evaluationDetail);
@@ -637,7 +650,7 @@
 		} catch (DebugException e) {
 			throw e;
 		} finally {
-			fIsPerformingEvaluation = false;
+			fEvaluationDetail = -1;
 			fEvaluationRunnable= null;
 			fHonorBreakpoints= true;
 			if (getBreakpoints().length == 0 && breakpoints.length > 0) {
@@ -780,7 +793,7 @@
 			preserveStackFrames();
 			int flags= ClassType.INVOKE_SINGLE_THREADED;
 			if (invokeNonvirtual) {
-				// Superclass method invocation must be performed nonvirtual.
+				// Superclass method invocation must be performed non virtual.
 				flags |= ObjectReference.INVOKE_NONVIRTUAL;
 			}
 			if (receiverClass == null) {
@@ -1291,7 +1304,7 @@
 	 * @see IStep#stepInto()
 	 */
 	public synchronized void stepInto() throws DebugException {
-		if (!canStepInto()) {
+		if (!canStep()) {
 			return;
 		}
 		StepHandler handler = new StepIntoHandler();
@@ -1305,7 +1318,7 @@
 	 * @see IStep#stepOver()
 	 */
 	public synchronized void stepOver() throws DebugException {
-		if (!canStepOver()) {
+		if (!canStep()) {
 			return;
 		}
 		StepHandler handler = new StepOverHandler();
@@ -1319,7 +1332,7 @@
 	 * @see IStep#stepReturn()
 	 */
 	public synchronized void stepReturn() throws DebugException {
-		if (!canStepReturn()) {
+		if (!canStep()) {
 			return;
 		}
 		StepHandler handler = new StepReturnHandler();
@@ -1558,7 +1571,7 @@
 			} catch (InvalidStackFrameException exception) {
 				// InvalidStackFrameException can be thrown when all but the
 				// deepest frame were popped. Fire a changed notification
-				// in case this has occured.
+				// in case this has occurred.
 				fireChangeEvent(DebugEvent.CONTENT);
 				targetRequestFailed(exception.toString(),exception); 
 			} catch (RuntimeException exception) {
@@ -1613,7 +1626,7 @@
 					}
 				}
 			} catch (DebugException e) {
-				// if the thread has since reusmed, return null (no need to report error)
+				// if the thread has since resumed, return null (no need to report error)
 				if (e.getStatus().getCode() != IJavaThread.ERR_THREAD_NOT_SUSPENDED) {
 					throw e;
 				}
@@ -1694,12 +1707,12 @@
 	 * @see IJavaThread#isPerformingEvaluation()
 	 */
 	public boolean isPerformingEvaluation() {
-		return fIsPerformingEvaluation;
+		return fEvaluationDetail >= 0;
 	}
 	
 	/**
 	 * Returns whether this thread is currently performing
-	 * a method invokation 
+	 * a method invocation 
 	 */
 	public boolean isInvokingMethod() {
 		return fIsInvokingMethod;
@@ -2211,7 +2224,7 @@
 		public boolean handleEvent(Event event, JDIDebugTarget target) {
 			try {
 				int numFrames = getUnderlyingFrameCount();
-				// tos should not be null
+				// TOS should not be null
 				if (numFrames <= getRemainingFrames()) {
 					stepEnd();
 					return false;