Bug 271700 - testDeclaringTypes failing in nightly build
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/TypeTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/TypeTests.java
index 70d3e59..0023af9 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/TypeTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/TypeTests.java
@@ -30,7 +30,7 @@
 		super(name);
 	}
 
-	public void XtestDeclaringTypes() throws Exception {
+	public void testDeclaringTypes() throws Exception {
 		IJavaType[] types = new IJavaType[3];
 		int index = 0;
 		String typeName = "Breakpoints";
diff --git a/org.eclipse.jdt.debug/.options b/org.eclipse.jdt.debug/.options
new file mode 100644
index 0000000..2eb48a6
--- /dev/null
+++ b/org.eclipse.jdt.debug/.options
@@ -0,0 +1,2 @@
+org.eclipse.jdt.debug/debug=false
+org.eclipse.jdt.debug/debug/jdiEvents=false
\ No newline at end of file
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 1f604bd..5f7228f 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
@@ -105,6 +105,17 @@
 		if (isShutdown()) {
 			return;
 		}
+		if (JDIDebugOptions.DEBUG_JDI_EVENTS) {
+			EventIterator eventIter = eventSet.eventIterator();
+			System.out.print("JDI Event Set: {"); //$NON-NLS-1$
+			while (eventIter.hasNext()) {
+				System.out.print(eventIter.next());
+				if (eventIter.hasNext()) {
+					System.out.print(", "); //$NON-NLS-1$
+				}
+			}
+			System.out.println("}"); //$NON-NLS-1$
+		}
 		EventIterator iter= eventSet.eventIterator();
 		IJDIEventListener[] listeners = new IJDIEventListener[eventSet.size()];
 		boolean vote = false; 
@@ -239,6 +250,22 @@
 								dispatch(set);
 								return Status.OK_STATUS;
 							}
+							/* (non-Javadoc)
+							 * @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object)
+							 */
+							public boolean belongsTo(Object family) {
+								if (family instanceof Class) {
+									Class clazz = (Class) family;
+									EventIterator iterator = set.eventIterator();
+									while (iterator.hasNext()) {
+										Event event = iterator.nextEvent();
+										if (clazz.isInstance(event)) {
+											return true;
+										}
+									}									
+								}
+								return false;
+							}
 						};
 						job.setSystem(true);
 						job.schedule();
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugOptions.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugOptions.java
new file mode 100644
index 0000000..9f1fdc3
--- /dev/null
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugOptions.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.debug.core;
+
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * Debug flags in options file.
+ * 
+ * @since 3.5
+ */
+public class JDIDebugOptions {
+	// debug option flags
+	public static boolean DEBUG = false;
+	public static boolean DEBUG_JDI_EVENTS = false;
+
+	public static void initDebugOptions() {
+		DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.jdt.debug/debug"));  //$NON-NLS-1$//$NON-NLS-2$
+		DEBUG_JDI_EVENTS = DEBUG && "true".equals( //$NON-NLS-1$
+				 Platform.getDebugOption("org.eclipse.jdt.debug/debug/jdiEvents")); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java
index 06bd3d7..cb782ae 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java
@@ -250,6 +250,7 @@
 	
 	public void start(BundleContext context) throws Exception {
 		super.start(context);
+		JDIDebugOptions.initDebugOptions();
 		ResourcesPlugin.getWorkspace().addSaveParticipant(this, new ISaveParticipant() {
 			public void doneSaving(ISaveContext c) {}
 			public void prepareToSave(ISaveContext c)	throws CoreException {}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java
index c09d185..f85527e 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java
@@ -23,7 +23,9 @@
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.debug.core.DebugEvent;
 import org.eclipse.debug.core.DebugPlugin;
 import org.eclipse.debug.core.IDebugEventSetListener;
@@ -51,6 +53,7 @@
 import com.sun.jdi.event.Event;
 import com.sun.jdi.event.EventSet;
 import com.sun.jdi.event.LocatableEvent;
+import com.sun.jdi.event.ThreadStartEvent;
 import com.sun.jdi.request.ClassPrepareRequest;
 import com.sun.jdi.request.EventRequest;
 import com.sun.jdi.request.EventRequestManager;
@@ -262,6 +265,16 @@
 		}
 		ThreadReference threadRef= ((LocatableEvent)event).thread();
 		JDIThread thread= target.findThread(threadRef);	
+		if (thread == null) {
+			// wait for any thread start event sets to complete processing
+			// see bug 271700
+			try {
+				Job.getJobManager().join(ThreadStartEvent.class, null);
+			} catch (OperationCanceledException e) {
+			} catch (InterruptedException e) {
+			}
+			thread = target.findThread(threadRef);	
+		}
 		if (thread == null || thread.isIgnoringBreakpoints()) {
 			return true;
 		}