Bug 534319 - Debug View has wrong selection due to short lived threads

Delay thread removal from the internal model after all other events are
dispatched to allow other listeners properly update they models.

Change-Id: If25eb16a5fe8d4ed40f555cb0986ff4b1dd2b3af
Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java
index 299d99b..7b3a7a2 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java
@@ -33,6 +33,7 @@
 import com.sun.jdi.event.EventIterator;
 import com.sun.jdi.event.EventQueue;
 import com.sun.jdi.event.EventSet;
+import com.sun.jdi.event.ThreadDeathEvent;
 import com.sun.jdi.event.VMDeathEvent;
 import com.sun.jdi.event.VMDisconnectEvent;
 import com.sun.jdi.event.VMStartEvent;
@@ -189,6 +190,8 @@
 			}
 		}
 
+		List<Runnable> threadDeathRunnables = new ArrayList<>();
+
 		// notify handlers of the end result
 		index = -1;
 		iter = eventSet.eventIterator();
@@ -198,13 +201,21 @@
 			// notify registered listener, if any
 			IJDIEventListener listener = listeners[index];
 			if (listener != null) {
-				listener.eventSetComplete(event, fTarget, !resume, eventSet);
+				if (event instanceof ThreadDeathEvent) {
+					final boolean res = resume;
+					threadDeathRunnables.add(() -> listener.eventSetComplete(event, fTarget, !res, eventSet));
+				} else {
+					listener.eventSetComplete(event, fTarget, !resume, eventSet);
+				}
 			}
 		}
 
 		// fire queued DEBUG events
 		fireEvents(eventSet);
 
+		// Queue runnables which will remove terminated threads once other queued events are proceeded
+		threadDeathRunnables.forEach(runnable -> DebugPlugin.getDefault().asyncExec(runnable));
+
 		if (vote && resume) {
 			try {
 				eventSet.resume();
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java
index 24aff60..1436337 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java
@@ -2323,7 +2323,7 @@
 		 * @return <code>true</code> - the thread should be resumed
 		 */
 		@Override
-		public boolean handleEvent(Event event, JDIDebugTarget target,
+		public void eventSetComplete(Event event, JDIDebugTarget target,
 				boolean suspendVote, EventSet eventSet) {
 			ThreadReference ref = ((ThreadDeathEvent) event).thread();
 			JDIThread thread = findThread(ref);
@@ -2336,13 +2336,12 @@
 				}
 				thread.terminated();
 			}
-			return true;
 		}
 
 		@Override
-		public void eventSetComplete(Event event, JDIDebugTarget target,
+		public boolean handleEvent(Event event, JDIDebugTarget target,
 				boolean suspend, EventSet eventSet) {
-			// do nothing
+			return true;
 		}
 
 	}