Bug 304129 - Post move packaging and bundling
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/META-INF/MANIFEST.MF
index b96e9e7..25d5926 100644
--- a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/META-INF/MANIFEST.MF
@@ -3,8 +3,6 @@
 Bundle-Name: Tests
 Bundle-SymbolicName: org.eclipse.wst.jsdt.debug.rhino.tests;singleton:=true
 Bundle-Version: 1.0.0.qualifier
-Bundle-Activator: org.eclipse.wst.jsdt.debug.rhino.tests.RhinoDebugTestPlugin
-Bundle-Vendor: IBM
 Require-Bundle: org.eclipse.core.runtime,
  org.junit;bundle-version="3.8.2",
  org.eclipse.wst.jsdt.debug.core,
@@ -12,5 +10,4 @@
  org.eclipse.wst.jsdt.debug.rhino.debugger;bundle-version="1.0.0",
  org.mozilla.javascript;bundle-version="1.7.2"
 Bundle-RequiredExecutionEnvironment: J2SE-1.4
-Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.wst.jsdt.debug.rhino.tests
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/Activator.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/Activator.java
deleted file mode 100644
index 95efe93..0000000
--- a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/Activator.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.wst.jsdt.debug.rhino.tests;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.packageadmin.PackageAdmin;
-
-public class Activator implements BundleActivator {
-
-	private static PackageAdmin packageAdmin;
-	private static BundleContext bundleContext;
-	private ServiceReference packageAdminRef;
-
-	public void start(BundleContext context) throws Exception {
-		packageAdminRef = context.getServiceReference(PackageAdmin.class.getName());
-		setPackageAdmin((PackageAdmin) context.getService(packageAdminRef));
-		setBundleContext(context);
-	}
-
-	private static synchronized void setBundleContext(BundleContext context) {
-		bundleContext = context;
-	}
-
-	private static synchronized void setPackageAdmin(PackageAdmin service) {
-		packageAdmin = service;
-	}
-
-	static synchronized BundleContext getBundleContext() {
-		return bundleContext;
-	}
-
-	static synchronized Bundle getBundle(String symbolicName) {
-		if (packageAdmin == null)
-			return null;
-
-		Bundle[] bundles = packageAdmin.getBundles(symbolicName, null);
-		if (bundles == null)
-			return null;
-		//Return the first bundle that is not installed or uninstalled
-		for (int i = 0; i < bundles.length; i++) {
-			if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
-				return bundles[i];
-			}
-		}
-		return null;
-	}
-	
-	public void stop(BundleContext context) throws Exception {
-		setBundleContext(null);
-		setPackageAdmin(null);
-		context.ungetService(packageAdminRef);
-	}
-
-	
-}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/AllTests.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/AllTests.java
new file mode 100644
index 0000000..f7d0b50
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/AllTests.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests extends TestSuite {
+
+	public static Test suite() {
+		return new AllTests();
+	}
+
+	public AllTests() {
+		addTestSuite(TransportTest.class);
+		addTestSuite(DebugSessionTest.class);
+		addTestSuite(RhinoDebuggerTest.class);
+		addTestSuite(RequestBadCommandTest.class);
+		addTestSuite(RequestBreakpointsTest.class);
+		addTestSuite(RequestBreakpointTest.class);
+		addTestSuite(RequestClearBreakpointTest.class);
+		addTestSuite(RequestThreadsTest.class);
+		addTestSuite(RequestThreadTest.class);
+		addTestSuite(RequestContinueTest.class);
+		addTestSuite(RequestDisposeTest.class);
+		addTestSuite(RequestEvaluateTest.class);
+		addTestSuite(RequestFramesTest.class);
+		addTestSuite(RequestFrameTest.class);
+		addTestSuite(RequestLookupTest.class);
+		addTestSuite(RequestScriptsTest.class);
+		addTestSuite(RequestScriptTest.class);
+		addTestSuite(RequestSetBreakpointTest.class);
+		addTestSuite(RequestSuspendTest.class);
+		addTestSuite(RequestVersionTest.class);
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/ConnectionHelper.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/ConnectionHelper.java
new file mode 100644
index 0000000..465fed1
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/ConnectionHelper.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.io.IOException;
+
+import org.eclipse.wst.jsdt.debug.rhino.transport.Connection;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TransportService;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TransportService.ListenerKey;
+
+
+
+public class ConnectionHelper {
+
+	private TransportService transportService;
+	private String address;
+
+	public ConnectionHelper(final TransportService transportService, final String address) {
+		this.transportService = transportService;
+		this.address = address;
+	}
+
+	public Connection getClientConnection() {
+		try {
+			return transportService.attach(address, 5000, 5000);
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	public Connection getServerConnection() {
+		ListenerKey key = null;
+		try {
+			key = transportService.startListening(address);
+			return transportService.accept(key, 5000, 5000);
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (key != null)
+				try {
+					transportService.stopListening(key);
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+		}
+		return null;
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/DebugSessionTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/DebugSessionTest.java
new file mode 100644
index 0000000..ef8d299
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/DebugSessionTest.java
@@ -0,0 +1,245 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.eclipse.wst.jsdt.debug.rhino.transport.Connection;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DebugSession;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.EventPacket;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Packet;
+import org.eclipse.wst.jsdt.debug.rhino.transport.PipedTransportService;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TransportService;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TransportService.ListenerKey;
+
+
+
+public class DebugSessionTest extends TestCase {
+
+	boolean complete = false;
+	
+	public void testReceiveEvent() throws IOException, InterruptedException, TimeoutException, DisconnectedException {
+		final TransportService service = new PipedTransportService();
+		final ListenerKey key = service.startListening("9000");
+
+		Thread t = new Thread() {
+			public void run() {
+				Connection c = null;
+				DebugSession runtime = null;
+				try {
+					c = service.accept(key, 5000, 5000);
+					assertNotNull(c);
+
+					runtime = new DebugSession(c);
+					runtime.sendEvent(new EventPacket("test"));
+					synchronized (Thread.currentThread()) {
+						Thread.currentThread().wait();
+					}
+				} catch (IOException e) {
+					e.printStackTrace();
+					fail();
+				} catch (DisconnectedException e) {
+					fail();
+				} catch (InterruptedException e) {
+					fail();
+				} finally {
+					if (runtime != null)
+						runtime.dispose();
+				}
+			}
+		};
+		t.start();
+
+		Connection c = service.attach("9000", 5000, 5000);
+		assertNotNull(c);
+		DebugSession session = new DebugSession(c);
+		try {
+			EventPacket event = session.receiveEvent(5000);
+			assertTrue(event.getEvent().equals("test"));
+		} finally {
+			session.dispose();
+			synchronized (t) {
+				t.notify();
+			}
+		}
+		t.join(5000);
+		service.stopListening(key);
+	}
+
+	public void testSendRequestReceiveResponse() throws IOException, InterruptedException, DisconnectedException, TimeoutException {
+		final TransportService service = new PipedTransportService();
+		final ListenerKey key = service.startListening("9000");
+
+		Thread t = new Thread() {
+			public void run() {
+				Connection c = null;
+				DebugSession runtime = null;
+				try {
+					c = service.accept(key, 5000, 5000);
+					assertNotNull(c);
+
+					runtime = new DebugSession(c);
+					Request request = runtime.receiveRequest(5000);
+					runtime.sendResponse(new Response(request.getSequence(), request.getCommand()));
+					synchronized (Thread.currentThread()) {
+						Thread.currentThread().wait();
+					}
+				} catch (IOException e) {
+					e.printStackTrace();
+					fail();
+				} catch (DisconnectedException e) {
+					fail();
+				} catch (InterruptedException e) {
+					fail();
+				} catch (TimeoutException e) {
+					fail();
+				} finally {
+					if (runtime != null)
+						runtime.dispose();
+				}
+			}
+		};
+		t.start();
+
+		Connection c = service.attach("9000", 5000, 5000);
+		assertNotNull(c);
+		DebugSession session = new DebugSession(c);
+		try {
+			Request request = new Request("test");
+			session.sendRequest(request);
+			Response response = session.receiveResponse(request.getSequence(), 5000);
+			assertTrue(response.getCommand().equals("test"));
+			assertTrue(response.getRequestSequence() == request.getSequence());
+		} finally {
+			session.dispose();
+			synchronized (t) {
+				t.notify();
+			}
+		}
+		t.join(5000);
+		service.stopListening(key);
+	}
+	
+	public void testSendEvent() throws IOException, InterruptedException {
+		final TransportService service = new PipedTransportService();
+		final ListenerKey key = service.startListening("9000");
+
+		Thread t = new Thread() {
+			public void run() {
+				Connection c = null;
+				DebugSession runtime = null;
+				try {
+					c = service.accept(key, 5000, 5000);
+					assertNotNull(c);
+
+					runtime = new DebugSession(c);
+					runtime.sendEvent(new EventPacket("test"));
+					synchronized (Thread.currentThread()) {
+						if (!complete)
+							Thread.currentThread().wait(5000);
+					}
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+					fail();
+				} catch (DisconnectedException e) {
+					e.printStackTrace();
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				} finally {
+					if (runtime != null)
+						runtime.dispose();
+				}
+			}
+		};
+		t.start();
+
+		Connection c = service.attach("9000", 5000, 5000);
+		assertNotNull(c);
+		try {
+			Packet packet = c.readPacket();
+			assertTrue(packet instanceof EventPacket);
+			EventPacket event = (EventPacket) packet;
+			assertTrue(event.getEvent().equals("test"));
+		} finally {
+			c.close();
+			synchronized (t) {
+				complete = true;
+				t.notify();
+			}
+		}
+		t.join(5000);
+		service.stopListening(key);
+	}
+
+	public void testReceiveRequestSendResponse() throws IOException, InterruptedException {
+		final TransportService service = new PipedTransportService();
+		final ListenerKey key = service.startListening("9000");
+
+		Thread t = new Thread() {
+			public void run() {
+				Connection c = null;
+				DebugSession runtime = null;
+				try {
+					c = service.accept(key, 5000, 5000);
+					assertNotNull(c);
+
+					runtime = new DebugSession(c);
+					Request request = runtime.receiveRequest(5000);
+					runtime.sendResponse(new Response(request.getSequence(), request.getCommand()));
+					synchronized (Thread.currentThread()) {
+						Thread.currentThread().wait();
+					}
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+					fail();
+				} catch (DisconnectedException e) {
+					e.printStackTrace();
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				} catch (TimeoutException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} finally {
+					if (runtime != null)
+						runtime.dispose();
+				}
+			}
+		};
+		t.start();
+
+		Connection c = service.attach("9000", 5000, 5000);
+		assertNotNull(c);
+		try {
+			Request request = new Request("test");
+			c.writePacket(request);
+			Packet packet = c.readPacket();
+			assertTrue(packet instanceof Response);
+			Response response = (Response) packet;
+			assertTrue(response.getCommand().equals("test"));
+			assertTrue(response.getRequestSequence() == request.getSequence());
+		} finally {
+			c.close();
+			synchronized (t) {
+				t.notify();
+			}
+		}
+		t.join(5000);
+		service.stopListening(key);
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestBadCommandTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestBadCommandTest.java
new file mode 100644
index 0000000..8f7e333
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestBadCommandTest.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+
+public class RequestBadCommandTest extends RequestTest {
+
+	public void testBadCommand() throws DisconnectedException, TimeoutException {
+		Request request = new Request("bad_command");
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertFalse(response.isSuccess());
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestBreakpointsTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestBreakpointsTest.java
new file mode 100644
index 0000000..41fc8d5
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestBreakpointsTest.java
@@ -0,0 +1,295 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.jsdt.debug.rhino.tests.TestEventHandler.Subhandler;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DebugSession;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.EventPacket;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+
+public class RequestBreakpointsTest extends RequestTest {
+
+	public void testBreakpointsWithNoBreakpoints() throws DisconnectedException, TimeoutException {
+		Request request = new Request("breakpoints");
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		Collection breakpoints = (Collection) response.getBody().get("breakpoints");
+		assertNotNull(breakpoints);
+		assertTrue(breakpoints.isEmpty());
+	}
+
+	public void testBreakpoints() throws DisconnectedException, TimeoutException {
+		Subhandler setbreakpointHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("script")) {
+					Object scriptId = event.getBody().get("scriptId");
+					Request request = new Request("script");
+					request.getArguments().put("scriptId", scriptId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Map result = (Map) response.getBody().get("script");
+
+						// line numbers
+						List lineNumbers = (List) result.get("lines");
+						for (Iterator iterator = lineNumbers.iterator(); iterator.hasNext();) {
+							Number lineNumber = (Number) iterator.next();
+							request = new Request("setbreakpoint");
+							request.getArguments().put("scriptId", scriptId);
+							request.getArguments().put("line", lineNumber);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						}
+
+						// functions
+						List functionNames = (List) result.get("functions");
+						for (Iterator iterator = functionNames.iterator(); iterator.hasNext();) {
+							String functionName = (String) iterator.next();
+							request = new Request("setbreakpoint");
+							request.getArguments().put("scriptId", scriptId);
+							request.getArguments().put("function", functionName);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						}
+
+						// script onEnter
+						request = new Request("setbreakpoint");
+						request.getArguments().put("scriptId", scriptId);
+						debugSession.sendRequest(request);
+						response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(setbreakpointHandler);
+
+		Request request = new Request("breakpoints");
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		Collection breakpoints = (Collection) response.getBody().get("breakpoints");
+		assertNotNull(breakpoints);
+		assertTrue(breakpoints.isEmpty());
+
+		String script = "var line1 = true;\r\n";
+		script += "function test() { // line 2 \r\n";
+		script += " return \"line 3\";\r\n";
+		script += "} // line 4 \r\n";
+		script += "// line 5\r\n";
+		script += "var line6 = test();\r\n";
+		script += "var line7 = test();\r\n";
+		script += "// line 8\r\n";
+		script += "// line 9\r\n";
+		script += "var line10 = test();\r\n";
+		script += "// line 11\r\n";
+		script += "// line 12\r\n";
+		script += "function test2() { // line 13 \r\n";
+		script += " return \"line 14\";\r\n";
+		script += "} // line 15 \r\n";
+		script += "// line 16\r\n";
+		script += "// line 17\r\n";
+
+		Scriptable scope = null;
+		Context context = contextFactory.enterContext();
+		try {
+			scope = context.initStandardObjects();
+			context.evaluateString(scope, script, "script", 0, null);
+		} finally {
+			Context.exit();
+		}
+
+		waitForEvents(1);
+
+		request = new Request("breakpoints");
+		debugSession.sendRequest(request);
+		response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		breakpoints = (Collection) response.getBody().get("breakpoints");
+		assertNotNull(breakpoints);
+		assertEquals(10, breakpoints.size());
+
+		for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) {
+			Number breakpointId = (Number) iterator.next();
+			request = new Request("breakpoint");
+			request.getArguments().put("breakpointId", breakpointId);
+			debugSession.sendRequest(request);
+			response = debugSession.receiveResponse(request.getSequence(), 10000);
+			assertTrue(response.isSuccess());
+			Map breakpoint = (Map) response.getBody().get("breakpoint");
+			assertEquals(breakpointId.intValue(), Util.numberAsInt(breakpoint.get("breakpointId")));
+			assertTrue(breakpoint.containsKey("scriptId"));
+		}
+	}
+
+	public void testBreakpointsWithClear() throws DisconnectedException, TimeoutException {
+		Subhandler setbreakpointHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("script")) {
+					Object scriptId = event.getBody().get("scriptId");
+					Request request = new Request("script");
+					request.getArguments().put("scriptId", scriptId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Map result = (Map) response.getBody().get("script");
+
+						// line numbers
+						List lineNumbers = (List) result.get("lines");
+						for (Iterator iterator = lineNumbers.iterator(); iterator.hasNext();) {
+							Number lineNumber = (Number) iterator.next();
+							request = new Request("setbreakpoint");
+							request.getArguments().put("scriptId", scriptId);
+							request.getArguments().put("line", lineNumber);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						}
+
+						// functions
+						List functionNames = (List) result.get("functions");
+						for (Iterator iterator = functionNames.iterator(); iterator.hasNext();) {
+							String functionName = (String) iterator.next();
+							request = new Request("setbreakpoint");
+							request.getArguments().put("scriptId", scriptId);
+							request.getArguments().put("function", functionName);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						}
+
+						// script onEnter
+						request = new Request("setbreakpoint");
+						request.getArguments().put("scriptId", scriptId);
+						debugSession.sendRequest(request);
+						response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(setbreakpointHandler);
+
+		Subhandler clearbreakpointHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("break")) {
+					List breakpoints = (List) event.getBody().get("breakpoints");
+					for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) {
+						Number breakpointId = (Number) iterator.next();
+						Request request = new Request("clearbreakpoint");
+						request.getArguments().put("breakpointId", breakpointId);
+						try {
+							debugSession.sendRequest(request);
+							Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						} catch (DisconnectedException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						} catch (TimeoutException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(clearbreakpointHandler);
+
+		Request request = new Request("breakpoints");
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		Collection breakpoints = (Collection) response.getBody().get("breakpoints");
+		assertNotNull(breakpoints);
+		assertTrue(breakpoints.isEmpty());
+
+		String script = "var line1 = true;\r\n";
+		script += "function test() { // line 2 \r\n";
+		script += " return \"line 3\";\r\n";
+		script += "} // line 4 \r\n";
+		script += "// line 5\r\n";
+		script += "var line6 = test();\r\n";
+		script += "var line7 = test();\r\n";
+		script += "// line 8\r\n";
+		script += "// line 9\r\n";
+		script += "var line10 = test();\r\n";
+		script += "// line 11\r\n";
+		script += "// line 12\r\n";
+		script += "function test2() { // line 13 \r\n";
+		script += " return \"line 14\";\r\n";
+		script += "} // line 15 \r\n";
+		script += "// line 16\r\n";
+		script += "// line 17\r\n";
+
+		Scriptable scope = null;
+		Context context = contextFactory.enterContext();
+		try {
+			scope = context.initStandardObjects();
+			context.evaluateString(scope, script, "script", 0, null);
+		} finally {
+			Context.exit();
+		}
+		waitForEvents(7);
+		request = new Request("breakpoints");
+		debugSession.sendRequest(request);
+		response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		breakpoints = (Collection) response.getBody().get("breakpoints");
+		assertNotNull(breakpoints);
+		assertEquals(3, breakpoints.size());
+
+		for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) {
+			Number breakpointId = (Number) iterator.next();
+			request = new Request("breakpoint");
+			request.getArguments().put("breakpointId", breakpointId);
+			debugSession.sendRequest(request);
+			response = debugSession.receiveResponse(request.getSequence(), 10000);
+			assertTrue(response.isSuccess());
+			Map breakpoint = (Map) response.getBody().get("breakpoint");
+			assertEquals(breakpointId.intValue(), Util.numberAsInt(breakpoint.get("breakpointId")));
+			assertTrue(breakpoint.containsKey("scriptId"));
+		}
+	}
+
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestDisposeTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestDisposeTest.java
new file mode 100644
index 0000000..ace87b9
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestDisposeTest.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+
+public class RequestDisposeTest extends RequestTest {
+
+	public void testDispose() throws DisconnectedException, TimeoutException {
+		Request request = new Request("dispose");
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestEvaluateTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestEvaluateTest.java
new file mode 100644
index 0000000..5656a0e
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestEvaluateTest.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.jsdt.debug.rhino.tests.TestEventHandler.Subhandler;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DebugSession;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.EventPacket;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+
+public class RequestEvaluateTest extends RequestTest {
+
+	public void testFramesAndFrameLookupAndEvaluate() throws DisconnectedException, TimeoutException {
+
+		Subhandler setbreakpointHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("script")) {
+					Object scriptId = event.getBody().get("scriptId");
+					Request request = new Request("script");
+					request.getArguments().put("scriptId", scriptId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Map result = (Map) response.getBody().get("script");
+						// functions
+						List functionNames = (List) result.get("functions");
+						for (Iterator iterator = functionNames.iterator(); iterator.hasNext();) {
+							String functionName = (String) iterator.next();
+							request = new Request("setbreakpoint");
+							request.getArguments().put("scriptId", scriptId);
+							request.getArguments().put("function", functionName);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						}
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(setbreakpointHandler);
+
+		final Object[] success = new Object[1];
+
+		Subhandler frameCheckHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("break")) {
+					Number threadId = (Number) event.getBody().get("threadId");
+					Number contextId = (Number) event.getBody().get("contextId");
+					Request request = new Request("frames");
+					request.getArguments().put("threadId", threadId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Collection frames = (Collection) response.getBody().get("frames");
+						for (Iterator iterator = frames.iterator(); iterator.hasNext();) {
+							Number frameId = (Number) iterator.next();
+							request = new Request("evaluate");
+							request.getArguments().put("threadId", threadId);
+							request.getArguments().put("contextId", contextId);
+							request.getArguments().put("frameId", frameId);
+							request.getArguments().put("expression", "this");
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+							assertTrue(response.getBody().containsKey("evaluate"));
+						}
+						success[0] = Boolean.TRUE;
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(frameCheckHandler);
+
+		String script = "var line1 = true;\r\n";
+		script += "function test() { // line 2 \r\n";
+		script += " return \"line 3\";\r\n";
+		script += "} // line 4 \r\n";
+		script += "// line 5\r\n";
+		script += "var line6 = test();\r\n";
+		script += "var line7 = test();\r\n";
+		script += "// line 8\r\n";
+		script += "// line 9\r\n";
+		script += "var line10 = test();\r\n";
+		script += "// line 11\r\n";
+		script += "// line 12\r\n";
+		script += "function test2() { // line 13 \r\n";
+		script += " return \"line 14\";\r\n";
+		script += "} // line 15 \r\n";
+		script += "// line 16\r\n";
+		script += "// line 17\r\n";
+
+		Scriptable scope = null;
+		Context context = contextFactory.enterContext();
+		try {
+			scope = context.initStandardObjects();
+			context.evaluateString(scope, script, "script", 0, null);
+		} finally {
+			Context.exit();
+		}
+		waitForEvents(4);
+		assertEquals(Boolean.TRUE, success[0]);
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestFrameTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestFrameTest.java
new file mode 100644
index 0000000..bd95107
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestFrameTest.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.jsdt.debug.rhino.tests.TestEventHandler.Subhandler;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DebugSession;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.EventPacket;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+import org.osgi.framework.Constants;
+
+public class RequestFrameTest extends RequestTest {
+
+	public void testFramesAndFrameLookupAndEvaluate() throws DisconnectedException, TimeoutException {
+
+		Subhandler setbreakpointHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("script")) {
+					Object scriptId = event.getBody().get("scriptId");
+					Request request = new Request("script");
+					request.getArguments().put("scriptId", scriptId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Map result = (Map) response.getBody().get("script");
+						// functions
+						List functionNames = (List) result.get("functions");
+						for (Iterator iterator = functionNames.iterator(); iterator.hasNext();) {
+							String functionName = (String) iterator.next();
+							request = new Request("setbreakpoint");
+							request.getArguments().put("scriptId", scriptId);
+							request.getArguments().put("function", functionName);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						}
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(setbreakpointHandler);
+
+		final Object[] success = new Object[1];
+
+		Subhandler frameCheckHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("break")) {
+					Number threadId = (Number) event.getBody().get("threadId");
+					Number contextId = (Number) event.getBody().get("contextId");
+					Request request = new Request("frames");
+					request.getArguments().put("threadId", threadId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Collection frames = (Collection) response.getBody().get("frames");
+						for (Iterator iterator = frames.iterator(); iterator.hasNext();) {
+							Number frameId = (Number) iterator.next();
+							request = new Request("frame");
+							request.getArguments().put("threadId", threadId);
+							request.getArguments().put("contextId", contextId);
+							request.getArguments().put("frameId", frameId);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						}
+						success[0] = Boolean.TRUE;
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(frameCheckHandler);
+
+		Map headers = new HashMap();
+		headers.put(Constants.BUNDLE_SYMBOLICNAME, "test");
+		String script = "var line1 = true;\r\n";
+		script += "function test() { // line 2 \r\n";
+		script += " return \"line 3\";\r\n";
+		script += "} // line 4 \r\n";
+		script += "// line 5\r\n";
+		script += "var line6 = test();\r\n";
+		script += "var line7 = test();\r\n";
+		script += "// line 8\r\n";
+		script += "// line 9\r\n";
+		script += "var line10 = test();\r\n";
+		script += "// line 11\r\n";
+		script += "// line 12\r\n";
+		script += "function test2() { // line 13 \r\n";
+		script += " return \"line 14\";\r\n";
+		script += "} // line 15 \r\n";
+		script += "// line 16\r\n";
+		script += "// line 17\r\n";
+		Scriptable scope = null;
+		Context context = contextFactory.enterContext();
+		try {
+			scope = context.initStandardObjects();
+			context.evaluateString(scope, script, "script", 0, null);
+		} finally {
+			Context.exit();
+		}
+		waitForEvents(4);
+		assertEquals(Boolean.TRUE, success[0]);
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestFramesTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestFramesTest.java
new file mode 100644
index 0000000..d7c38a9
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestFramesTest.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.jsdt.debug.rhino.tests.TestEventHandler.Subhandler;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DebugSession;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.EventPacket;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+import org.osgi.framework.Constants;
+
+public class RequestFramesTest extends RequestTest {
+
+	public void testFramesAndFrameLookupAndEvaluate() throws DisconnectedException, TimeoutException {
+
+		Subhandler setbreakpointHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("script")) {
+					Object scriptId = event.getBody().get("scriptId");
+					Request request = new Request("script");
+					request.getArguments().put("scriptId", scriptId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Map result = (Map) response.getBody().get("script");
+						// functions
+						List functionNames = (List) result.get("functions");
+						for (Iterator iterator = functionNames.iterator(); iterator.hasNext();) {
+							String functionName = (String) iterator.next();
+							request = new Request("setbreakpoint");
+							request.getArguments().put("scriptId", scriptId);
+							request.getArguments().put("function", functionName);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						}
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(setbreakpointHandler);
+
+		final Object[] success = new Object[1];
+
+		Subhandler frameCheckHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("break")) {
+					Number threadId = (Number) event.getBody().get("threadId");
+					Number contextId = (Number) event.getBody().get("contextId");
+					Request request = new Request("frames");
+					request.getArguments().put("threadId", threadId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Collection frames = (Collection) response.getBody().get("frames");
+						for (Iterator iterator = frames.iterator(); iterator.hasNext();) {
+							Number frameId = (Number) iterator.next();
+							request = new Request("frame");
+							request.getArguments().put("threadId", threadId);
+							request.getArguments().put("contextId", contextId);
+							request.getArguments().put("frameId", frameId);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+
+							request = new Request("lookup");
+							request.getArguments().put("threadId", threadId);
+							request.getArguments().put("contextId", contextId);
+							request.getArguments().put("frameId", frameId);
+							request.getArguments().put("handle", new Integer(0));
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+							assertTrue(response.getBody().containsKey("lookup"));
+
+							request = new Request("evaluate");
+							request.getArguments().put("threadId", threadId);
+							request.getArguments().put("contextId", contextId);
+							request.getArguments().put("frameId", frameId);
+							request.getArguments().put("expression", "this");
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+							assertTrue(response.getBody().containsKey("evaluate"));
+						}
+						success[0] = Boolean.TRUE;
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(frameCheckHandler);
+
+		Map headers = new HashMap();
+		headers.put(Constants.BUNDLE_SYMBOLICNAME, "test");
+		String script = "var line1 = true;\r\n";
+		script += "function test() { // line 2 \r\n";
+		script += " return \"line 3\";\r\n";
+		script += "} // line 4 \r\n";
+		script += "// line 5\r\n";
+		script += "var line6 = test();\r\n";
+		script += "var line7 = test();\r\n";
+		script += "// line 8\r\n";
+		script += "// line 9\r\n";
+		script += "var line10 = test();\r\n";
+		script += "// line 11\r\n";
+		script += "// line 12\r\n";
+		script += "function test2() { // line 13 \r\n";
+		script += " return \"line 14\";\r\n";
+		script += "} // line 15 \r\n";
+		script += "// line 16\r\n";
+		script += "// line 17\r\n";
+
+		Scriptable scope = null;
+		Context context = contextFactory.enterContext();
+		try {
+			scope = context.initStandardObjects();
+			context.evaluateString(scope, script, "script", 0, null);
+		} finally {
+			Context.exit();
+		}
+		waitForEvents(4);
+		assertEquals(Boolean.TRUE, success[0]);
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestLookupTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestLookupTest.java
new file mode 100644
index 0000000..fe705cb
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestLookupTest.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.jsdt.debug.rhino.tests.TestEventHandler.Subhandler;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DebugSession;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.EventPacket;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+import org.osgi.framework.Constants;
+
+public class RequestLookupTest extends RequestTest {
+
+	public void testLookup() throws DisconnectedException, TimeoutException {
+
+		Subhandler setbreakpointHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("script")) {
+					Object scriptId = event.getBody().get("scriptId");
+					Request request = new Request("script");
+					request.getArguments().put("scriptId", scriptId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Map result = (Map) response.getBody().get("script");
+						// functions
+						List functionNames = (List) result.get("functions");
+						for (Iterator iterator = functionNames.iterator(); iterator.hasNext();) {
+							String functionName = (String) iterator.next();
+							request = new Request("setbreakpoint");
+							request.getArguments().put("scriptId", scriptId);
+							request.getArguments().put("function", functionName);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						}
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(setbreakpointHandler);
+
+		final Object[] success = new Object[1];
+
+		Subhandler frameCheckHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("break")) {
+					Number threadId = (Number) event.getBody().get("threadId");
+					Number contextId = (Number) event.getBody().get("contextId");
+					Request request = new Request("frames");
+					request.getArguments().put("threadId", threadId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Collection frames = (Collection) response.getBody().get("frames");
+						for (Iterator iterator = frames.iterator(); iterator.hasNext();) {
+							Number frameId = (Number) iterator.next();
+							request = new Request("lookup");
+							request.getArguments().put("threadId", threadId);
+							request.getArguments().put("contextId", contextId);
+							request.getArguments().put("frameId", frameId);
+							request.getArguments().put("handle", new Integer(0));
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+							assertTrue(response.getBody().containsKey("lookup"));
+						}
+						success[0] = Boolean.TRUE;
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(frameCheckHandler);
+
+		Map headers = new HashMap();
+		headers.put(Constants.BUNDLE_SYMBOLICNAME, "test");
+		String script = "var line1 = true;\r\n";
+		script += "function test() { // line 2 \r\n";
+		script += " return \"line 3\";\r\n";
+		script += "} // line 4 \r\n";
+		script += "// line 5\r\n";
+		script += "var line6 = test();\r\n";
+		script += "var line7 = test();\r\n";
+		script += "// line 8\r\n";
+		script += "// line 9\r\n";
+		script += "var line10 = test();\r\n";
+		script += "// line 11\r\n";
+		script += "// line 12\r\n";
+		script += "function test2() { // line 13 \r\n";
+		script += " return \"line 14\";\r\n";
+		script += "} // line 15 \r\n";
+		script += "// line 16\r\n";
+		script += "// line 17\r\n";
+
+		Scriptable scope = null;
+		Context context = contextFactory.enterContext();
+		try {
+			scope = context.initStandardObjects();
+			context.evaluateString(scope, script, "script", 0, null);
+		} finally {
+			Context.exit();
+		}
+		waitForEvents(4);
+		assertEquals(Boolean.TRUE, success[0]);
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestScriptTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestScriptTest.java
new file mode 100644
index 0000000..86b0ddc
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestScriptTest.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+import org.osgi.framework.Constants;
+
+public class RequestScriptTest extends RequestTest {
+
+	public void testScript() throws DisconnectedException, TimeoutException {
+
+		Map headers = new HashMap();
+		headers.put(Constants.BUNDLE_SYMBOLICNAME, "test");
+		String script = "var line1 = true;\r\n";
+		script += "function test() { // line 2 \r\n";
+		script += " return \"line 3\";\r\n";
+		script += "} // line 4 \r\n";
+		script += "// line 5\r\n";
+		script += "var line6 = test();\r\n";
+		script += "var line7 = test();\r\n";
+		script += "// line 8\r\n";
+		script += "// line 9\r\n";
+		script += "var line10 = test();\r\n";
+		script += "// line 11\r\n";
+		script += "// line 12\r\n";
+		script += "function test2() { // line 13 \r\n";
+		script += " return \"line 14\";\r\n";
+		script += "} // line 15 \r\n";
+		script += "// line 16\r\n";
+		script += "// line 17\r\n";
+
+		Scriptable scope = null;
+		Context context = contextFactory.enterContext();
+		try {
+			scope = context.initStandardObjects();
+			context.evaluateString(scope, script, "script", 0, null);
+		} finally {
+			Context.exit();
+		}
+
+		Request request = new Request("scripts");
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		List scripts = (List) response.getBody().get("scripts");
+		assertNotNull(scripts);
+		assertFalse(scripts.isEmpty());
+
+		request = new Request("script");
+		request.getArguments().put("scriptId", scripts.get(0));
+		debugSession.sendRequest(request);
+		response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		Map result = (Map) response.getBody().get("script");
+		assertEquals(script, result.get("source"));
+		List lineNumbers = (List) result.get("lines");
+		assertEquals(7, lineNumbers.size());
+		assertEquals(2, Util.numberAsInt(lineNumbers.get(0)));
+		assertEquals(3, Util.numberAsInt(lineNumbers.get(1)));
+		assertEquals(6, Util.numberAsInt(lineNumbers.get(2)));
+		assertEquals(7, Util.numberAsInt(lineNumbers.get(3)));
+		assertEquals(10, Util.numberAsInt(lineNumbers.get(4)));
+		assertEquals(13, Util.numberAsInt(lineNumbers.get(5)));
+		assertEquals(14, Util.numberAsInt(lineNumbers.get(6)));
+
+		List functionNames = (List) result.get("functions");
+		assertEquals(2, functionNames.size());
+		assertEquals("test", functionNames.get(0));
+		assertEquals("test2", functionNames.get(1));
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestScriptsTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestScriptsTest.java
new file mode 100644
index 0000000..055efbb
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestScriptsTest.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.util.Collection;
+
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+
+public class RequestScriptsTest extends RequestTest {
+
+	public void testScriptsWithNoScripts() throws DisconnectedException, TimeoutException {
+		Request request = new Request("scripts");
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		Collection scripts = (Collection) response.getBody().get("scripts");
+		assertNotNull(scripts);
+		assertTrue(scripts.isEmpty());
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestSetBreakpointTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestSetBreakpointTest.java
new file mode 100644
index 0000000..6c665f2
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestSetBreakpointTest.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.jsdt.debug.rhino.tests.TestEventHandler.Subhandler;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DebugSession;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.EventPacket;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+import org.osgi.framework.Constants;
+
+public class RequestSetBreakpointTest extends RequestTest {
+
+	public void testBreakpointsWithNoBreakpoints() throws DisconnectedException, TimeoutException {
+		Request request = new Request("breakpoints");
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		Collection breakpoints = (Collection) response.getBody().get("breakpoints");
+		assertNotNull(breakpoints);
+		assertTrue(breakpoints.isEmpty());
+	}
+
+	public void testGetSetClearBreakpoint() throws DisconnectedException, TimeoutException {
+
+		Subhandler setbreakpointHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("script")) {
+					Object scriptId = event.getBody().get("scriptId");
+					Request request = new Request("script");
+					request.getArguments().put("scriptId", scriptId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Map result = (Map) response.getBody().get("script");
+
+						// line numbers
+						List lineNumbers = (List) result.get("lines");
+						for (Iterator iterator = lineNumbers.iterator(); iterator.hasNext();) {
+							Number lineNumber = (Number) iterator.next();
+							request = new Request("setbreakpoint");
+							request.getArguments().put("scriptId", scriptId);
+							request.getArguments().put("line", lineNumber);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						}
+
+						// functions
+						List functionNames = (List) result.get("functions");
+						for (Iterator iterator = functionNames.iterator(); iterator.hasNext();) {
+							String functionName = (String) iterator.next();
+							request = new Request("setbreakpoint");
+							request.getArguments().put("scriptId", scriptId);
+							request.getArguments().put("function", functionName);
+							debugSession.sendRequest(request);
+							response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						}
+
+						// script onEnter
+						request = new Request("setbreakpoint");
+						request.getArguments().put("scriptId", scriptId);
+						debugSession.sendRequest(request);
+						response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(setbreakpointHandler);
+
+		Subhandler clearbreakpointHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("break")) {
+					List breakpoints = (List) event.getBody().get("breakpoints");
+					for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) {
+						Number breakpointId = (Number) iterator.next();
+						Request request = new Request("clearbreakpoint");
+						request.getArguments().put("breakpointId", breakpointId);
+						try {
+							debugSession.sendRequest(request);
+							Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+							assertTrue(response.isSuccess());
+						} catch (DisconnectedException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						} catch (TimeoutException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(clearbreakpointHandler);
+
+		Request request = new Request("breakpoints");
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		Collection breakpoints = (Collection) response.getBody().get("breakpoints");
+		assertNotNull(breakpoints);
+		assertTrue(breakpoints.isEmpty());
+
+		Map headers = new HashMap();
+		headers.put(Constants.BUNDLE_SYMBOLICNAME, "test");
+		String script = "var line1 = true;\r\n";
+		script += "function test() { // line 2 \r\n";
+		script += " return \"line 3\";\r\n";
+		script += "} // line 4 \r\n";
+		script += "// line 5\r\n";
+		script += "var line6 = test();\r\n";
+		script += "var line7 = test();\r\n";
+		script += "// line 8\r\n";
+		script += "// line 9\r\n";
+		script += "var line10 = test();\r\n";
+		script += "// line 11\r\n";
+		script += "// line 12\r\n";
+		script += "function test2() { // line 13 \r\n";
+		script += " return \"line 14\";\r\n";
+		script += "} // line 15 \r\n";
+		script += "// line 16\r\n";
+		script += "// line 17\r\n";
+
+		Scriptable scope = null;
+		Context context = contextFactory.enterContext();
+		try {
+			scope = context.initStandardObjects();
+			context.evaluateString(scope, script, "script", 0, null);
+		} finally {
+			Context.exit();
+		}
+		waitForEvents(7);
+		request = new Request("breakpoints");
+		debugSession.sendRequest(request);
+		response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		breakpoints = (Collection) response.getBody().get("breakpoints");
+		assertNotNull(breakpoints);
+		assertEquals(3, breakpoints.size());
+
+		for (Iterator iterator = breakpoints.iterator(); iterator.hasNext();) {
+			Number breakpointId = (Number) iterator.next();
+			request = new Request("breakpoint");
+			request.getArguments().put("breakpointId", breakpointId);
+			debugSession.sendRequest(request);
+			response = debugSession.receiveResponse(request.getSequence(), 10000);
+			assertTrue(response.isSuccess());
+			Map breakpoint = (Map) response.getBody().get("breakpoint");
+			assertEquals(breakpointId.intValue(), Util.numberAsInt(breakpoint.get("breakpointId")));
+			assertTrue(breakpoint.containsKey("scriptId"));
+		}
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestSuspendTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestSuspendTest.java
new file mode 100644
index 0000000..d30ef11
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestSuspendTest.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+
+public class RequestSuspendTest extends RequestTest {
+
+	public void testSuspendWithNoContexts() throws DisconnectedException, TimeoutException {
+		Request request = new Request("suspend");
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestTest.java
new file mode 100644
index 0000000..0f7c7ea
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestTest.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import junit.framework.TestCase;
+
+import org.eclipse.wst.jsdt.debug.rhino.debugger.RhinoDebugger;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DebugSession;
+import org.eclipse.wst.jsdt.debug.rhino.transport.PipedTransportService;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TransportService;
+import org.mozilla.javascript.ContextFactory;
+
+public class RequestTest extends TestCase {
+	protected RhinoDebugger debugger;
+	protected DebugSession debugSession;
+	protected TestEventHandler eventHandler;
+	protected ContextFactory contextFactory;
+
+	protected void setUp() throws Exception {
+		TransportService pipedTransport = new PipedTransportService();
+		ConnectionHelper helper = new ConnectionHelper(pipedTransport, null);
+
+		debugger = new RhinoDebugger(pipedTransport, null, false);
+		debugger.start();
+
+		debugSession = new DebugSession(helper.getClientConnection());
+		eventHandler = new TestEventHandler(debugSession);
+		eventHandler.start();
+
+		assertTrue(debugger.suspendForRuntime(5000));
+		contextFactory = new ContextFactory();
+		contextFactory.addListener(debugger);
+		super.setUp();
+	}
+
+	protected void tearDown() throws Exception {
+		super.tearDown();
+		contextFactory.removeListener(debugger);
+		eventHandler.stop();
+		debugger.stop();
+		debugSession.dispose();
+	}
+
+	synchronized void waitForEvents(int count) {
+		eventHandler.waitForEvents(count);
+	}
+
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestThreadTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestThreadTest.java
new file mode 100644
index 0000000..8820684
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestThreadTest.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.wst.jsdt.debug.rhino.tests.TestEventHandler.Subhandler;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DebugSession;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.EventPacket;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+import org.osgi.framework.Constants;
+
+public class RequestThreadTest extends RequestTest {
+
+	public void testInvalidThread() throws DisconnectedException, TimeoutException {
+		Request request = new Request("context");
+		request.getArguments().put("threadId", new Integer("9999"));
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertFalse(response.isSuccess());
+	}
+
+	public void testThread() throws DisconnectedException, TimeoutException {
+
+		Subhandler setbreakpointHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("script")) {
+					Object scriptId = event.getBody().get("scriptId");
+					Request request = new Request("script");
+					request.getArguments().put("scriptId", scriptId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						// script onEnter
+						request = new Request("setbreakpoint");
+						request.getArguments().put("scriptId", scriptId);
+						debugSession.sendRequest(request);
+						response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(setbreakpointHandler);
+
+		final Object[] success = new Object[1];
+
+		Subhandler contextCheckHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("break")) {
+					Number threadId = (Number) event.getBody().get("threadId");
+					Request request = new Request("thread");
+					request.getArguments().put("threadId", threadId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						Map thread = (Map) response.getBody().get("thread");
+						assertEquals(threadId.intValue(), Util.numberAsInt(thread.get("threadId")));
+						assertEquals("suspended", thread.get("state"));
+						success[0] = Boolean.TRUE;
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(contextCheckHandler);
+
+		Map headers = new HashMap();
+		headers.put(Constants.BUNDLE_SYMBOLICNAME, "test");
+		String script = "var line1 = true;\r\n";
+		script += "function test() { // line 2 \r\n";
+		script += " return \"line 3\";\r\n";
+		script += "} // line 4 \r\n";
+		script += "// line 5\r\n";
+		script += "var line6 = test();\r\n";
+		script += "var line7 = test();\r\n";
+		script += "// line 8\r\n";
+		script += "// line 9\r\n";
+		script += "var line10 = test();\r\n";
+		script += "// line 11\r\n";
+		script += "// line 12\r\n";
+		script += "function test2() { // line 13 \r\n";
+		script += " return \"line 14\";\r\n";
+		script += "} // line 15 \r\n";
+		script += "// line 16\r\n";
+		script += "// line 17\r\n";
+
+		Scriptable scope = null;
+		Context context = contextFactory.enterContext();
+		try {
+			scope = context.initStandardObjects();
+			context.evaluateString(scope, script, "script", 0, null);
+		} finally {
+			Context.exit();
+		}
+
+		// TODO: figure out this intermittent problem
+		// junit.framework.AssertionFailedError: expected:<suspended> but was:<running>
+		// at junit.framework.Assert.fail(Assert.java:47)
+		// at junit.framework.Assert.failNotEquals(Assert.java:280)
+		// at junit.framework.Assert.assertEquals(Assert.java:64)
+		// at junit.framework.Assert.assertEquals(Assert.java:71)
+		// at org.eclipse.e4.languages.javascript.debug.connect.test.RequestThreadTest$2.handleEvent(RequestThreadTest.java:74)
+		// at org.eclipse.e4.languages.javascript.debug.connect.test.TestEventHandler.handleEvent(TestEventHandler.java:117)
+		// at org.eclipse.e4.languages.javascript.debug.connect.test.TestEventHandler.run(TestEventHandler.java:93)
+		// at java.lang.Thread.run(Thread.java:619)
+
+		waitForEvents(2);
+		assertEquals(Boolean.TRUE, success[0]);
+
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestThreadsTest.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestThreadsTest.java
new file mode 100644
index 0000000..08adec4
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/RequestThreadsTest.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.jsdt.debug.rhino.tests.TestEventHandler.Subhandler;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DebugSession;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.EventPacket;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+import org.osgi.framework.Constants;
+
+public class RequestThreadsTest extends RequestTest {
+
+	public void testThreadsWithNoThreads() throws DisconnectedException, TimeoutException {
+		Request request = new Request("threads");
+		debugSession.sendRequest(request);
+		Response response = debugSession.receiveResponse(request.getSequence(), 30000);
+		assertTrue(response.isSuccess());
+		Collection threads = (Collection) response.getBody().get("threads");
+		assertNotNull(threads);
+		assertTrue(threads.isEmpty());
+	}
+
+	public void testThreads() throws DisconnectedException, TimeoutException {
+
+		Subhandler setbreakpointHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("script")) {
+					Object scriptId = event.getBody().get("scriptId");
+					Request request = new Request("script");
+					request.getArguments().put("scriptId", scriptId);
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						// script onEnter
+						request = new Request("setbreakpoint");
+						request.getArguments().put("scriptId", scriptId);
+						debugSession.sendRequest(request);
+						response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(setbreakpointHandler);
+
+		final Object[] success = new Object[1];
+
+		Subhandler contextCheckHandler = new Subhandler() {
+			public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+				if (event.getEvent().equals("break")) {
+					Number threadId = (Number) event.getBody().get("threadId");
+					Request request = new Request("threads");
+					try {
+						debugSession.sendRequest(request);
+						Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+						assertTrue(response.isSuccess());
+						List threads = (List) response.getBody().get("threads");
+						assertEquals(threadId.intValue(), Util.numberAsInt(threads.get(0)));
+						success[0] = Boolean.TRUE;
+					} catch (DisconnectedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (TimeoutException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+					return true;
+				}
+				return false;
+			}
+		};
+		eventHandler.addSubhandler(contextCheckHandler);
+
+		Map headers = new HashMap();
+		headers.put(Constants.BUNDLE_SYMBOLICNAME, "test");
+		String script = "var line1 = true;\r\n";
+		script += "function test() { // line 2 \r\n";
+		script += " return \"line 3\";\r\n";
+		script += "} // line 4 \r\n";
+		script += "// line 5\r\n";
+		script += "var line6 = test();\r\n";
+		script += "var line7 = test();\r\n";
+		script += "// line 8\r\n";
+		script += "// line 9\r\n";
+		script += "var line10 = test();\r\n";
+		script += "// line 11\r\n";
+		script += "// line 12\r\n";
+		script += "function test2() { // line 13 \r\n";
+		script += " return \"line 14\";\r\n";
+		script += "} // line 15 \r\n";
+		script += "// line 16\r\n";
+		script += "// line 17\r\n";
+
+		Scriptable scope = null;
+		Context context = contextFactory.enterContext();
+		try {
+			scope = context.initStandardObjects();
+			context.evaluateString(scope, script, "script", 0, null);
+		} finally {
+			Context.exit();
+		}
+		waitForEvents(2);
+		assertEquals(Boolean.TRUE, success[0]);
+
+	}
+}
diff --git a/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/TestEventHandler.java b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/TestEventHandler.java
new file mode 100644
index 0000000..177a8f9
--- /dev/null
+++ b/tests/org.eclipse.wst.jsdt.debug.rhino.tests/src/org/eclipse/wst/jsdt/debug/rhino/tests/TestEventHandler.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.debug.rhino.tests;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.wst.jsdt.debug.rhino.transport.DebugSession;
+import org.eclipse.wst.jsdt.debug.rhino.transport.DisconnectedException;
+import org.eclipse.wst.jsdt.debug.rhino.transport.EventPacket;
+import org.eclipse.wst.jsdt.debug.rhino.transport.JSONUtil;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Request;
+import org.eclipse.wst.jsdt.debug.rhino.transport.Response;
+import org.eclipse.wst.jsdt.debug.rhino.transport.TimeoutException;
+
+public class TestEventHandler implements Runnable {
+
+	public interface Subhandler {
+		boolean handleEvent(DebugSession debugSession, EventPacket event);
+	}
+
+	public static Subhandler debugScriptSubhandler = new Subhandler() {
+
+		public boolean handleEvent(DebugSession debugSession, EventPacket event) {
+			if (event.getEvent().equals("script")) {
+				Object scriptId = event.getBody().get("scriptId");
+				Request request = new Request("script");
+				request.getArguments().put("scriptId", scriptId);
+				try {
+					debugSession.sendRequest(request);
+					Response response = debugSession.receiveResponse(request.getSequence(), 10000);
+					System.out.println(JSONUtil.write(response.toJSON()));
+					String lines = (String) ((Map) response.getBody().get("script")).get("source");
+					BufferedReader reader = new BufferedReader(new StringReader(lines));
+					try {
+						int lineNumber = 1;
+						String line = reader.readLine();
+						while (line != null) {
+							System.out.println("[" + lineNumber++ + "]: " + line);
+							line = reader.readLine();
+						}
+					} catch (IOException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+				} catch (DisconnectedException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} catch (TimeoutException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+			return false;
+		}
+
+	};
+
+	private DebugSession debugSession;
+	private Thread thread;
+	private final ArrayList subhandlers = new ArrayList();
+	private volatile boolean shutdown = false;
+
+	private int eventCount = 0;
+
+	public TestEventHandler(DebugSession debugSession) {
+		this.debugSession = debugSession;
+		this.thread = new Thread(this, "TestEventHandler");
+	}
+
+	public void start() {
+		thread.start();
+	}
+
+	public void stop() {
+		shutdown = true;
+		thread.interrupt();
+		try {
+			thread.join();
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+
+	public void run() {
+		while (!shutdown) {
+			try {
+				EventPacket event = debugSession.receiveEvent(1000);
+				handleEvent(event);
+			} catch (TimeoutException e) {
+				// ignore
+			} catch (DisconnectedException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+
+	}
+
+	public synchronized void addSubhandler(Subhandler subhandler) {
+		subhandlers.add(subhandler);
+	}
+
+	public synchronized void removeSubhandler(Subhandler subhandler) {
+		subhandlers.remove(subhandler);
+	}
+
+	private synchronized void handleEvent(EventPacket event) {
+		// System.out.println(JSONUtil.write(event.toJSON()));
+		for (Iterator iterator = subhandlers.iterator(); iterator.hasNext();) {
+			Subhandler subhandler = (Subhandler) iterator.next();
+			try {
+				if (subhandler.handleEvent(debugSession, event)) {
+					eventCount++;
+					notifyAll();
+				}
+			} catch (Throwable t) {
+				t.printStackTrace();
+			}
+		}
+		if (!event.getEvent().equals("thread")) {
+			sendContinue(event, null);
+		}
+
+	}
+
+	protected void sendContinue(EventPacket event, String step) {
+		Number threadId = (Number) event.getBody().get("threadId");
+
+		Request request = new Request("continue");
+		request.getArguments().put("threadId", threadId);
+		request.getArguments().put("step", step);
+		try {
+			debugSession.sendRequest(request);
+			debugSession.receiveResponse(request.getSequence(), 1000);
+		} catch (DisconnectedException e) {
+			if (!shutdown)
+				e.printStackTrace();
+		} catch (TimeoutException e) {
+			if (!shutdown)
+				e.printStackTrace();
+		}
+	}
+
+	public synchronized void waitForEvents(int count) {
+		long timeout = System.currentTimeMillis() + 5000;
+		while (eventCount < count && System.currentTimeMillis() < timeout) {
+			try {
+				wait(1000);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		if (eventCount != count) {
+			throw new IllegalStateException("eventcount was: " + eventCount + " expected: " + count);
+		}
+	}
+
+	public int eventCount() {
+		return eventCount;
+	}
+}