You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2014/04/26 05:39:36 UTC

[15/27] fdb with worker support

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSession.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSession.java b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSession.java
new file mode 100644
index 0000000..4d25e5d
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSession.java
@@ -0,0 +1,435 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import flash.tools.debugger.Frame;
+import flash.tools.debugger.ILauncher;
+import flash.tools.debugger.Isolate;
+import flash.tools.debugger.IsolateSession;
+import flash.tools.debugger.Location;
+import flash.tools.debugger.NoResponseException;
+import flash.tools.debugger.NotConnectedException;
+import flash.tools.debugger.NotSupportedException;
+import flash.tools.debugger.NotSuspendedException;
+import flash.tools.debugger.PlayerDebugException;
+import flash.tools.debugger.Session;
+import flash.tools.debugger.SourceLocator;
+import flash.tools.debugger.SuspendedException;
+import flash.tools.debugger.SwfInfo;
+import flash.tools.debugger.Value;
+import flash.tools.debugger.Variable;
+import flash.tools.debugger.VersionException;
+import flash.tools.debugger.Watch;
+import flash.tools.debugger.events.DebugEvent;
+import flash.tools.debugger.expression.PlayerFaultException;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.Session
+ * @author Mike Morearty
+ */
+public class ThreadSafeSession extends ThreadSafeDebuggerObject implements Session {
+
+	private Session fSession;
+
+	private ThreadSafeSession(Object syncObj, Session session) {
+		super(syncObj);
+		fSession = session;
+	}
+
+	/**
+	 * Wraps a Session inside a ThreadSafeSession.  If the passed-in Session
+	 * is null, then this function returns null.
+	 */
+	public static ThreadSafeSession wrap(Object syncObj, Session session) {
+		if (session != null)
+			return new ThreadSafeSession(syncObj, session);
+		else
+			return null;
+	}
+
+	/**
+	 * Returns the raw Session underlying a ThreadSafeSession.
+	 */
+	public static Session getRaw(Session s) {
+		if (s instanceof ThreadSafeSession)
+			return ((ThreadSafeSession)s).fSession;
+		else
+			return s;
+	}
+
+	public static Object getSyncObject(Session s) {
+		return ((ThreadSafeSession)s).getSyncObject();
+	}
+
+	public boolean bind() throws VersionException {
+		synchronized (getSyncObject()) {
+			return fSession.bind();
+		}
+	}
+
+	public Location clearBreakpoint(Location location)
+			throws NoResponseException, NotConnectedException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeLocation.wrap(getSyncObject(), fSession.clearBreakpoint(ThreadSafeLocation.getRaw(location)));
+		}
+	}
+
+	public Watch clearWatch(Watch watch) throws NoResponseException,
+			NotConnectedException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeWatch.wrap(getSyncObject(), fSession.clearWatch(ThreadSafeWatch.getRaw(watch)));
+		}
+	}
+
+	public Location[] getBreakpointList() throws NoResponseException,
+			NotConnectedException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeLocation.wrapArray(getSyncObject(), fSession.getBreakpointList());
+		}
+	}
+
+	public int getEventCount() {
+		// Session.getEventCount() is guaranteed to be thread-safe, so we
+		// don't have to do a "synchronized" block around this call.
+		return fSession.getEventCount();
+	}
+
+	public Frame[] getFrames() throws NotConnectedException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeFrame.wrapArray(getSyncObject(), fSession.getFrames());
+		}
+	}
+
+	public Process getLaunchProcess() {
+		synchronized (getSyncObject()) {
+			return fSession.getLaunchProcess();
+		}
+	}
+
+	public int getPreference(String pref) throws NullPointerException {
+		synchronized (getSyncObject()) {
+			return fSession.getPreference(pref);
+		}
+	}
+
+	public SwfInfo[] getSwfs() throws NoResponseException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeSwfInfo.wrapArray(getSyncObject(), fSession.getSwfs());
+		}
+	}
+
+	public String getURI() {
+		synchronized (getSyncObject()) {
+			return fSession.getURI();
+		}
+	}
+
+	public Value getValue(long valueId) throws NotSuspendedException,
+			NoResponseException, NotConnectedException
+	{
+		synchronized (getSyncObject()) {
+			return ThreadSafeValue.wrap(getSyncObject(), fSession.getValue(valueId));
+		}
+	}
+
+	/** @deprecated */
+	public Variable[] getVariableList() throws NotSuspendedException,
+			NoResponseException, NotConnectedException, VersionException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeVariable.wrapArray(getSyncObject(), fSession.getVariableList());
+		}
+	}
+
+	public Watch[] getWatchList() throws NoResponseException,
+			NotConnectedException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeWatch.wrapArray(getSyncObject(), fSession.getWatchList());
+		}
+	}
+
+	public boolean isConnected() {
+		// Session.isConnected() is guaranteed to be thread-safe, so we
+		// don't have to do a "synchronized" block around this call.
+		return fSession.isConnected();
+	}
+
+	public boolean isSuspended() throws NotConnectedException {
+		// Session.isSuspended() is guaranteed to be thread-safe, so we
+		// don't have to do a "synchronized" block around this call.
+		return fSession.isSuspended();
+	}
+
+	public DebugEvent nextEvent() {
+		synchronized (getSyncObject()) {
+			return fSession.nextEvent();
+		}
+	}
+
+	public void resume() throws NotSuspendedException, NotConnectedException,
+			NoResponseException {
+		synchronized (getSyncObject()) {
+			fSession.resume();
+		}
+	}
+
+	public Location setBreakpoint(int fileId, int lineNum)
+			throws NoResponseException, NotConnectedException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeLocation.wrap(getSyncObject(), fSession.setBreakpoint(fileId, lineNum));
+		}
+	}
+
+	public void setPreference(String pref, int value) {
+		synchronized (getSyncObject()) {
+			fSession.setPreference(pref, value);
+		}
+	}
+
+	public Watch setWatch(Value v, String memberName, int kind)
+			throws NoResponseException, NotConnectedException, NotSupportedException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeWatch.wrap(getSyncObject(), fSession.setWatch(ThreadSafeValue.getRaw(v), memberName, kind));
+		}
+	}
+
+	public Watch setWatch(Watch watch) throws NoResponseException,
+			NotConnectedException, NotSupportedException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeWatch.wrap(getSyncObject(), fSession.setWatch(ThreadSafeWatch.getRaw(watch)));
+		}
+	}
+
+	public void stepContinue() throws NotSuspendedException,
+			NoResponseException, NotConnectedException {
+		synchronized (getSyncObject()) {
+			fSession.stepContinue();
+		}
+	}
+
+	public void stepInto() throws NotSuspendedException, NoResponseException,
+			NotConnectedException {
+		synchronized (getSyncObject()) {
+			fSession.stepInto();
+		}
+	}
+
+	public void stepOut() throws NotSuspendedException, NoResponseException,
+			NotConnectedException {
+		synchronized (getSyncObject()) {
+			fSession.stepOut();
+		}
+	}
+
+	public void stepOver() throws NotSuspendedException, NoResponseException,
+			NotConnectedException {
+		synchronized (getSyncObject()) {
+			fSession.stepOver();
+		}
+	}
+
+	public void suspend() throws SuspendedException, NotConnectedException,
+			NoResponseException {
+		synchronized (getSyncObject()) {
+			fSession.suspend();
+		}
+	}
+
+	public int suspendReason() throws NotConnectedException {
+		synchronized (getSyncObject()) {
+			return fSession.suspendReason();
+		}
+	}
+
+	public void terminate() {
+		synchronized (getSyncObject()) {
+			fSession.terminate();
+		}
+	}
+
+	public void unbind() {
+		synchronized (getSyncObject()) {
+			fSession.unbind();
+		}
+	}
+
+	public void waitForEvent() throws NotConnectedException, InterruptedException {
+		synchronized (getSyncObject()) {
+			fSession.waitForEvent();
+		}
+	}
+
+	public SourceLocator getSourceLocator()
+	{
+		synchronized (getSyncObject()) {
+			return ThreadSafeSourceLocator.wrap(getSyncObject(), fSession.getSourceLocator());
+		}
+	}
+
+	public void setSourceLocator(SourceLocator sourceLocator)
+	{
+		synchronized (getSyncObject()) {
+			fSession.setSourceLocator(sourceLocator);
+		}
+	}
+
+	public Value callConstructor(String classname, Value[] args)
+			throws PlayerDebugException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeValue.wrap(getSyncObject(), fSession.callConstructor(classname, args));
+		}
+	}
+
+	public Value callFunction(Value thisObject, String functionName, Value[] args)
+			throws PlayerDebugException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeValue.wrap(getSyncObject(), fSession.callFunction(thisObject, functionName, args));
+		}
+	}
+
+	public Value getGlobal(String name) throws NotSuspendedException, NoResponseException, NotConnectedException
+	{
+		synchronized (getSyncObject())
+		{
+			return ThreadSafeValue.wrap(getSyncObject(), fSession.getGlobal(name));
+		}
+	}
+
+	public void breakOnCaughtExceptions(boolean b) throws NotSupportedException, NoResponseException {
+		synchronized (getSyncObject())	{
+			fSession.breakOnCaughtExceptions(b);
+		}
+	}
+
+	public boolean evalIs(Value value, Value type) throws PlayerDebugException, PlayerFaultException {
+		synchronized (getSyncObject()) {
+			return fSession.evalIs(value, type);
+		}
+	}
+
+	public boolean evalIs(Value value, String type) throws PlayerDebugException, PlayerFaultException {
+		synchronized (getSyncObject()) {
+			return fSession.evalIs(value, type);
+		}
+	}
+
+	public boolean evalInstanceof(Value value, Value type) throws PlayerDebugException, PlayerFaultException {
+		synchronized (getSyncObject()) {
+			return fSession.evalInstanceof(value, type);
+		}
+	}
+
+	public boolean evalInstanceof(Value value, String type) throws PlayerDebugException, PlayerFaultException {
+		synchronized (getSyncObject()) {
+			return fSession.evalInstanceof(value, type);
+		}
+	}
+
+	public boolean evalIn(Value property, Value object) throws PlayerDebugException, PlayerFaultException {
+		synchronized (getSyncObject()) {
+			return fSession.evalIn(property, object);
+		}
+	}
+
+	public Value evalAs(Value value, Value type) throws PlayerDebugException, PlayerFaultException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeValue.wrap(getSyncObject(), fSession.evalAs(value, type));
+		}
+	}
+
+	public boolean supportsWatchpoints() {
+		synchronized (getSyncObject()) {
+			return fSession.supportsWatchpoints();
+		}
+	}
+	
+	public boolean supportsConcurrency() {
+		synchronized (getSyncObject()) {
+			return fSession.supportsConcurrency();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see flash.tools.debugger.Session#getDisconnectCause()
+	 */
+	public Exception getDisconnectCause() {
+		synchronized (getSyncObject()) {
+			return fSession.getDisconnectCause();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see flash.tools.debugger.Session#refreshWorkers()
+	 */
+	@Override
+	public Isolate[] refreshWorkers() throws NotSupportedException,
+			NotSuspendedException, NoResponseException, NotConnectedException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeIsolate.wrapArray(getSyncObject(), fSession.getWorkers());
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see flash.tools.debugger.Session#getWorkers()
+	 */
+	@Override
+	public Isolate[] getWorkers() {
+		synchronized (getSyncObject()) {
+			return fSession.getWorkers();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see flash.tools.debugger.Session#getWorkerSession(int)
+	 */
+	@Override
+	public IsolateSession getWorkerSession(int isolateId) {
+		synchronized (getSyncObject()) {
+			return ThreadSafeIsolateSession.wrap(getSyncObject(), fSession.getWorkerSession(isolateId));
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see flash.tools.debugger.Session#setExceptionBreakpoint(String)
+	 */
+	@Override
+	public boolean setExceptionBreakpoint(String exceptionClass)
+			throws NoResponseException, NotConnectedException {
+		synchronized (getSyncObject()) {
+			return fSession.setExceptionBreakpoint(exceptionClass);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see flash.tools.debugger.Session#clearExceptionBreakpoint(String)
+	 */
+	@Override
+	public boolean clearExceptionBreakpoint(String exceptionClass)
+			throws NoResponseException, NotConnectedException {
+		synchronized (getSyncObject()) {
+			return fSession.clearExceptionBreakpoint(exceptionClass);
+		}
+	}
+
+	@Override
+	public void setLauncher(ILauncher launcher) {
+		synchronized (getSyncObject()) {
+			fSession.setLauncher(launcher);
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSessionManager.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSessionManager.java b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSessionManager.java
new file mode 100644
index 0000000..66145fb
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSessionManager.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import java.io.IOException;
+
+import flash.tools.debugger.AIRLaunchInfo;
+import flash.tools.debugger.IDebuggerCallbacks;
+import flash.tools.debugger.ILaunchNotification;
+import flash.tools.debugger.ILauncher;
+import flash.tools.debugger.IProgress;
+import flash.tools.debugger.Player;
+import flash.tools.debugger.Session;
+import flash.tools.debugger.SessionManager;
+import flash.tools.debugger.SessionManager2;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.SessionManager
+ * @author Mike Morearty
+ */
+public class ThreadSafeSessionManager extends ThreadSafeDebuggerObject implements SessionManager2 {
+
+	private SessionManager fSessionManager;
+	
+	private ThreadSafeSessionManager(SessionManager sessionManager) {
+		super(new Object());
+		fSessionManager = sessionManager;
+	}
+
+	/**
+	 * Wraps a SessionManager inside a ThreadSafeSessionManager.  If the passed-in SessionManager
+	 * is null, then this function returns null.
+	 */
+	public static ThreadSafeSessionManager wrap(SessionManager sessionManager) {
+		if (sessionManager != null)
+			return new ThreadSafeSessionManager(sessionManager);
+		else
+			return null;
+	}
+
+	public static Object getSyncObject(SessionManager sm) {
+		return ((ThreadSafeSessionManager)sm).getSyncObject();
+	}
+
+	public Session accept(IProgress waitReporter) throws IOException {
+		// WARNING: This function is not thread-safe.
+		//
+		// accept() can take a very long time -- e.g. if there is something wrong,
+		// then it might hang for two minutes while waiting for the Flash player.
+		// So, it is not acceptable to put this in a "synchronized" block.
+		return ThreadSafeSession.wrap(getSyncObject(), fSessionManager.accept(waitReporter));
+	}
+
+	public int getPreference(String pref) throws NullPointerException {
+		synchronized (getSyncObject()) {
+			return fSessionManager.getPreference(pref);
+		}
+	}
+
+	public boolean isListening() {
+		synchronized (getSyncObject()) {
+			return fSessionManager.isListening();
+		}
+	}
+
+	public Session launch(String uri, AIRLaunchInfo airLaunchInfo, boolean forDebugging, IProgress waitReporter, ILaunchNotification launchNotification) throws IOException {
+		// WARNING: This function is not thread-safe.
+		//
+		// launch() can take a very long time -- e.g. if there is something wrong,
+		// then it might hang for two minutes while waiting for the Flash player.
+		// So, it is not acceptable to put this in a "synchronized" block.
+		return ThreadSafeSession.wrap(getSyncObject(), fSessionManager.launch(uri, airLaunchInfo, forDebugging, waitReporter,launchNotification));
+	}
+
+	public Player playerForUri(String uri, AIRLaunchInfo airLaunchInfo) {
+		synchronized (getSyncObject()) {
+			return ThreadSafePlayer.wrap(getSyncObject(), fSessionManager.playerForUri(uri, airLaunchInfo));
+		}
+	}
+
+	public boolean supportsLaunch()
+	{
+		synchronized (getSyncObject()) {
+			return fSessionManager.supportsLaunch();
+		}
+	}
+
+	public void setPreference(String pref, int value) {
+		synchronized (getSyncObject()) {
+			fSessionManager.setPreference(pref, value);
+		}
+	}
+
+	public void setPreference(String pref, String value) {
+		synchronized (getSyncObject()) {
+			fSessionManager.setPreference(pref, value);
+		}
+	}
+
+	public void startListening() throws IOException {
+		synchronized (getSyncObject()) {
+			fSessionManager.startListening();
+		}
+	}
+
+	public void stopListening() throws IOException {
+		synchronized (getSyncObject()) {
+			fSessionManager.stopListening();
+		}
+	}
+
+	public void setDebuggerCallbacks(IDebuggerCallbacks debuggerCallbacks) {
+		synchronized (getSyncObject()) {
+			fSessionManager.setDebuggerCallbacks(debuggerCallbacks);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see flash.tools.debugger.SessionManager#connect(int, flash.tools.debugger.IProgress)
+	 */
+	public Session connect(int port, IProgress waitReporter) throws IOException {
+		// WARNING: This function is not thread-safe.
+		//
+		// connect() can take a very long time -- e.g. if there is something wrong,
+		// then it might hang for two minutes while waiting for the Flash player.
+		// So, it is not acceptable to put this in a "synchronized" block.
+		return ThreadSafeSession.wrap(getSyncObject(), fSessionManager.connect(port, waitReporter));		
+	}
+	
+	public void stopConnecting() throws IOException {
+		synchronized (getSyncObject()) {
+			fSessionManager.stopConnecting();
+		}
+	}
+	
+	public boolean isConnecting() {
+		synchronized (getSyncObject()) {
+			return fSessionManager.isConnecting();
+		}
+	}
+
+	@Override
+	public Process launchForRun(String uri, AIRLaunchInfo airLaunchInfo,
+			IProgress waitReporter, ILaunchNotification launchNotification)
+			throws IOException {
+		/*
+		 * launch used to return null when the session was null.
+		 * The session will be null in this case because this is invoked for run launches.
+		 * We just return the process to be consistent with PlayerSessionManager. 
+		 */
+		assert fSessionManager instanceof SessionManager2;
+		
+		Process process = ((SessionManager2) fSessionManager).launchForRun(uri, airLaunchInfo, waitReporter, launchNotification);
+			
+		return process;	
+	}
+
+	@Override
+	public Process launchForRun(String uri, AIRLaunchInfo airLaunchInfo,
+			IProgress waitReporter, ILaunchNotification launchNotification,
+			ILauncher launcher) throws IOException {
+		/*
+		 * launch used to return null when the session was null.
+		 * The session will be null in this case because this is invoked for run launches.
+		 * We just return the process to be consistent with PlayerSessionManager. 
+		 */
+		assert fSessionManager instanceof SessionManager2;
+		
+		Process process = ((SessionManager2) fSessionManager).launchForRun(uri, airLaunchInfo, waitReporter, launchNotification,launcher);
+			
+		return process;	
+	}
+
+	@Override
+	public Session launch(String uri, AIRLaunchInfo airLaunchInfo,
+			boolean forDebugging, IProgress waitReporter,
+			ILaunchNotification launchNotification, ILauncher launcher)
+			throws IOException {
+		// WARNING: This function is not thread-safe.
+				//
+				// launch() can take a very long time -- e.g. if there is something wrong,
+				// then it might hang for two minutes while waiting for the Flash player.
+				// So, it is not acceptable to put this in a "synchronized" block.
+				assert fSessionManager instanceof SessionManager2;
+				
+				return ThreadSafeSession.wrap(getSyncObject(), ((SessionManager2) fSessionManager).launch(uri, airLaunchInfo, forDebugging, waitReporter,launchNotification,launcher));
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSourceFile.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSourceFile.java b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSourceFile.java
new file mode 100644
index 0000000..7a1b680
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSourceFile.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import flash.tools.debugger.Session;
+import flash.tools.debugger.SourceFile;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.SourceFile
+ * @author Mike Morearty
+ */
+public class ThreadSafeSourceFile extends ThreadSafeDebuggerObject implements SourceFile {
+	
+	private SourceFile fSourceFile;
+	
+	private ThreadSafeSourceFile(Object syncObj, SourceFile sourceFile) {
+		super(syncObj);
+		fSourceFile = sourceFile;
+	}
+
+	/**
+	 * Wraps a SourceFile inside a ThreadSafeSourceFile.  If the passed-in SourceFile
+	 * is null, then this function returns null.
+	 */
+	public static ThreadSafeSourceFile wrap(Object syncObj, SourceFile sourceFile) {
+		if (sourceFile != null)
+			return new ThreadSafeSourceFile(syncObj, sourceFile);
+		else
+			return null;
+	}
+
+	/**
+	 * Wraps an array of SourceFiles inside an array of ThreadSafeSourceFiles.
+	 */
+	public static ThreadSafeSourceFile[] wrapArray(Object syncObj, SourceFile[] sourceFiles) {
+		ThreadSafeSourceFile[] threadSafeSourceFiles = new ThreadSafeSourceFile[sourceFiles.length];
+		for (int i=0; i<sourceFiles.length; ++i) {
+			threadSafeSourceFiles[i] = wrap(syncObj, sourceFiles[i]);
+		}
+		return threadSafeSourceFiles;
+	}
+
+	/**
+	 * Returns the raw SourceFile underlying a ThreadSafeSourceFile.
+	 */
+	public static SourceFile getRaw(SourceFile f) {
+		if (f instanceof ThreadSafeSourceFile)
+			return ((ThreadSafeSourceFile)f).fSourceFile;
+		else
+			return f;
+	}
+
+	public static Object getSyncObject(SourceFile sf) {
+		return ((ThreadSafeSourceFile)sf).getSyncObject();
+	}
+
+	public String getRawName() {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getRawName();
+		}
+	}
+
+	public String getFunctionNameForLine(Session session, int lineNum) {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getFunctionNameForLine(session, lineNum);
+		}
+	}
+
+	public String[] getFunctionNames(Session session) {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getFunctionNames(session);
+		}
+	}
+
+	public int getId() {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getId();
+		}
+	}
+
+	public String getLine(int lineNum) {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getLine(lineNum);
+		}
+	}
+
+	public int getLineCount() {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getLineCount();
+		}
+	}
+
+	public int getLineForFunctionName(Session session, String name) {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getLineForFunctionName(session, name);
+		}
+	}
+
+	public String getName() {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getName();
+		}
+	}
+
+	public int getOffsetForLine(int lineNum) {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getOffsetForLine(lineNum);
+		}
+	}
+
+	public String getPackageName() {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getPackageName();
+		}
+	}
+
+	public String getFullPath() {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getFullPath();
+		}
+	}
+
+	public String getBasePath() {
+		synchronized (getSyncObject()) {
+			return fSourceFile.getBasePath();
+		}
+	}
+
+	@Override
+	public String toString() {
+		synchronized (getSyncObject()) {
+			return fSourceFile.toString();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSourceLocator.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSourceLocator.java b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSourceLocator.java
new file mode 100644
index 0000000..a4d6c21
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSourceLocator.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import java.io.InputStream;
+
+import flash.tools.debugger.SourceLocator;
+
+/**
+ * @author Mike Morearty
+ */
+public class ThreadSafeSourceLocator extends ThreadSafeDebuggerObject implements SourceLocator
+{
+	private SourceLocator fSourceLocator;
+	
+	/**
+	 * @param syncObj
+	 */
+	public ThreadSafeSourceLocator(Object syncObj, SourceLocator sourceLocator)
+	{
+		super(syncObj);
+		fSourceLocator = sourceLocator;
+	}
+
+	/**
+	 * Wraps a SourceLocator inside a ThreadSafeSourceLocator.  If the passed-in SourceLocator
+	 * is null, then this function returns null.
+	 */
+	public static ThreadSafeSourceLocator wrap(Object syncObj, SourceLocator sourceLocator) {
+		if (sourceLocator != null)
+			return new ThreadSafeSourceLocator(syncObj, sourceLocator);
+		else
+			return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see flash.tools.debugger.SourceLocator#locateSource(java.lang.String, java.lang.String, java.lang.String)
+	 */
+	public InputStream locateSource(String arg0, String arg1, String arg2)
+	{
+		synchronized (getSyncObject()) {
+			return fSourceLocator.locateSource(arg0, arg1, arg2);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see flash.tools.debugger.SourceLocator#getChangeCount()
+	 */
+	public int getChangeCount()
+	{
+		synchronized (getSyncObject()) {
+			return fSourceLocator.getChangeCount();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSwfInfo.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSwfInfo.java b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSwfInfo.java
new file mode 100644
index 0000000..a3d698c
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeSwfInfo.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import flash.tools.debugger.InProgressException;
+import flash.tools.debugger.Session;
+import flash.tools.debugger.SourceFile;
+import flash.tools.debugger.SwfInfo;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.SwfInfo
+ * @author Mike Morearty
+ */
+public class ThreadSafeSwfInfo extends ThreadSafeDebuggerObject implements SwfInfo {
+	
+	private SwfInfo fSwfInfo;
+	
+	private ThreadSafeSwfInfo(Object syncObj, SwfInfo swfInfo) {
+		super(syncObj);
+		fSwfInfo = swfInfo;
+	}
+
+	/**
+	 * Wraps a SwfInfo inside a ThreadSafeSwfInfo.  If the passed-in SwfInfo
+	 * is null, then this function returns null.
+	 */
+	public static ThreadSafeSwfInfo wrap(Object syncObj, SwfInfo swfInfo) {
+		if (swfInfo != null)
+			return new ThreadSafeSwfInfo(syncObj, swfInfo);
+		else
+			return null;
+	}
+
+	/**
+	 * Wraps an array of SwfInfos inside an array of ThreadSafeSwfInfos.
+	 */
+	public static ThreadSafeSwfInfo[] wrapArray(Object syncObj, SwfInfo[] swfinfos) {
+		ThreadSafeSwfInfo[] threadSafeSwfInfos = new ThreadSafeSwfInfo[swfinfos.length];
+		for (int i=0; i<swfinfos.length; ++i) {
+			threadSafeSwfInfos[i] = wrap(syncObj, swfinfos[i]);
+		}
+		return threadSafeSwfInfos;
+	}
+
+	public static Object getSyncObject(SwfInfo swfInfo) {
+		return ((ThreadSafeSwfInfo)swfInfo).getSyncObject();
+	}
+
+	public boolean containsSource(SourceFile f) {
+		synchronized (getSyncObject()) {
+			return fSwfInfo.containsSource(ThreadSafeSourceFile.getRaw(f));
+		}
+	}
+
+	public String getPath() {
+		synchronized (getSyncObject()) {
+			return fSwfInfo.getPath();
+		}
+	}
+
+	public int getSourceCount(Session s) throws InProgressException {
+		synchronized (getSyncObject()) {
+			return fSwfInfo.getSourceCount(ThreadSafeSession.getRaw(s));
+		}
+	}
+
+	public SourceFile[] getSourceList(Session s) throws InProgressException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeSourceFile.wrapArray(getSyncObject(), fSwfInfo.getSourceList(ThreadSafeSession.getRaw(s)));
+		}
+	}
+
+	public int getSwdSize(Session s) throws InProgressException {
+		synchronized (getSyncObject()) {
+			return fSwfInfo.getSwdSize(ThreadSafeSession.getRaw(s));
+		}
+	}
+
+	public int getSwfSize() {
+		synchronized (getSyncObject()) {
+			return fSwfInfo.getSwfSize();
+		}
+	}
+
+	public String getUrl() {
+		synchronized (getSyncObject()) {
+			return fSwfInfo.getUrl();
+		}
+	}
+
+	public boolean isProcessingComplete() {
+		synchronized (getSyncObject()) {
+			return fSwfInfo.isProcessingComplete();
+		}
+	}
+
+	public boolean isUnloaded() {
+		synchronized (getSyncObject()) {
+			return fSwfInfo.isUnloaded();
+		}
+	}
+
+	@Override
+	public int getIsolateId() {
+		synchronized (getSyncObject()) {
+			return fSwfInfo.getIsolateId();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeValue.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeValue.java b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeValue.java
new file mode 100644
index 0000000..f78414d
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeValue.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import flash.tools.debugger.NoResponseException;
+import flash.tools.debugger.NotConnectedException;
+import flash.tools.debugger.NotSuspendedException;
+import flash.tools.debugger.Session;
+import flash.tools.debugger.Value;
+import flash.tools.debugger.Variable;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.Value
+ * @author Mike Morearty
+ */
+public class ThreadSafeValue extends ThreadSafeDebuggerObject implements Value {
+
+	private Value fVal;
+
+	private ThreadSafeValue(Object syncObj, Value val) {
+		super(syncObj);
+		fVal = val;
+	}
+
+	/**
+	 * Wraps a Value inside a ThreadSafeValue.  If the passed-in Value
+	 * is null, then this function returns null.
+	 */
+	public static ThreadSafeValue wrap(Object syncObj, Value val) {
+		if (val != null)
+			return new ThreadSafeValue(syncObj, val);
+		else
+			return null;
+	}
+
+	/**
+	 * Wraps an array of Values inside an array of ThreadSafeValues.
+	 */
+	public static ThreadSafeValue[] wrapArray(Object syncObj, Value[] values) {
+		ThreadSafeValue[] threadSafeValues = new ThreadSafeValue[values.length];
+		for (int i=0; i<values.length; ++i) {
+			threadSafeValues[i] = wrap(syncObj, values[i]);
+		}
+		return threadSafeValues;
+	}
+
+	/**
+	 * Returns the raw Value underlying a ThreadSafeValue.
+	 */
+	public static Value getRaw(Value v) {
+		if (v instanceof ThreadSafeValue)
+			return ((ThreadSafeValue)v).fVal;
+		else
+			return v;
+	}
+
+	public static Object getSyncObject(Value v) {
+		return ((ThreadSafeValue)v).getSyncObject();
+	}
+	
+	@Override
+	public boolean equals(Object other) {
+		if (other instanceof Value)
+			return fVal.equals(getRaw((Value)other));
+		else
+			return false;
+	}
+
+	public int getAttributes() {
+		synchronized (getSyncObject()) { return fVal.getAttributes(); }
+	}
+
+	public String getClassName() {
+		synchronized (getSyncObject()) { return fVal.getClassName(); }
+	}
+
+	public long getId() {
+		synchronized (getSyncObject()) { return fVal.getId(); }
+	}
+
+	public int getMemberCount(Session s) throws NotSuspendedException, NoResponseException, NotConnectedException {
+		synchronized (getSyncObject()) { return fVal.getMemberCount(ThreadSafeSession.getRaw(s)); }
+	}
+
+	public Variable getMemberNamed(Session s, String name) throws NotSuspendedException, NoResponseException, NotConnectedException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeVariable.wrap(getSyncObject(), fVal.getMemberNamed(ThreadSafeSession.getRaw(s), name));
+		}
+	}
+
+	public Variable[] getMembers(Session s) throws NotSuspendedException, NoResponseException, NotConnectedException {
+		synchronized (getSyncObject()) {
+			return ThreadSafeVariable.wrapArray(getSyncObject(), fVal.getMembers(ThreadSafeSession.getRaw(s)));
+		}
+	}
+
+	public int getType() {
+		synchronized (getSyncObject()) { return fVal.getType(); }
+	}
+
+	public String getTypeName() {
+		synchronized (getSyncObject()) { return fVal.getTypeName(); }
+	}
+
+	public Object getValueAsObject() {
+		synchronized (getSyncObject()) { return fVal.getValueAsObject(); }
+	}
+
+	public String getValueAsString() {
+		synchronized (getSyncObject()) { return fVal.getValueAsString(); }
+	}
+
+	public boolean isAttributeSet(int variableAttribute) {
+		synchronized (getSyncObject()) { return fVal.isAttributeSet(variableAttribute); }
+	}
+
+	public String[] getClassHierarchy(boolean allLevels) {
+		synchronized (getSyncObject()) { return fVal.getClassHierarchy(allLevels); }
+	}
+
+	@Override
+	public String toString() {
+		synchronized (getSyncObject()) { return fVal.toString(); }
+	}
+
+	public Variable[] getPrivateInheritedMembers() {
+		synchronized (getSyncObject()) {
+			return ThreadSafeVariable.wrapArray(getSyncObject(), fVal.getPrivateInheritedMembers());
+		}
+	}
+
+	public Variable[] getPrivateInheritedMemberNamed(String name) {
+		synchronized (getSyncObject()) {
+			return ThreadSafeVariable.wrapArray(getSyncObject(), fVal.getPrivateInheritedMemberNamed(name));
+		}
+	}
+
+	@Override
+	public int getIsolateId() {
+		synchronized (getSyncObject()) {
+			return fVal.getIsolateId();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeValueExp.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeValueExp.java b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeValueExp.java
new file mode 100644
index 0000000..1b5b75c
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeValueExp.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import flash.tools.debugger.PlayerDebugException;
+import flash.tools.debugger.expression.Context;
+import flash.tools.debugger.expression.NoSuchVariableException;
+import flash.tools.debugger.expression.PlayerFaultException;
+import flash.tools.debugger.expression.ValueExp;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.expression.ValueExp
+ * @author Mike Morearty
+ */
+public class ThreadSafeValueExp extends ThreadSafeDebuggerObject implements ValueExp
+{
+	private final ValueExp m_valueExp;
+
+	public ThreadSafeValueExp(Object syncObj, ValueExp valueExp)
+	{
+		super(syncObj);
+		m_valueExp = valueExp;
+	}
+
+	/**
+	 * Wraps a ValueExp inside a ThreadSafeValueExp. If the passed-in
+	 * ValueExp is null, then this function returns null.
+	 */
+	public static ThreadSafeValueExp wrap(Object syncObj, ValueExp valueExp) {
+		if (valueExp != null)
+			return new ThreadSafeValueExp(syncObj, valueExp);
+		else
+			return null;
+	}
+
+	public Object evaluate(Context context) throws NumberFormatException, NoSuchVariableException, PlayerFaultException, PlayerDebugException
+	{
+		synchronized (getSyncObject()) {
+			return m_valueExp.evaluate(context);
+		}
+	}
+
+	public boolean containsAssignment()
+	{
+		synchronized (getSyncObject()) {
+			return m_valueExp.containsAssignment();
+		}
+	}
+
+	public boolean isLookupMembers()
+	{
+		synchronized (getSyncObject()) {
+			return m_valueExp.isLookupMembers();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeVariable.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeVariable.java b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeVariable.java
new file mode 100644
index 0000000..126a224
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeVariable.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import flash.tools.debugger.NoResponseException;
+import flash.tools.debugger.NotConnectedException;
+import flash.tools.debugger.NotSuspendedException;
+import flash.tools.debugger.Session;
+import flash.tools.debugger.Value;
+import flash.tools.debugger.Variable;
+import flash.tools.debugger.events.FaultEvent;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.Variable
+ * @author Mike Morearty
+ */
+public class ThreadSafeVariable extends ThreadSafeDebuggerObject implements Variable {
+
+	private Variable fVar;
+
+	private ThreadSafeVariable(Object syncObj, Variable var) {
+		super(syncObj);
+		fVar = var;
+	}
+
+	/**
+	 * Wraps a Variable inside a ThreadSafeVariable.  If the passed-in Variable
+	 * is null, then this function returns null.
+	 */
+	public static ThreadSafeVariable wrap(Object syncObj, Variable variable) {
+		if (variable != null)
+			return new ThreadSafeVariable(syncObj, variable);
+		else
+			return null;
+	}
+
+	/**
+	 * Wraps an array of Variables inside an array of ThreadSafeVariables.
+	 */
+	public static ThreadSafeVariable[] wrapArray(Object syncObj, Variable[] variables) {
+		ThreadSafeVariable[] threadSafeVariables = new ThreadSafeVariable[variables.length];
+		for (int i=0; i<variables.length; ++i) {
+			threadSafeVariables[i] = wrap(syncObj, variables[i]);
+		}
+		return threadSafeVariables;
+	}
+
+	/**
+	 * Returns the raw Variable underlying a ThreadSafeVariable.
+	 */
+	public static Variable getRaw(Variable v) {
+		if (v instanceof ThreadSafeVariable)
+			return ((ThreadSafeVariable)v).fVar;
+		else
+			return v;
+	}
+
+	public static Object getSyncObject(Variable v) {
+		return ((ThreadSafeVariable)v).getSyncObject();
+	}
+
+	public String getName() {
+		synchronized (getSyncObject()) { return fVar.getName(); }
+	}
+
+	public int getAttributes() {
+		synchronized (getSyncObject()) { return fVar.getAttributes(); }
+	}
+
+	public boolean isAttributeSet(int variableAttribute) {
+		synchronized (getSyncObject()) { return fVar.isAttributeSet(variableAttribute); }
+	}
+
+	public Value getValue() {
+		synchronized (getSyncObject()) {
+			return ThreadSafeValue.wrap(getSyncObject(), fVar.getValue());
+		}
+	}
+
+	public boolean hasValueChanged(Session s) {
+		synchronized (getSyncObject()) {
+			return fVar.hasValueChanged(ThreadSafeSession.getRaw(s));
+		}
+	}
+
+	public boolean needsToInvokeGetter() {
+		synchronized (getSyncObject()) { return fVar.needsToInvokeGetter(); }
+	}
+
+	public void invokeGetter(Session s) throws NotSuspendedException, NoResponseException, NotConnectedException {
+		synchronized (getSyncObject()) { fVar.invokeGetter(ThreadSafeSession.getRaw(s)); }
+	}
+
+	public String getQualifiedName() {
+		synchronized (getSyncObject()) { return fVar.getQualifiedName(); }
+	}
+
+	public String getNamespace() {
+		synchronized (getSyncObject()) { return fVar.getNamespace(); }
+	}
+	
+	public int getScope() {
+		synchronized (getSyncObject()) { return fVar.getScope(); }
+	}
+
+	public FaultEvent setValue(Session s, int type, String value) throws NotSuspendedException, NoResponseException, NotConnectedException {
+		synchronized (getSyncObject()) { return fVar.setValue(ThreadSafeSession.getRaw(s), type, value); }
+	}
+
+	public String getDefiningClass() {
+		synchronized (getSyncObject()) { return fVar.getDefiningClass(); }
+	}
+
+	public int getLevel() {
+		synchronized (getSyncObject()) { return fVar.getLevel(); }
+	}
+
+	@Override
+	public String toString() {
+		synchronized (getSyncObject()) { return fVar.toString(); }
+	}
+
+	@Override
+	public int getIsolateId() {
+		synchronized (getSyncObject()) { return fVar.getIsolateId(); }
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeWatch.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeWatch.java b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeWatch.java
new file mode 100644
index 0000000..276a0c5
--- /dev/null
+++ b/modules/fdbworkers/src/flash/tools/debugger/threadsafe/ThreadSafeWatch.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.tools.debugger.threadsafe;
+
+import flash.tools.debugger.Watch;
+
+/**
+ * Thread-safe wrapper for flash.tools.debugger.Watch
+ * @author Mike Morearty
+ */
+public class ThreadSafeWatch extends ThreadSafeDebuggerObject implements Watch {
+	
+	private Watch fWatch;
+	
+	private ThreadSafeWatch(Object syncObj, Watch watch) {
+		super(syncObj);
+		fWatch = watch;
+	}
+
+	/**
+	 * Wraps a Watch inside a ThreadSafeWatch.  If the passed-in Watch
+	 * is null, then this function returns null.
+	 */
+	public static ThreadSafeWatch wrap(Object syncObj, Watch watch) {
+		if (watch != null)
+			return new ThreadSafeWatch(syncObj, watch);
+		else
+			return null;
+	}
+
+	/**
+	 * Wraps an array of Watches inside an array of ThreadSafeWatches.
+	 */
+	public static ThreadSafeWatch[] wrapArray(Object syncObj, Watch[] watchs) {
+		ThreadSafeWatch[] threadSafeWatches = new ThreadSafeWatch[watchs.length];
+		for (int i=0; i<watchs.length; ++i) {
+			threadSafeWatches[i] = wrap(syncObj, watchs[i]);
+		}
+		return threadSafeWatches;
+	}
+
+	/**
+	 * Returns the raw Watch underlying a ThreadSafeWatch.
+	 */
+	public static Watch getRaw(Watch w) {
+		if (w instanceof ThreadSafeWatch)
+			return ((ThreadSafeWatch)w).fWatch;
+		else
+			return w;
+	}
+
+	public static Object getSyncObject(Watch w) {
+		return ((ThreadSafeWatch)w).getSyncObject();
+	}
+
+	public int getKind() {
+		synchronized (getSyncObject()) {
+			return fWatch.getKind();
+		}
+	}
+
+	public String getMemberName() {
+		synchronized (getSyncObject()) {
+			return fWatch.getMemberName();
+		}
+	}
+
+	public long getValueId() {
+		synchronized (getSyncObject()) {
+			return fWatch.getValueId();
+		}
+	}
+
+	@Override
+	public int getIsolateId() {
+		synchronized (getSyncObject()) {
+			return fWatch.getIsolateId();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/util/URLEncoder.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/util/URLEncoder.java b/modules/fdbworkers/src/flash/util/URLEncoder.java
new file mode 100644
index 0000000..52afb29
--- /dev/null
+++ b/modules/fdbworkers/src/flash/util/URLEncoder.java
@@ -0,0 +1,150 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Licensed to the Apache Software Foundation (ASF) under one or more
+//  contributor license agreements.  See the NOTICE file distributed with
+//  this work for additional information regarding copyright ownership.
+//  The ASF licenses this file to You under the Apache License, Version 2.0
+//  (the "License"); you may not use this file except in compliance with
+//  the License.  You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package flash.util;
+
+import java.io.*;
+
+public final class URLEncoder
+{
+	public static final String charset = "UTF8"; //$NON-NLS-1$
+
+	private URLEncoder()
+	{
+	}
+
+	public static final String encode(String s)
+	{
+		try
+		{
+			return encode(s, charset);
+		}
+		catch (UnsupportedEncodingException ex)
+		{
+			throw new IllegalArgumentException(charset);
+		}
+	}
+
+	public static final String encode(String s, String enc) throws UnsupportedEncodingException
+	{
+		if (!needsEncoding(s))
+		{
+			return s;
+		}
+
+		int length = s.length();
+
+		StringBuilder out = new StringBuilder(length);
+
+		ByteArrayOutputStream buf = new ByteArrayOutputStream(10); // why 10? w3c says so.
+
+		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(buf, enc));
+
+		for (int i = 0; i < length; i++)
+		{
+			int c = s.charAt(i);
+			if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == ' ')
+			{
+				if (c == ' ')
+				{
+					c = '+';
+				}
+
+				toHex(out, buf.toByteArray());
+				buf.reset();
+
+				out.append((char) c);
+			}
+			else
+			{
+				try
+				{
+					writer.write(c);
+
+					if (c >= 0xD800 && c <= 0xDBFF && i < length - 1)
+					{
+						int d = s.charAt(i + 1);
+						if (d >= 0xDC00 && d <= 0xDFFF)
+						{
+							writer.write(d);
+							i++;
+						}
+					}
+
+					writer.flush();
+				}
+				catch (IOException ex)
+				{
+					throw new IllegalArgumentException(s);
+				}
+			}
+		}
+
+		toHex(out, buf.toByteArray());
+
+		return out.toString();
+	}
+
+	private static final void toHex(StringBuilder buffer, byte[] b)
+	{
+		for (int i = 0; i < b.length; i++)
+		{
+			buffer.append('%');
+
+			char ch = Character.forDigit((b[i] >> 4) & 0xF, 16);
+			if (Character.isLetter(ch))
+			{
+				ch -= 32;
+			}
+			buffer.append(ch);
+
+			ch = Character.forDigit(b[i] & 0xF, 16);
+			if (Character.isLetter(ch))
+			{
+				ch -= 32;
+			}
+			buffer.append(ch);
+		}
+	}
+
+	private static final boolean needsEncoding(String s)
+	{
+		if (s == null)
+		{
+			return false;
+		}
+
+		int length = s.length();
+
+		for (int i = 0; i < length; i++)
+		{
+			int c = s.charAt(i);
+			if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9')
+			{
+				// keep going
+			}
+			else
+			{
+				return true;
+			}
+		}
+
+		return false;
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flash/util/URLHelper.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flash/util/URLHelper.java b/modules/fdbworkers/src/flash/util/URLHelper.java
new file mode 100644
index 0000000..a3b3f60
--- /dev/null
+++ b/modules/fdbworkers/src/flash/util/URLHelper.java
@@ -0,0 +1,283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flash.util;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class URLHelper
+{
+	private static Pattern URL_PATTERN = Pattern.compile("^(.*?)(\\?.*?)?(#.*)?$"); //$NON-NLS-1$
+
+	/**
+	 * Everything before the "query" part of the URL.  E.g. for
+	 * "http://www.example.com/file?firstname=Bob&lastname=Smith#foo"
+	 * this would be "http://www.example.com/file".
+	 */
+	private String m_everythingBeforeQuery;
+	
+	/**
+	 * The "query" in a URL is the "?firstname=Bob&lastname=Smith" part.
+	 * m_query contains the query (including "?"), or contains "" if the
+	 * URL has no query.  Never null.
+	 */
+	private String m_query;
+	
+	/**
+	 * The "fragment" in a URL is the "#foo" part at the end of a URL.
+	 * m_fragment contains the fragment (including "#"), or contains "" if the
+	 * URL has no fragment. Never null.
+	 */
+	private String m_fragment;
+
+	public URLHelper(String url)
+	{
+		Matcher matcher = URL_PATTERN.matcher(url);
+
+		if (!matcher.matches())
+			throw new IllegalArgumentException(url);
+
+		if (matcher.matches())
+		{
+			m_everythingBeforeQuery = matcher.group(1);
+
+			m_query = matcher.group(2);
+			if (m_query == null) m_query = ""; //$NON-NLS-1$
+
+			m_fragment = matcher.group(3);
+			if (m_fragment == null) m_fragment = ""; //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Everything before the "query" part of the URL.  E.g. for
+	 * "http://www.example.com/file?firstname=Bob&lastname=Smith#foo"
+	 * this would be "http://www.example.com/file".
+	 */
+	public String getEverythingBeforeQuery()
+	{
+		return m_everythingBeforeQuery;
+	}
+
+	public void setEverythingBeforeQuery(String everythingBeforeQuery)
+	{
+		assertValidArguments(everythingBeforeQuery, getQuery(), getFragment());
+		m_everythingBeforeQuery = everythingBeforeQuery;
+	}
+
+	/**
+	 * Rturns the "query" portion of the URL, e.g. the
+	 * "?firstname=Bob&lastname=Smith" part. m_query contains the query
+	 * (including "?"), or "" if the URL has no query. Never null.
+	 */
+	public String getQuery()
+	{
+		return m_query;
+	}
+
+	/**
+	 * Sets the "query" portion of the URL.  This must be either the
+	 * empty string or a string that begins with "?".
+	 */
+	public void setQuery(String query)
+	{
+		// if there is a query, make sure it starts with "?"
+		if (query.length() > 0 && query.charAt(0) != '?')
+			query = "?" + query; //$NON-NLS-1$
+
+		assertValidArguments(getEverythingBeforeQuery(), query, getFragment());
+
+		m_query = query;
+	}
+
+	/**
+	 * Returns the "fragment" portion of the URL, e.g. the "#foo" part, or
+	 * "" if the URL has no fragment. Never null.
+	 */
+	public String getFragment()
+	{
+		return m_fragment;
+	}
+
+	/**
+	 * Sets the "fragment" portion of the URL.  This must be either the
+	 * empty string or a string that begins with "#".
+	 * @param fragment
+	 */
+	public void setFragment(String fragment)
+	{
+		// if there is a fragment, make sure it starts with "#"
+		if (fragment.length() > 0 && fragment.charAt(0) != '#')
+			fragment = "#" + fragment; //$NON-NLS-1$
+
+		assertValidArguments(getEverythingBeforeQuery(), getQuery(), fragment);
+		m_fragment = fragment;
+	}
+
+	private static void assertValidArguments(String everythingBeforeQuery, String query, String fragment)
+	{
+		assert areArgumentsValid(everythingBeforeQuery, query, fragment);
+	}
+
+	/**
+	 * This will test for various error conditions, e.g. a query string that
+	 * contains "#" or has incorrect contents.
+	 */
+	private static boolean areArgumentsValid(String everythingBeforeQuery, String query, String fragment)
+	{
+		if (everythingBeforeQuery == null || query == null || fragment == null)
+			return false;
+
+		URLHelper newHelper = new URLHelper(everythingBeforeQuery + query + fragment);
+		if (!newHelper.getEverythingBeforeQuery().equals(everythingBeforeQuery) ||
+			!newHelper.getQuery().equals(query) ||
+			!newHelper.getFragment().equals(fragment))
+		{
+			return false;
+		}
+		
+		return true;
+	}
+
+	/**
+	 * Returns the entire URL.
+	 */
+	public String getURL()
+	{
+		return m_everythingBeforeQuery + m_query + m_fragment;
+	}
+
+	/**
+	 * Returns the query portion of the URL, broken up into individual key/value
+	 * pairs. Does NOT unescape the keys and values.
+	 */
+    public LinkedHashMap<String, String> getParameterMap()
+	{
+		LinkedHashMap<String, String> map;
+
+		StringTokenizer tokens = new StringTokenizer(getQuery(), "?&"); //$NON-NLS-1$
+		// multiply by 2 to create a sufficiently large HashMap
+		map = new LinkedHashMap<String, String>(tokens.countTokens() * 2);
+
+		while (tokens.hasMoreElements())
+		{
+			String nameValuePair = tokens.nextToken();
+			String name = nameValuePair;
+			String value = ""; //$NON-NLS-1$
+			int equalsIndex = nameValuePair.indexOf('=');
+			if (equalsIndex != -1)
+			{
+				name = nameValuePair.substring(0, equalsIndex);
+				if (name.length() > 0)
+				{
+					value = nameValuePair.substring(equalsIndex + 1);
+				}
+			}
+			map.put(name, value);
+		}
+
+		return map;
+	}
+
+    /**
+	 * Sets the query portion of the URL.
+	 * 
+	 * @param parameterMap
+	 *            a key/value mapping; these must already be escaped!
+	 */
+    public void setParameterMap(Map<String,String> parameterMap)
+	{
+		if ((parameterMap != null) && (!parameterMap.isEmpty()))
+		{
+			StringBuilder queryString = new StringBuilder();
+
+			Iterator<Map.Entry<String,String>> it = parameterMap.entrySet().iterator();
+			while (it.hasNext())
+			{
+				Map.Entry<String,String> entry = it.next();
+				String name = (String) entry.getKey();
+				String value = String.valueOf(entry.getValue());
+				queryString.append(name);
+				if ((value != null) && (!value.equals(""))) //$NON-NLS-1$
+				{
+					queryString.append('=');
+					queryString.append(value);
+				}
+				if (it.hasNext())
+				{
+					queryString.append('&');
+				}
+			}
+
+			setQuery(queryString.toString());
+		} else
+		{
+			setQuery(""); //$NON-NLS-1$
+		}
+	}
+
+	// shortcut for converting spaces to %20 in URIs
+	public static String escapeSpace(String uri)
+	{
+		return escapeCharacter(uri, ' ', "%20"); //$NON-NLS-1$
+	}
+
+	/**
+	 * Locates characters 'c' in the scheme specific portion of a URI and
+	 * translates them into 'to'
+	 */
+	public static String escapeCharacter(String uri, char c, String to)
+	{
+		StringBuilder sb = new StringBuilder();
+
+		int size = uri.length();
+		int at = uri.indexOf(':');
+		int lastAt = 0;
+
+		// skip the scheme
+		if (at > -1)
+		{
+			for(int i=0; i<=at; i++)
+				sb.append(uri.charAt(i));
+			lastAt = ++at;
+		}
+
+		// while we have 'c's in uri
+		while( (at = uri.indexOf(c, at)) > -1)
+		{
+			// original portion
+			for(int i=lastAt; i<at; i++)
+				sb.append(uri.charAt(i));
+
+			// conversion
+			sb.append(to);
+			lastAt = ++at;  // advance to char after conversion
+		}
+
+		if (lastAt < size)
+		{
+			for(int i=lastAt; i<size; i++)
+				sb.append(uri.charAt(i));
+		}
+		return sb.toString();
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flex/tools/debugger/cli/AmbiguousException.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flex/tools/debugger/cli/AmbiguousException.java b/modules/fdbworkers/src/flex/tools/debugger/cli/AmbiguousException.java
new file mode 100644
index 0000000..d670b3d
--- /dev/null
+++ b/modules/fdbworkers/src/flex/tools/debugger/cli/AmbiguousException.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flex.tools.debugger.cli;
+
+/**
+ * An exception that is thrown when some ambiguous condition or state
+ * was encountered.  It is usually not fatal, and normally caused
+ * by some user interaction which can be overcome. 
+ */
+public class AmbiguousException extends Exception
+{
+    private static final long serialVersionUID = -1627900831637441719L;
+    
+    public AmbiguousException() {}
+    public AmbiguousException(String s) { super(s); }
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flex/tools/debugger/cli/BreakAction.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flex/tools/debugger/cli/BreakAction.java b/modules/fdbworkers/src/flex/tools/debugger/cli/BreakAction.java
new file mode 100644
index 0000000..d3829e2
--- /dev/null
+++ b/modules/fdbworkers/src/flex/tools/debugger/cli/BreakAction.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flex.tools.debugger.cli;
+
+import java.util.Vector;
+import java.util.Iterator;
+
+import flash.tools.debugger.Location;
+import flash.tools.debugger.expression.ValueExp;
+
+
+/**
+ * An object that relates a CLI debugger breakpoint with an associated set
+ * of CLI commands to perform.
+ * 
+ * A breakpoint can be enabled or disabled.  It can be set such
+ * that it disabled or deletes itself after being hit N times.
+ */
+public class BreakAction
+{
+	// return values for getStatus()
+	public final static int		RESOLVED = 1;
+	public final static int		UNRESOLVED = 2;
+	public final static int		AMBIGUOUS = 3;
+	public final static int		NOCODE = 4;	// there is no executable code at the specified line
+
+	/**
+	 * This will be null if the user typed in a breakpoint expression which
+	 * did not match any currently loaded location, but we have saved it
+	 * (with status == UNRESOLVED) in case it gets resolved later when another
+	 * SWF or ABC gets loaded.
+	 */
+	private LocationCollection	m_where;				// may be null
+
+	/**
+	 * This will be null if the breakpoint was created via the
+	 * <code>BreakAction(String unresolvedLocation)</code> constructor.
+	 */
+	private String				m_breakpointExpression;	// may be null
+
+	private Vector<String>		m_commands;
+	private boolean				m_enabled;
+	private boolean				m_autoDelete;
+	private boolean				m_autoDisable;
+	private boolean				m_silent;
+	private boolean				m_singleSwf;			// is breakpoint meant for a single swf only
+	private int					m_id;
+	private int					m_hits;
+	private ValueExp			m_condition;
+	private String				m_conditionString;
+	private int					m_status;
+
+	public BreakAction(LocationCollection c) throws NullPointerException
+	{
+		m_where = c;
+		m_where.first().getFile();  // force NullPointerException if l == null
+		m_status = RESOLVED;
+		init();
+	}
+
+	public BreakAction(String unresolvedLocation)
+	{
+		m_breakpointExpression = unresolvedLocation;
+		m_status = UNRESOLVED;
+		init();
+	}
+
+	private void init()
+	{
+		m_id = BreakIdentifier.next();
+		m_commands = new Vector<String>();
+	}
+
+	/* getters */
+	public int					getCommandCount()				{ return m_commands.size(); }
+	public String				commandAt(int i)				{ return m_commands.elementAt(i); }
+	public Location				getLocation()					{ return (m_where != null) ? m_where.first() : null; }
+    public LocationCollection	getLocations()					{ return m_where; }
+	public int					getId()							{ return m_id; }
+	public int					getHits()						{ return m_hits; }
+	public boolean				isEnabled()						{ return m_enabled; }
+	public boolean				isAutoDisable()					{ return m_autoDisable; }
+	public boolean				isAutoDelete()					{ return m_autoDelete; }
+	public boolean				isSilent()						{ return m_silent; }
+	public boolean				isSingleSwf()					{ return m_singleSwf; }
+	public ValueExp				getCondition()					{ return m_condition; }
+	public String				getConditionString()			{ return m_conditionString; }
+	public String				getBreakpointExpression()		{ return m_breakpointExpression; }
+	public int					getStatus()						{ return m_status; }
+
+	/* setters */
+	public void addCommand(String cmd)					{ m_commands.add(cmd); }
+	public void clearCommands()							{ m_commands.clear(); }
+	public void addLocation(Location l)					{ m_where.add(l); }
+	public void setEnabled(boolean enable)				{ m_enabled = enable; }
+	public void setAutoDisable(boolean disable)			{ m_autoDisable = disable; }
+	public void setAutoDelete(boolean delete)			{ m_autoDelete = delete; }
+	public void setSilent(boolean silent)				{ m_silent = silent; }
+	public void setCondition(ValueExp c, String s)		{ m_condition = c;  m_conditionString = s; }
+	public void clearCondition()						{ setCondition(null, ""); } //$NON-NLS-1$
+	public void hit()									{ m_hits++; }
+	public void clearHits()								{ m_hits = 0; }
+	public void setSingleSwf(boolean singleSwf)			{ m_singleSwf = singleSwf; }
+	public void setBreakpointExpression(String expr)	{ m_breakpointExpression = expr; }
+	public void setStatus(int status)					{ m_status = status; }
+
+	public void setLocations(LocationCollection loc)
+	{
+		m_where = loc;
+		if (loc != null)
+			setStatus(RESOLVED);
+	}
+
+	/*
+	 * Check to see if our location matches the requested one
+	 */
+	public boolean locationMatches(int fileId, int line)
+	{
+		boolean match = false;
+		LocationCollection col = getLocations();
+		if (col != null)
+		{
+			Iterator itr = col.iterator();
+		
+			// probe all locations looking for a match
+			while(!match && itr.hasNext())
+			{
+				Location l = (Location)itr.next();
+				if (l != null && l.getFile().getId() == fileId && l.getLine() == line)
+					match = true;
+			}
+		}
+		return match;
+	}
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flex/tools/debugger/cli/BreakIdentifier.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flex/tools/debugger/cli/BreakIdentifier.java b/modules/fdbworkers/src/flex/tools/debugger/cli/BreakIdentifier.java
new file mode 100644
index 0000000..9a32cca
--- /dev/null
+++ b/modules/fdbworkers/src/flex/tools/debugger/cli/BreakIdentifier.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flex.tools.debugger.cli;
+
+/**
+ * An singleton object that doles out unique identifiers to breakpoints and watchpoints
+ */
+public class BreakIdentifier
+{
+	private static int s_uniqueIdentifier  = 1;
+
+	public static int next() { return s_uniqueIdentifier++; }
+}

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/a3765ae5/modules/fdbworkers/src/flex/tools/debugger/cli/CatchAction.java
----------------------------------------------------------------------
diff --git a/modules/fdbworkers/src/flex/tools/debugger/cli/CatchAction.java b/modules/fdbworkers/src/flex/tools/debugger/cli/CatchAction.java
new file mode 100644
index 0000000..6dac5e9
--- /dev/null
+++ b/modules/fdbworkers/src/flex/tools/debugger/cli/CatchAction.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flex.tools.debugger.cli;
+
+/**
+ * 
+ * An object that relates a CLI debugger catchpoint with the
+ * actual Catch obtained from the Session
+ * 
+ * @author Mike Morearty
+ */
+public class CatchAction
+{
+	private final int m_id;
+	private final String m_typeToCatch;
+
+	/**
+	 * @param typeToCatch
+	 *            the type, e.g. "ReferenceError" or "com.example.MyError". If
+	 *            typeToCatch is <code>null</code>, that means to halt on any
+	 *            exception.
+	 */
+	public CatchAction(String typeToCatch)
+	{
+		m_typeToCatch = typeToCatch;
+		m_id = BreakIdentifier.next();
+	}
+
+	public int getId()
+	{
+		return m_id;
+	}
+
+	/**
+	 * Returns the type being caught, or <code>null</code> to catch all
+	 * exceptions.
+	 */
+	public String getTypeToCatch()
+	{
+		return m_typeToCatch;
+	}
+}