Bug 350813 - Simulation control buttons are not extendable
It seems like a ENDED state is needed as well.
diff --git a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/EngineStateAdapter.java b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/EngineStateAdapter.java
index 68d2ae4..2f3aee0 100644
--- a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/EngineStateAdapter.java
+++ b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/EngineStateAdapter.java
@@ -5,9 +5,6 @@
  * in a complex inner state. Instead we want to be informed if a simulation is running, stopped or paused. That's what
  * this adapter does for you. It simplifies the inner state of an {@link IEngine} and keeps track of the former state.
  * That way state changes can be detected.
- * <p/>
- * Obviously, there is no state "STOPPED". Why not? - It's just not needed at this point in time. If you need it,
- * implement it!
  * 
  * @author jonas.ruettimann
  */
@@ -21,11 +18,14 @@
 		RUNNING,
 
 		/** Simulation was running but has been set to pause. */
-		PAUSED
+		PAUSED,
+
+		/** Simulation has reached its stop period. */
+		ENDED
 	}
 
-	public EngineStateAdapter(boolean isRunning, boolean isStepping, boolean isPausing) {
-		update(isRunning, isStepping, isPausing);
+	public EngineStateAdapter(boolean isRunning, boolean isStepping, boolean isPausing, boolean isEndReached) {
+		update(isRunning, isStepping, isPausing, isEndReached);
 	}
 
 	private boolean running;
@@ -34,23 +34,31 @@
 
 	private boolean pausing;
 
+	private boolean endReached;
+
 	/**
 	 * @param isRunning
 	 * @param isStepping
 	 * @param isPausing
+	 * @param isEndReached
 	 * @return <code>true</code> if a new {@link EngineState} is detected
 	 */
-	public boolean update(boolean isRunning, boolean isStepping, boolean isPausing) {
+	public boolean update(boolean isRunning, boolean isStepping, boolean isPausing, boolean isEndReached) {
 		EngineState stateBefore = getState();
 
 		this.running = isRunning;
 		this.stepping = isStepping;
 		this.pausing = isPausing;
+		this.endReached = isEndReached;
 
 		return stateBefore != getState();
 	}
 
 	public EngineState getState() {
+		if (isEndReached()) {
+			return EngineState.ENDED;
+		}
+
 		if (!isRunning()) {
 			return EngineState.IDLE;
 		}
@@ -74,4 +82,8 @@
 		return stepping;
 	}
 
+	public boolean isEndReached() {
+		return endReached;
+	}
+
 }
\ No newline at end of file
diff --git a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/plugin.xml b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/plugin.xml
index 0f2d8ec..fa5f94d 100644
--- a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/plugin.xml
+++ b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/plugin.xml
@@ -463,9 +463,14 @@
           <enabledWhen>
              <with
                    variable="org.eclipse.amp.axf.ide.engine.state">
-                <equals
-                      value="IDLE">
-                </equals>
+                <or>
+                   <equals
+                         value="IDLE">
+                   </equals>
+                   <equals
+                         value="ENDED">
+                   </equals>
+                </or>
              </with>
           </enabledWhen>
        </handler>
@@ -535,6 +540,9 @@
                    <equals
                          value="PAUSED">
                    </equals>
+                   <equals
+                         value="ENDED">
+                   </equals>
                 </or>
              </with>
           </enabledWhen>
@@ -555,6 +563,9 @@
                    <equals
                          value="RUNNING">
                    </equals>
+                   <equals
+                         value="ENDED">
+                   </equals>
                 </or>
              </with>
           </enabledWhen>
diff --git a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/EngineStateService.java b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/EngineStateService.java
index bda20fb..3d748a1 100644
--- a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/EngineStateService.java
+++ b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/EngineStateService.java
@@ -81,9 +81,14 @@
 		engine.addEngineObserver(this);
 		activeModel = newModel;
 
-		// There is no stepping state. Use pause instead, that has the same effect.
-		boolean isStepping = engine.isPaused();
-		possibleStateChange(new EngineStateAdapter(engine.isRunning(), isStepping, engine.isPaused()).getState());
+		boolean isStepping = engine.isPaused(); // There is no stepping state. Use pause instead, that has the same effect.
+		boolean isEnded = activeModel.isEnded(); // The engine does not know whether it's stopped. Lets ask the model.
+
+		/*
+		 * Just before executing a model it's being activated. So a state that is generated right here might not be as
+		 * relevant since it will be changed to running in a few instances anyway.
+		 */
+		possibleStateChange(new EngineStateAdapter(engine.isRunning(), isStepping, engine.isPaused(), isEnded).getState());
 	}
 
 	public void modelAdded(IModel model) {
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/src/org/eclipse/amp/axf/core/EngineStateAdapterTest.java b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/src/org/eclipse/amp/axf/core/EngineStateAdapterTest.java
index d50aaa6..ee23127 100644
--- a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/src/org/eclipse/amp/axf/core/EngineStateAdapterTest.java
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/src/org/eclipse/amp/axf/core/EngineStateAdapterTest.java
@@ -14,7 +14,7 @@
 
 	@Before
 	public void setUp() {
-		classToTest = new EngineStateAdapter(false, false, false);
+		classToTest = new EngineStateAdapter(false, false, false, false);
 	}
 
 	/**
@@ -22,57 +22,63 @@
 	 */
 	@Test
 	public void testUpdate() {
-		classToTest.update(false, false, false); // reset.
-		assertFalse(classToTest.update(false, false, false));
+		classToTest.update(false, false, false, false); // reset.
+		assertFalse(classToTest.update(false, false, false, false));
 
-		classToTest.update(false, false, false); // reset.
-		assertTrue(classToTest.update(true, false, false));
+		classToTest.update(false, false, false, false); // reset.
+		assertTrue(classToTest.update(true, false, false, false));
 
-		classToTest.update(false, false, false); // reset.
-		assertTrue(classToTest.update(true, true, false));
+		classToTest.update(false, false, false, false); // reset.
+		assertTrue(classToTest.update(true, true, false, false));
 
-		classToTest.update(false, false, false); // reset.
-		assertTrue(classToTest.update(true, false, true));
+		classToTest.update(false, false, false, false); // reset.
+		assertTrue(classToTest.update(true, false, true, false));
 
-		classToTest.update(false, false, false); // reset.
-		assertTrue(classToTest.update(true, false, true));
+		classToTest.update(false, false, false, false); // reset.
+		assertTrue(classToTest.update(true, false, true, false));
 
-		classToTest.update(true, true, true); // reset.
-		assertTrue(classToTest.update(true, false, false));
+		classToTest.update(false, false, false, false); // reset.
+		assertTrue(classToTest.update(false, false, false, true));
 
-		classToTest.update(true, true, true); // reset.
-		assertFalse(classToTest.update(true, false, true)); // Still paused.
+		classToTest.update(true, true, true, false); // reset.
+		assertTrue(classToTest.update(true, false, false, false));
 
-		classToTest.update(true, true, true); // reset.
-		assertFalse(classToTest.update(true, true, false)); // Still paused.
+		classToTest.update(true, true, true, false); // reset.
+		assertFalse(classToTest.update(true, false, true, false)); // Still paused.
 
-		classToTest.update(true, false, true); // reset.
-		assertFalse(classToTest.update(true, true, false)); // Still paused.
+		classToTest.update(true, true, true, false); // reset.
+		assertFalse(classToTest.update(true, true, false, false)); // Still paused.
+
+		classToTest.update(true, false, true, false); // reset.
+		assertFalse(classToTest.update(true, true, false, false)); // Still paused.
 	}
 
 	@Test
 	public void testGetState() {
 		assertEquals(EngineState.IDLE, classToTest.getState()); // default.
 
-		classToTest.update(false, false, false); // not running, not paused. Same as default.
+		classToTest.update(false, false, false, false); // not running, not paused. Same as default.
 		assertEquals(EngineState.IDLE, classToTest.getState());
 
-		classToTest.update(true, false, false); // running.
+		classToTest.update(true, false, false, false); // running.
 		assertEquals(EngineState.RUNNING, classToTest.getState());
 
-		classToTest.update(true, true, false); // paused.
+		classToTest.update(true, true, false, false); // paused.
 		assertEquals(EngineState.PAUSED, classToTest.getState());
 
-		classToTest.update(true, false, true); // stepping - should also lead to paused state.
+		classToTest.update(true, false, true, false); // stepping - should also lead to paused state.
 		assertEquals(EngineState.PAUSED, classToTest.getState());
+
+		classToTest.update(false, false, false, true); // stop period reached
+		assertEquals(EngineState.ENDED, classToTest.getState());
 	}
 
 	@Test
 	public void testGetState_invalidStates() {
-		classToTest.update(false, true, false); // paused without running makes no sense.
+		classToTest.update(false, true, false, false); // paused without running makes no sense.
 		assertEquals(EngineState.IDLE, classToTest.getState());
 
-		classToTest.update(false, false, true); // stepping without running neither.
+		classToTest.update(false, false, true, false); // stepping without running neither.
 		assertEquals(EngineState.IDLE, classToTest.getState());
 	}
 }
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/CloseHandlerTest.java b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/CloseHandlerTest.java
index fd7da9f..f127c9f 100644
--- a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/CloseHandlerTest.java
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/CloseHandlerTest.java
@@ -18,7 +18,7 @@
 
 	@Override
 	protected EngineStateAdapter[] getEnabledStates() {
-		return new EngineStateAdapter[] { STATE_IDLE, STATE_PAUSED, STATE_RUNNING };
+		return new EngineStateAdapter[] { STATE_IDLE, STATE_PAUSED, STATE_RUNNING, STATE_ENDED };
 	}
 
 	@Override
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/ModelRunHandlerTest.java b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/ModelRunHandlerTest.java
index 6f40b8b..0a5e07b 100644
--- a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/ModelRunHandlerTest.java
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/ModelRunHandlerTest.java
@@ -30,18 +30,24 @@
 	/**
 	 * Using the adapter as a state container. This is kind of a hack.
 	 */
-	static final EngineStateAdapter STATE_IDLE = new EngineStateAdapter(false, false, false);
+	static final EngineStateAdapter STATE_IDLE = new EngineStateAdapter(false, false, false, false);
 
 	/**
 	 * Using the adapter as a state container. This is kind of a hack.
 	 */
-	static final EngineStateAdapter STATE_RUNNING = new EngineStateAdapter(true, false, false);
+	static final EngineStateAdapter STATE_RUNNING = new EngineStateAdapter(true, false, false, false);
 
 	/**
 	 * Using the adapter as a state container. This is kind of a hack. The {@link IEngine} is paused. Instead we could
 	 * have used the "step" state with the same effects.
 	 */
-	static final EngineStateAdapter STATE_PAUSED = new EngineStateAdapter(true, true, false);
+	static final EngineStateAdapter STATE_PAUSED = new EngineStateAdapter(true, true, false, false);
+
+	/**
+	 * Using the adapter as a state container. This is kind of a hack. The {@link IEngine} is has stopped executing since
+	 * it has reached the simulation end period.
+	 */
+	static final EngineStateAdapter STATE_ENDED = new EngineStateAdapter(false, false, false, true);
 
 	private DummyModel model;
 
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/PauseHandlerTest.java b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/PauseHandlerTest.java
index be75f8c..f42d81b 100644
--- a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/PauseHandlerTest.java
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/PauseHandlerTest.java
@@ -22,7 +22,7 @@
 
 	@Override
 	protected EngineStateAdapter[] getDisabledStates() {
-		return new EngineStateAdapter[] { STATE_IDLE, STATE_PAUSED };
+		return new EngineStateAdapter[] { STATE_IDLE, STATE_PAUSED, STATE_ENDED };
 	}
 
 }
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/RestartHandlerTest.java b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/RestartHandlerTest.java
index 2f857c7..f8a422e 100644
--- a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/RestartHandlerTest.java
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/RestartHandlerTest.java
@@ -16,7 +16,7 @@
 
 	@Override
 	protected EngineStateAdapter[] getEnabledStates() {
-		return new EngineStateAdapter[] { STATE_RUNNING, STATE_PAUSED };
+		return new EngineStateAdapter[] { STATE_RUNNING, STATE_PAUSED, STATE_ENDED };
 	}
 
 	@Override
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/ResumeHandlerTest.java b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/ResumeHandlerTest.java
index 71a3cfd..ede9e2b 100644
--- a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/ResumeHandlerTest.java
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/ResumeHandlerTest.java
@@ -21,7 +21,7 @@
 
 	@Override
 	protected EngineStateAdapter[] getDisabledStates() {
-		return new EngineStateAdapter[] { STATE_IDLE, STATE_RUNNING };
+		return new EngineStateAdapter[] { STATE_IDLE, STATE_RUNNING, STATE_ENDED };
 	}
 
 }
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StartHandlerTest.java b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StartHandlerTest.java
index 5270c02..5864c78 100644
--- a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StartHandlerTest.java
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StartHandlerTest.java
@@ -16,7 +16,7 @@
 
 	@Override
 	protected EngineStateAdapter[] getEnabledStates() {
-		return new EngineStateAdapter[] { STATE_IDLE };
+		return new EngineStateAdapter[] { STATE_IDLE, STATE_ENDED };
 	}
 
 	@Override
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StepHandlerTest.java b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StepHandlerTest.java
index d2edb6e..2a47593 100644
--- a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StepHandlerTest.java
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StepHandlerTest.java
@@ -21,7 +21,7 @@
 
 	@Override
 	protected EngineStateAdapter[] getDisabledStates() {
-		return new EngineStateAdapter[] { STATE_IDLE, STATE_RUNNING };
+		return new EngineStateAdapter[] { STATE_IDLE, STATE_RUNNING, STATE_ENDED };
 	}
 
 }
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StopHandlerTest.java b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StopHandlerTest.java
index c2175f5..82932e6 100644
--- a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StopHandlerTest.java
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/handlers/StopHandlerTest.java
@@ -21,7 +21,7 @@
 
 	@Override
 	protected EngineStateAdapter[] getDisabledStates() {
-		return new EngineStateAdapter[] { STATE_IDLE };
+		return new EngineStateAdapter[] { STATE_IDLE, STATE_ENDED };
 	}
 
 }
diff --git a/org.eclipse.amp.escape/plugins/org.eclipse.amp.escape.ide/src/org/eclipse/amp/escape/ide/EclipseEscapeRunner.java b/org.eclipse.amp.escape/plugins/org.eclipse.amp.escape.ide/src/org/eclipse/amp/escape/ide/EclipseEscapeRunner.java
index b6de283..e919fe9 100644
--- a/org.eclipse.amp.escape/plugins/org.eclipse.amp.escape.ide/src/org/eclipse/amp/escape/ide/EclipseEscapeRunner.java
+++ b/org.eclipse.amp.escape/plugins/org.eclipse.amp.escape.ide/src/org/eclipse/amp/escape/ide/EclipseEscapeRunner.java
@@ -80,7 +80,8 @@
 
 	private ArrayList<IEngineObserver> observers = new ArrayList<IEngineObserver>();
 
-	private EngineStateAdapter engineStateAdapter = new EngineStateAdapter(isRunning(), isStep(), isPaused());
+	private EngineStateAdapter engineStateAdapter = new EngineStateAdapter(isRunning(), isStep(), isPaused(),
+			getPeriod() == getStopPeriod());
 
 	/**
 	 * Open.
@@ -400,7 +401,7 @@
 	}
 
 	private void updateStateAdapter() {
-		if (engineStateAdapter.update(isRunning(), isStep(), isPaused())) {
+		if (engineStateAdapter.update(isRunning(), isStep(), isPaused(), getPeriod() == getStopPeriod())) {
 			for (IEngineObserver observer : observers) {
 				observer.engineStateChanged(this, engineStateAdapter.getState());
 			}