Bug 350813: Enablement of pause button fixed.
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
new file mode 100644
index 0000000..68d2ae4
--- /dev/null
+++ b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/EngineStateAdapter.java
@@ -0,0 +1,77 @@
+package org.eclipse.amp.axf.core;
+
+/**
+ * An {@link IEngine} has an awful lot of booleans that define its internal state. For many tasks, we're not interested
+ * 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
+ */
+public class EngineStateAdapter {
+
+	public enum EngineState {
+		/** Simulation has not been started at all or is in undefined state. */
+		IDLE,
+
+		/** Simulation is currently running. */
+		RUNNING,
+
+		/** Simulation was running but has been set to pause. */
+		PAUSED
+	}
+
+	public EngineStateAdapter(boolean isRunning, boolean isStepping, boolean isPausing) {
+		update(isRunning, isStepping, isPausing);
+	}
+
+	private boolean running;
+
+	private boolean stepping;
+
+	private boolean pausing;
+
+	/**
+	 * @param isRunning
+	 * @param isStepping
+	 * @param isPausing
+	 * @return <code>true</code> if a new {@link EngineState} is detected
+	 */
+	public boolean update(boolean isRunning, boolean isStepping, boolean isPausing) {
+		EngineState stateBefore = getState();
+
+		this.running = isRunning;
+		this.stepping = isStepping;
+		this.pausing = isPausing;
+
+		return stateBefore != getState();
+	}
+
+	public EngineState getState() {
+		if (!isRunning()) {
+			return EngineState.IDLE;
+		}
+
+		if (isStepping() || isPausing()) {
+			return EngineState.PAUSED;
+		}
+
+		return EngineState.RUNNING;
+	}
+
+	public boolean isPausing() {
+		return pausing;
+	}
+
+	public boolean isRunning() {
+		return running;
+	}
+
+	public boolean isStepping() {
+		return stepping;
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/IEngine.java b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/IEngine.java
index 95bbd13..6e510ad 100644
--- a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/IEngine.java
+++ b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/IEngine.java
@@ -72,6 +72,10 @@
 	 */
 	void control(EngineControl ModelControl);
 
+	public void addEngineObserver(IEngineObserver observer);
+
+	public void removeEngineObserver(IEngineObserver observer);
+
 	/**
 	 * Observation complete.
 	 * 
diff --git a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/IEngineObserver.java b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/IEngineObserver.java
new file mode 100644
index 0000000..dddabba
--- /dev/null
+++ b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.core/src/org/eclipse/amp/axf/core/IEngineObserver.java
@@ -0,0 +1,19 @@
+package org.eclipse.amp.axf.core;
+
+import org.eclipse.amp.axf.core.EngineStateAdapter.EngineState;
+
+/**
+ * This is another concept to propagate state changes from a {@link IEngine}. How does it differ from
+ * {@link ILifeCycleListener}? - Well, {@link ILifeCycleListener#stateChange(Object, Object)}s doesn't get called upon
+ * pause events. For GUI updates, pause events are central.
+ * <p/>
+ * Instances of classes that implement this interface can be added to an {@link IEngine} of an {@link IModel} as
+ * observers.
+ * 
+ * @author jonas.ruettimann
+ */
+public interface IEngineObserver {
+
+	public void engineStateChanged(IEngine engine, EngineState state);
+
+}
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 38c75a9..a7717b5 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
@@ -58,7 +58,6 @@
              locationURI="toolbar:org.eclipse.ui.main.toolbar?after=additions">
                 <toolbar
                       id="org.eclipse.amp.axf.ui.execute">
-
                 </toolbar>
        </menuContribution>
        <menuContribution
@@ -467,7 +466,7 @@
              <with
                    variable="org.eclipse.amp.axf.ide.engine.state">
                 <equals
-                      value="STOPPED">
+                      value="IDLE">
                 </equals>
              </with>
           </enabledWhen>
@@ -558,12 +557,6 @@
                    <equals
                          value="RUNNING">
                    </equals>
-                   <equals
-                         value="STOPPED">
-                   </equals>
-                   <equals
-                         value="CLOSING">
-                   </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 d6849a1..bda20fb 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
@@ -3,11 +3,12 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.eclipse.amp.axf.core.EngineStateAdapter;
+import org.eclipse.amp.axf.core.EngineStateAdapter.EngineState;
 import org.eclipse.amp.axf.core.IEngine;
-import org.eclipse.amp.axf.core.ILifeCycleListener;
+import org.eclipse.amp.axf.core.IEngineObserver;
 import org.eclipse.amp.axf.core.IModel;
-import org.eclipse.amp.axf.core.IObservationProvider;
-import org.eclipse.amp.axf.core.LifeCycleState;
+import org.eclipse.core.commands.IHandler;
 import org.eclipse.ui.AbstractSourceProvider;
 import org.eclipse.ui.ISourceProvider;
 import org.eclipse.ui.ISources;
@@ -15,34 +16,19 @@
 
 /**
  * This {@link ISourceProvider} defines states that can be used to enable or
- * disable handlers. The states are related to the execution of only the active
- * {@link IModel}s. Execution states are {@link #IDLE}, {@link #RUNNING} and
- * {@link #PAUSED}. This is a simplification of all {@link IEngine} states that
- * are possible.
+ * disable {@link IHandler}s or other GUI elements. The states are related to
+ * the execution of only the active {@link IModel}. They are a simplification of
+ * all possible states of an {@link IEngine}.
  * 
  * @author jonas.ruettimann
  */
-public class EngineStateService extends AbstractSourceProvider implements IModelWorkbenchListener, ILifeCycleListener {
+public class EngineStateService extends AbstractSourceProvider implements IModelWorkbenchListener, IEngineObserver {
+
 	public static final String ID = "org.eclipse.amp.axf.ide.engine.state";
 
-	/** Simulation has not been started at all or is in undefined state. */
-	public static final String IDLE = "IDLE";
-
-	/** Simulation is currently running. */
-	public static final String RUNNING = "RUNNING";
-
-	/** Simulation was running but has been set to pause. */
-	public static final String PAUSED = "PAUSED";
-
-	/** Simulation run has finished and stopped. */
-	public static final String STOPPED = "STOPPED";
-
-	/** Simulation was running but has been requested to be closed. */
-	public static final String CLOSING = "CLOSING";
-
 	private IModel activeModel = null;
 
-	private String lastState;
+	private EngineState lastState = EngineState.IDLE;
 
 	public EngineStateService() {
 		ModelViewManager.getInstance().getManagerListeners().addModelManagerListener(this);
@@ -50,7 +36,7 @@
 
 	public Map<String, String> getCurrentState() {
 		Map<String, String> map = new HashMap<String, String>(1);
-		map.put(ID, getEngineState());
+		map.put(ID, lastState.toString());
 		return map;
 	}
 
@@ -58,35 +44,12 @@
 		return new String[] { ID };
 	}
 
-	private String getEngineState() {
-		if (activeModel != null) {
-			if (activeModel.isInitialized() && activeModel.isCreated() && activeModel.isActive() && activeModel.isRunning()) {
-				if (activeModel.isPaused()) {
-					return PAUSED;
-				}
-				return RUNNING;
-			}
-
-			if (activeModel.isInitialized() && activeModel.isStopped()) {
-				if (activeModel.isEnding()) {
-					return CLOSING;
-				}
-				return STOPPED;
-			}
-		}
-
-		return IDLE; // used as default
+	public void engineStateChanged(IEngine engine, EngineState state) {
+		possibleStateChange(state);
 	}
 
-	public void stateChange(Object key, Object updated) {
-		if (key instanceof LifeCycleState) {
-			possibleStateChange();
-		}
-	}
-
-	private void possibleStateChange() {
-		String currentState = getEngineState();
-		if (!currentState.equals(lastState)) {
+	private void possibleStateChange(EngineState currentState) {
+		if (currentState != lastState) {
 			lastState = currentState;
 			notifyObservers(currentState);
 		}
@@ -97,27 +60,30 @@
 	 * 
 	 * @param currentState
 	 */
-	protected void notifyObservers(String currentState) {
-		fireSourceChanged(ISources.WORKBENCH, ID, currentState);
+	protected void notifyObservers(EngineState currentState) {
+		fireSourceChanged(ISources.WORKBENCH, ID, currentState.toString());
 	}
 
-	public void dispose() {
-		unregister();
+	private void unregister() {
+		if (activeModel != null) {
+			assert activeModel.getEngine() != null : "Engine occurs to be null.";
+			activeModel.getEngine().removeEngineObserver(this);
+			activeModel = null;
+		}
 	}
 
 	public void modelActivated(IModel newModel) {
 		unregister();
 
-		newModel.addModelListener(this);
+		IEngine engine = newModel.getEngine();
+		assert engine != null : "Engine occurs to be null.";
+
+		engine.addEngineObserver(this);
 		activeModel = newModel;
 
-		possibleStateChange();
-	}
-
-	private void unregister() {
-		if (activeModel != null) {
-			activeModel.removeModelListener(this);
-		}
+		// 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());
 	}
 
 	public void modelAdded(IModel model) {
@@ -125,7 +91,10 @@
 	}
 
 	public void modelRemoved(IModel model) {
-		//
+		if (model == activeModel) {
+			unregister();
+			possibleStateChange(EngineState.IDLE);
+		}
 	}
 
 	public void viewAdded(IWorkbenchPart part) {
@@ -140,36 +109,8 @@
 		//
 	}
 
-	public void observing(IObservationProvider observed) {
-		//
-	}
-
-	public void observeCreate(IObservationProvider observed) {
-		//
-	}
-
-	public void observeInitialize(IObservationProvider observed) {
-		//
-	}
-
-	public void observeStart(IObservationProvider observed) {
-		//
-	}
-
-	public void observeUpdate(IObservationProvider observed) {
-		//
-	}
-
-	public void observeStop(IObservationProvider observed) {
-		//
-	}
-
-	public void observationEnding(IObservationProvider observed) {
-		//
-	}
-
-	public void observationEnd(IObservationProvider observed) {
-		//
+	public void dispose() {
+		unregister();
 	}
 
 }
diff --git a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/handlers/ModelRunHandler.java b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/handlers/ModelRunHandler.java
index e1d479f..5a60cd8 100644
--- a/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/handlers/ModelRunHandler.java
+++ b/org.eclipse.amp.axf/plugins/org.eclipse.amp.axf.ide/src/org/eclipse/amp/axf/ide/handlers/ModelRunHandler.java
@@ -17,39 +17,28 @@
 
 import org.eclipse.amp.axf.core.EngineControl;
 import org.eclipse.amp.axf.core.IEngine;
-import org.eclipse.amp.axf.core.ILifeCycleListener;
 import org.eclipse.amp.axf.core.IModel;
-import org.eclipse.amp.axf.core.IObservationProvider;
-import org.eclipse.amp.axf.core.IStateListener;
-import org.eclipse.amp.axf.core.LifecycleObservationAdapter;
-import org.eclipse.amp.axf.ide.AXFWorkbenchPlugin;
-import org.eclipse.amp.axf.ide.IModelWorkbenchListener;
 import org.eclipse.amp.axf.ide.ModelViewManager;
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.commands.HandlerEvent;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IWorkbenchPart;
 
 /**
- * Super class for all {@link AbstractHandler}s to control the {@link IEngine}
- * execution.
+ * Super class for all {@link AbstractHandler}s to control the {@link IEngine} execution.
  * 
  * @author jonas.ruettimann
  */
-public abstract class ModelRunHandler extends AbstractHandler implements ILifeCycleListener, IModelWorkbenchListener {
+public abstract class ModelRunHandler extends AbstractHandler {
 
 	private EngineControl control;
 
-	private IStateListener delegate;
-
 	public ModelRunHandler(EngineControl control) {
 		this.control = control;
-		delegate = new LifecycleObservationAdapter(this);
 	}
 
 	public Object execute(ExecutionEvent event) throws ExecutionException {
+		assert getRunner() != null : "There is no active runner!";
+
 		getRunner().control(control);
 		return null;
 	}
@@ -62,69 +51,4 @@
 		return model.getEngine();
 	}
 
-	public void notifyChange() {
-		// its possible we've already left workbench
-		if (AXFWorkbenchPlugin.getDefault() != null) {
-			Display display = AXFWorkbenchPlugin.getDefault().getWorkbench().getDisplay();
-			if (display != null && !display.isDisposed()) {
-				display.asyncExec(new Runnable() {
-					public void run() {
-						fireChangeEvent();
-					}
-				});
-			}
-		}
-	}
-
-	protected void fireChangeEvent() {
-		fireHandlerChanged(new HandlerEvent(this, true, false));
-	}
-
-	public void stateChange(Object key, Object updated) {
-		delegate.stateChange(key, updated);
-		notifyChange();
-	}
-
-	public synchronized void modelActivated(IModel model) {
-		notifyChange();
-	}
-
-	public synchronized void observing(IObservationProvider model) {
-	}
-
-	public synchronized void observationEnd(IObservationProvider model) {
-	}
-
-	public void modelAdded(IModel model) {
-	}
-
-	public void modelRemoved(IModel model) {
-	}
-
-	public void viewActivated(IWorkbenchPart part) {
-	}
-
-	public void viewAdded(IWorkbenchPart part) {
-	}
-
-	public void viewRemoved(IWorkbenchPart part) {
-	}
-
-	public void observationEnding(IObservationProvider observed) {
-	}
-
-	public void observeCreate(IObservationProvider observed) {
-	}
-
-	public void observeInitialize(IObservationProvider observed) {
-	}
-
-	public void observeStart(IObservationProvider observed) {
-	}
-
-	public void observeStop(IObservationProvider observed) {
-	}
-
-	public void observeUpdate(IObservationProvider observed) {
-	}
 }
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/.classpath b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/.project b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/.project
new file mode 100644
index 0000000..79a0940
--- /dev/null
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.amp.axf.core.test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/META-INF/MANIFEST.MF b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..10cf885
--- /dev/null
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Tests for org.eclipse.amp.axf.core
+Bundle-SymbolicName: org.eclipse.amp.axf.core.test
+Bundle-Version: 1.0.0.qualifier
+Fragment-Host: org.eclipse.amp.axf.core
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.junit;bundle-version="4.8.1"
diff --git a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/build.properties b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
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
new file mode 100644
index 0000000..d50aaa6
--- /dev/null
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.core.test/src/org/eclipse/amp/axf/core/EngineStateAdapterTest.java
@@ -0,0 +1,78 @@
+package org.eclipse.amp.axf.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.amp.axf.core.EngineStateAdapter.EngineState;
+import org.junit.Before;
+import org.junit.Test;
+
+public class EngineStateAdapterTest {
+
+	private EngineStateAdapter classToTest;
+
+	@Before
+	public void setUp() {
+		classToTest = new EngineStateAdapter(false, false, false);
+	}
+
+	/**
+	 * A change in running state or a change in step and pause state should lead to an update.
+	 */
+	@Test
+	public void testUpdate() {
+		classToTest.update(false, false, false); // reset.
+		assertFalse(classToTest.update(false, false, false));
+
+		classToTest.update(false, false, false); // reset.
+		assertTrue(classToTest.update(true, false, false));
+
+		classToTest.update(false, false, false); // reset.
+		assertTrue(classToTest.update(true, true, false));
+
+		classToTest.update(false, false, false); // reset.
+		assertTrue(classToTest.update(true, false, true));
+
+		classToTest.update(false, false, false); // reset.
+		assertTrue(classToTest.update(true, false, true));
+
+		classToTest.update(true, true, true); // reset.
+		assertTrue(classToTest.update(true, false, false));
+
+		classToTest.update(true, true, true); // reset.
+		assertFalse(classToTest.update(true, false, true)); // Still paused.
+
+		classToTest.update(true, true, true); // reset.
+		assertFalse(classToTest.update(true, true, false)); // Still paused.
+
+		classToTest.update(true, false, true); // reset.
+		assertFalse(classToTest.update(true, true, 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.
+		assertEquals(EngineState.IDLE, classToTest.getState());
+
+		classToTest.update(true, false, false); // running.
+		assertEquals(EngineState.RUNNING, classToTest.getState());
+
+		classToTest.update(true, true, false); // paused.
+		assertEquals(EngineState.PAUSED, classToTest.getState());
+
+		classToTest.update(true, false, true); // stepping - should also lead to paused state.
+		assertEquals(EngineState.PAUSED, classToTest.getState());
+	}
+
+	@Test
+	public void testGetState_invalidStates() {
+		classToTest.update(false, true, false); // paused without running makes no sense.
+		assertEquals(EngineState.IDLE, classToTest.getState());
+
+		classToTest.update(false, false, true); // 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/EngineStateServiceTest.java b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/EngineStateServiceTest.java
index 3b8e64f..36b314b 100644
--- a/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/EngineStateServiceTest.java
+++ b/org.eclipse.amp.axf/tests/org.eclipse.amp.axf.ide.test/src/org/eclipse/amp/axf/ide/EngineStateServiceTest.java
@@ -7,12 +7,14 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.List;
 
+import org.eclipse.amp.axf.core.EngineControl;
+import org.eclipse.amp.axf.core.EngineStateAdapter.EngineState;
 import org.eclipse.amp.axf.core.IEngine;
+import org.eclipse.amp.axf.core.IEngineObserver;
 import org.eclipse.amp.axf.core.ILifeCycleListener;
 import org.eclipse.amp.axf.core.IModel;
-import org.eclipse.amp.axf.core.LifeCycleState;
+import org.eclipse.amp.axf.time.ITimeGranularity;
 import org.eclipse.ui.ISourceProvider;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.services.ISourceProviderService;
@@ -36,14 +38,15 @@
 	 */
 	@Test
 	public void testWasRegisteredByPluginXML() {
-		ISourceProviderService service = (ISourceProviderService) PlatformUI.getWorkbench().getService(ISourceProviderService.class);
+		ISourceProviderService service = (ISourceProviderService) PlatformUI.getWorkbench().getService(
+				ISourceProviderService.class);
 		ISourceProvider sourceProvider = service.getSourceProvider(EngineStateService.ID);
 		assertTrue(sourceProvider instanceof EngineStateService);
 	}
 
 	/**
-	 * Does the {@link EngineStateService} register itself as a
-	 * {@link IModelWorkbenchListener} on the {@link ModelManagerListeners}?
+	 * Does the {@link EngineStateService} register itself as a {@link IModelWorkbenchListener} on the
+	 * {@link ModelManagerListeners}?
 	 */
 	@Test
 	public void testEngineStateService() {
@@ -51,121 +54,100 @@
 	}
 
 	/**
-	 * The activation of an {@link IModel} should cause the
-	 * {@link EngineStateService} to be registered as an
+	 * The activation of an {@link IModel} should cause the {@link EngineStateService} to be registered as an
 	 * {@link ILifeCycleListener} on the active {@link IModel}.
 	 */
 	@Test
 	public void testModelActivated() {
-		IModel modelA = new DummyModel();
-		IModel modelB = new DummyModel();
+		DummyModel modelA = new DummyModel();
+		DummyModel modelB = new DummyModel();
 
 		// not registered:
-		assertFalse(modelA.getModelListeners().contains(classToTest));
-		assertFalse(modelB.getModelListeners().contains(classToTest));
+		assertFalse(modelA.getEngine().observers.contains(classToTest));
+		assertFalse(modelB.getEngine().observers.contains(classToTest));
 
 		// register to modelA:
 		classToTest.modelActivated(modelA);
-		assertTrue(modelA.getModelListeners().contains(classToTest));
-		assertFalse(modelB.getModelListeners().contains(classToTest));
+		assertTrue(modelA.getEngine().observers.contains(classToTest));
+		assertFalse(modelB.getEngine().observers.contains(classToTest));
 
 		// unregister at modelA, register at modelB:
 		classToTest.modelActivated(modelB);
-		assertTrue(modelB.getModelListeners().contains(classToTest));
-		assertFalse(modelA.getModelListeners().contains(classToTest));
+		assertTrue(modelB.getEngine().observers.contains(classToTest));
+		assertFalse(modelA.getEngine().observers.contains(classToTest));
 	}
 
 	/**
-	 * Without an active {@link IModel} the default state
-	 * {@link EngineStateService#IDLE} should be returned. Otherwise the state of
-	 * the {@link IModel} matters.
+	 * Without an active {@link IModel} the default state {@link EngineState#IDLE} should be returned. Otherwise the state
+	 * of the {@link IEngine} matters.
 	 */
 	@Test
 	public void testGetCurrentState() {
-		assertEquals(EngineStateService.IDLE, classToTest.getCurrentState().get(EngineStateService.ID));
+		assertEquals(EngineState.IDLE.toString(), classToTest.getCurrentState().get(EngineStateService.ID));
 
 		DummyModel model = new DummyModel();
+		model.getEngine().running = true;
 		classToTest.modelActivated(model);
-		assertEquals(EngineStateService.IDLE, classToTest.getCurrentState().get(EngineStateService.ID));
+		assertEquals(EngineState.RUNNING.toString(), classToTest.getCurrentState().get(EngineStateService.ID));
 
-		model.initialized = true;
-		model.stopped = true;
-		assertEquals(EngineStateService.STOPPED, classToTest.getCurrentState().get(EngineStateService.ID));
-
-		model.initialized = true;
-		model.created = true;
-		model.active = true;
-		model.running = true;
-		model.stopped = false;
-		assertEquals(EngineStateService.RUNNING, classToTest.getCurrentState().get(EngineStateService.ID));
-
-		model.paused = true;
-		assertEquals(EngineStateService.PAUSED, classToTest.getCurrentState().get(EngineStateService.ID));
-
-		model.created = false;
-		model.active = false;
-		model.running = false;
-		model.initialized = true;
-		model.stopped = true;
-		model.ending = true;
-		assertEquals(EngineStateService.CLOSING, classToTest.getCurrentState().get(EngineStateService.ID));
+		classToTest.modelRemoved(model);
+		assertEquals(EngineState.IDLE.toString(), classToTest.getCurrentState().get(EngineStateService.ID));
 	}
 
 	/**
-	 * Only a changing state should lead to firing an event.
+	 * Only a change of state should cause notifications to be fired. An engine state change without any change state
+	 * change in the {@link EngineStateService} should not lead to a notification being fired. No unnecessary events,
+	 * please!
 	 */
 	@Test
-	public void testStateChange() {
-		DummyModel model = new DummyModel();
+	public void testEngineStateChanged() {
+		assertFalse(classToTest.notificationFired);
+		assertEquals(EngineState.IDLE.toString(), classToTest.getCurrentState().get(EngineStateService.ID));
 
-		// First state change ever; this should cause a notification:
-		classToTest.modelActivated(model);
-		assertTrue(classToTest.isNotificationFired());
+		classToTest.engineStateChanged(null, EngineState.IDLE);
+		assertFalse(classToTest.notificationFired); // No state change.
 
-		// Not another notification:
-		classToTest.stateChange(LifeCycleState.UPDATE, "");
-		assertFalse(classToTest.isNotificationFired());
-
-		// Changing the state should cause notification:
-		model.initialized = true;
-		model.stopped = true;
-		classToTest.stateChange(LifeCycleState.UPDATE, "");
-		assertTrue(classToTest.isNotificationFired());
-
-		// Not another notification:
-		classToTest.stateChange(LifeCycleState.UPDATE, "");
-		assertFalse(classToTest.isNotificationFired());
-
-		// A new model that is different should cause notification:
-		DummyModel differentModel = new DummyModel();
-		classToTest.modelActivated(differentModel);
-		assertTrue(classToTest.isNotificationFired());
-
-		// But not an equal one:
-		DummyModel equalModel = new DummyModel();
-		classToTest.modelActivated(equalModel);
-		assertFalse(classToTest.isNotificationFired());
+		classToTest.engineStateChanged(null, EngineState.RUNNING);
+		assertTrue(classToTest.notificationFired); // New state.
 	}
 
 	/**
-	 * Disposing the {@link EngineStateService} should unregister itself at the
-	 * active {@link IModel}.
+	 * Even when activating a new {@link IModel}, a notification should only be fired if the {@link EngineStateService}
+	 * state changes. No unnecessary events, please!
+	 */
+	@Test
+	public void testEngineStateChanged_newModel() {
+		classToTest.engineStateChanged(null, EngineState.RUNNING);
+		classToTest.notificationFired = false;
+
+		DummyModel modelA = new DummyModel();
+		modelA.getEngine().running = true;
+		classToTest.modelActivated(modelA);
+		assertFalse(classToTest.notificationFired); // New model, but no new state.
+
+		DummyModel modelB = new DummyModel();
+		classToTest.modelActivated(modelB);
+		assertTrue(classToTest.notificationFired); // New model, new state.
+	}
+
+	/**
+	 * Disposing the {@link EngineStateService} should unregister itself at the {@link IEngine} of the active
+	 * {@link IModel}.
 	 */
 	@Test
 	public void testDispose() {
-		IModel modelA = new DummyModel();
-		assertFalse(modelA.getModelListeners().contains(classToTest));
+		DummyModel modelA = new DummyModel();
+		assertFalse(modelA.getEngine().observers.contains(classToTest));
 
 		classToTest.modelActivated(modelA);
-		assertTrue(modelA.getModelListeners().contains(classToTest));
+		assertTrue(modelA.getEngine().observers.contains(classToTest));
 
 		classToTest.dispose();
-		assertFalse(modelA.getModelListeners().contains(classToTest));
+		assertFalse(modelA.getEngine().observers.contains(classToTest));
 	}
 
 	/**
-	 * Disposing the {@link EngineStateService} without an active {@link IModel}
-	 * should not lead to an {@link Exception}.
+	 * Disposing the {@link EngineStateService} without an active {@link IModel} should not lead to an {@link Exception}.
 	 */
 	@Test
 	public void testDispose_noActiveModel() {
@@ -179,107 +161,78 @@
 	}
 
 	private class EngineStateServiceMock extends EngineStateService {
-		private boolean notificationFired = false;
+
+		boolean notificationFired = false;
 
 		public EngineStateServiceMock() {
 		}
 
-		public boolean isNotificationFired() {
-			return notificationFired;
-		}
-
 		@Override
-		public void stateChange(Object key, Object updated) {
-			notificationFired = false;
-			super.stateChange(key, updated);
-		}
-
-		@Override
-		public void modelActivated(IModel newModel) {
-			notificationFired = false;
-			super.modelActivated(newModel);
-		}
-
-		@Override
-		protected void notifyObservers(String currentState) {
-			notificationFired = true;
+		protected void notifyObservers(EngineState currentState) {
 			super.notifyObservers(currentState);
+			notificationFired = true;
 		}
+
 	}
 
 	private class DummyModel implements IModel {
 
-		boolean initialized = false;
-
-		boolean created = false;
-
-		boolean active = false;
-
-		boolean running = false;
-
-		boolean paused = false;
-
-		boolean stopped = false;
-
-		boolean ending = false;
-
-		boolean ended = false;
-
-		private List<ILifeCycleListener> listeners = new ArrayList<ILifeCycleListener>();
+		private DummyEngine engine;
 
 		public DummyModel() {
+			engine = new DummyEngine(this);
 		}
 
 		public boolean isCreated() {
-			return created;
+			return false;
 		}
 
 		public boolean isInitialized() {
-			return initialized;
+			return false;
 		}
 
 		public boolean isStopped() {
-			return stopped;
+			return false;
 		}
 
 		public boolean isRunning() {
-			return running;
+			return false;
 		}
 
 		public boolean isPaused() {
-			return paused;
+			return false;
 		}
 
 		public boolean isActive() {
-			return active;
+			return false;
 		}
 
 		public boolean isEnding() {
-			return ending;
+			return false;
 		}
 
 		public boolean isEnded() {
-			return ended;
+			return false;
 		}
 
 		public void addModelListener(ILifeCycleListener listener) {
-			listeners.add(listener);
+			//
 		}
 
 		public Collection<ILifeCycleListener> getModelListeners() {
-			return listeners;
+			return null;
 		}
 
 		public void removeModelListener(ILifeCycleListener listener) {
-			listeners.remove(listener);
+			//
 		}
 
 		public String getTimeDescription() {
 			return null;
 		}
 
-		public IEngine getEngine() {
-			return null;
+		public DummyEngine getEngine() {
+			return engine;
 		}
 
 		public Object getRoot() {
@@ -299,4 +252,75 @@
 		}
 	}
 
+	private class DummyEngine implements IEngine {
+
+		ArrayList<IEngineObserver> observers = new ArrayList<IEngineObserver>();
+
+		boolean running = false;
+
+		boolean paused = false;
+
+		private DummyModel model;
+
+		public DummyEngine(DummyModel model) {
+			this.model = model;
+		}
+
+		public void close() {
+			//
+		}
+
+		public void closeFinally() {
+			//
+		}
+
+		public boolean isCloseRequested() {
+			return false;
+		}
+
+		public boolean isThreadAlive() {
+			return false;
+		}
+
+		public boolean isRunning() {
+			return running;
+		}
+
+		public boolean isPaused() {
+			return paused;
+		}
+
+		public void stop() {
+			//
+		}
+
+		public void control(EngineControl ModelControl) {
+			//
+		}
+
+		public void observationComplete(ILifeCycleListener observer) {
+			//
+		}
+
+		public DummyModel getModel() {
+			return model;
+		}
+
+		public void setUpdateGranularity(ITimeGranularity granularity) {
+			//
+		}
+
+		public ITimeGranularity getUpdateGranularity() {
+			return null;
+		}
+
+		public void addEngineObserver(IEngineObserver observer) {
+			observers.add(observer);
+		}
+
+		public void removeEngineObserver(IEngineObserver observer) {
+			observers.remove(observer);
+		}
+
+	}
 }
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 fb10369..fd7da9f 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
@@ -1,12 +1,11 @@
 package org.eclipse.amp.axf.ide.handlers;
 
-import org.eclipse.amp.axf.ide.EngineStateService;
+import org.eclipse.amp.axf.core.EngineStateAdapter;
+import org.eclipse.amp.axf.core.EngineStateAdapter.EngineState;
 
 /**
- * Closing should be enabled when {@link EngineStateService#IDLE},
- * {@link EngineStateService#RUNNING}, {@link EngineStateService#PAUSED},
- * {@link EngineStateService#STOPPED} and {@link EngineStateService#CLOSING}. So
- * basically at all times, except when already closing.
+ * Closing should be enabled when {@link EngineState#IDLE}, {@link EngineState#RUNNING}, {@link EngineState#PAUSED}.
+ * basically at all times.
  * 
  * @author jonas.ruettimann
  */
@@ -18,13 +17,13 @@
 	}
 
 	@Override
-	protected TestRunningState[] getEnabledStates() {
-		return new TestRunningState[] { STATE_IDLE, STATE_PAUSED, STATE_RUNNING, STATE_STOPPED, STATE_ENDING };
+	protected EngineStateAdapter[] getEnabledStates() {
+		return new EngineStateAdapter[] { STATE_IDLE, STATE_PAUSED, STATE_RUNNING };
 	}
 
 	@Override
-	protected TestRunningState[] getDisabledStates() {
-		return new TestRunningState[] {};
+	protected EngineStateAdapter[] getDisabledStates() {
+		return new EngineStateAdapter[] {};
 	}
 
 }
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 5545dd6..6f40b8b 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
@@ -6,11 +6,12 @@
 import java.util.Collection;
 
 import org.eclipse.amp.axf.core.EngineControl;
+import org.eclipse.amp.axf.core.EngineStateAdapter;
 import org.eclipse.amp.axf.core.IEngine;
+import org.eclipse.amp.axf.core.IEngineObserver;
 import org.eclipse.amp.axf.core.ILifeCycleListener;
 import org.eclipse.amp.axf.core.IModel;
 import org.eclipse.amp.axf.core.IObservationProvider;
-import org.eclipse.amp.axf.core.LifeCycleState;
 import org.eclipse.amp.axf.ide.EngineStateService;
 import org.eclipse.amp.axf.ide.ModelViewManager;
 import org.eclipse.amp.axf.time.ITimeGranularity;
@@ -26,15 +27,21 @@
 
 public abstract class ModelRunHandlerTest {
 
-	static final TestRunningState STATE_IDLE = new TestRunningState("IDLE", false, false, false, false, false, true, false, false);
+	/**
+	 * 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 TestRunningState STATE_STOPPED = new TestRunningState("STOPPED", true, false, false, false, false, true, 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 TestRunningState STATE_RUNNING = new TestRunningState("RUNNING", true, true, true, true, false, false, false, false);
-
-	static final TestRunningState STATE_PAUSED = new TestRunningState("PAUSED", true, true, true, true, true, false, false, false);
-
-	static final TestRunningState STATE_ENDING = new TestRunningState("ENDING", true, false, false, false, false, true, true, 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);
 
 	private DummyModel model;
 
@@ -44,15 +51,16 @@
 
 	protected abstract String getCommandToTestId();
 
-	protected abstract TestRunningState[] getEnabledStates();
+	protected abstract EngineStateAdapter[] getEnabledStates();
 
-	protected abstract TestRunningState[] getDisabledStates();
+	protected abstract EngineStateAdapter[] getDisabledStates();
 
 	@Before
 	public void setUp() {
 		model = new DummyModel();
 
-		ISourceProviderService sourceProviderService = (ISourceProviderService) PlatformUI.getWorkbench().getService(ISourceProviderService.class);
+		ISourceProviderService sourceProviderService = (ISourceProviderService) PlatformUI.getWorkbench().getService(
+				ISourceProviderService.class);
 		stateService = (EngineStateService) sourceProviderService.getSourceProvider(EngineStateService.ID);
 
 		handlerService = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);
@@ -63,25 +71,25 @@
 
 	@Test
 	public void testEnabled() {
-		for (TestRunningState state : getEnabledStates()) {
+		for (EngineStateAdapter state : getEnabledStates()) {
 			applyTestState(state);
 			try {
 				handlerService.executeCommand(getCommandToTestId(), null);
 				assertTrue(true); // There should not be an Exception.
 
 			} catch (Exception e) {
-				fail("Exception during state " + state + ": " + e.getMessage());
+				fail("Exception during state " + state.getState() + ": " + e.getMessage());
 			}
 		}
 	}
 
 	@Test
 	public void testDisabled() throws ExecutionException, NotDefinedException, NotHandledException {
-		for (TestRunningState state : getDisabledStates()) {
+		for (EngineStateAdapter state : getDisabledStates()) {
 			applyTestState(state);
 			try {
 				handlerService.executeCommand(getCommandToTestId(), null);
-				fail(getCommandToTestId() + " should not be enabled during state " + state + ".");
+				fail(getCommandToTestId() + " should not be enabled during state " + state.getState() + ".");
 
 			} catch (NotEnabledException e) {
 				assertTrue(true); // This is expected to happen.
@@ -89,62 +97,54 @@
 		}
 	}
 
-	private void applyTestState(TestRunningState testState) {
-		testState.applyTo(model);
-		stateService.stateChange(LifeCycleState.UPDATE, ""); // Cause state update.
+	private void applyTestState(EngineStateAdapter testState) {
+		model.getEngine().running = testState.isRunning();
+		model.getEngine().paused = testState.isPausing();
+		stateService.engineStateChanged(model.getEngine(), testState.getState()); // Enforce a state update.
 	}
 
 	private class DummyModel implements IModel {
 
-		boolean initialized = false;
-
-		boolean created = false;
-
-		boolean active = false;
-
-		boolean running = false;
-
-		boolean paused = false;
-
-		boolean stopped = false;
-
-		boolean ending = false;
-
-		boolean ended = false;
+		private DummyEngine engine;
 
 		public DummyModel() {
+			engine = new DummyEngine();
+		}
+
+		public DummyEngine getEngine() {
+			return engine;
 		}
 
 		public boolean isCreated() {
-			return created;
+			return false;
 		}
 
 		public boolean isInitialized() {
-			return initialized;
+			return false;
 		}
 
 		public boolean isStopped() {
-			return stopped;
+			return false;
 		}
 
 		public boolean isRunning() {
-			return running;
+			return false;
 		}
 
 		public boolean isPaused() {
-			return paused;
+			return false;
 		}
 
 		public boolean isActive() {
-			return active;
+			return false;
 		}
 
 		public boolean isEnding() {
-			return ending;
+			return false;
 		}
 
 		public boolean isEnded() {
-			return ended;
+			return false;
 		}
 
 		public void addModelListener(ILifeCycleListener listener) {
@@ -155,7 +155,7 @@
 			return null;
 		}
 
-		public void removeModelListener(ILifeCycleListener listener) {
+		public void removeModelListener(ILifeCycleListener view) {
 			//
 		}
 
@@ -178,106 +178,71 @@
 		public int getStopPeriod() {
 			return 0;
 		}
-
-		public IEngine getEngine() {
-			return new IEngine() {
-
-				public void stop() {
-					//
-				}
-
-				public void setUpdateGranularity(ITimeGranularity granularity) {
-					//
-				}
-
-				public void observationComplete(ILifeCycleListener observer) {
-					//
-				}
-
-				public boolean isThreadAlive() {
-					return false;
-				}
-
-				public boolean isRunning() {
-					return false;
-				}
-
-				public boolean isPaused() {
-					return false;
-				}
-
-				public boolean isCloseRequested() {
-					return false;
-				}
-
-				public ITimeGranularity getUpdateGranularity() {
-					return null;
-				}
-
-				public IObservationProvider getModel() {
-					return DummyModel.this;
-				}
-
-				public void control(EngineControl ModelControl) {
-					//
-				}
-
-				public void closeFinally() {
-					//
-				}
-
-				public void close() {
-					//
-				}
-			};
-		}
 	}
 
-	static class TestRunningState {
-		private String name;
+	private class DummyEngine implements IEngine {
 
-		private boolean initialized;
+		boolean running = false;
 
-		private boolean created;
+		boolean paused = false;
 
-		private boolean active;
-
-		private boolean running;
-
-		private boolean paused;
-
-		private boolean stopped;
-
-		private boolean ending;
-
-		private boolean ended;
-
-		public TestRunningState(String name, boolean initialized, boolean created, boolean active, boolean running, boolean paused, boolean stopped, boolean ending, boolean ended) {
-			this.name = name;
-			this.initialized = initialized;
-			this.created = created;
-			this.active = active;
-			this.running = running;
-			this.paused = paused;
-			this.stopped = stopped;
-			this.ending = ending;
-			this.ended = ended;
+		public DummyEngine() {
 		}
 
-		public void applyTo(DummyModel model) {
-			model.initialized = initialized;
-			model.created = created;
-			model.active = active;
-			model.running = running;
-			model.paused = paused;
-			model.stopped = stopped;
-			model.ending = ending;
-			model.ended = ended;
+		public void close() {
+			//
 		}
 
-		@Override
-		public String toString() {
-			return name;
+		public void closeFinally() {
+			//
+		}
+
+		public boolean isCloseRequested() {
+			return false;
+		}
+
+		public boolean isThreadAlive() {
+			return false;
+		}
+
+		public boolean isRunning() {
+			return running;
+		}
+
+		public boolean isPaused() {
+			return paused;
+		}
+
+		public void stop() {
+			//
+		}
+
+		public void control(EngineControl ModelControl) {
+			//
+		}
+
+		public void addEngineObserver(IEngineObserver observer) {
+			//
+		}
+
+		public void removeEngineObserver(IEngineObserver observer) {
+			//
+		}
+
+		public void observationComplete(ILifeCycleListener observer) {
+			//
+		}
+
+		public IObservationProvider getModel() {
+			return null;
+		}
+
+		public void setUpdateGranularity(ITimeGranularity granularity) {
+			//
+		}
+
+		public ITimeGranularity getUpdateGranularity() {
+			return null;
 		}
 	}
 
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 034159f..be75f8c 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
@@ -1,5 +1,7 @@
 package org.eclipse.amp.axf.ide.handlers;
 
+import org.eclipse.amp.axf.core.EngineStateAdapter;
+
 /**
  * Pausing should be enabled whenever a simulation is running and
  * <emph>not</emph> in pause state.
@@ -14,13 +16,13 @@
 	}
 
 	@Override
-	protected TestRunningState[] getEnabledStates() {
-		return new TestRunningState[] { STATE_RUNNING };
+	protected EngineStateAdapter[] getEnabledStates() {
+		return new EngineStateAdapter[] { STATE_RUNNING };
 	}
 
 	@Override
-	protected TestRunningState[] getDisabledStates() {
-		return new TestRunningState[] { STATE_IDLE, STATE_STOPPED, STATE_PAUSED, STATE_ENDING };
+	protected EngineStateAdapter[] getDisabledStates() {
+		return new EngineStateAdapter[] { STATE_IDLE, STATE_PAUSED };
 	}
 
 }
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 cdeb6cd..2f857c7 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
@@ -1,5 +1,12 @@
 package org.eclipse.amp.axf.ide.handlers;
 
+import org.eclipse.amp.axf.core.EngineStateAdapter;
+
+/**
+ * Restarting should be enabled while running or paused.
+ * 
+ * @author jonas.ruettimann
+ */
 public class RestartHandlerTest extends ModelRunHandlerTest {
 
 	@Override
@@ -8,13 +15,13 @@
 	}
 
 	@Override
-	protected TestRunningState[] getEnabledStates() {
-		return new TestRunningState[] { STATE_RUNNING, STATE_PAUSED };
+	protected EngineStateAdapter[] getEnabledStates() {
+		return new EngineStateAdapter[] { STATE_RUNNING, STATE_PAUSED };
 	}
 
 	@Override
-	protected TestRunningState[] getDisabledStates() {
-		return new TestRunningState[] { STATE_IDLE, STATE_STOPPED, STATE_ENDING };
+	protected EngineStateAdapter[] getDisabledStates() {
+		return new EngineStateAdapter[] { STATE_IDLE };
 	}
 
 }
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 abf46d6..71a3cfd 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
@@ -1,5 +1,12 @@
 package org.eclipse.amp.axf.ide.handlers;
 
+import org.eclipse.amp.axf.core.EngineStateAdapter;
+
+/**
+ * Resuming should only be possible if in paused state.
+ * 
+ * @author jonas.ruettimann
+ */
 public class ResumeHandlerTest extends ModelRunHandlerTest {
 
 	@Override
@@ -8,13 +15,13 @@
 	}
 
 	@Override
-	protected TestRunningState[] getEnabledStates() {
-		return new TestRunningState[] { STATE_PAUSED };
+	protected EngineStateAdapter[] getEnabledStates() {
+		return new EngineStateAdapter[] { STATE_PAUSED };
 	}
 
 	@Override
-	protected TestRunningState[] getDisabledStates() {
-		return new TestRunningState[] { STATE_IDLE, STATE_RUNNING, STATE_STOPPED, STATE_ENDING };
+	protected EngineStateAdapter[] getDisabledStates() {
+		return new EngineStateAdapter[] { STATE_IDLE, STATE_RUNNING };
 	}
 
 }
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 8233df7..5270c02 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
@@ -1,5 +1,12 @@
 package org.eclipse.amp.axf.ide.handlers;
 
+import org.eclipse.amp.axf.core.EngineStateAdapter;
+
+/**
+ * Starting makes no sense in running state. Otherwise it does.
+ * 
+ * @author jonas.ruettimann
+ */
 public class StartHandlerTest extends ModelRunHandlerTest {
 
 	@Override
@@ -8,13 +15,13 @@
 	}
 
 	@Override
-	protected TestRunningState[] getEnabledStates() {
-		return new TestRunningState[] { STATE_STOPPED };
+	protected EngineStateAdapter[] getEnabledStates() {
+		return new EngineStateAdapter[] { STATE_IDLE };
 	}
 
 	@Override
-	protected TestRunningState[] getDisabledStates() {
-		return new TestRunningState[] { STATE_IDLE, STATE_RUNNING, STATE_PAUSED, STATE_ENDING };
+	protected EngineStateAdapter[] getDisabledStates() {
+		return new EngineStateAdapter[] { STATE_PAUSED, STATE_RUNNING };
 	}
 
 }
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 350e8f9..d2edb6e 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
@@ -1,5 +1,12 @@
 package org.eclipse.amp.axf.ide.handlers;
 
+import org.eclipse.amp.axf.core.EngineStateAdapter;
+
+/**
+ * Running a single step only makes sense in paused state.
+ * 
+ * @author jonas.ruettimann
+ */
 public class StepHandlerTest extends ModelRunHandlerTest {
 
 	@Override
@@ -8,13 +15,13 @@
 	}
 
 	@Override
-	protected TestRunningState[] getEnabledStates() {
-		return new TestRunningState[] { STATE_PAUSED };
+	protected EngineStateAdapter[] getEnabledStates() {
+		return new EngineStateAdapter[] { STATE_PAUSED };
 	}
 
 	@Override
-	protected TestRunningState[] getDisabledStates() {
-		return new TestRunningState[] { STATE_IDLE, STATE_STOPPED, STATE_RUNNING, STATE_ENDING };
+	protected EngineStateAdapter[] getDisabledStates() {
+		return new EngineStateAdapter[] { STATE_IDLE, STATE_RUNNING };
 	}
 
 }
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 dea892f..c2175f5 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
@@ -1,5 +1,7 @@
 package org.eclipse.amp.axf.ide.handlers;
 
+import org.eclipse.amp.axf.core.EngineStateAdapter;
+
 /**
  * Stopping should be enabled when paused or running.
  * 
@@ -13,13 +15,13 @@
 	}
 
 	@Override
-	protected TestRunningState[] getEnabledStates() {
-		return new TestRunningState[] { STATE_RUNNING, STATE_PAUSED };
+	protected EngineStateAdapter[] getEnabledStates() {
+		return new EngineStateAdapter[] { STATE_RUNNING, STATE_PAUSED };
 	}
 
 	@Override
-	protected TestRunningState[] getDisabledStates() {
-		return new TestRunningState[] { STATE_IDLE, STATE_STOPPED, STATE_ENDING };
+	protected EngineStateAdapter[] getDisabledStates() {
+		return new EngineStateAdapter[] { STATE_IDLE };
 	}
 
 }
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 4bd1f3d..b6de283 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
@@ -26,7 +26,9 @@
 import org.ascape.model.event.ScapeListener;
 import org.ascape.model.rule.PropogateScapeOnly;
 import org.ascape.runtime.NonGraphicRunner;
+import org.eclipse.amp.axf.core.EngineStateAdapter;
 import org.eclipse.amp.axf.core.IEngine;
+import org.eclipse.amp.axf.core.IEngineObserver;
 import org.eclipse.amp.axf.core.ILifeCycleListener;
 import org.eclipse.amp.axf.core.IModel;
 import org.eclipse.amp.axf.ide.ModelViewManager;
@@ -76,6 +78,10 @@
 
 	private Job escapeRun;
 
+	private ArrayList<IEngineObserver> observers = new ArrayList<IEngineObserver>();
+
+	private EngineStateAdapter engineStateAdapter = new EngineStateAdapter(isRunning(), isStep(), isPaused());
+
 	/**
 	 * Open.
 	 * 
@@ -360,14 +366,59 @@
 		}).start();
 	}
 
-	/**
-	 * 
-	 * @see org.eclipse.amp.axf.core.IEngine#control(org.eclipse.amp.axf.core.EngineControl)
-	 */
 	public void control(org.eclipse.amp.axf.core.EngineControl control) {
 		super.respondControl(adaptEngineControl(control));
 	}
 
+	@Override
+	public void waitForViewsUpdate() {
+		super.waitForViewsUpdate();
+
+		/*
+		 * Running, paused and step are not all update using setter methods. So this
+		 * is a workaround to not miss any state changes.
+		 */
+		updateStateAdapter();
+	}
+
+	@Override
+	public void setPaused(boolean paused) {
+		super.setPaused(paused);
+		updateStateAdapter();
+	}
+
+	@Override
+	public void setStep(boolean step) {
+		super.setStep(step);
+		updateStateAdapter();
+	}
+
+	@Override
+	public void setRunning(boolean running) {
+		super.setRunning(running);
+		updateStateAdapter();
+	}
+
+	private void updateStateAdapter() {
+		if (engineStateAdapter.update(isRunning(), isStep(), isPaused())) {
+			for (IEngineObserver observer : observers) {
+				observer.engineStateChanged(this, engineStateAdapter.getState());
+			}
+		}
+	}
+
+	public void addEngineObserver(IEngineObserver observer) {
+		if (!observers.contains(observer)) {
+			observers.add(observer);
+		}
+	}
+
+	public void removeEngineObserver(IEngineObserver observer) {
+		if (observers.contains(observer)) {
+			observers.remove(observer);
+		}
+	}
+
 	private ControlEvent adaptEngineControl(org.eclipse.amp.axf.core.EngineControl control) {
 		int id = 0;
 		switch (control) {