initial release of debug test suite
diff --git a/org.eclipse.jdt.debug.tests/.classpath b/org.eclipse.jdt.debug.tests/.classpath
new file mode 100644
index 0000000..b1cb6e4
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/.classpath
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" path="test plugin"/>
+    <classpathentry kind="src" path="tests"/>
+    <classpathentry kind="src" path="/org.eclipse.core.boot"/>
+    <classpathentry kind="src" path="/org.eclipse.core.runtime"/>
+    <classpathentry kind="src" path="/org.junit"/>
+    <classpathentry kind="src" path="/org.eclipse.core.resources"/>
+    <classpathentry kind="src" path="/org.apache.xerces"/>
+    <classpathentry kind="src" path="/org.eclipse.ui"/>
+    <classpathentry kind="src" path="/org.eclipse.jdt.core"/>
+    <classpathentry kind="src" path="/org.eclipse.jdt.ui"/>
+    <classpathentry kind="src" path="/org.eclipse.jdt.launching"/>
+    <classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/>
+    <classpathentry kind="src" path="/org.eclipse.jdt.debug.ui"/>
+    <classpathentry kind="src" path="/org.eclipse.jdt.debug"/>
+    <classpathentry kind="src" path="/org.eclipse.debug.ui"/>
+    <classpathentry kind="src" path="/org.eclipse.debug.core"/>
+    <classpathentry kind="src" path="test programs"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.jdt.debug.tests/.cvsignore b/org.eclipse.jdt.debug.tests/.cvsignore
new file mode 100644
index 0000000..c5e82d7
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/.cvsignore
@@ -0,0 +1 @@
+bin
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/.plugins-path b/org.eclipse.jdt.debug.tests/.plugins-path
new file mode 100644
index 0000000..36f1716
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/.plugins-path
@@ -0,0 +1 @@
+platformPath = file:/d:/workspaces/eclipse-sh1/plugins/
diff --git a/org.eclipse.jdt.debug.tests/.project b/org.eclipse.jdt.debug.tests/.project
new file mode 100644
index 0000000..25a51ce
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.jdt.debug.tests</name>

+	<comment></comment>

+	<projects>

+		<project>org.apache.xerces</project>

+		<project>org.eclipse.core.boot</project>

+		<project>org.eclipse.core.resources</project>

+		<project>org.eclipse.core.runtime</project>

+		<project>org.eclipse.debug.core</project>

+		<project>org.eclipse.debug.ui</project>

+		<project>org.eclipse.jdt.core</project>

+		<project>org.eclipse.jdt.debug</project>

+		<project>org.eclipse.jdt.debug.ui</project>

+		<project>org.eclipse.jdt.junit.eclipse</project>

+		<project>org.eclipse.jdt.launching</project>

+		<project>org.eclipse.jdt.ui</project>

+		<project>org.eclipse.swt</project>

+		<project>org.eclipse.ui</project>

+		<project>org.junit</project>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+		<nature>org.eclipse.team.cvs.core.cvsnature</nature>

+	</natures>

+</projectDescription>

diff --git a/org.eclipse.jdt.debug.tests/about.html b/org.eclipse.jdt.debug.tests/about.html
new file mode 100644
index 0000000..441774f
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/about.html
@@ -0,0 +1,42 @@
+<html>
+<head>
+<title>About</title>
+<style type="text/css">
+p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect(   ); margin-top: 5mm; margin-left: 3mm}
+</style>
+</head>
+<body lang="EN-US" link="blue" vlink="purple">
+<table border="0" cellspacing="5" cellpadding="2" width="100%" >
+  <tr> 
+    <td align="LEFT" valign="TOP" colspan="2" bgcolor="#0080C0"><b><font color="#FFFFFF">About This Content</font></b></td>
+  </tr>
+  <tr> 
+    <td> 
+<p>11th December, 2001</p>	
+<h3>License</h3>
+<p>Eclipse.org makes available all content in this plug-in &quot;Content&quot;.  Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+<a href="http://www.eclipse.org/legal/cpl-v05.html">Common Public License Version 0.5</a> &quot;CPL&quot;.  For purposes of the CPL, &quot;Program&quot; will mean the Content.</p>
+
+<h3>Contributions</h3>
+
+<p>If this Content is licensed to you under the terms and conditions of the CPL, any Contributions, as defined in the CPL, uploaded, submitted, or otherwise
+made available to Eclipse.org, members of Eclipse.org and/or the host of Eclipse.org web site, by you that relate to such
+Content are provided under the terms and conditions of the CPL and can be made available to others under the terms of the CPL.</p>
+
+<p>If this Content is licensed to you under license terms and conditions other than the CPL &quot;Other License&quot;, any modifications, enhancements and/or
+other code and/or documentation &quot;Modifications&quot; uploaded, submitted, or otherwise made available to Eclipse.org, members of Eclipse.org and/or the
+host of Eclipse.org, by you that relate to such Content are provided under terms and conditions of the Other License and can be made available
+to others under the terms of the Other License.  In addition, with regard to Modifications for which you are the copyright holder, you are also
+providing the Modifications under the terms and conditions of the CPL and such Modifications can be made available to others under the terms of
+the CPL.</p>
+</td></tr></table>
+</body>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/build.properties b/org.eclipse.jdt.debug.tests/build.properties
new file mode 100644
index 0000000..945b01f
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/build.properties
@@ -0,0 +1,7 @@
+bin.includes = plugin.xml,\
+               test.xml,\
+               about.html,\
+               testresources/,\
+               *.jar
+source.javadebugtests.jar = test plugin/,\
+                         tests/
diff --git a/org.eclipse.jdt.debug.tests/plugin.xml b/org.eclipse.jdt.debug.tests/plugin.xml
new file mode 100644
index 0000000..3fb0c02
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/plugin.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin
+   name="Java Debug Test Plugin"
+   id="org.eclipse.jdt.debug.tests"
+   version="2.0.0"
+   vendor-name="IBM"
+   class="org.eclipse.jdt.debug.testplugin.JavaTestPlugin">
+   
+   <requires>
+	  <import plugin="org.junit"/>   
+      <import plugin="org.eclipse.core.resources"/>
+      <import plugin="org.apache.xerces"/>
+      <import plugin="org.eclipse.ui"/>
+      <import plugin="org.eclipse.jdt.core"/>
+      <import plugin="org.eclipse.jdt.ui"/>
+	  <import plugin="org.eclipse.jdt.launching"/>
+	  <import plugin="org.eclipse.jdt.debug"/>
+	  <import plugin="org.eclipse.jdt.debug.ui"/>
+	  <import plugin="org.eclipse.debug.core"/>
+	  <import plugin="org.eclipse.debug.ui"/>
+   </requires>
+
+<runtime>
+  <library name="javadebugtests.jar" >
+     <export name = "*"/>
+  </library> 
+</runtime>
+
+<extension id="app" point="org.eclipse.core.runtime.applications">
+  <application> 
+     <run class="org.eclipse.jdt.debug.testplugin.TestWorkbench">
+		<parameter name="productInfo" value="product.ini"/>
+     </run>
+  </application>
+</extension>
+
+
+</plugin>
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/DebugElementEventWaiter.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/DebugElementEventWaiter.java
new file mode 100644
index 0000000..8402201
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/DebugElementEventWaiter.java
@@ -0,0 +1,22 @@
+package org.eclipse.jdt.debug.testplugin;
+
+import org.eclipse.debug.core.DebugEvent;
+
+/**
+ * Waits for an event on a specific element
+ */
+
+public class DebugElementEventWaiter extends DebugEventWaiter {
+	
+	protected Object fElement;
+	
+	public DebugElementEventWaiter(int kind, Object element) {
+		super(kind);
+		fElement = element;
+	}
+	
+	public boolean accept(DebugEvent event) {
+		return super.accept(event) && fElement == event.getSource();
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/DebugElementKindEventWaiter.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/DebugElementKindEventWaiter.java
new file mode 100644
index 0000000..26dac87
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/DebugElementKindEventWaiter.java
@@ -0,0 +1,27 @@
+package org.eclipse.jdt.debug.testplugin;
+
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.model.IDebugElement;
+
+/**
+ * Waits for a type of event on a kind of element.  Compare this to SpecificDebugElementEventWaiter which is
+ * used to wait for a type of event on a specific debug element object.
+ */
+
+public class DebugElementKindEventWaiter extends DebugEventWaiter {
+	
+	protected Class fElementClass;
+	
+	public DebugElementKindEventWaiter(int eventKind, Class elementClass) {
+		super(eventKind);
+		fElementClass = elementClass;
+	}
+	
+	public boolean accept(DebugEvent event) {
+		Object o = event.getSource();
+		return super.accept(event) && fElementClass.isInstance(o);
+	}
+
+}
+
+
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/DebugEventWaiter.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/DebugEventWaiter.java
new file mode 100644
index 0000000..3cdac10
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/DebugEventWaiter.java
@@ -0,0 +1,158 @@
+package org.eclipse.jdt.debug.testplugin;
+
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IDebugEventSetListener;
+
+/**
+ * The <code>DebugEventWaiter</code> is
+ * to wait for a specific kind of debug event.
+ * <p>
+ * When a <code>DebugEventWaiter</code> is created, it
+ * registers itself with the <code>IDebugModelManager</code> as
+ * a <code>IDebugModelEventListener</code>.
+ * <p>
+ * NOTE: <code>DebugEventWaiter</code> objects are intended for
+ * one time use only!
+ */
+public class DebugEventWaiter implements IDebugEventSetListener {
+	/**
+	 * The kind of event the waiter is waiting for
+	 */
+	protected int fEventType;
+
+	/**
+	 * The number of milliseconds the waiter will wait before timing out.
+	 */
+	protected long fTimeout;
+
+	/**
+	 * The <code>IDebugModelManager</code> this waiter is listening to.
+	 */
+	protected DebugPlugin fDebugPlugin;
+
+	/**
+	 * The <code>DebugEvent</code> received.
+	 */
+	protected DebugEvent fEvent;
+	
+	/**
+	 * The event set that was accepted
+	 */
+	protected DebugEvent[] fEventSet;
+
+	/**
+	 * The default timeout value if none is given (20000).
+	 */
+	public static final long DEFAULT_TIMEOUT= 15000;
+
+	/**
+	 * Creates a new <code>DebugEventWaiter</code> which
+	 * waits for events of a kind <code>eventType</code>.
+	 * The wait method will wait the default timeout value.
+	 */
+	public DebugEventWaiter(int eventType) {
+		fDebugPlugin= DebugPlugin.getDefault();
+		fEventType= eventType;
+		fTimeout= DEFAULT_TIMEOUT;
+
+		fDebugPlugin.addDebugEventListener(this);
+	}
+
+	/**
+	 * Answers true if the <code>DebugEvent</code> is acceptable.
+	 */
+	public boolean accept(DebugEvent event) {
+		return event.getKind() == fEventType;
+	}
+	/**
+	 * Answers the event name associated with the given flag.
+	 */
+	public String getEventName(int flag) {
+		switch (flag) {
+			case DebugEvent.CREATE :
+				return "Create";
+			case DebugEvent.TERMINATE :
+				return "Terminate";
+			case DebugEvent.RESUME :
+				return "Resume";
+			case DebugEvent.SUSPEND :
+				return "Suspend";
+			default :
+				return "UNKNOWN";
+		}
+	}
+
+	/**
+	 * Handles debug events.
+	 *
+	 * @see IDebugEventListener
+	 * @see #accept(DebugEvent)
+	 */
+	public synchronized void handleDebugEvents(DebugEvent[] events) {
+		//printReceived(event);
+		//printReceived(event);
+		for (int i = 0; i < events.length; i++) {
+			if (accept(events[i])) {
+				fEvent= events[i];
+				fEventSet = events;
+				notifyAll();
+				return;
+			}
+		}
+	}
+
+	/**
+	 * Prints a message indicating which event was received.
+	 */
+	protected void printReceived(DebugEvent event) {
+		System.out.println(this +" got " + event);
+	}
+
+	/**
+	 * Sets the number of milliseconds to wait for this callback
+	 */
+	public void setTimeout(long milliseconds) {
+		fTimeout= milliseconds;
+	}
+
+	/**
+	 * Unregisters this waiter as a listener
+	 */
+	public void unregister() {
+		fDebugPlugin.removeDebugEventListener(this);
+	}
+
+	/**
+	 * Returns the source of the accepted event, or <code>null</code>
+	 * if no event was accepted.
+	 */
+	public synchronized Object waitForEvent() {
+		if (fEvent == null) {
+			try {
+				wait(fTimeout);
+			} catch (InterruptedException ie) {
+				System.err.println("Interrupted waiting for event");
+			}
+		}
+		unregister();
+		if (fEvent == null)
+			return null;
+		return fEvent.getSource();
+	}
+
+	/**
+	 * Returns the accepted event, if any.
+	 */
+	public DebugEvent getEvent() {
+		return fEvent;
+	}
+	
+	/**
+	 * Returns the accepted event set, if any.
+	 */
+	public DebugEvent[] getEventSet() {
+		return fEventSet;
+	}	
+}
+
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaProjectHelper.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaProjectHelper.java
new file mode 100644
index 0000000..be461f3
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaProjectHelper.java
@@ -0,0 +1,279 @@
+package org.eclipse.jdt.debug.testplugin;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.ClasspathEntry;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
+import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
+import org.eclipse.ui.wizards.datatransfer.ImportOperation;
+import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;
+
+/**
+ * Helper methods to set up a IJavaProject.
+ */
+public class JavaProjectHelper {
+	
+	public static final IPath TEST_SRC_DIR= new Path("test programs");	
+
+	/**
+	 * Creates a IJavaProject.
+	 */	
+	public static IJavaProject createJavaProject(String projectName, String binFolderName) throws CoreException {
+		IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
+		IProject project= root.getProject(projectName);
+		if (!project.exists()) {
+			project.create(null);
+		} else {
+			project.refreshLocal(IResource.DEPTH_INFINITE, null);
+		}
+		
+		if (!project.isOpen()) {
+			project.open(null);
+		}
+		
+		IPath outputLocation;
+		if (binFolderName != null && binFolderName.length() > 0) {
+			IFolder binFolder= project.getFolder(binFolderName);
+			if (!binFolder.exists()) {
+				binFolder.create(false, true, null);
+			}
+			outputLocation= binFolder.getFullPath();
+		} else {
+			outputLocation= project.getFullPath();
+		}
+		
+		if (!project.hasNature(JavaCore.NATURE_ID)) {
+			addNatureToProject(project, JavaCore.NATURE_ID, null);
+		}
+		
+		IJavaProject jproject= JavaCore.create(project);
+		
+		jproject.setOutputLocation(outputLocation, null);
+		jproject.setRawClasspath(new IClasspathEntry[0], null);
+		
+		return jproject;	
+	}
+	
+	/**
+	 * Removes a IJavaProject.
+	 */		
+	public static void delete(IJavaProject jproject) throws CoreException {
+		jproject.setRawClasspath(new ClasspathEntry[0], jproject.getProject().getFullPath(), null);
+		jproject.getProject().delete(true, true, null);
+	}
+
+
+	/**
+	 * Adds a source container to a IJavaProject.
+	 */		
+	public static IPackageFragmentRoot addSourceContainer(IJavaProject jproject, String containerName) throws CoreException {
+		IProject project= jproject.getProject();
+		IContainer container= null;
+		if (containerName == null || containerName.length() == 0) {
+			container= project;
+		} else {
+			IFolder folder= project.getFolder(containerName);
+			if (!folder.exists()) {
+				folder.create(false, true, null);
+			}
+			container= folder;
+		}
+		IPackageFragmentRoot root= jproject.getPackageFragmentRoot(container);
+		
+		IClasspathEntry cpe= JavaCore.newSourceEntry(root.getPath());
+		addToClasspath(jproject, cpe);		
+		return root;
+	}
+
+	/**
+	 * Adds a source container to a IJavaProject and imports all files contained
+	 * in the given Zip file.
+	 */	
+	public static IPackageFragmentRoot addSourceContainerWithImport(IJavaProject jproject, String containerName, ZipFile zipFile) throws InvocationTargetException, CoreException {
+		IPackageFragmentRoot root= addSourceContainer(jproject, containerName);
+		importFilesFromZip(zipFile, root.getPath(), null);
+		return root;
+	}
+
+	/**
+	 * Removes a source folder from a IJavaProject.
+	 */		
+	public static void removeSourceContainer(IJavaProject jproject, String containerName) throws CoreException {
+		IFolder folder= jproject.getProject().getFolder(containerName);
+		removeFromClasspath(jproject, folder.getFullPath());
+		folder.delete(true, null);
+	}
+
+	/**
+	 * Adds a library entry to a IJavaProject.
+	 */	
+	public static IPackageFragmentRoot addLibrary(IJavaProject jproject, IPath path) throws JavaModelException {
+		return addLibrary(jproject, path, null, null);
+	}
+
+	/**
+	 * Adds a library entry with source attchment to a IJavaProject.
+	 */			
+	public static IPackageFragmentRoot addLibrary(IJavaProject jproject, IPath path, IPath sourceAttachPath, IPath sourceAttachRoot) throws JavaModelException {
+		IClasspathEntry cpe= JavaCore.newLibraryEntry(path, sourceAttachPath, sourceAttachRoot);
+		addToClasspath(jproject, cpe);
+		return jproject.getPackageFragmentRoot(path.toString());
+	}
+
+	/**
+	 * Copies the library into the project and adds it as library entry.
+	 */			
+	public static IPackageFragmentRoot addLibraryWithImport(IJavaProject jproject, IPath jarPath, IPath sourceAttachPath, IPath sourceAttachRoot) throws IOException, CoreException {
+		IProject project= jproject.getProject();
+		IFile newFile= project.getFile(jarPath.lastSegment());
+		InputStream inputStream= null;
+		try {
+			inputStream= new FileInputStream(jarPath.toFile()); 
+			newFile.create(inputStream, true, null);
+		} finally {
+			if (inputStream != null) {
+				try { inputStream.close(); } catch (IOException e) { }
+			}
+		}				
+		return addLibrary(jproject, newFile.getFullPath(), sourceAttachPath, sourceAttachRoot);
+	}	
+
+		
+	/**
+	 * Adds a variable entry with source attchment to a IJavaProject.
+	 * Can return null if variable can not be resolved.
+	 */			
+	public static IPackageFragmentRoot addVariableEntry(IJavaProject jproject, IPath path, IPath sourceAttachPath, IPath sourceAttachRoot) throws JavaModelException {
+		IClasspathEntry cpe= JavaCore.newVariableEntry(path, sourceAttachPath, sourceAttachRoot);
+		addToClasspath(jproject, cpe);
+		IPath resolvedPath= JavaCore.getResolvedVariablePath(path);
+		if (resolvedPath != null) {
+			return jproject.getPackageFragmentRoot(resolvedPath.toString());
+		}
+		return null;
+	}
+	
+	
+	/**
+	 * Adds a required project entry.
+	 */		
+	public static void addRequiredProject(IJavaProject jproject, IJavaProject required) throws JavaModelException {
+		IClasspathEntry cpe= JavaCore.newProjectEntry(required.getProject().getFullPath());
+		addToClasspath(jproject, cpe);
+	}	
+	
+	public static void removeFromClasspath(IJavaProject jproject, IPath path) throws JavaModelException {
+		IClasspathEntry[] oldEntries= jproject.getRawClasspath();
+		int nEntries= oldEntries.length;
+		ArrayList list= new ArrayList(nEntries);
+		for (int i= 0 ; i < nEntries ; i++) {
+			IClasspathEntry curr= oldEntries[i];
+			if (!path.equals(curr.getPath())) {
+				list.add(curr);			
+			}
+		}
+		IClasspathEntry[] newEntries= (IClasspathEntry[])list.toArray(new IClasspathEntry[list.size()]);
+		jproject.setRawClasspath(newEntries, null);
+	}	
+
+	private static void addToClasspath(IJavaProject jproject, IClasspathEntry cpe) throws JavaModelException {
+		IClasspathEntry[] oldEntries= jproject.getRawClasspath();
+		for (int i= 0; i < oldEntries.length; i++) {
+			if (oldEntries[i].equals(cpe)) {
+				return;
+			}
+		}
+		int nEntries= oldEntries.length;
+		IClasspathEntry[] newEntries= new IClasspathEntry[nEntries + 1];
+		System.arraycopy(oldEntries, 0, newEntries, 0, nEntries);
+		newEntries[nEntries]= cpe;
+		jproject.setRawClasspath(newEntries, null);
+	}
+	
+			
+	private static void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException {
+		IProjectDescription description = proj.getDescription();
+		String[] prevNatures= description.getNatureIds();
+		String[] newNatures= new String[prevNatures.length + 1];
+		System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
+		newNatures[prevNatures.length]= natureId;
+		description.setNatureIds(newNatures);
+		proj.setDescription(description, monitor);
+	}
+	
+	private static void importFilesFromZip(ZipFile srcZipFile, IPath destPath, IProgressMonitor monitor) throws InvocationTargetException {		
+		ZipFileStructureProvider structureProvider=	new ZipFileStructureProvider(srcZipFile);
+		try {
+			ImportOperation op= new ImportOperation(destPath, structureProvider.getRoot(), structureProvider, new ImportOverwriteQuery());
+			op.run(monitor);
+		} catch (InterruptedException e) {
+			// should not happen
+		}
+	}
+	
+	public static void importFilesFromDirectory(File rootDir, IPath destPath, IProgressMonitor monitor) throws InvocationTargetException, IOException {		
+		IImportStructureProvider structureProvider = FileSystemStructureProvider.INSTANCE;
+		List files = new ArrayList(100);
+		addJavaFiles(rootDir, files);
+		try {
+			ImportOperation op= new ImportOperation(destPath, rootDir, structureProvider, new ImportOverwriteQuery(), files);
+			op.setCreateContainerStructure(false);
+			op.run(monitor);
+		} catch (InterruptedException e) {
+			// should not happen
+		}
+	}	
+	
+	private static void addJavaFiles(File dir, List collection) throws IOException {
+		File[] files = dir.listFiles();
+		List subDirs = new ArrayList(2);
+		for (int i = 0; i < files.length; i++) {
+			if (files[i].isFile()) {
+				collection.add(files[i]);
+			} else if (files[i].isDirectory()) {
+				subDirs.add(files[i]);
+			}
+		}
+		Iterator iter = subDirs.iterator();
+		while (iter.hasNext()) {
+			File subDir = (File)iter.next();
+			addJavaFiles(subDir, collection);
+		}
+	}
+	
+	private static class ImportOverwriteQuery implements IOverwriteQuery {
+		public String queryOverwrite(String file) {
+			return ALL;
+		}	
+	}		
+	
+	
+}
+
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaTestPlugin.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaTestPlugin.java
new file mode 100644
index 0000000..0d15511
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaTestPlugin.java
@@ -0,0 +1,56 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package org.eclipse.jdt.debug.testplugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceDescription;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+
+public class JavaTestPlugin extends AbstractUIPlugin {
+	
+	private static JavaTestPlugin fgDefault;
+	
+	public JavaTestPlugin(IPluginDescriptor descriptor) {
+		super(descriptor);
+		fgDefault= this;
+	}
+	
+	public static JavaTestPlugin getDefault() {
+		return fgDefault;
+	}
+	
+	public static IWorkspace getWorkspace() {
+		return ResourcesPlugin.getWorkspace();
+	}
+	
+	public static void enableAutobuild(boolean enable) throws CoreException {
+		// disable auto build
+		IWorkspace workspace= fgDefault.getWorkspace();
+		IWorkspaceDescription desc= workspace.getDescription();
+		desc.setAutoBuilding(enable);
+		workspace.setDescription(desc);
+	}
+	
+	public File getFileInPlugin(IPath path) {
+		try {
+			URL installURL= new URL(getDescriptor().getInstallURL(), path.toString());
+			URL localURL= Platform.asLocalURL(installURL);
+			return new File(localURL.getFile());
+		} catch (IOException e) {
+			return null;
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaTestSetup.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaTestSetup.java
new file mode 100644
index 0000000..786e268
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaTestSetup.java
@@ -0,0 +1,32 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package org.eclipse.jdt.debug.testplugin;
+
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+
+import org.eclipse.core.resources.IWorkspaceRoot;
+
+
+public class JavaTestSetup extends TestSetup {
+	
+	/**
+	 * @deprecated
+	 * Not needed anymore. No added value
+	 */
+	public JavaTestSetup(Test test) {
+		super(test);
+	}	
+	
+	protected void setUp() throws Exception {
+	}
+
+	protected void tearDown() throws Exception {
+	}
+	
+
+	
+	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/Main.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/Main.java
new file mode 100644
index 0000000..ebea8c5
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/Main.java
@@ -0,0 +1,528 @@
+package org.eclipse.jdt.debug.testplugin;
+
+// copied from startup.jar. planned to be removed soon
+
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.net.*;
+import java.lang.reflect.*;
+import java.io.*;
+import java.util.*;
+/**
+ * Startup class for Eclipse. Creates a class loader using
+ * supplied URL of platform installation, loads and calls
+ * the Eclipse Boot Loader.  The startup arguments are as follows:
+ * <dl>
+ * <dd>
+ *    -application &lt;id&gt;: the identifier of the application to run
+ * </dd>
+ * <dd>
+ *    -boot &lt;location&gt;: the location, expressed as a URL, of the platform's boot.jar
+ * </dd>
+ * <dd>
+ *    -consolelog : enables log to the console. Handy when combined with -debug
+ * </dd>
+ * <dd>
+ *    -data &lt;location&gt;: sets the workspace location and the default location for projects
+ * </dd>
+ * <dd>
+ *    -debug [options file]: turns on debug mode for the platform and optionally specifies a location
+ * for the .options file. This file indicates what debug points are available for a
+ * plug-in and whether or not they are enabled. If a location is not specified, the platform searches
+ * for the .options file under the install directory
+ * </dd>
+ * <dd>
+ *    -dev [entries]: turns on dev mode and optionally specifies comma-separated class path entries
+ * which are added to the class path of each plug-in
+ * </dd>
+ * <dd>
+ *    -keyring &lt;location&gt;: the location of the authorization database on disk. This argument
+ * has to be used together with the -password argument
+ * </dd>
+ * <dd>
+ *    -password &lt;passwd&gt;: the password for the authorization database
+ * </dd>
+ * <dd>
+ *    -plugins &lt;location&gt;: The arg is a URL pointing to a file which specs the plugin 
+ * path for the platform.  The file is in property file format where the keys are user-defined 
+ * names and the values are comma separated lists of either explicit paths to plugin.xml 
+ * files or directories containing plugins. (e.g., .../eclipse/plugins).
+ * </dd>
+ * <dd>
+ *    -ws &lt;window system&gt;: sets the window system value
+ * </dd>
+ * </dl>
+ */
+public class Main {
+	/**
+	 * Indicates whether this instance is running in debug mode.
+	 */
+	protected boolean debug = false;
+	
+	/**
+	 * The location of the launcher to run.
+	 */
+	protected String bootLocation = null;
+	
+	/**
+	 * The identifier of the application to run.
+	 */
+	protected String application;
+	
+	/**
+	 * The path for finding find plugins.
+	 */
+	protected URL pluginPathLocation;
+	
+	/**
+	 * The boot path location.
+	 */
+	protected String location;
+	
+	/**
+	 * Indicates whether items for UNinstallation should be looked for.
+	 */
+	protected boolean uninstall = false;
+	
+	/**
+	 * The item to be uninstalled.
+	 */
+	protected String uninstallCookie;
+	
+	/**
+	 * The class path entries.
+	 */
+	protected String devClassPath = null;
+	
+	/**
+	 * Indicates whether this instance is running in development mode.
+	 */
+	protected boolean inDevelopmentMode = false;
+
+	// static token describing how to take down the splash screen
+	private static String endSplash = null;
+	
+	// constants
+	private static final String APPLICATION = "-application";
+	private static final String BOOT = "-boot";
+	private static final String DEBUG = "-debug";
+	private static final String DEV = "-dev";
+	private static final String ENDSPLASH = "-endsplash";
+	private static final String UNINSTALL = "-uninstall";
+	private static final String PI_BOOT = "org.eclipse.core.boot";
+	private static final String BOOTLOADER = "org.eclipse.core.boot.BootLoader";
+	private static final String UPDATELOADER = "org.eclipse.core.internal.boot.LaunchInfo";
+
+	// The project containing the boot loader code.  This is used to construct
+	// the correct class path for running in VAJ and VAME.
+	private static final String PROJECT_NAME = "Eclipse Core Boot";
+
+	private static boolean inVAJ;
+	static {
+		try {
+			Class.forName("com.ibm.uvm.lang.ProjectClassLoader");
+			inVAJ = true;
+		} catch (Exception e) {
+			inVAJ = false;
+		}
+	}
+	private static boolean inVAME;
+	static {
+		try {
+			Class.forName("com.ibm.eclipse.core.VAME");
+			inVAME = true;
+		} catch (Exception e) {
+			inVAME = false;
+		}
+	}
+
+/**
+ * Executes the launch.
+ * 
+ * @return the result of performing the launch
+ * @param args command-line arguments
+ * @exception Exception thrown if a problem occurs during the launch
+ */
+protected Object basicRun(String[] args) throws Exception {
+	Class clazz = getBootLoader(bootLocation);
+	Method method = clazz.getDeclaredMethod("run", new Class[] { String.class, URL.class, String.class, String[].class });
+	try {
+		return method.invoke(clazz, new Object[] { application, pluginPathLocation, location, args });
+	} catch (InvocationTargetException e) {
+		if (e.getTargetException() instanceof Error)
+			throw (Error) e.getTargetException();
+		else
+			throw e;
+	}
+}
+
+/**
+ * Returns the result of converting a list of comma-separated tokens into an array
+ * 
+ * @return the array of string tokens
+ * @param prop the initial comma-separated string
+ */
+private String[] getArrayFromList(String prop) {
+	if (prop == null || prop.trim().equals(""))
+		return new String[0];
+	Vector list = new Vector();
+	StringTokenizer tokens = new StringTokenizer(prop, ",");
+	while (tokens.hasMoreTokens()) {
+		String token = tokens.nextToken().trim();
+		if (!token.equals(""))
+			list.addElement(token);
+	}
+	return list.isEmpty() ? new String[0] : (String[]) list.toArray(new String[0]);
+}
+/**
+ * Creates and returns a platform <code>BootLoader</code> which can be used to start
+ * up and run the platform.  The given base, if not <code>null</code>,
+ * is the location of the boot loader code.  If the value is <code>null</code>
+ * then the boot loader is located relative to this class.
+ * 
+ * @return the new boot loader
+ * @param base the location of the boot loader
+ */
+public Class getBootLoader(String base) throws Exception {
+	URLClassLoader loader = new URLClassLoader(getBootPath(base), null);
+	return loader.loadClass(BOOTLOADER);
+}
+/**
+ * Returns the <code>URL</code>-based class path describing where the boot classes
+ * are located when running in development mode.
+ * 
+ * @return the url-based class path
+ * @param base the base location
+ * @exception MalformedURLException if a problem occurs computing the class path
+ */
+protected URL[] getDevPath(URL base) throws MalformedURLException {
+	URL url;
+	String devBase = base.toExternalForm();
+	if (!inDevelopmentMode) {
+		url = new URL(devBase + "boot.jar");
+		return new URL[] {url};
+	}
+	String[] locations = getArrayFromList(devClassPath);
+	ArrayList result = new ArrayList(locations.length);
+	for (int i = 0; i < locations.length; i++) {
+		String spec = devBase + locations[i];
+		char lastChar = spec.charAt(spec.length() - 1);
+		if ((spec.endsWith(".jar") || (lastChar == '/' || lastChar == '\\')))
+			url = new URL (spec);
+		else
+			url = new URL(spec + "/");
+		//make sure URL exists before adding to path
+		if (new java.io.File(url.getFile()).exists())
+			result.add(url);
+	}
+	url = new URL(devBase + "boot.jar");
+	if (new java.io.File(url.getFile()).exists())
+		result.add(url);
+	return (URL[])result.toArray(new URL[result.size()]);
+}
+
+/**
+ * Returns the <code>URL</code>-based class path describing where the boot classes are located.
+ * 
+ * @return the url-based class path
+ * @param base the base location
+ * @exception MalformedURLException if a problem occurs computing the class path
+ */
+protected URL[] getBootPath(String base) throws MalformedURLException {
+	URL url = null;
+	// if the given location is not null, assume it is correct and use it. 
+	if (base != null) {
+		url = new URL(base);
+		if (debug)
+			System.out.println("Boot URL: " + url.toExternalForm());
+		return new URL[] {url};	
+	}
+	// Create a URL based on the location of this class' code.
+	// strip off jar file and/or last directory to get 
+	// to the directory containing projects.
+	URL[] result = null;
+	url = getClass().getProtectionDomain().getCodeSource().getLocation();
+	String path = url.getFile();
+	if (path.endsWith(".jar"))
+		path = path.substring(0, path.lastIndexOf("/"));
+	else 
+		if (path.endsWith("/"))
+			path = path.substring(0, path.length() - 1);
+	if (inVAJ || inVAME) {
+		int ix = path.lastIndexOf("/");
+		path = path.substring(0, ix + 1);
+		path = path + PROJECT_NAME + "/";
+		url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
+		result = new URL[] {url};
+	} else {
+		path = searchForPlugins(path);
+		path = searchForBoot(path);
+		// add on any dev path elements
+		url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path);
+		result = getDevPath(url);
+	}
+	if (debug) {
+		System.out.println("Boot URL:");
+		for (int i = 0; i < result.length; i++)
+			System.out.println("    " + result[i].toExternalForm());	
+	}
+	return result;
+}
+
+/**
+ * Searches for a plugins root starting at a given location.  If one is
+ * found then this location is returned; otherwise an empty string is
+ * returned.
+ * 
+ * @return the location where plugins were found, or an empty string
+ * @param start the location to begin searching at
+ */
+protected String searchForPlugins(String start) {
+	File path = new File(start);
+	while (path != null) {
+		File test = new File(path, "plugins");
+		if (test.exists())
+			return test.toString();
+		path = path.getParentFile();
+		path = (path == null || path.length() == 1)  ? null : path;
+	}
+	return "";
+}
+/**
+ * Searches for a boot directory starting at a given location.  If one
+ * is found then this location is returned; otherwise an empty string
+ * is returned.
+ * 
+ * @return the location where plugins were found, or an empty string
+ * @param start the location to begin searching at
+ */
+protected String searchForBoot(String start) {
+	FileFilter filter = new FileFilter() {
+		public boolean accept(File candidate) {
+			return candidate.getName().startsWith(PI_BOOT);
+		}
+	};
+	File[] boots = new File(start).listFiles(filter);
+	String result = null;
+	String maxVersion = null;
+	for (int i = 0; i < boots.length; i++) {
+		String name = boots[i].getName();
+		int index = name.lastIndexOf('_');
+		if (index == -1) {
+			result = boots[i].getAbsolutePath();
+			i = boots.length;
+		} else {
+			if (index > 0) {
+				String version = name.substring(index + 1);
+				if (maxVersion == null) {
+					result = boots[i].getAbsolutePath();
+					maxVersion = version;
+				} else
+					if (maxVersion.compareTo(version) == -1) {
+						result = boots[i].getAbsolutePath();
+						maxVersion = version;
+					}						
+			}
+		}
+	}
+	if (result == null)
+		throw new RuntimeException("Could not find bootstrap code. Check location of boot plug-in or specify -boot.");
+	return result.replace(File.separatorChar, '/') + "/";
+}
+/**
+ * Returns the update loader for the given boot path.
+ * 
+ * @return the update loader
+ * @param base the boot path base
+ * @exception Exception thrown is a problem occurs determining this loader
+ */
+public Class getUpdateLoader(String base) throws Exception {
+	URLClassLoader loader = new URLClassLoader(getBootPath(base), null);
+	return loader.loadClass(UPDATELOADER);
+}
+/**
+ * Runs the platform with the given arguments.  The arguments must identify
+ * an application to run (e.g., <code>-application com.example.application</code>).
+ * After running the application <code>System.exit(N)</code> is executed.
+ * The value of N is derived from the value returned from running the application.
+ * If the application's return value is an <code>Integer</code>, N is this value.
+ * In all other cases, N = 0.
+ * <p>
+ * Clients wishing to run the platform without a following <code>System.exit</code>
+ * call should use <code>run()</code>.
+ *
+ * @see #run
+ * 
+ * @param args the command line arguments
+ */
+public static void main(String[] args) {
+	Object result = null;
+	try {
+		result = new Main().run(args);
+	} catch (Throwable e) {
+		// try and take down the splash screen.
+		endSplash();
+		System.out.println("Exception launching the Eclipse Platform:");
+		e.printStackTrace();
+	}
+	int exitCode = result instanceof Integer ? ((Integer) result).intValue() : 0;
+	System.exit(exitCode);
+}
+/**
+ * Tears down the currently-displayed splash screen.
+ */
+public static void endSplash() {
+	if (endSplash == null)
+		return;
+	try {
+		Runtime.getRuntime().exec(endSplash);
+	} catch (Exception e) {
+	}
+}
+
+/**
+ * Runs this launcher with the arguments specified in the given string.
+ * 
+ * @param argString the arguments string
+ * @exception Exception thrown if a problem occurs during launching
+ */
+public static void main(String argString) throws Exception {
+	Vector list = new Vector(5);
+	for (StringTokenizer tokens = new StringTokenizer(argString, " "); tokens.hasMoreElements();)
+		list.addElement((String) tokens.nextElement());
+	main((String[]) list.toArray(new String[list.size()]));
+}
+
+/**
+ * Processes the command line arguments
+ * 
+ * @return the arguments to pass through to the launched application
+ * @param args the command line arguments
+ */
+protected String[] processCommandLine(String[] args) throws Exception {
+	int[] configArgs = new int[100];
+	configArgs[0] = -1; // need to initialize the first element to something that could not be an index.
+	int configArgIndex = 0;
+	for (int i = 0; i < args.length; i++) {
+		boolean found = false;
+		// check for args without parameters (i.e., a flag arg)
+		// check if debug should be enabled for the entire platform
+		if (args[i].equalsIgnoreCase(DEBUG)) {
+			debug = true;
+			// passed thru this arg (i.e., do not set found = true
+			continue;
+		}
+		
+		// check if development mode should be enabled for the entire platform
+		// If this is the last arg or there is a following arg (i.e., arg+1 has a leading -), 
+		// simply enable development mode.  Otherwise, assume that that the following arg is
+		// actually some additional development time class path entries.  This will be processed below.
+		if (args[i].equalsIgnoreCase(DEV) && ((i + 1 == args.length) || ((i + 1 < args.length) && (args[i + 1].startsWith("-"))))) {
+			inDevelopmentMode = true;
+			// do not mark the arg as found so it will be passed through
+			continue;
+		}
+
+		// done checking for args.  Remember where an arg was found 
+		if (found) {
+			configArgs[configArgIndex++] = i;
+			continue;
+		}
+		// check for args with parameters. If we are at the last argument or if the next one
+		// has a '-' as the first character, then we can't have an arg with a parm so continue.
+		if (i == args.length - 1 || args[i + 1].startsWith("-")) 
+			continue;
+		String arg = args[++i];
+
+		// look for the laucher to run
+		if (args[i - 1].equalsIgnoreCase(BOOT)) {
+			bootLocation = arg;
+			found = true;
+		}
+
+		// look for the development mode and class path entries.  
+		if (args[i - 1].equalsIgnoreCase(DEV)) {
+			inDevelopmentMode = true;
+			devClassPath = arg;
+			continue;
+		}
+
+		// look for the application to run
+		if (args[i - 1].equalsIgnoreCase(APPLICATION)) {
+			application = arg;
+			found = true;
+		}
+
+		// look for token to use to end the splash screen
+		if (args[i - 1].equalsIgnoreCase(ENDSPLASH)) {
+			endSplash = arg;
+			continue;
+		}
+
+		// look for items to uninstall
+		if (args[i - 1].equalsIgnoreCase(UNINSTALL)) {
+			uninstall = true;
+			uninstallCookie = arg;
+			found = true;
+		}
+
+		// done checking for args.  Remember where an arg was found 
+		if (found) {
+			configArgs[configArgIndex++] = i - 1;
+			configArgs[configArgIndex++] = i;
+		}
+	}
+	// remove all the arguments consumed by this argument parsing
+	if (configArgIndex == 0)
+		return args;
+	String[] passThruArgs = new String[args.length - configArgIndex];
+	configArgIndex = 0;
+	int j = 0;
+	for (int i = 0; i < args.length; i++) {
+		if (i == configArgs[configArgIndex])
+			configArgIndex++;
+		else
+			passThruArgs[j++] = args[i];
+	}
+	return passThruArgs;
+}
+/**
+ * Runs the application to be launched.
+ * 
+ * @return the return value from the launched application
+ * @param args the arguments to pass to the application
+ * @exception thrown if a problem occurs during launching
+ */
+public Object run(String[] args) throws Exception {
+	String[] passThruArgs = processCommandLine(args);
+	if (uninstall)
+		return updateRun(UNINSTALL, uninstallCookie, passThruArgs);
+	else
+		return basicRun(passThruArgs);
+}
+/**
+ * Performs an update run.
+ * 
+ * @return the return value from the update loader
+ * @param flag flag to give to the update loader
+ * @param value value to give to the update loader
+ * @param args arguments to give to the update loader.
+ * @exception Exception thrown if a problem occurs during execution
+ */
+protected Object updateRun(String flag, String value, String[] args) throws Exception {
+	Class clazz = getUpdateLoader(bootLocation);
+	Method method = clazz.getDeclaredMethod("run", new Class[] { String.class, String.class, String.class, String[].class });
+	try {
+		return method.invoke(clazz, new Object[] { flag, value, location, args });
+	} catch (InvocationTargetException e) {
+		if (e.getTargetException() instanceof Error)
+			throw (Error) e.getTargetException();
+		else
+			throw e;
+	}
+}
+}
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/NewMain.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/NewMain.java
new file mode 100644
index 0000000..346367c
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/NewMain.java
@@ -0,0 +1,74 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package org.eclipse.jdt.debug.testplugin;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/** 
+ * Application is responsible for calling core launch api
+ */
+
+public class NewMain extends Main {
+	private static final String DEFAULT_APPLICATION= "org.eclipse.ui.workbench";
+	
+	
+	public NewMain(String application, String location, URL pluginPathLocation, String bootLocation, boolean debug) throws IOException {
+		this.application= application;
+		this.location= location;
+		this.pluginPathLocation= pluginPathLocation;
+		this.bootLocation= bootLocation;
+	}
+	
+	public static void main(String[] args) {
+		try {
+			String location= getLocationFromProperties("platform");
+			new NewMain(DEFAULT_APPLICATION, location, null, null, true).run(args);
+		} catch (Throwable e) {
+			System.out.println("Exception launching the Eclipse Platform UI:");
+			e.printStackTrace();
+		}
+		System.exit(0);
+	}
+	
+
+	/**
+	 * Run this launcher with the arguments specified in the given string.
+	 * This is a short cut method for people running the launcher from
+	 * a scrapbook (i.e., swip-and-doit facility).
+	 */
+	public static void main(String argString) throws Exception {
+		Vector list= new Vector(5);
+		for (StringTokenizer tokens= new StringTokenizer(argString, " "); tokens.hasMoreElements();)
+			list.addElement((String) tokens.nextElement());
+		main((String[]) list.toArray(new String[list.size()]));
+	}
+	
+	public static String getLocationFromProperties(String key) {
+		Properties properties= new Properties();
+		try {
+			FileInputStream fis= new FileInputStream(getSettingsFile());
+			properties.load(fis);
+			return properties.getProperty(key);
+		} catch (IOException e) {
+		}
+		return null;
+	}	
+	
+	private static File getSettingsFile() {
+		String home= System.getProperty("user.home");
+		if (home == null) {
+			System.out.println("Home dir not defined");
+			return null;
+		}
+		return new File(home, "eclipse-workspaces.properties");	
+	}	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/SpecificDebugElementEventWaiter.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/SpecificDebugElementEventWaiter.java
new file mode 100644
index 0000000..e3c4d69
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/SpecificDebugElementEventWaiter.java
@@ -0,0 +1,30 @@
+package org.eclipse.jdt.debug.testplugin;
+
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.model.IDebugElement;
+
+/**
+ * This event waiter is used to wait for a certain type of event (create, terminate, suspend, etc.) 
+ * on a *specific* debug element.  Contrast this with DebugElementKindEventWaiter which is similar, 
+ * but is used to wait for a certain type of event on a *kind* of debug element (thread, debug target, etc.)
+ */
+public class SpecificDebugElementEventWaiter extends DebugEventWaiter {
+
+	protected IDebugElement fDebugElement;
+	
+	public SpecificDebugElementEventWaiter(int eventKind, IDebugElement element) {
+		super(eventKind);
+		fDebugElement = element;
+	}
+	
+	public boolean accept(DebugEvent event) {
+		Object o = event.getSource();
+		if (o instanceof IDebugElement) {
+			return super.accept(event) && ((IDebugElement)o).equals(fDebugElement);
+		} else {
+			return false;
+		}
+	}
+
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/TestPluginLauncher.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/TestPluginLauncher.java
new file mode 100644
index 0000000..ad07a37
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/TestPluginLauncher.java
@@ -0,0 +1,57 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package org.eclipse.jdt.debug.testplugin;
+
+import java.net.URL;
+
+/**
+ * Helper class to launch a test
+ */
+public class TestPluginLauncher {
+	
+	public static final String APP_NAME= "org.eclipse.jdt.ui.tests.app";
+	
+	public static void run(String location, Class testCase, String[] args) {
+		run(APP_NAME, location, testCase, args);
+	}
+	
+	public static void run(String application, String location, Class testCase, String[] args) {
+		try {
+			String bootLocation= getBootLocation();
+			int nArgs= args.length;
+			String[] newArgs= new String[4 + nArgs];
+			newArgs[0]= testCase.getName();
+			for (int i= 0; i < nArgs; i++) {
+				newArgs[1 + i]= args[i];
+			}
+			newArgs[1 + nArgs]= "-dev";
+			newArgs[1 + nArgs + 1]= "bin";
+			newArgs[1 + nArgs + 2]= "-debug";
+			NewMain newMain= new NewMain(application, location, null, bootLocation, false);
+			newMain.run(newArgs);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public static String getLocationFromProperties(String key) {
+		return NewMain.getLocationFromProperties(key);
+	}
+	
+	public static String getLocationFromProperties() {
+		return NewMain.getLocationFromProperties("tests");
+	}
+	
+	public static String getBootLocation() {
+		URL url= TestPluginLauncher.class.getResource("TestPluginLauncher.class");
+		String s= url.toString();
+		int index= s.indexOf("/org.eclipse.jdt.ui.tests");
+		if (index == -1)
+			throw new IllegalArgumentException();
+		s= s.substring(0, index);
+		s= s + "/org.eclipse.core.boot/boot.jar";
+		return s;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/TestWorkbench.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/TestWorkbench.java
new file mode 100644
index 0000000..64c1fdd
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/TestWorkbench.java
@@ -0,0 +1,96 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package org.eclipse.jdt.debug.testplugin;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.eclipse.core.runtime.IPath;
+
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.ui.internal.Workbench;
+
+public class TestWorkbench extends Workbench {
+
+	/**
+	 * Run an event loop for the workbench.
+	 */
+	protected void runEventLoop() {
+		// Dispatch all events.
+		Display display = Display.getCurrent();
+		while (true) {
+			try {
+				if (!display.readAndDispatch())
+					break;
+			} catch (Throwable e) {
+				break;
+			}
+		}
+		IPath location= JavaTestPlugin.getDefault().getWorkspace().getRoot().getLocation();
+		System.out.println("Workspace-location: " + location.toString());
+				
+		
+		Thread thread = null;
+		try {
+			String[] args= getCommandLineArgs();
+			if (args.length > 2) {
+				// must run tests in a separate thread - or event
+				// waiter will block UI thread on a resource change
+				final Test test= getTest(args[2]);
+				Runnable r = new Runnable() {
+					public void run() {
+						TestRunner.run(test);
+					}
+				};
+				thread = new Thread(r);
+				thread.start();
+			} else {
+				System.out.println("TestWorkbench: Argument must be class name");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			display.wake();
+		}
+				
+		while (thread != null && thread.isAlive()) {
+			try {
+				if (!display.readAndDispatch())
+					display.sleep();
+			} catch (Throwable e) {
+				e.printStackTrace();
+			}			
+		}
+		
+	}
+	
+	public Test getTest(String className) throws Exception {
+		Class testClass= getClass().getClassLoader().loadClass(className);
+
+		Method suiteMethod= null;
+		try {
+			suiteMethod= testClass.getMethod(TestRunner.SUITE_METHODNAME, new Class[0]);
+	 	} catch (Exception e) {
+	 		// try to extract a test suite automatically	
+			return new TestSuite(testClass);
+		}
+		try {
+			return (Test) suiteMethod.invoke(null, new Class[0]); // static method
+		} catch (InvocationTargetException e) {
+			System.out.println("Failed to invoke suite():" + e.getTargetException().toString());
+		} catch (IllegalAccessException e) {
+			System.out.println("Failed to invoke suite():" + e.toString());
+		}
+		return null; 
+
+	}
+	
+	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/ArgumentsTests.java b/org.eclipse.jdt.debug.tests/test programs/ArgumentsTests.java
new file mode 100644
index 0000000..5e93195
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/ArgumentsTests.java
@@ -0,0 +1,22 @@
+public class ArgumentsTests {
+	public static void nop() {
+		// used to allow breakpoint on otherwise empty lines
+	}
+	
+	public static void simpleTest(Object obj) {
+		nop();	// should see obj
+	}
+	
+	// Tests recursion (multiple stack frames for the same method with different variable values)
+	public static int fact(int n) {
+		if (n == 0 || n == 1)
+			return 1;
+		else
+			return n*fact(n-1);
+	}
+	
+	public static void main(String[] args) {
+		simpleTest(null);
+		fact(2);
+	}	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/Breakpoints.java b/org.eclipse.jdt.debug.tests/test programs/Breakpoints.java
new file mode 100644
index 0000000..dcb1b88
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/Breakpoints.java
@@ -0,0 +1,150 @@
+import java.util.*;
+
+public class Breakpoints implements IBreakpoints {
+	static {
+	 	Vector v= new Vector(1);
+	 	System.out.println("Initializer");
+    }
+
+    public class InnerBreakpoints {
+    	public void innerInstanceMethod() {
+    		System.out.println("inner instance");
+    	}
+    }
+
+        Enumeration myNamedEnumerate(final Object array[]) {
+        	final int count[] = {0}; // final reference to mutable array
+        	class E implements Enumeration {
+           	 public boolean hasMoreElements(){
+           	 	 return count[0] < array.length;
+           	 }
+           	 public Object nextElement(){
+           	 	 return array[count[0]++];
+           	 }
+        	}
+        	return new E();
+        }
+
+	    Enumeration myAnonymousEnumerate(final Object array[]) {
+    	    return new Enumeration() {
+        	    int count = 0;
+           		 public boolean hasMoreElements(){
+           	 		 return count < array.length;
+           	 	}
+           	 	public Object nextElement(){
+           	 		 return array[count++];
+           	 	}
+        	};
+    	}
+
+ public static void main (String[] args) {
+ 	threading();
+	Breakpoints bp= new Breakpoints();
+	bp.instanceMethod();
+	bp.instanceMethod2();
+
+ }
+
+public class InnerRunnable implements Runnable {
+  	public void run() {
+  		System.out.println("Threading");
+  	}
+ }
+ public static boolean threading() {
+ 	try {
+ 		Thread runner = new Thread(new Breakpoints().new InnerRunnable(), "BreakpointsThread");
+		runner.setPriority(Thread.MIN_PRIORITY);
+		runner.start();
+		runner.join();
+	} catch (InterruptedException ie) {
+	}
+	return false;
+ }
+
+ public Breakpoints() {
+ 	super();
+ 	System.out.println("Constructor");
+ }
+ public void instanceMethod() {
+ 	if (true) {
+ 		System.out.println("If");
+ 	} else {
+ 		System.out.println("Can't get here");
+ 	}
+ 	if (false) {
+ 		System.out.println("Can't get here");
+ 	} else {
+ 		System.out.println("Else");
+ 	}
+
+ 	int i;
+ 	for (i= 0; i < 3; i++) {
+ 		System.out.println("for");
+ 	}
+
+ 	while (i < 6) {
+ 		System.out.println("while");
+ 		i++;
+ 	}
+
+ 	{
+ 		System.out.println("block");
+ 	}
+ }
+
+  public void instanceMethod2() {
+  	int count= 0;
+  	do {
+		System.out.println("dowhile");
+		count++;
+	} while (count < 5);
+
+
+	try {
+			Vector v= new Vector(1);
+			Object o= v.firstElement();
+		} catch (NoSuchElementException nsee) {
+			System.out.println("catch block");
+		} finally {
+			System.out.println("finally after catch");
+
+	}
+	try {
+			Vector v= new Vector(1);
+			System.out.println("try");
+		} catch (NoSuchElementException nsee) {
+		} finally {
+			System.out.println("finally after try");
+
+	}
+	switch (count) {
+		case 5:
+		System.out.println("switch");
+		break;
+	}
+		switch (count) {
+		case 3:
+		break;
+		default:
+		System.out.println("switch default");
+	}
+
+
+  	Object lock= new Object();
+  	synchronized (lock) {
+  		System.out.println("synchronized");
+  	}
+
+	InnerBreakpoints ibp= new InnerBreakpoints();
+	ibp.innerInstanceMethod();
+
+	String[] array= {"1", "2", "3"};
+	Enumeration myNamed= myNamedEnumerate(array);
+	myNamed.hasMoreElements();
+
+	Enumeration myAnonymous= myAnonymousEnumerate(array);
+	myAnonymous.hasMoreElements();
+
+	ibp.innerInstanceMethod();
+  }
+}
diff --git a/org.eclipse.jdt.debug.tests/test programs/DropTests.java b/org.eclipse.jdt.debug.tests/test programs/DropTests.java
new file mode 100644
index 0000000..758603e
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/DropTests.java
@@ -0,0 +1,24 @@
+public class DropTests {
+ 
+ 	public static void main(String[] args) {
+ 		DropTests dt = new DropTests();
+ 		dt.method1();
+ 	}
+ 
+ 	public void method1() {
+ 		method2();
+ 	}
+ 	
+ 	public void method2() {
+ 		method3();
+ 	}
+ 	
+ 	public void method3() {
+ 		method4();
+ 	}
+ 	
+ 	public void method4() {
+ 		System.out.println("Finally, I got to method 4");
+ 	}
+ 
+ }
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/EvaluationTests.java b/org.eclipse.jdt.debug.tests/test programs/EvaluationTests.java
new file mode 100644
index 0000000..29b002b
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/EvaluationTests.java
@@ -0,0 +1,33 @@
+import java.util.Date;
+import java.util.Vector;
+
+public class EvaluationTests {
+
+	protected int fInt= 5;
+	protected String fString= "testing";
+	protected static final String CONSTANT= "constant";
+	private Date fADate= new Date();
+
+	public static void main(java.lang.String[] args) {
+		EvaluationTests tests= new EvaluationTests(); //line 12
+		tests.method();
+	}
+
+	public void method() {
+		System.out.println(returnInt());
+		System.out.println(returnDate());
+		int x= 5; //line 19
+		System.out.println(x);
+		Vector v= new Vector();
+		v.isEmpty();
+	}
+
+	public int returnInt() {
+		return 7;
+	}
+
+	public Date returnDate() {
+		return new Date();
+	}
+}
+
diff --git a/org.eclipse.jdt.debug.tests/test programs/GotNewName.java b/org.eclipse.jdt.debug.tests/test programs/GotNewName.java
new file mode 100644
index 0000000..e16e3f1
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/GotNewName.java
@@ -0,0 +1,42 @@
+public class GotNewName {
+
+	public static void main(String[] args) {
+		GotNewName anObject = new GotNewName();
+
+		try {
+			anObject.throwBaby();
+		} catch(NullPointerException ne) {
+			// do nothing
+		}
+
+		anObject.killTime();
+
+		try {
+			anObject.throwBaby();
+		} catch(NullPointerException ne) {
+			// do nothing
+		}
+
+		try {
+			anObject.throwAnotherBaby();
+		} catch(IllegalArgumentException ie) {
+			// do nothing
+		}
+	}
+
+	public void throwBaby() {
+		throw new NullPointerException();
+	}
+
+	public void throwAnotherBaby() {
+		throw new IllegalArgumentException();
+	}
+
+	public void killTime() {
+		int j = 0;
+		while(j < 1000) {
+			j++;
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/HitCountLooper.java b/org.eclipse.jdt.debug.tests/test programs/HitCountLooper.java
new file mode 100644
index 0000000..c883fa5
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/HitCountLooper.java
@@ -0,0 +1,40 @@
+public class HitCountLooper {
+	public static void main(String[] args) {
+		int i = 0;
+		while (i < 20) {
+			System.out.println("Main Looping " + i);
+			i++;
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException e) {
+			}
+		}
+		(new HitCountLooper()).loop();
+	}
+
+	public void loop() {
+		Runnable r= new Runnable() {
+			public void run() {
+				while (true) {
+					int i = 0;
+					System.out.println("Thread Looping " + i);
+					i++;
+					try {
+						Thread.sleep(1000);
+					} catch (InterruptedException e) {
+					}
+				}
+			}
+		};
+		new Thread(r).start();
+		int i = 0;
+		while (true) {
+			System.out.println("Instance Looping " + i);
+			i++;
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException e) {
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/IBreakpoints.java b/org.eclipse.jdt.debug.tests/test programs/IBreakpoints.java
new file mode 100644
index 0000000..b83ca80
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/IBreakpoints.java
@@ -0,0 +1,5 @@
+import java.util.NoSuchElementException;
+import java.util.Vector;
+public interface IBreakpoints {
+	 public abstract void instanceMethod();
+ }
diff --git a/org.eclipse.jdt.debug.tests/test programs/InstanceVariablesTests.java b/org.eclipse.jdt.debug.tests/test programs/InstanceVariablesTests.java
new file mode 100644
index 0000000..986ed19
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/InstanceVariablesTests.java
@@ -0,0 +1,39 @@
+import java.util.Date;
+
+public class InstanceVariablesTests {
+	public void nop() {
+	}
+	
+	public InstanceVariablesTests() {
+		nop(); // should see this.*Str with correct values
+	}
+
+	public static void main(String[] args) {
+		InstanceVariablesTests ivt = new InstanceVariablesTests();
+		ivt.run();
+	}
+	
+	public void run() {
+		nop(); // should see this
+		InstanceVariablesTests ivt = new IVTSubclass();
+		ivt.run();
+	}
+	
+	public String pubStr = "public";
+	protected String protStr = "protected";
+	/* default */ String defStr = "default";
+	private String privStr = "private";
+	protected String nullStr= null;
+	protected Date date= new Date();
+	protected Date nullDate= null;
+}
+
+class IVTSubclass extends InstanceVariablesTests {
+	public void run() {
+		nop();
+	}
+	
+	public String pubStr = "redefined public";
+	protected String protStr = "redefined protected";
+	/* default */ String defStr = "redefined default";
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/LocalVariablesTests.java b/org.eclipse.jdt.debug.tests/test programs/LocalVariablesTests.java
new file mode 100644
index 0000000..f8bf595
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/LocalVariablesTests.java
@@ -0,0 +1,90 @@
+public class LocalVariablesTests {
+	public static void nop() {
+		// used to allow breakpoint on otherwise empty lines
+	}
+	
+	public static void simpleTest() {
+		nop(); // should see no local variables here
+		int i1 = 0;
+		nop(); // should see 1 local variable: i1
+		int i2 = 1;
+		nop(); // should see 2 local variables: i1 && i2
+	}
+
+	public static void outerMethod() {
+		int i1 = 0;
+		innerMethod();
+		// i1 visible and i1==0, i2 not visible
+		int i2 = 1;
+		nop();
+	}
+
+	public static void innerMethod() {
+		int i2 = 7;
+		nop(); // i1 not visible in the top stack frame, i2 visible
+	}
+	
+	public static void testFor() {
+		nop(); // should see no variable
+		for (int i = 0; i < 1; i++) {
+			nop(); // should see i
+			for (int j = 0; j < 1; j++) {
+				nop(); // 	should see i, j
+				Object obj = null;
+				nop(); // should see i, j, obj
+				obj = "foo";
+			}
+		}
+		nop(); // should not see i and j
+	}
+	
+	public static void testIf(boolean cond) {
+		if (cond) {
+			Object ifObj = new String("true");
+			nop();
+		} else {
+			Object elseObj = new String("false");
+			nop();
+		}
+		nop();
+	}
+	
+	public static void testWhile() {
+		int i = 0;
+		while (i < 1) {
+			int j = i/2;
+			nop(); // should see i & j
+			i++;
+		}
+	}
+	
+	public static void testTryCatch() {
+		try {
+			String str = null;
+			nop(); // should see str
+			str.length();
+		} catch (NullPointerException ex) {
+			nop(); // should see ex
+ 		} finally {
+ 			nop(); // should see str
+ 		}
+	}
+	
+	public static void testAliasing() {
+		String str1 = new String("value");
+		String str2 = str1;
+		nop();
+	}
+
+	public static void main(String[] args) {
+		simpleTest();  // @see LocalVariablesTests.testSimple()
+		outerMethod(); // @see LocalVariablesTests.testMethodCall()
+		testFor();    // @see LocalVariablesTests.testFor()
+		testIf(true);  // @see LocalVariablesTests.testIf()
+		testIf(false); // @see LocalVariablesTests.testIf()
+		testWhile();   // @see LocalVariablesTests.testWhile()
+		testTryCatch();// @see LocalVariablesTests.testTryCatch()
+		testAliasing(); // @see LocalVariablesTests.testAliasing()
+
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/MethodEntryRunner.java b/org.eclipse.jdt.debug.tests/test programs/MethodEntryRunner.java
new file mode 100644
index 0000000..23a20e4
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/MethodEntryRunner.java
@@ -0,0 +1,19 @@
+import java.lang.reflect.Method;
+
+public class MethodEntryRunner {
+
+	// Why the reflection?  Because this class fires up a class that is meant to exist only as 
+	// a .class file in the tests, and MethodEntryRunner wouldn't compile in
+	// development if we directly invoked MethodEntryTest, since there's no source for it
+	public static void main(java.lang.String[] args) {
+		try {
+			Class clazz= Class.forName("MethodEntryTest");
+			Method method= clazz.getMethod("main", new Class[] {String[].class});
+			method.invoke(null, new Object[] { new String[] {} } );
+		} catch (Exception ex) {
+			System.err.println("Exception trying to invoke MethodEntryTest");
+			ex.printStackTrace();
+		}
+	}
+	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/NativeDropTests.java b/org.eclipse.jdt.debug.tests/test programs/NativeDropTests.java
new file mode 100644
index 0000000..7e500bd
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/NativeDropTests.java
@@ -0,0 +1,16 @@
+public class NativeDropTests {
+	public static void foo() {
+		System.out.println("foo"); 
+		System.out.println("breakpoint"); // breakpoint on this line
+	}
+	
+	public static void bar() {
+		foo();
+	}
+
+	public static void main(String[] args) throws Exception {
+		Class clazz = NativeDropTests.class;
+		java.lang.reflect.Method method = clazz.getMethod("bar", new Class[] {});
+		method.invoke(null, new Object[] {});
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/test programs/StaticVariablesTests.java b/org.eclipse.jdt.debug.tests/test programs/StaticVariablesTests.java
new file mode 100644
index 0000000..2b570b2
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/StaticVariablesTests.java
@@ -0,0 +1,31 @@
+public class StaticVariablesTests {
+	
+	private int i;
+	private String s;
+	
+	public StaticVariablesTests() {
+		i = 1;
+		s = "string";	
+	}
+	
+	public static void nop() {
+	}
+	
+	public static String pubStr = "public";
+	protected static String protStr = "protected";
+	/* default */ static String defStr = "default";
+	private static String privStr = "private";	
+ 		
+	public static void run() {
+		nop();
+	}
+	
+	public int fcn() {
+		return 1;	
+	}
+	
+	public static void main(String[] args) {
+		run();
+		(new StaticVariablesTests()).fcn();
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/TestIO.java b/org.eclipse.jdt.debug.tests/test programs/TestIO.java
new file mode 100644
index 0000000..5e5003b
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/TestIO.java
@@ -0,0 +1,16 @@
+import java.io.*;
+
+public class TestIO {
+	
+	public static void main(String[] args) {
+		TestIO tio = new TestIO();
+		try {
+			tio.testBaby();
+		} catch (EOFException e) {
+		}
+	}
+
+	public void testBaby() throws EOFException {
+		throw new EOFException("test");
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/test programs/ThrowsNPE.java b/org.eclipse.jdt.debug.tests/test programs/ThrowsNPE.java
new file mode 100644
index 0000000..5f46a74
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/ThrowsNPE.java
@@ -0,0 +1,16 @@
+public class ThrowsNPE {
+	
+	public static void main(String[] args) {
+		ThrowsNPE anObject = new ThrowsNPE();
+		try {
+			anObject.throwBaby();
+		} catch(NullPointerException ne) {
+			// do nothing
+		}
+	}
+
+
+	public void throwBaby() {
+		throw new NullPointerException();
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/test programs/WorkingDirectoryTest.java b/org.eclipse.jdt.debug.tests/test programs/WorkingDirectoryTest.java
new file mode 100644
index 0000000..33c31d4
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/WorkingDirectoryTest.java
@@ -0,0 +1,7 @@
+public class WorkingDirectoryTest {
+
+	public static void main(String[] args) {
+		String dir = System.getProperty("user.dir");
+		System.out.println(dir);
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/CallLoop.java b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/CallLoop.java
new file mode 100644
index 0000000..6e9bb20
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/CallLoop.java
@@ -0,0 +1,7 @@
+package org.eclipse.debug.tests.targets;
+
+public class CallLoop {
+	public static void main(String[] args) {
+		(new Looper()).loop();
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HelloLauncher.java b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HelloLauncher.java
new file mode 100644
index 0000000..452a4dd
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HelloLauncher.java
@@ -0,0 +1,10 @@
+package org.eclipse.debug.tests.targets;
+
+public class HelloLauncher {
+	public static void main(String args[]) {
+		for (int i = 0; i < 10; i++) {
+			System.out.println("Hello Launcher");
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HelloLauncherWithArg.java b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HelloLauncherWithArg.java
new file mode 100644
index 0000000..ba134ad
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HelloLauncherWithArg.java
@@ -0,0 +1,13 @@
+package org.eclipse.debug.tests.targets;
+
+public class HelloLauncherWithArg {
+	public static void main(String args[]) {
+		int argCount = args.length;
+		if (argCount > 0) {
+			if (args[0].equals("foo")) {
+				System.out.println("First argument was foo");
+			}
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HelloLauncherWithArgs.java b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HelloLauncherWithArgs.java
new file mode 100644
index 0000000..3550e01
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HelloLauncherWithArgs.java
@@ -0,0 +1,13 @@
+package org.eclipse.debug.tests.targets;
+
+public class HelloLauncherWithArgs {
+	public static void main(String args[]) {
+		int argCount = args.length;
+		if (argCount > 1) {
+			if (args[0].equals("foo") && args[1].equals("bar")) {
+				System.out.println("First argument was foo and second argument was bar");
+			}
+		}			
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HitCountLooper.java b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HitCountLooper.java
new file mode 100644
index 0000000..220090b
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/HitCountLooper.java
@@ -0,0 +1,43 @@
+package org.eclipse.debug.tests.targets;
+
+
+public class HitCountLooper {
+	public static void main(String[] args) {
+		int i = 0;
+		while (i < 20) {
+			System.out.println("Main Looping " + i);
+			i++;
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException e) {
+			}
+		}
+		(new HitCountLooper()).loop();
+	}
+
+	public void loop() {
+		Runnable r= new Runnable() {
+			public void run() {
+				while (true) {
+					int i = 0;
+					System.out.println("Thread Looping " + i);
+					i++;
+					try {
+						Thread.sleep(1000);
+					} catch (InterruptedException e) {
+					}
+				}
+			}
+		};
+		new Thread(r).start();
+		int i = 0;
+		while (true) {
+			System.out.println("Instance Looping " + i);
+			i++;
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException e) {
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/InfiniteLoop.java b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/InfiniteLoop.java
new file mode 100644
index 0000000..b5cedb1
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/InfiniteLoop.java
@@ -0,0 +1,19 @@
+package org.eclipse.debug.tests.targets;
+
+public class InfiniteLoop {
+	public static void main(String[] args) {
+		(new InfiniteLoop()).loop();
+	}
+
+	public void loop() {
+		int i = 0;
+		while (true) {
+			System.out.println("Looping " + i);
+			i++;
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException e) {
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/Looper.java b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/Looper.java
new file mode 100644
index 0000000..84cc539
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/Looper.java
@@ -0,0 +1,15 @@
+package org.eclipse.debug.tests.targets;
+
+public class Looper {
+	public void loop() {
+		int i = 0;
+		while (true) {
+			System.out.println("Loop " + i);
+			i++;
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException e) {
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/Watchpoint.java b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/Watchpoint.java
new file mode 100644
index 0000000..2f86082
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test programs/org/eclipse/debug/tests/targets/Watchpoint.java
@@ -0,0 +1,32 @@
+package org.eclipse.debug.tests.targets;
+
+
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Watchpoint {
+	
+	public List list;
+	
+	public static void main(String[] args) {
+		Watchpoint wp = new Watchpoint();
+		wp.fillList();
+	}
+	
+	public void fillList() {
+		list = new ArrayList(10);
+		int value = 10;
+		while (value > 0) {
+			list.add(new Integer(value));
+			value--;
+		}
+		
+	}
+
+}
diff --git a/org.eclipse.jdt.debug.tests/test.xml b/org.eclipse.jdt.debug.tests/test.xml
new file mode 100644
index 0000000..24ecf1b
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/test.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+
+<project name="testsuite" default="run" basedir=".">
+  <!-- The property ${eclipse-home} should be passed into this script -->
+  <!-- Set a meaningful default value for when it is not. -->
+  <property name="eclipse-home" value="${basedir}\..\.."/>
+
+  <!-- sets the properties eclipse-home, and library-file -->
+  <property name="plugin-name" value="org.eclipse.jdt.debug.tests"/>
+  <property name="library-file"
+            value="${eclipse-home}/plugins/org.eclipse.test/library.xml"/>
+
+  <!-- This target holds all initialization code that needs to be done for -->
+  <!-- all tests that are to be run. Initialization for individual tests -->
+  <!-- should be done within the body of the suite target. -->
+  <target name="init">
+    <tstamp/>
+    <delete>
+      <fileset dir="${eclipse-home}" includes="org*.xml"/>
+    </delete>
+  </target>
+
+  <!-- This target defines the tests that need to be run. -->
+  <target name="suite">
+    <property name="jdt-folder" 
+              value="${eclipse-home}/jdt_folder"/>
+    <delete dir="${jdt-folder}" quiet="true"/>
+    <ant target="ui-test" antfile="${library-file}" dir="${eclipse-home}">
+      <property name="data-dir" value="${jdt-folder}"/>
+      <property name="plugin-name" value="${plugin-name}"/>
+      <property name="classname" 
+                value="org.eclipse.jdt.debug.tests.AutomatedSuite"/>
+    </ant>
+  </target>
+
+  <!-- This target holds code to cleanup the testing environment after -->
+  <!-- after all of the tests have been run. You can use this target to -->
+  <!-- delete temporary files that have been created. -->
+  <target name="cleanup">
+  </target>
+
+  <!-- This target runs the test suite. Any actions that need to happen -->
+  <!-- after all the tests have been run should go here. -->
+  <target name="run" depends="init,suite,cleanup">
+    <ant target="collect" antfile="${library-file}" dir="${eclipse-home}">
+      <property name="includes" value="org*.xml"/>
+      <property name="output-file" value="${plugin-name}.xml"/>
+    </ant>
+  </target>
+
+</project>
diff --git a/org.eclipse.jdt.debug.tests/testjars/A.jar b/org.eclipse.jdt.debug.tests/testjars/A.jar
new file mode 100644
index 0000000..74d8b44
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testjars/A.jar
Binary files differ
diff --git a/org.eclipse.jdt.debug.tests/testresources/TestSource.jar b/org.eclipse.jdt.debug.tests/testresources/TestSource.jar
new file mode 100644
index 0000000..4c0bdf4
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testresources/TestSource.jar
Binary files differ
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
new file mode 100644
index 0000000..e6ffe01
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
@@ -0,0 +1,290 @@
+package org.eclipse.jdt.debug.tests;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import junit.framework.TestCase;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.debug.core.IJavaDebugTarget;
+import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaPatternBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaTargetPatternBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.core.IJavaWatchpoint;
+import org.eclipse.jdt.debug.core.JDIDebugModel;
+import org.eclipse.jdt.debug.testplugin.DebugElementEventWaiter;
+import org.eclipse.jdt.debug.testplugin.DebugElementKindEventWaiter;
+import org.eclipse.jdt.debug.testplugin.DebugEventWaiter;
+
+
+ 
+/**
+ * Tests for launch configurations
+ */
+public abstract class AbstractDebugTest extends TestCase {
+	
+	public static final int DEFAULT_TIMEOUT = 30000;
+	
+	/**
+	 * The last relevent event set - for example, that caused
+	 * a thread to suspend
+	 */
+	protected DebugEvent[] fEventSet;
+	
+	public AbstractDebugTest(String name) {
+		super(name);
+	}
+	
+	/**
+	 * Sets the last relevant event set
+	 *
+	 * @param set event set
+	 */
+	protected void setEventSet(DebugEvent[] set) {
+		fEventSet = set;
+	}
+	
+	/**
+	 * Returns the last relevant event set
+	 * 
+	 * @return event set
+	 */
+	protected DebugEvent[] getEventSet() {
+		return fEventSet;
+	}
+	
+	/**
+	 * Returns the launch manager
+	 * 
+	 * @return launch manager
+	 */
+	protected ILaunchManager getLaunchManager() {
+		return DebugPlugin.getDefault().getLaunchManager();
+	}
+	
+	/**
+	 * Returns the breakpoint manager
+	 * 
+	 * @return breakpoint manager
+	 */
+	protected IBreakpointManager getBreakpointManager() {
+		return DebugPlugin.getDefault().getBreakpointManager();
+	}	
+	
+	/**
+	 * Returns the 'DebugTests' project.
+	 * 
+	 * @return the test project
+	 */
+	protected IJavaProject getJavaProject() {
+		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("DebugTests");
+		return JavaCore.create(project);
+	}
+	
+	/**
+	 * Launches the type with the given name, and waits for a suspend
+	 * event in that program. Returns the thread in which the suspend
+	 * event occurred.
+	 * 
+	 * @param mainTypeName the program to launch
+	 * @return thread in which the first suspend event occurred
+	 */
+	protected IJavaThread launch(String mainTypeName) throws Exception {
+		DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
+		waiter.setTimeout(DEFAULT_TIMEOUT);
+		
+		ILaunchConfiguration config = getLaunchConfiguration(mainTypeName);
+		assertNotNull("Could not locate launch configuration for " + mainTypeName, config);
+		config.launch(getLaunchManager().DEBUG_MODE, null);
+
+		Object suspendee= waiter.waitForEvent();
+		setEventSet(waiter.getEventSet());
+		assertNotNull("Program did not suspend.", suspendee);
+		return (IJavaThread)suspendee;
+	}
+	
+	/**
+	 * Resumes the given thread, and waits for another suspend event.
+	 * Returns the thread in which the suspend event occurrs.
+	 * 
+	 * @param thread thread to resume
+	 * @return thread in which the first suspend event occurrs
+	 */
+	protected IJavaThread resume(IJavaThread thread) throws Exception {
+		DebugEventWaiter waiter= new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class);
+		waiter.setTimeout(DEFAULT_TIMEOUT);
+		
+		thread.resume();
+
+		Object suspendee= waiter.waitForEvent();
+		setEventSet(waiter.getEventSet());
+		assertNotNull("Program did not suspend.", suspendee);
+		return (IJavaThread)suspendee;
+	}	
+	
+	/**
+	 * Resumes the given thread, and waits the associated debug
+	 * target to terminate.
+	 * 
+	 * @param thread thread to resume
+	 * @return the terminated debug target
+	 */
+	protected IJavaDebugTarget resumeAndExit(IJavaThread thread) throws Exception {
+		DebugEventWaiter waiter= new DebugElementEventWaiter(DebugEvent.TERMINATE, thread.getDebugTarget());
+		waiter.setTimeout(DEFAULT_TIMEOUT);
+		
+		thread.resume();
+
+		Object suspendee= waiter.waitForEvent();
+		setEventSet(waiter.getEventSet());
+		assertNotNull("Program did not terminate.", suspendee);
+		IJavaDebugTarget target = (IJavaDebugTarget)suspendee;
+		assertTrue("program should have exited", target.isTerminated() || target.isDisconnected());
+		return target;
+	}	
+		
+	/**
+	 * Returns the launch configuration for the given main type
+	 * 
+	 * @param mainTypeName program to launch
+	 * @see ProjectCreationDecorator
+	 */
+	protected ILaunchConfiguration getLaunchConfiguration(String mainTypeName) {
+		IFile file = getJavaProject().getProject().getFolder("launchConfigurations").getFile(mainTypeName + ".launch");
+		ILaunchConfiguration config = getLaunchManager().getLaunchConfiguration(file);
+		assertTrue("Could not find launch configuration for " + mainTypeName, config.exists());
+		return config;
+	}
+	
+	/**
+	 * Creates and returns a line breakpoint at the given line number in the type with the
+	 * given name.
+	 * 
+	 * @param lineNumber line number
+	 * @param typeName type name
+	 */
+	protected IJavaLineBreakpoint createLineBreakpoint(int lineNumber, String typeName) throws Exception {
+		return JDIDebugModel.createLineBreakpoint(getJavaProject().getProject(), typeName, lineNumber, -1, -1, 0, true, null);
+	}
+	
+	/**
+	 * Creates and returns a pattern breakpoint at the given line number in the
+	 * source file with the given name.
+	 * 
+	 * @param lineNumber line number
+	 * @param sourceName name of source file
+	 * @param pattern the pattern of the class file name
+	 */
+	protected IJavaPatternBreakpoint createPatternBreakpoint(int lineNumber, String sourceName, String pattern) throws Exception {
+		return JDIDebugModel.createPatternBreakpoint(getJavaProject().getProject(), sourceName, pattern, lineNumber, -1, -1, 0, true, null);
+	}
+	
+	/**
+	 * Creates and returns a target pattern breakpoint at the given line number in the
+	 * source file with the given name.
+	 * 
+	 * @param lineNumber line number
+	 * @param sourceName name of source file
+	 */
+	protected IJavaTargetPatternBreakpoint createTargetPatternBreakpoint(int lineNumber, String sourceName) throws Exception {
+		return JDIDebugModel.createTargetPatternBreakpoint(getJavaProject().getProject(), sourceName, lineNumber, -1, -1, 0, true, null);
+	}	
+		
+	/**
+	 * Creates and returns a method breakpoint
+	 * 
+	 * @param typeNamePattern type name pattern
+	 * @param methodName method name
+	 * @param methodSignature method signature
+	 * @param entry whether to break on entry
+	 * @param exit whether to break on exit
+	 */
+	protected IJavaMethodBreakpoint createMethodBreakpoint(String typeNamePattern, String methodName, String methodSignature, boolean entry, boolean exit) throws Exception {
+		return JDIDebugModel.createMethodBreakpoint(getJavaProject().getProject(), typeNamePattern, methodName, methodSignature, entry, exit,false, -1, -1, -1, 0, true, null);
+	}	
+	
+	/**
+	 * Creates and returns an exception breakpoint
+	 * 
+	 * @param exName exception name
+	 * @param caught whether to suspend in caught locations
+	 * @param uncaught whether to suspend in uncaught locations
+	 */	
+	protected IJavaExceptionBreakpoint createExceptionBreakpoint(String exName, boolean caught, boolean uncaught) throws CoreException {
+		return JDIDebugModel.createExceptionBreakpoint(getJavaProject().getProject(),exName, caught, uncaught, false, true, null);
+	}
+	
+	/**
+	 * Creates and returns a watchpoint
+	 * 
+	 * @param typeNmae type name
+	 * @param fieldName field name
+	 * @param access whether to suspend on field access
+	 * @param modification whether to suspend on field modification
+	 */	
+	protected IJavaWatchpoint createWatchpoint(String typeName, String fieldName, boolean access, boolean modification) throws CoreException {
+		IJavaWatchpoint wp = JDIDebugModel.createWatchpoint(getJavaProject().getProject(), typeName, fieldName, -1, -1, -1, 0, true, null);
+		wp.setAccess(access);
+		wp.setModification(modification);
+		return wp;
+	}
+		
+	/**
+	 * Terminates the given thread and removes its launch
+	 */
+	protected void terminateAndRemove(IJavaThread thread) {
+		ILaunch launch = thread.getLaunch();
+		try {
+			thread.getDebugTarget().terminate();
+		} catch (CoreException e) {
+		} finally {
+			getLaunchManager().removeLaunch(launch);
+		}
+	}
+	
+	/**
+	 * Deletes all existing breakpoints
+	 */
+	protected void removeAllBreakpoints() {
+		IBreakpoint[] bps = getBreakpointManager().getBreakpoints();
+		for (int i = 0; i < bps.length; i++) {
+			try {
+				bps[i].delete();
+			} catch (CoreException e) {
+			}
+		}
+	}
+	
+	/**
+	 * Returns the first breakpoint the given thread is suspended
+	 * at, or <code>null</code> if none.
+	 * 
+	 * @return the first breakpoint the given thread is suspended
+	 * at, or <code>null</code> if none
+	 */
+	protected IBreakpoint getBreakpoint(IThread thread) {
+		IBreakpoint[] bps = thread.getBreakpoints();
+		if (bps.length > 0) {
+			return bps[0];
+		}
+		return null;
+	}
+}
+
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java
new file mode 100644
index 0000000..201db43
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java
@@ -0,0 +1,58 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package org.eclipse.jdt.debug.tests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.eclipse.jdt.debug.testplugin.TestPluginLauncher;
+import org.eclipse.jdt.debug.tests.core.DeferredBreakpointTests;
+import org.eclipse.jdt.debug.tests.core.EventSetTests;
+import org.eclipse.jdt.debug.tests.core.ExceptionBreakpointTests;
+import org.eclipse.jdt.debug.tests.core.InstanceVariableTests;
+import org.eclipse.jdt.debug.tests.core.LaunchConfigurationTests;
+import org.eclipse.jdt.debug.tests.core.MethodBreakpointTests;
+import org.eclipse.jdt.debug.tests.core.PatternBreakpointTests;
+import org.eclipse.jdt.debug.tests.core.StaticVariableTests;
+import org.eclipse.jdt.debug.tests.core.TargetPatternBreakpointTests;
+import org.eclipse.jdt.debug.tests.core.WatchpointTests;
+
+/**
+ * Test all areas of the UI.
+ */
+public class AutomatedSuite extends TestSuite {
+
+	/**
+	 * Returns the suite.  This is required to
+	 * use the JUnit Launcher.
+	 */
+	public static Test suite() {
+		return new AutomatedSuite();
+	}
+
+	/**
+	 * Construct the test suite.
+	 */
+	public AutomatedSuite() {
+		addTest(new TestSuite(ProjectCreationDecorator.class));
+		addTest(new TestSuite(LaunchConfigurationTests.class));
+		addTest(new TestSuite(DeferredBreakpointTests.class));
+		addTest(new TestSuite(InstanceVariableTests.class));
+		addTest(new TestSuite(StaticVariableTests.class));
+		addTest(new TestSuite(MethodBreakpointTests.class));
+		addTest(new TestSuite(ExceptionBreakpointTests.class));
+		addTest(new TestSuite(WatchpointTests.class));
+		addTest(new TestSuite(PatternBreakpointTests.class));
+		addTest(new TestSuite(TargetPatternBreakpointTests.class));
+		addTest(new TestSuite(EventSetTests.class));
+		addTest(new TestSuite(CloseWorkbenchDecorator.class));
+	}
+	
+	public static void main(String[] args) {
+		TestPluginLauncher.run(TestPluginLauncher.getLocationFromProperties(), AutomatedSuite.class, args);
+	}		
+
+
+}
+
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/CloseWorkbenchDecorator.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/CloseWorkbenchDecorator.java
new file mode 100644
index 0000000..3aef1fa
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/CloseWorkbenchDecorator.java
@@ -0,0 +1,37 @@
+package org.eclipse.jdt.debug.tests;
+
+import org.eclipse.jdt.debug.testplugin.JavaTestPlugin;
+import org.eclipse.swt.widgets.Display;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+
+
+
+/**
+ * Creates the initial project for
+ * all debug tests. A project called "DebugTests" is created,
+ * and source is imported from "testresources/TestSource.jar"
+ * <p>
+ * Launch configurations are created for the programs launched
+ * in this test suite.
+ * </p>
+ */
+public class CloseWorkbenchDecorator extends AbstractDebugTest {
+	
+	public CloseWorkbenchDecorator(String name) {
+		super(name);
+	}
+	
+	public void testCloseWorkbnech() {
+		Runnable r = new Runnable() {
+			public void run() {
+				JavaTestPlugin.getDefault().getWorkbench().close();
+			}
+		};
+		Display.getDefault().syncExec(r);
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ProjectCreationDecorator.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ProjectCreationDecorator.java
new file mode 100644
index 0000000..f570048
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ProjectCreationDecorator.java
@@ -0,0 +1,102 @@
+package org.eclipse.jdt.debug.tests;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+
+import java.io.File;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.debug.testplugin.JavaProjectHelper;
+import org.eclipse.jdt.debug.testplugin.JavaTestPlugin;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.JavaRuntime;
+
+/**
+ * Test to close the workbench, since debug tests do not run in the UI
+ * thread.
+ */
+public class ProjectCreationDecorator extends AbstractDebugTest {
+	
+	public ProjectCreationDecorator(String name) {
+		super(name);
+	}
+	
+	public void testProjectCreation() throws Exception {
+		// delete any pre-existing project
+		IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject("DebugTests");
+		if (pro.exists()) {
+			pro.delete(true, true, null);
+		}
+		// create project and import source
+		IJavaProject project = JavaProjectHelper.createJavaProject("DebugTests", "bin");
+		IPackageFragmentRoot src = JavaProjectHelper.addSourceContainer(project, "src");
+		File root = JavaTestPlugin.getDefault().getFileInPlugin(JavaProjectHelper.TEST_SRC_DIR);
+		JavaProjectHelper.importFilesFromDirectory(root, src.getPath(), null);
+		
+		// add rt.jar
+		IVMInstall vm = JavaRuntime.getDefaultVMInstall();
+		assertNotNull("No default JRE", vm);
+		IPath path = vm.getVMInstallType().getDefaultLibraryLocation(vm.getInstallLocation()).getSystemLibraryPath();
+		JavaProjectHelper.addLibrary(project, path);
+		
+		pro = project.getProject();
+		
+		//add A.jar
+		root = JavaTestPlugin.getDefault().getFileInPlugin(new Path("testjars"));
+		JavaProjectHelper.importFilesFromDirectory(root, src.getPath(), null);
+		path = src.getPath().append("A.jar");
+		JavaProjectHelper.addLibrary(project, path);
+		
+		// create launch configuration folder
+		
+		IFolder folder = pro.getFolder("launchConfigurations");
+		if (folder.exists()) {
+			folder.delete(true,null);
+		}
+		folder.create(true, true, null);
+		
+		// delete any existing launch configs
+		ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
+		for (int i = 0; i < configs.length; i++) {
+			configs[i].delete();
+		}
+		
+		// create launch configurations
+		createLaunchConfiguration("Breakpoints");
+		createLaunchConfiguration("InstanceVariablesTests");
+		createLaunchConfiguration("StaticVariablesTests");
+		createLaunchConfiguration("DropTests");
+		createLaunchConfiguration("ThrowsNPE");
+		createLaunchConfiguration("org.eclipse.debug.tests.targets.Watchpoint");
+		createLaunchConfiguration("A");
+				
+	}
+	
+	/**
+	 * Creates a shared lanuch configuration for the type with the given
+	 * name.
+	 */
+	protected void createLaunchConfiguration(String mainTypeName) throws Exception {
+		ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
+		ILaunchConfigurationWorkingCopy config = type.newInstance(getJavaProject().getProject().getFolder("launchConfigurations"), mainTypeName);
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, mainTypeName);
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, getJavaProject().getElementName());
+		IVMInstall vm = JavaRuntime.getDefaultVMInstall();
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE, vm.getVMInstallType().getId());
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL, vm.getId());
+		config.doSave();
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/DeferredBreakpointTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/DeferredBreakpointTests.java
new file mode 100644
index 0000000..8659a3e
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/DeferredBreakpointTests.java
@@ -0,0 +1,92 @@
+package org.eclipse.jdt.debug.tests.core;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+/**
+ * Tests deferred breakpoints.
+ */
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+
+public class DeferredBreakpointTests extends AbstractDebugTest {
+	
+	public DeferredBreakpointTests(String name) {
+		super(name);
+	}
+
+	public void testDeferredBreakpoints() throws Exception {
+		String typeName = "Breakpoints";
+		List bps = new ArrayList();
+		// anonymous class
+		bps.add(createLineBreakpoint(32, typeName));
+		// blocks
+		bps.add(createLineBreakpoint(91, typeName));
+		// constructor
+		bps.add(createLineBreakpoint(66, typeName));
+		// else
+		bps.add(createLineBreakpoint(77, typeName));
+		//finally after catch
+		bps.add(createLineBreakpoint(109, typeName));
+		//finally after try
+		bps.add(createLineBreakpoint(117, typeName));
+		// for loop
+		bps.add(createLineBreakpoint(82, typeName));
+		// if
+		bps.add(createLineBreakpoint(70, typeName));
+		// initializer
+		bps.add(createLineBreakpoint(6, typeName));
+		// inner class
+		bps.add(createLineBreakpoint(11, typeName));
+		// return true
+		bps.add(createLineBreakpoint(61, typeName));
+		// instance method
+		bps.add(createLineBreakpoint(96, typeName));
+		// static method 
+		bps.add(createLineBreakpoint(42, typeName));
+		// case statement
+		bps.add(createLineBreakpoint(122, typeName));
+		// default statement
+		bps.add(createLineBreakpoint(129, typeName));
+		// synchronized blocks
+		bps.add(createLineBreakpoint(135, typeName));
+		// try
+		bps.add(createLineBreakpoint(114, typeName));
+		//catch
+		bps.add(createLineBreakpoint(107, typeName));
+		// while
+		bps.add(createLineBreakpoint(86, typeName));
+		
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch(typeName);
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+			while (!bps.isEmpty()) {
+				IBreakpoint hit = getBreakpoint(thread);
+				assertNotNull("suspended, but not by breakpoint", hit);
+				assertTrue("hit un-registered breakpoint", bps.contains(hit));
+				assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint);
+				ILineBreakpoint breakpoint= (ILineBreakpoint) hit;
+				int lineNumber = breakpoint.getLineNumber();
+				int stackLine = thread.getTopStackFrame().getLineNumber();
+				assertTrue("line numbers of breakpoint and stack frame do not match", lineNumber == stackLine);
+				bps.remove(breakpoint);
+				breakpoint.delete();
+				if (!bps.isEmpty()) {
+					thread = resume(thread);
+				}
+			}
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/EventSetTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/EventSetTests.java
new file mode 100644
index 0000000..f26eb48
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/EventSetTests.java
@@ -0,0 +1,57 @@
+package org.eclipse.jdt.debug.tests.core;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+/**
+ * Tests event sets.
+ */
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+
+public class EventSetTests extends AbstractDebugTest {
+	
+	public EventSetTests(String name) {
+		super(name);
+	}
+
+	public void testDoubleBreakpoint() throws Exception {
+		String typeName = "Breakpoints";
+		List bps = new ArrayList();
+		// add two breakpoints at the same location
+		bps.add(createLineBreakpoint(77, typeName));
+		bps.add(createLineBreakpoint(77, typeName));
+		
+
+		IJavaThread thread= null;
+		try {
+			thread= launch(typeName);
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+			while (!bps.isEmpty()) {
+				DebugEvent[] set = getEventSet();
+				assertTrue("Should be two events", set!= null && set.length == 2);
+				for (int i = 0; i < set.length; i++) {
+					assertTrue("should be a breakpoint event", set[i].getDetail() == DebugEvent.BREAKPOINT);
+				}
+				IBreakpoint[] hits = thread.getBreakpoints();
+				assertTrue("should be two breakpoints", hits != null && hits.length == 2);
+				for (int i = 0; i < hits.length; i++) {
+					bps.remove(hits[i]);
+				}
+				assertTrue("breakpoint collection should now be empty", bps.isEmpty());
+				
+			}
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ExceptionBreakpointTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ExceptionBreakpointTests.java
new file mode 100644
index 0000000..47b6adf
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ExceptionBreakpointTests.java
@@ -0,0 +1,42 @@
+package org.eclipse.jdt.debug.tests.core;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+
+
+/**
+ * Tests exception breakpoints.
+ */
+
+public class ExceptionBreakpointTests extends AbstractDebugTest {
+	
+	public ExceptionBreakpointTests(String name) {
+		super(name);
+	}
+
+	public void testCaughtNPE() throws Exception {
+		String typeName = "ThrowsNPE";
+		IJavaExceptionBreakpoint ex = createExceptionBreakpoint("java.lang.NullPointerException", true, false);		
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch(typeName);
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+			
+			IBreakpoint hit = getBreakpoint(thread);
+			assertNotNull("suspended, but not by breakpoint", hit);
+			assertEquals("should hit exception breakpoint ", ex ,hit);
+
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/InstanceVariableTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/InstanceVariableTests.java
new file mode 100644
index 0000000..86a0aa3
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/InstanceVariableTests.java
@@ -0,0 +1,63 @@
+package org.eclipse.jdt.debug.tests.core;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.jdt.debug.core.IJavaObject;
+import org.eclipse.jdt.debug.core.IJavaStackFrame;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.core.IJavaVariable;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+
+public class InstanceVariableTests extends AbstractDebugTest {
+	
+	public InstanceVariableTests(String name) {
+		super(name);
+	}
+
+	public void testGetField() throws Exception {
+		String typeName = "InstanceVariablesTests";
+		
+		createLineBreakpoint(19, typeName);		
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch(typeName);
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+
+			IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame();
+			IVariable ivt = frame.findVariable("ivt");
+			assertNotNull("Could not find variable 'ivt'", ivt);
+			
+			// retrieve an instance var
+			IJavaObject value = (IJavaObject)ivt.getValue();
+			assertNotNull(value);
+			IJavaVariable pubStr = value.getField("pubStr", false);
+			assertNotNull(pubStr);
+			assertEquals("value should be 'redefined public'", pubStr.getValue().getValueString(), "redefined public");
+			
+			// retrieve an instance var in superclass
+			IJavaVariable privStr = value.getField("privStr", false);
+			assertNotNull(privStr);
+			assertEquals("value should be 'private'", privStr.getValue().getValueString(), "private");			
+			
+			// retrieve an instance var in super class with same name
+			pubStr = value.getField("pubStr", true);
+			assertNotNull(pubStr);
+			assertEquals("value should be 'public'", pubStr.getValue().getValueString(), "public");			
+
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/LaunchConfigurationTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/LaunchConfigurationTests.java
new file mode 100644
index 0000000..75b8c72
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/LaunchConfigurationTests.java
@@ -0,0 +1,418 @@
+package org.eclipse.jdt.debug.tests.core;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.File;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+
+
+ 
+/**
+ * Tests for launch configurations
+ */
+public class LaunchConfigurationTests extends AbstractDebugTest {
+	
+	public LaunchConfigurationTests(String name) {
+		super(name);
+	}
+	
+	/** 
+	 * Creates and returns a new launch config the given name, local
+	 * or shared, with 4 attributes:
+	 *  - String1 = "String1"
+	 *  - Int1 = 1
+	 *  - Boolean1 = true
+	 *  - Boolean2 = faslse
+	 */
+	protected ILaunchConfigurationWorkingCopy newConfiguration(IContainer container, String name) throws CoreException {
+		 ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
+		 assertTrue("Should support debug mode", type.supportsMode(ILaunchManager.DEBUG_MODE));
+		 assertTrue("Should support run mode", type.supportsMode(ILaunchManager.RUN_MODE));
+		 ILaunchConfigurationWorkingCopy wc = type.newInstance(container, name);
+		 wc.setAttribute("String1", "String1");
+		 wc.setAttribute("Int1", 1);
+		 wc.setAttribute("Boolean1", true);
+		 wc.setAttribute("Boolean2", false);
+		 assertTrue("Should need saving", wc.isDirty());
+		 return wc;
+	}
+		
+	/**
+	 * Returns whether the given handle is contained in the specified
+	 * array of handles.
+	 */
+	protected boolean existsIn(ILaunchConfiguration[] configs, ILaunchConfiguration config) {
+		for (int i = 0; i < configs.length; i++) {
+			if (configs[i].equals(config)) {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * Creates a local working copy configuration, sets some attributes,
+	 * and saves the working copy, and retrieves the attributes.
+	 */
+	public void testCreateLocalConfiguration() throws CoreException {
+		 ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "config1");
+		 IPath location = wc.getLocation();
+		 ILaunchConfiguration handle = wc.doSave();
+		 File file = location.toFile();
+		 assertTrue("Configuration file should exist", file.exists());
+		 
+		 // retrieve attributes
+		 assertEquals("String1 should be String1", handle.getAttribute("String1", "Missing"), "String1");
+		 assertEquals("Int1 should be 1", handle.getAttribute("Int1", 0), 1);
+		 assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true));
+		 
+		 // ensure new handle is the index
+		 ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
+		 assertTrue("Configuration should exist in project index", existsIn(configs, handle));
+		 
+		 // cleanup
+		 handle.delete();
+		 assertTrue("Config should not exist after deletion", !handle.exists());
+	}
+	
+	
+	/**
+	 * Creates a local working copy configuration, sets some attributes,
+	 * and saves the working copy, and retrieves the attributes.
+	 * Copy the configuration and ensure the original still exists.
+	 */
+	public void testLocalCopy() throws CoreException {
+		 ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "configToCopy");
+		 IPath location = wc.getLocation();
+		 ILaunchConfiguration handle = wc.doSave();
+		 File file = location.toFile();
+		 assertTrue("Configuration file should exist", file.exists());
+		 
+		 // retrieve attributes
+		 assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true));
+		 
+		 // ensure new handle is the index
+		 ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
+		 assertTrue("Configuration should exist in project index", existsIn(configs, handle));
+		 
+		 ILaunchConfigurationWorkingCopy softCopy = handle.copy("CopyOf" + handle.getName());
+		 ILaunchConfiguration hardCopy = softCopy.doSave();
+
+		 // retrieve attributes
+		 assertTrue("String1 should be String1", hardCopy.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", hardCopy.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", hardCopy.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !hardCopy.getAttribute("Boolean2", true));		 
+		 
+		 assertTrue("Original should still exist", handle.exists());
+		 
+		 // cleanup
+		 handle.delete();
+		 assertTrue("Config should not exist after deletion", !handle.exists());
+		 hardCopy.delete();
+		 assertTrue("Config should not exist after deletion", !hardCopy.exists());		 		 
+	}
+		
+	/**
+	 * Create a config and save it tiwce, ensuring it only
+	 * ends up in the index once.
+	 */
+	public void testDoubleSave() throws CoreException {
+		 ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "configDoubleSave");
+		 IPath location = wc.getLocation();
+		 ILaunchConfiguration handle = wc.doSave();
+		 File file = location.toFile();
+		 assertTrue("Configuration file should exist", file.exists());
+		 
+		 // retrieve attributes
+		 assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true));
+		 
+		 // ensure new handle is the index
+		 ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
+		 assertTrue("Configuration should exist in project index", existsIn(configs, handle));
+		 
+		String name = wc.getName();
+		wc.rename("newName");
+		wc.rename(name);
+		assertTrue("Should be dirty", wc.isDirty());
+		wc.doSave();
+		
+		ILaunchConfiguration[] newConfigs = getLaunchManager().getLaunchConfigurations();
+		assertTrue("Should be the same number of configs", newConfigs.length == configs.length);
+		
+		 // cleanup
+		 handle.delete();
+		 assertTrue("Config should not exist after deletion", !handle.exists());
+		
+	}
+		
+	/**
+	 * Creates a local working copy configuration, sets some attributes,
+	 * and saves the working copy, and retrieves the attributes. Deletes
+	 * the configuration and ensures it no longer exists.
+	 */
+	public void testDeleteLocalConfiguration() throws CoreException {
+		 ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "config2delete");
+		 ILaunchConfiguration handle = wc.doSave();
+		 File file = wc.getLocation().toFile();
+		 assertTrue("Configuration file should exist", file.exists());
+		 
+		 // retrieve attributes
+		 assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true));
+		 
+		 // delete 
+		 handle.delete();		 
+		 assertTrue("Config should no longer exist", !handle.exists());
+		 
+		 // ensure handle is not in the index
+		 ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
+		 assertTrue("Configuration should not exist in project index", !existsIn(configs, handle));		 
+	}	
+	
+	/**
+	 * Creates a local working copy configuration, sets some attributes,
+	 * and saves the working copy, and retrieves the attributes. Renames
+	 * the configuration and ensures it's old config no longer exists,
+	 * and that attributes are retrievable from the new (renamed) config.
+	 */
+	public void testRenameLocalConfiguration() throws CoreException {
+		 ILaunchConfigurationWorkingCopy wc = newConfiguration(null, "config2rename");
+		 IPath location = wc.getLocation();
+		 ILaunchConfiguration handle = wc.doSave();
+		 File file = location.toFile();
+		 assertTrue("Configuration file should exist", file.exists());
+		 
+		 // retrieve attributes
+		 assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true));
+		 
+		 // rename
+		 wc = handle.getWorkingCopy();
+		 wc.rename("config-2-rename");
+		 ILaunchConfiguration newHandle = wc.doSave();
+		 assertTrue("Config should no longer exist", !handle.exists());
+		 
+		 // retrieve new attributes
+		 assertTrue("String1 should be String1", newHandle.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", newHandle.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", newHandle.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !newHandle.getAttribute("Boolean2", true));		 
+
+		 // ensure new handle is in the index
+		 ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
+		 assertTrue("Renamed configuration should exist in project index", existsIn(configs, newHandle));		 
+		 assertTrue("Original configuration should NOT exist in project index", !existsIn(configs, handle));	
+		 
+		 // cleanup
+		 newHandle.delete();
+		 assertTrue("Config should not exist after deletion", !newHandle.exists());		 	 
+	}		
+	
+	/**
+	 * Creates a shared working copy configuration, sets some attributes,
+	 * and saves the working copy, and retrieves the attributes.
+	 */
+	public void testCreateSharedConfiguration() throws CoreException {
+		 ILaunchConfigurationWorkingCopy wc = newConfiguration(getJavaProject().getProject(), "config2");
+		 ILaunchConfiguration handle = wc.doSave();
+		 assertTrue("Configuration should exist", handle.exists());
+		 
+		 // retrieve attributes
+		 assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true));
+		 
+ 		 // ensure new handle is in the index
+		 ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
+		 assertTrue("Configuration should exist in project index", existsIn(configs, handle)); 
+		 
+ 		 // cleanup
+		 handle.delete();
+		 assertTrue("Config should not exist after deletion", !handle.exists());
+	}	
+	
+	/**
+	 * Creates a shared working copy configuration, sets some attributes,
+	 * and saves the working copy, and retrieves the attributes.
+	 * Copies the configuration and ensures the original still exists.
+	 */
+	public void testSharedCopy() throws CoreException {
+		 ILaunchConfigurationWorkingCopy wc = newConfiguration(getJavaProject().getProject(), "config2Copy");
+		 ILaunchConfiguration handle = wc.doSave();
+		 assertTrue("Configuration should exist", handle.exists());
+		 
+		 // retrieve attributes
+		 assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true));
+		 
+ 		 // ensure new handle is in the index
+		 ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
+		 assertTrue("Configuration should exist in project index", existsIn(configs, handle)); 
+		 
+		 // copy 
+		 ILaunchConfigurationWorkingCopy softCopy = handle.copy("CopyOf" + handle.getName());
+		 ILaunchConfiguration hardCopy = softCopy.doSave();
+		 
+		 // retrieve attributes
+		 assertTrue("String1 should be String1", hardCopy.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", hardCopy.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", hardCopy.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !hardCopy.getAttribute("Boolean2", true));		 
+		 
+		 assertTrue("Original should still exist", handle.exists());
+		 
+		 // cleanup
+		 handle.delete();
+		 assertTrue("Config should not exist after deletion", !handle.exists());
+		 hardCopy.delete();
+		 assertTrue("Config should not exist after deletion", !hardCopy.exists());		 		 		 
+	}		
+	
+
+	/**
+	 * Creates a shared working copy configuration, sets some attributes,
+	 * and saves the working copy, and retrieves the attributes. Deletes
+	 * the configuration and ensures it no longer exists.
+	 */
+	public void testDeleteSharedConfiguration() throws CoreException {
+ 		 ILaunchConfigurationWorkingCopy wc = newConfiguration(getJavaProject().getProject(), "shared2delete");
+		 ILaunchConfiguration handle = wc.doSave();
+		 assertTrue("Configuration should exist", handle.exists());
+		 
+		 // retrieve attributes
+		 assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true));
+		 
+		 // delete 
+		 handle.delete();		 
+		 assertTrue("Config should no longer exist", !handle.exists());
+		 
+		 // ensure handle is not in the index
+		 ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
+		 assertTrue("Configuration should not exist in project index", !existsIn(configs, handle));		 
+	}	
+	
+	/**
+	 * Creates a shared working copy configuration, sets some attributes,
+	 * and saves the working copy, and retrieves the attributes. Renames
+	 * the configuration and ensures it's old config no longer exists,
+	 * and that attributes are retrievable from the new (renamed) config.
+	 */
+	public void testRenameSharedConfiguration() throws CoreException {
+		 ILaunchConfigurationWorkingCopy wc = newConfiguration(getJavaProject().getProject(), "shared2rename");
+		 ILaunchConfiguration handle = wc.doSave();
+		 assertTrue("Configuration should exist", handle.exists());
+		 
+		 // retrieve attributes
+		 assertTrue("String1 should be String1", handle.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", handle.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", handle.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !handle.getAttribute("Boolean2", true));
+		 
+		 // rename
+		 wc = handle.getWorkingCopy();
+		 wc.rename("shared-2-rename");
+		 ILaunchConfiguration newHandle = wc.doSave();
+		 assertTrue("Config should no longer exist", !handle.exists());
+		 
+		 // retrieve new attributes
+		 assertTrue("String1 should be String1", newHandle.getAttribute("String1", "Missing").equals("String1"));
+		 assertTrue("Int1 should be 1", newHandle.getAttribute("Int1", 0) == 1);
+		 assertTrue("Boolean1 should be true", newHandle.getAttribute("Boolean1", false));
+		 assertTrue("Boolean2 should be false", !newHandle.getAttribute("Boolean2", true));		 
+
+		 // ensure new handle is in the index
+		 ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations();
+		 assertTrue("Renamed configuration should exist in project index", existsIn(configs, newHandle));		 
+		 assertTrue("Original configuration should NOT exist in project index", !existsIn(configs, handle));		 
+		 
+		 // cleanup
+		 newHandle.delete();
+		 assertTrue("Config should not exist after deletion", !newHandle.exists());		 
+	}
+	
+	/** 
+	 * Creates a few configs, closes the project and re-opens the
+	 * project to ensure the config index is persisted properly
+	 */
+	public void testPersistIndex() throws CoreException {
+		ILaunchConfigurationWorkingCopy wc1 = newConfiguration(null, "persist1local");
+		ILaunchConfigurationWorkingCopy wc2 = newConfiguration(getJavaProject().getProject(), "persist2shared");
+		ILaunchConfiguration lc1 = wc1.doSave();
+		ILaunchConfiguration lc2 = wc2.doSave();
+		
+		IProject project = getJavaProject().getProject();
+		ILaunchConfiguration[] before = getLaunchManager().getLaunchConfigurations();
+		assertTrue("config should be in index", existsIn(before, lc1));
+		assertTrue("config should be in index", existsIn(before, lc2));
+		
+		project.close(null);
+		ILaunchConfiguration[] during = getLaunchManager().getLaunchConfigurations();
+		boolean local = true;
+		for (int i = 0; i < during.length; i++) {
+			local = local && during[i].isLocal();
+		}
+		assertTrue("Should only be local configs when closed", local);
+		
+		project.open(null);
+		ILaunchConfiguration[] after = getLaunchManager().getLaunchConfigurations();
+		assertTrue("Should be same number of configs after openning", after.length == before.length);
+		for (int i = 0; i < before.length; i++) {
+			assertTrue("Config should exist after openning", existsIn(after, before[i]));
+		}
+
+		 // cleanup
+		 lc1.delete();
+		 assertTrue("Config should not exist after deletion", !lc1.exists());
+		 lc2.delete();
+		 assertTrue("Config should not exist after deletion", !lc2.exists());		 
+		 
+		
+	}	
+		
+	/**
+	 * Test setting & retrieving of default launch configuration type
+	 */
+	public void testDefaultLaunchConfigurationType() throws CoreException {
+		IProject pro = getJavaProject().getProject();
+		ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
+		assertNotNull("could not find launch configuration type", type);
+		getLaunchManager().setDefaultLaunchConfigurationType(pro, type.getIdentifier());
+		ILaunchConfigurationType def = getLaunchManager().getDefaultLaunchConfigurationType(pro, false);
+		assertEquals("default not set properly", type, def);
+		
+		
+	}
+	
+}
+
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/MethodBreakpointTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/MethodBreakpointTests.java
new file mode 100644
index 0000000..443747d
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/MethodBreakpointTests.java
@@ -0,0 +1,117 @@
+package org.eclipse.jdt.debug.tests.core;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+/**
+ * Tests method breakpoints.
+ */
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+
+public class MethodBreakpointTests extends AbstractDebugTest {
+	
+	public MethodBreakpointTests(String name) {
+		super(name);
+	}
+
+	public void testEntryAndExitBreakpoints() throws Exception {
+		String typeName = "DropTests";
+		List bps = new ArrayList();
+		// method 4 - entry
+		bps.add(createMethodBreakpoint(typeName, "method4", "()V", true, false));
+		// method 1 - exit
+		bps.add(createMethodBreakpoint(typeName, "method1", "()V", false, true));
+		
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch(typeName);
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+			
+			IBreakpoint hit = getBreakpoint(thread);
+			assertNotNull("suspended, but not by breakpoint", hit);
+			assertEquals("should hit entry breakpoint first", bps.get(0),hit);
+
+			// onto the next breakpoint			
+			thread = resume(thread);
+			
+			hit = getBreakpoint(thread);
+			assertNotNull("suspended, but not by breakpoint", hit);
+			assertEquals("should hit exit breakpoint second", bps.get(1), hit);			
+
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}
+	
+	public void testInnerClassNotHit() throws Exception {
+		String typeNamePattern = "A";
+		List bps = new ArrayList();
+		// method b - entry
+		bps.add(createMethodBreakpoint(typeNamePattern, "b", "()V", true, false));
+		
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch(typeNamePattern);
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+			
+			IBreakpoint hit = getBreakpoint(thread);
+			assertNotNull("suspended, but not by breakpoint", hit);
+			assertEquals("should hit entry breakpoint first", bps.get(0),hit);
+
+		
+			resumeAndExit(thread);
+
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}
+	
+	public void testInnerClassesHit() throws Exception {
+		String typeNamePattern = "A*";
+		List bps = new ArrayList();
+		// method b - entry
+		bps.add(createMethodBreakpoint(typeNamePattern, "b", "()V", true, false));
+		
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch("A");
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+			
+			IBreakpoint hit = getBreakpoint(thread);
+			assertNotNull("suspended, but not by breakpoint", hit);
+			assertEquals("should hit entry breakpoint first", bps.get(0),hit);
+
+			thread= resume(thread);
+			hit = getBreakpoint(thread);
+			assertNotNull("suspended, but not by breakpoint", hit);
+			assertEquals("should hit entry breakpoint first", bps.get(0),hit);
+
+			thread= resume(thread);
+			hit = getBreakpoint(thread);
+			assertNotNull("suspended, but not by breakpoint", hit);
+			assertEquals("should hit entry breakpoint first", bps.get(0),hit);
+			
+			thread= resume(thread);
+			hit = getBreakpoint(thread);
+			assertNotNull("suspended, but not by breakpoint", hit);
+			assertEquals("should hit entry breakpoint first", bps.get(0),hit);
+			
+			resumeAndExit(thread);
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/PatternBreakpointTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/PatternBreakpointTests.java
new file mode 100644
index 0000000..7fd1405
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/PatternBreakpointTests.java
@@ -0,0 +1,93 @@
+package org.eclipse.jdt.debug.tests.core;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+/**
+ * Tests deferred pattern breakpoints.
+ */
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+
+public class PatternBreakpointTests extends AbstractDebugTest {
+	
+	public PatternBreakpointTests(String name) {
+		super(name);
+	}
+
+	public void testPatternBreakpoints() throws Exception {
+		String sourceName = "Breakpoints.java";
+		String pattern = "Break";
+		List bps = new ArrayList();
+		// anonymous class
+		bps.add(createPatternBreakpoint(32, sourceName, pattern));
+		// blocks
+		bps.add(createPatternBreakpoint(91, sourceName, pattern));
+		// constructor
+		bps.add(createPatternBreakpoint(66, sourceName, pattern));
+		// else
+		bps.add(createPatternBreakpoint(77, sourceName, pattern));
+		//finally after catch
+		bps.add(createPatternBreakpoint(109, sourceName, pattern));
+		//finally after try
+		bps.add(createPatternBreakpoint(117, sourceName, pattern));
+		// for loop
+		bps.add(createPatternBreakpoint(82, sourceName, pattern));
+		// if
+		bps.add(createPatternBreakpoint(70, sourceName, pattern));
+		// initializer
+		bps.add(createPatternBreakpoint(6, sourceName, pattern));
+		// inner class
+		bps.add(createPatternBreakpoint(11, sourceName, pattern));
+		// return true
+		bps.add(createPatternBreakpoint(61, sourceName, pattern));
+		// instance method
+		bps.add(createPatternBreakpoint(96, sourceName, pattern));
+		// static method 
+		bps.add(createPatternBreakpoint(42, sourceName, pattern));
+		// case statement
+		bps.add(createPatternBreakpoint(122, sourceName, pattern));
+		// default statement
+		bps.add(createPatternBreakpoint(129, sourceName, pattern));
+		// synchronized blocks
+		bps.add(createPatternBreakpoint(135, sourceName, pattern));
+		// try
+		bps.add(createPatternBreakpoint(114, sourceName, pattern));
+		//catch
+		bps.add(createPatternBreakpoint(107, sourceName, pattern));
+		// while
+		bps.add(createPatternBreakpoint(86, sourceName, pattern));
+		
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch("Breakpoints");
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+			while (!bps.isEmpty()) {
+				IBreakpoint hit = getBreakpoint(thread);
+				assertNotNull("suspended, but not by breakpoint", hit);
+				assertTrue("hit un-registered breakpoint", bps.contains(hit));
+				assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint);
+				ILineBreakpoint breakpoint= (ILineBreakpoint) hit;
+				int lineNumber = breakpoint.getLineNumber();
+				int stackLine = thread.getTopStackFrame().getLineNumber();
+				assertTrue("line numbers of breakpoint and stack frame do not match", lineNumber == stackLine);
+				bps.remove(breakpoint);
+				breakpoint.delete();
+				if (!bps.isEmpty()) {
+					thread = resume(thread);
+				}
+			}
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/StaticVariableTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/StaticVariableTests.java
new file mode 100644
index 0000000..32ea720
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/StaticVariableTests.java
@@ -0,0 +1,51 @@
+package org.eclipse.jdt.debug.tests.core;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.jdt.debug.core.IJavaDebugTarget;
+import org.eclipse.jdt.debug.core.IJavaObject;
+import org.eclipse.jdt.debug.core.IJavaStackFrame;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.core.IJavaVariable;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+
+public class StaticVariableTests extends AbstractDebugTest {
+	
+	public StaticVariableTests(String name) {
+		super(name);
+	}
+
+	public void testSetValue() throws Exception {
+		String typeName = "StaticVariablesTests";
+		
+		createLineBreakpoint(29, typeName);		
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch(typeName);
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+
+			IJavaStackFrame frame = (IJavaStackFrame)thread.getTopStackFrame();
+			IVariable pubStr = frame.findVariable("pubStr");
+			assertNotNull("Could not find variable 'pubStr'", pubStr);
+			
+			assertEquals("Value should be 'public'","public", pubStr.getValue().getValueString());
+			pubStr.setValue(((IJavaDebugTarget)frame.getDebugTarget()).newValue("test"));
+			assertEquals("Value should be 'test'","test", pubStr.getValue().getValueString());
+			
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/TargetPatternBreakpointTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/TargetPatternBreakpointTests.java
new file mode 100644
index 0000000..8b4b08a
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/TargetPatternBreakpointTests.java
@@ -0,0 +1,169 @@
+package org.eclipse.jdt.debug.tests.core;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+/**
+ * Tests deferred target pattern breakpoints.
+ */
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.jdt.core.dom.Message;
+import org.eclipse.jdt.debug.core.IJavaBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaBreakpointListener;
+import org.eclipse.jdt.debug.core.IJavaDebugTarget;
+import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaTargetPatternBreakpoint;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.core.IJavaType;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
+
+public class TargetPatternBreakpointTests extends AbstractDebugTest implements IJavaBreakpointListener {
+	
+	public TargetPatternBreakpointTests(String name) {
+		super(name);
+	}
+
+	public void testTargetPatternBreakpoints() throws Exception {
+		JDIDebugPlugin.getDefault().addJavaBreakpointListener(this);
+		
+		String sourceName = "Breakpoints.java";
+		List bps = new ArrayList();
+		// anonymous class
+		bps.add(createTargetPatternBreakpoint(32, sourceName));
+		// blocks
+		bps.add(createTargetPatternBreakpoint(91, sourceName));
+		// constructor
+		bps.add(createTargetPatternBreakpoint(66, sourceName));
+		// else
+		bps.add(createTargetPatternBreakpoint(77, sourceName));
+		//finally after catch
+		bps.add(createTargetPatternBreakpoint(109, sourceName));
+		//finally after try
+		bps.add(createTargetPatternBreakpoint(117, sourceName));
+		// for loop
+		bps.add(createTargetPatternBreakpoint(82, sourceName));
+		// if
+		bps.add(createTargetPatternBreakpoint(70, sourceName));
+		// initializer
+		bps.add(createTargetPatternBreakpoint(6, sourceName));
+		// inner class
+		bps.add(createTargetPatternBreakpoint(11, sourceName));
+		// return true
+		bps.add(createTargetPatternBreakpoint(61, sourceName));
+		// instance method
+		bps.add(createTargetPatternBreakpoint(96, sourceName));
+		// static method 
+		bps.add(createTargetPatternBreakpoint(42, sourceName));
+		// case statement
+		bps.add(createTargetPatternBreakpoint(122, sourceName));
+		// default statement
+		bps.add(createTargetPatternBreakpoint(129, sourceName));
+		// synchronized blocks
+		bps.add(createTargetPatternBreakpoint(135, sourceName));
+		// try
+		bps.add(createTargetPatternBreakpoint(114, sourceName));
+		//catch
+		bps.add(createTargetPatternBreakpoint(107, sourceName));
+		// while
+		bps.add(createTargetPatternBreakpoint(86, sourceName));
+		
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch("Breakpoints");
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+			while (!bps.isEmpty()) {
+				IBreakpoint hit = getBreakpoint(thread);
+				assertNotNull("suspended, but not by breakpoint", hit);
+				assertTrue("hit un-registered breakpoint", bps.contains(hit));
+				assertTrue("suspended, but not by line breakpoint", hit instanceof ILineBreakpoint);
+				ILineBreakpoint breakpoint= (ILineBreakpoint) hit;
+				int lineNumber = breakpoint.getLineNumber();
+				int stackLine = thread.getTopStackFrame().getLineNumber();
+				assertTrue("line numbers of breakpoint and stack frame do not match", lineNumber == stackLine);
+				bps.remove(breakpoint);
+				breakpoint.delete();
+				if (!bps.isEmpty()) {
+					thread = resume(thread);
+				}
+			}
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+			JDIDebugPlugin.getDefault().removeJavaBreakpointListener(this);
+		}		
+	}
+	/**
+	 * @see IJavaBreakpointListener#addingBreakpoint(IJavaDebugTarget, IJavaBreakpoint)
+	 */
+	public void addingBreakpoint(
+		IJavaDebugTarget target,
+		IJavaBreakpoint breakpoint) {
+			if (breakpoint instanceof IJavaTargetPatternBreakpoint) {
+				IJavaTargetPatternBreakpoint bp = (IJavaTargetPatternBreakpoint)breakpoint;
+				try {
+					bp.setPattern(target,"Breakp");
+				} catch (CoreException e) {
+					assertTrue("Failed to set pattern", false);
+				}
+			}
+	}
+
+	/**
+	 * @see IJavaBreakpointListener#breakpointHit(IJavaThread, IJavaBreakpoint)
+	 */
+	public boolean breakpointHit(IJavaThread thread, IJavaBreakpoint breakpoint) {
+		return true;
+	}
+
+	/**
+	 * @see IJavaBreakpointListener#breakpointInstalled(IJavaDebugTarget, IJavaBreakpoint)
+	 */
+	public void breakpointInstalled(
+		IJavaDebugTarget target,
+		IJavaBreakpoint breakpoint) {
+	}
+
+	/**
+	 * @see IJavaBreakpointListener#breakpointRemoved(IJavaDebugTarget, IJavaBreakpoint)
+	 */
+	public void breakpointRemoved(
+		IJavaDebugTarget target,
+		IJavaBreakpoint breakpoint) {
+	}
+
+	/**
+	 * @see IJavaBreakpointListener#installingBreakpoint(IJavaDebugTarget, IJavaBreakpoint, IJavaType)
+	 */
+	public boolean installingBreakpoint(
+		IJavaDebugTarget target,
+		IJavaBreakpoint breakpoint,
+		IJavaType type) {
+		return true;
+	}
+
+	/**
+	 * @see IJavaBreakpointListener#breakpointHasCompilationErrors(IJavaLineBreakpoint, Message[])
+	 */
+	public void breakpointHasCompilationErrors(
+		IJavaLineBreakpoint breakpoint,
+		Message[] errors) {
+	}
+
+	/**
+	 * @see IJavaBreakpointListener#breakpointHasRuntimeException(IJavaLineBreakpoint, DebugException)
+	 */
+	public void breakpointHasRuntimeException(
+		IJavaLineBreakpoint breakpoint,
+		DebugException exception) {
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/WatchpointTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/WatchpointTests.java
new file mode 100644
index 0000000..22304e4
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/WatchpointTests.java
@@ -0,0 +1,131 @@
+package org.eclipse.jdt.debug.tests.core;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.jdt.debug.core.IJavaDebugTarget;
+import org.eclipse.jdt.debug.core.IJavaObject;
+import org.eclipse.jdt.debug.core.IJavaStackFrame;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.core.IJavaVariable;
+import org.eclipse.jdt.debug.core.IJavaWatchpoint;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+
+public class WatchpointTests extends AbstractDebugTest {
+	
+	public WatchpointTests(String name) {
+		super(name);
+	}
+
+	public void testAccessAndModification() throws Exception {
+		String typeName = "org.eclipse.debug.tests.targets.Watchpoint";
+		
+		IJavaWatchpoint wp = createWatchpoint(typeName, "list", true, true);
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch(typeName);
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+
+			IBreakpoint hit = getBreakpoint(thread);
+			IStackFrame frame = thread.getTopStackFrame();
+			assertNotNull("No breakpoint", hit);
+			
+			// should be modification
+			assertTrue("First hit should be modification", !wp.isAccessSuspend(thread.getDebugTarget()));
+			// line 23
+			assertEquals("Should be on line 23", frame.getLineNumber(), 23);
+			
+			// should hit access 10 times
+			int count = 10;
+			while (count > 0) {
+				thread = resume(thread);
+				hit = getBreakpoint(thread);
+				frame = thread.getTopStackFrame();
+				assertNotNull("No breakpoint", hit);
+				assertTrue("Should be an access", wp.isAccessSuspend(thread.getDebugTarget()));
+				assertEquals("Should be line 26", frame.getLineNumber(), 26);
+				count--;
+			}
+			
+			resumeAndExit(thread);
+
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}
+	
+	public void testModification() throws Exception {
+		String typeName = "org.eclipse.debug.tests.targets.Watchpoint";
+		
+		IJavaWatchpoint wp = createWatchpoint(typeName, "list", false, true);
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch(typeName);
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+
+			IBreakpoint hit = getBreakpoint(thread);
+			IStackFrame frame = thread.getTopStackFrame();
+			assertNotNull("No breakpoint", hit);
+			
+			// should be modification
+			assertTrue("First hit should be modification", !wp.isAccessSuspend(thread.getDebugTarget()));
+			// line 23
+			assertEquals("Should be on line 23", frame.getLineNumber(), 23);
+			
+			resumeAndExit(thread);
+
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}	
+	
+	public void testAccess() throws Exception {
+		String typeName = "org.eclipse.debug.tests.targets.Watchpoint";
+		
+		IJavaWatchpoint wp = createWatchpoint(typeName, "list", true, false);
+		
+		IJavaThread thread= null;
+		try {
+			thread= launch(typeName);
+			assertNotNull("Breakpoint not hit within timeout period", thread);
+
+			IBreakpoint hit = getBreakpoint(thread);
+			IStackFrame frame = thread.getTopStackFrame();
+			assertNotNull("No breakpoint", hit);
+			assertTrue("Should be an access", wp.isAccessSuspend(thread.getDebugTarget()));
+			assertEquals("Should be line 26", frame.getLineNumber(), 26);			
+			
+			// should hit access 9 more times
+			int count = 9;
+			while (count > 0) {
+				thread = resume(thread);
+				hit = getBreakpoint(thread);
+				frame = thread.getTopStackFrame();
+				assertNotNull("No breakpoint", hit);
+				assertTrue("Should be an access", wp.isAccessSuspend(thread.getDebugTarget()));
+				assertEquals("Should be line 26", frame.getLineNumber(), 26);
+				count--;
+			}
+			
+			resumeAndExit(thread);
+
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}		
+	}	
+}