testing: fire sessionTerminated() when ILaunch is terminated
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java
index 55dfe6c..7e6b509 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java
@@ -21,12 +21,16 @@
 
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.debug.core.DebugPlugin;
 import org.eclipse.debug.core.ILaunch;
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.ILaunchManager;
 import org.eclipse.debug.core.ILaunchesListener2;
+import org.eclipse.dltk.annotations.Internal;
 import org.eclipse.dltk.core.IScriptProject;
 import org.eclipse.dltk.internal.testing.TestCategoryEngineManager;
 import org.eclipse.dltk.internal.testing.launcher.NullTestRunnerUI;
@@ -203,6 +207,7 @@
 						fTestRunnerClient.stopWaiting();
 					}
 					launchManager.removeLaunchListener(this);
+					scheduleTestRunTerminated();
 				}
 			}
 			public void launchesRemoved(ILaunch[] launches) {
@@ -211,12 +216,30 @@
 						fTestRunnerClient.stopWaiting();
 					}
 					launchManager.removeLaunchListener(this);
+					scheduleTestRunTerminated();
 				}
 			}
 			public void launchesChanged(ILaunch[] launches) {
 			}
 			public void launchesAdded(ILaunch[] launches) {
 			}
+
+			private void scheduleTestRunTerminated() {
+				if (!fIsRunning)
+					return;
+				final Job job = new Job(
+						"TestRunSession - notify launch terminated") { //$NON-NLS-1$
+					@Override
+					protected IStatus run(IProgressMonitor monitor) {
+						testRunTerminated();
+						return org.eclipse.core.runtime.Status.OK_STATUS;
+					}
+				};
+				job.setSystem(true);
+				// small delay, giving a chance for the client to notify in a
+				// normal way.
+				job.schedule(750);
+			}
 		});
 
 		fSessionListeners= new ListenerList();
@@ -704,13 +727,7 @@
 		}
 	
 		public void testRunTerminated() {
-			fIsRunning= false;
-			fIsStopped= true;
-			
-			Object[] listeners= fSessionListeners.getListeners();
-			for (int i= 0; i < listeners.length; ++i) {
-				((ITestSessionListener) listeners[i]).sessionTerminated();
-			}
+			TestRunSession.this.testRunTerminated();
 		}
 	
 		/* (non-Javadoc)
@@ -873,6 +890,18 @@
 		}
 	}
 
+	@Internal
+	void testRunTerminated() {
+		if (!fIsRunning || fIsStopped)
+			return;
+		fIsRunning = false;
+		fIsStopped = true;
+		Object[] listeners = fSessionListeners.getListeners();
+		for (int i = 0; i < listeners.length; ++i) {
+			((ITestSessionListener) listeners[i]).sessionTerminated();
+		}
+	}
+
 	private static class IncompleteTestSuite {
 		public TestSuiteElement fTestSuiteElement;
 		public int fOutstandingChildren;