You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ft...@apache.org on 2014/04/30 11:58:58 UTC

[09/15] FLEX-34291: Merge the donated FDB with the current one.

http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/379cb609/modules/debugger/src/java/flex/tools/debugger/cli/DebugCLI.java
----------------------------------------------------------------------
diff --git a/modules/debugger/src/java/flex/tools/debugger/cli/DebugCLI.java b/modules/debugger/src/java/flex/tools/debugger/cli/DebugCLI.java
index 0f29cf3..6eb04ef 100644
--- a/modules/debugger/src/java/flex/tools/debugger/cli/DebugCLI.java
+++ b/modules/debugger/src/java/flex/tools/debugger/cli/DebugCLI.java
@@ -19,82 +19,12 @@
 
 package flex.tools.debugger.cli;
 
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.LineNumberReader;
-import java.io.PrintStream;
-import java.io.StringReader;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Stack;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
+import com.sun.org.apache.xml.internal.utils.LocaleUtility;
 import flash.localization.LocalizationManager;
-import flash.tools.debugger.Bootstrap;
-import flash.tools.debugger.DebuggerLocalizer;
-import flash.tools.debugger.Frame;
-import flash.tools.debugger.InProgressException;
-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.SessionManager;
-import flash.tools.debugger.SourceFile;
-import flash.tools.debugger.SourceLocator;
-import flash.tools.debugger.SuspendReason;
-import flash.tools.debugger.SuspendedException;
-import flash.tools.debugger.SwfInfo;
-import flash.tools.debugger.Value;
-import flash.tools.debugger.Variable;
-import flash.tools.debugger.VariableAttribute;
-import flash.tools.debugger.VariableType;
-import flash.tools.debugger.VersionException;
-import flash.tools.debugger.Watch;
-import flash.tools.debugger.WatchKind;
+import flash.tools.debugger.*;
 import flash.tools.debugger.concrete.DProtocol;
 import flash.tools.debugger.concrete.DSwfInfo;
-import flash.tools.debugger.events.BreakEvent;
-import flash.tools.debugger.events.ConsoleErrorFault;
-import flash.tools.debugger.events.DebugEvent;
-import flash.tools.debugger.events.DivideByZeroFault;
-import flash.tools.debugger.events.ExceptionFault;
-import flash.tools.debugger.events.FaultEvent;
-import flash.tools.debugger.events.FileListModifiedEvent;
-import flash.tools.debugger.events.FunctionMetaDataAvailableEvent;
-import flash.tools.debugger.events.InvalidTargetFault;
-import flash.tools.debugger.events.InvalidURLFault;
-import flash.tools.debugger.events.InvalidWithFault;
-import flash.tools.debugger.events.ProtoLimitFault;
-import flash.tools.debugger.events.RecursionLimitFault;
-import flash.tools.debugger.events.ScriptTimeoutFault;
-import flash.tools.debugger.events.StackUnderFlowFault;
-import flash.tools.debugger.events.SwfLoadedEvent;
-import flash.tools.debugger.events.SwfUnloadedEvent;
-import flash.tools.debugger.events.TraceEvent;
+import flash.tools.debugger.events.*;
 import flash.tools.debugger.expression.ECMA;
 import flash.tools.debugger.expression.NoSuchVariableException;
 import flash.tools.debugger.expression.PlayerFaultException;
@@ -102,6440 +32,6088 @@ import flash.tools.debugger.expression.ValueExp;
 import flash.util.FieldFormat;
 import flash.util.Trace;
 import flex.tools.debugger.cli.ExpressionCache.EvaluationResult;
+import flex.tools.debugger.cli.FaultActions.FaultActionsBuilder;
+
+import java.io.*;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.*;
 
 /**
  * This is a front end command line interface to the Flash Debugger
  * Player.
- *<p>
- * This tool utilizes the Debugger Java API (DJAPI) for Flash 
+ * <p/>
+ * This tool utilizes the Debugger Java API (DJAPI) for Flash
  * Player that exists in flash.tools.debuggger.
- *<p> 
+ * <p/>
  * This tool is not completely compliant with the API, since
  * some commands expose implementation specific information for
  * debugging purposes.  Instances where this occurs are kept to a
- * minimum and are isolated in a special class called Extensions.  
- * If you wish to build a version that is completely API 
- * compatible.  Replace Extensions with ExtensionsDisabled in 
- * the static method calls at the end of this file. 
+ * minimum and are isolated in a special class called Extensions.
+ * If you wish to build a version that is completely API
+ * compatible.  Replace Extensions with ExtensionsDisabled in
+ * the static method calls at the end of this file.
  */
-public class DebugCLI implements Runnable, SourceLocator
-{
-	public static final String VERSION			= "82"; //$NON-NLS-1$
-
-	public static final int CMD_UNKNOWN			= 0;
-	public static final int CMD_QUIT			= 1;
-	public static final int CMD_CONTINUE		= 2;
-	public static final int CMD_STEP			= 3;
-	public static final int CMD_NEXT			= 4;
-	public static final int CMD_FINISH			= 5;
-	public static final int CMD_BREAK			= 6;
-	public static final int CMD_SET				= 7;
-	public static final int CMD_LIST			= 8;
-	public static final int CMD_PRINT			= 9;
-	public static final int CMD_TUTORIAL		= 10;
-	public static final int CMD_INFO			= 11;
-	public static final int CMD_HOME			= 12;
-	public static final int CMD_RUN				= 13;
-	public static final int CMD_FILE			= 14;
-	public static final int CMD_DELETE			= 15;
-	public static final int CMD_SOURCE			= 16;
-	public static final int CMD_COMMENT			= 17;
-	public static final int CMD_CLEAR			= 18;
-	public static final int CMD_HELP			= 19;
-	public static final int CMD_SHOW			= 20;
-	public static final int CMD_KILL			= 21;
-	public static final int CMD_HANDLE			= 22;
-	public static final int CMD_ENABLE			= 23;
-	public static final int CMD_DISABLE			= 24;
-	public static final int CMD_DISPLAY			= 25;
-	public static final int CMD_UNDISPLAY		= 26;
- 	public static final int CMD_COMMANDS		= 27;
-    public static final int CMD_PWD             = 28;
-    public static final int CMD_CF              = 29;
-    public static final int CMD_CONDITION		= 30;
-	public static final int CMD_AWATCH			= 31;
-	public static final int CMD_WATCH			= 32;
-	public static final int CMD_RWATCH			= 33;
-	public static final int CMD_WHAT			= 34;
-	public static final int CMD_DISASSEMBLE		= 35;
-	public static final int CMD_HALT			= 36;
-	public static final int CMD_MCTREE			= 37;
-	public static final int CMD_VIEW_SWF		= 38;
-	public static final int CMD_DOWN			= 39;
-	public static final int CMD_UP				= 40;
-	public static final int CMD_FRAME			= 41;
-	public static final int CMD_DIRECTORY		= 42;
-	public static final int CMD_CATCH			= 43;
-	public static final int CMD_CONNECT			= 44;
-
-	/* info sub commands */
-	public static final int INFO_UNKNOWN_CMD	= 100;
-	public static final int INFO_ARGS_CMD		= 101;
-	public static final int INFO_BREAK_CMD		= 102;
-	public static final int INFO_FILES_CMD		= 103;
-	public static final int INFO_HANDLE_CMD		= 104;
-	public static final int INFO_FUNCTIONS_CMD	= 105;
-	public static final int INFO_LOCALS_CMD		= 106;
-	public static final int INFO_SCOPECHAIN_CMD	= 107;
-	public static final int INFO_SOURCES_CMD	= 108;
-	public static final int INFO_STACK_CMD		= 109;
-	public static final int INFO_VARIABLES_CMD	= 110;
-	public static final int INFO_DISPLAY_CMD	= 111;
-    public static final int INFO_TARGETS_CMD    = 112;
-    public static final int INFO_SWFS_CMD		= 113;
-
-	/* show subcommands */
-	public static final int SHOW_UNKNOWN_CMD	= 200;
-	public static final int SHOW_NET_CMD		= 201;
-	public static final int SHOW_FUNC_CMD		= 202;
-	public static final int SHOW_URI_CMD		= 203;
-	public static final int SHOW_PROPERTIES_CMD	= 204;
-	public static final int SHOW_FILES_CMD		= 205;
-	public static final int SHOW_BREAK_CMD		= 206;
-	public static final int SHOW_VAR_CMD		= 207;
-	public static final int SHOW_MEM_CMD		= 208;
-	public static final int SHOW_LOC_CMD		= 209;
-	public static final int SHOW_DIRS_CMD		= 210;
-
-	/* misc subcommands */
-	public static final int ENABLE_ONCE_CMD		= 301;
+public class DebugCLI implements Runnable, SourceLocator {
+    public static final String VERSION = "82"; //$NON-NLS-1$
+
+    public static final int CMD_UNKNOWN = 0;
+    public static final int CMD_QUIT = 1;
+    public static final int CMD_CONTINUE = 2;
+    public static final int CMD_STEP = 3;
+    public static final int CMD_NEXT = 4;
+    public static final int CMD_FINISH = 5;
+    public static final int CMD_BREAK = 6;
+    public static final int CMD_SET = 7;
+    public static final int CMD_LIST = 8;
+    public static final int CMD_PRINT = 9;
+    public static final int CMD_TUTORIAL = 10;
+    public static final int CMD_INFO = 11;
+    public static final int CMD_HOME = 12;
+    public static final int CMD_RUN = 13;
+    public static final int CMD_FILE = 14;
+    public static final int CMD_DELETE = 15;
+    public static final int CMD_SOURCE = 16;
+    public static final int CMD_COMMENT = 17;
+    public static final int CMD_CLEAR = 18;
+    public static final int CMD_HELP = 19;
+    public static final int CMD_SHOW = 20;
+    public static final int CMD_KILL = 21;
+    public static final int CMD_HANDLE = 22;
+    public static final int CMD_ENABLE = 23;
+    public static final int CMD_DISABLE = 24;
+    public static final int CMD_DISPLAY = 25;
+    public static final int CMD_UNDISPLAY = 26;
+    public static final int CMD_COMMANDS = 27;
+    public static final int CMD_PWD = 28;
+    public static final int CMD_CF = 29;
+    public static final int CMD_CONDITION = 30;
+    public static final int CMD_AWATCH = 31;
+    public static final int CMD_WATCH = 32;
+    public static final int CMD_RWATCH = 33;
+    public static final int CMD_WHAT = 34;
+    public static final int CMD_DISASSEMBLE = 35;
+    public static final int CMD_HALT = 36;
+    public static final int CMD_MCTREE = 37;
+    public static final int CMD_VIEW_SWF = 38;
+    public static final int CMD_DOWN = 39;
+    public static final int CMD_UP = 40;
+    public static final int CMD_FRAME = 41;
+    public static final int CMD_DIRECTORY = 42;
+    public static final int CMD_CATCH = 43;
+    public static final int CMD_CONNECT = 44;
+    public static final int CMD_WORKER = 45;
+
+    /* info sub commands */
+    public static final int INFO_UNKNOWN_CMD = 100;
+    public static final int INFO_ARGS_CMD = 101;
+    public static final int INFO_BREAK_CMD = 102;
+    public static final int INFO_FILES_CMD = 103;
+    public static final int INFO_HANDLE_CMD = 104;
+    public static final int INFO_FUNCTIONS_CMD = 105;
+    public static final int INFO_LOCALS_CMD = 106;
+    public static final int INFO_SCOPECHAIN_CMD = 107;
+    public static final int INFO_SOURCES_CMD = 108;
+    public static final int INFO_STACK_CMD = 109;
+    public static final int INFO_VARIABLES_CMD = 110;
+    public static final int INFO_DISPLAY_CMD = 111;
+    public static final int INFO_TARGETS_CMD = 112;
+    public static final int INFO_SWFS_CMD = 113;
+    public static final int INFO_WORKERS_CMD = 114;
+
+    /* show subcommands */
+    public static final int SHOW_UNKNOWN_CMD = 200;
+    public static final int SHOW_NET_CMD = 201;
+    public static final int SHOW_FUNC_CMD = 202;
+    public static final int SHOW_URI_CMD = 203;
+    public static final int SHOW_PROPERTIES_CMD = 204;
+    public static final int SHOW_FILES_CMD = 205;
+    public static final int SHOW_BREAK_CMD = 206;
+    public static final int SHOW_VAR_CMD = 207;
+    public static final int SHOW_MEM_CMD = 208;
+    public static final int SHOW_LOC_CMD = 209;
+    public static final int SHOW_DIRS_CMD = 210;
+
+    /* misc subcommands */
+    public static final int ENABLE_ONCE_CMD = 301;
 
     // default metadata retry count 8 attempts per waitForMetadata() call * 5 calls
-    public static final int METADATA_RETRIES    = 8*5;
-
-	Stack<LineNumberReader> m_readerStack = new Stack<LineNumberReader>();
-	PrintStream m_err;
-	PrintStream m_out;
-	Session		m_session;
-	String		m_launchURI;
-	boolean		m_fullnameOption; // emacs mode
-	String		m_cdPath;
-	String		m_mruURI;
-	String m_connectPort;
-	public final static String m_newline = System.getProperty("line.separator"); //$NON-NLS-1$
-
-	private final static LocalizationManager m_localizationManager = new LocalizationManager();
-
-	List<String>	m_sourceDirectories; // List of String
-	int				m_sourceDirectoriesChangeCount;
-	private File	m_flexHomeDirectory; // <application.home>/frameworks/projects/*/src always goes in m_sourceDirectories
-	private boolean	m_initializedFlexHomeDirectory;
-
-	// context information for our current session
-	FileInfoCache	m_fileInfo;
-	ExpressionCache m_exprCache;
-	FaultActions	m_faultTable;
-	Vector<BreakAction>	        m_breakpoints;
-	Vector<WatchAction>			m_watchpoints;
-	Vector<CatchAction>			m_catchpoints;
-	ArrayList<DisplayAction>	m_displays;
-	boolean			m_requestResume;
-	boolean			m_requestHalt;
-	boolean			m_stepResume;
-
-	/* our current input processing context */
-	LineNumberReader	m_in;
-	LineNumberReader	m_keyboardStream;
-	Vector<String>		m_keyboardInput;
-	boolean				m_keyboardReadRequest;
-	StringTokenizer		m_currentTokenizer;
-	String				m_currentToken;
-	String				m_currentLine;
-	public String		m_repeatLine;
-    private boolean     m_isIde;
-
-	/**
-	 * The module that the next "list" command should display if no
-	 * module is explicitly specified.
-	 */
-	public static final String LIST_MODULE = "$listmodule"; //$NON-NLS-1$
+    public static final int METADATA_RETRIES = 8 * 5;
 
-	/**
-	 * The line number at which the next "list" command should begin if no
-	 * line number is explicitly specified.
-	 */
-	public static final String LIST_LINE = "$listline"; //$NON-NLS-1$
+    /* Enum for the state of the initial prompt shown when a swf is loaded */
+    public static enum InitialPromptState {
+        NEVER_SHOWN, SHOWN_ONCE, DONE
+    }
 
-	/**
-	 * The number of lines displayed by the "list" command.
-	 */
-	private static final String LIST_SIZE = "$listsize"; //$NON-NLS-1$
+    Stack<LineNumberReader> m_readerStack = new Stack<LineNumberReader>();
+    public PrintStream m_err;
+    public PrintStream m_out;
+    Session m_session;
+    String m_launchURI;
+    boolean m_fullnameOption; // emacs mode
+    String m_cdPath;
+    String m_mruURI;
+    String m_connectPort;
+    public final static String m_newline = System.getProperty("line.separator"); //$NON-NLS-1$
+
+    private final static LocalizationManager m_localizationManager = new LocalizationManager();
+    private final static FaultActionsBuilder faultActionsBuilder = new FaultActionsBuilder(m_localizationManager);
+
+    List<String> m_sourceDirectories; // List of String
+    int m_sourceDirectoriesChangeCount;
+    private File m_flexHomeDirectory; // <application.home>/frameworks/projects/*/src always goes in m_sourceDirectories
+    private boolean m_initializedFlexHomeDirectory;
+
+    // context information for our current session
+    FileInfoCache m_fileInfo;
+    FaultActions m_faultTable;
+    Vector<Integer> m_breakIsolates;
+    ExpressionCache m_exprCache;
+    Vector<BreakAction> m_breakpoints;
+    Vector<WatchAction> m_watchpoints;
+    Vector<CatchAction> m_catchpoints;
+    ArrayList<DisplayAction> m_displays;
+    //	boolean			m_requestResume;
+//	boolean			m_requestHalt;
+//	boolean			m_stepResume;
+    int m_activeIsolate;
+    DebugCLIIsolateState m_mainState;
+
+    /* This indicates the isolate for which we have been showing prompts for setting
+     * breakpoints( so that we don't switch worker while the user is setting breakpoints) */
+    int m_lastPromptIsolate;
+
+    private HashMap<Integer, DebugCLIIsolateState> m_isolateState;
+
+    class DebugCLIIsolateState {
+        //		public FileInfoCache	m_fileInfo;
+//		public ExpressionCache m_exprCache;
+        public boolean m_requestResume;
+        public boolean m_requestHalt;
+        public boolean m_stepResume;
+        /* Indicates whether the prompt for setting initial breakpoints has been displayed for this isolate */
+        public InitialPromptState m_promptState;
+//		public Vector<BreakAction>	        m_breakpoints;
+//		public Vector<WatchAction>			m_watchpoints;
+//		public Vector<CatchAction>			m_catchpoints;
+//		public ArrayList<DisplayAction>	m_displays;
+
+
+        public DebugCLIIsolateState(DebugCLI debugcli) {
+//			m_exprCache = new ExpressionCache(debugcli);
+            m_faultTable = faultActionsBuilder.build();//new FaultActions();
+//			m_breakpoints = new Vector<BreakAction>();
+//			m_watchpoints = new Vector<WatchAction>();
+//			m_catchpoints = new Vector<CatchAction>();
+//			m_displays = new ArrayList<DisplayAction>();
+        }
+    }
 
-	private static final String COLUMN_WIDTH = "$columnwidth"; //$NON-NLS-1$
+    private DebugCLIIsolateState getIsolateState(int isolateId) {
+        if (isolateId == Isolate.DEFAULT_ID)
+            return m_mainState;
+        DebugCLIIsolateState isolateState = null;
+        if (!m_isolateState.containsKey(isolateId)) {
+            isolateState = new DebugCLIIsolateState(this);
+            m_isolateState.put(isolateId, isolateState);
+        } else
+            isolateState = m_isolateState.get(isolateId);
+        return isolateState;
+    }
 
-	private static final String UPDATE_DELAY = "$updatedelay"; //$NON-NLS-1$
+    public int getActiveIsolateId() {
+        return m_activeIsolate;
+    }
 
-	private static final String HALT_TIMEOUT = "$halttimeout"; //$NON-NLS-1$
+    private boolean getRequestResume(int isolateId) {
+        return getIsolateState(isolateId).m_requestResume;
+    }
 
-	/**
-	 * Current breakpoint number.
-	 */
-	private static final String BPNUM = "$bpnum"; //$NON-NLS-1$
+    private void setRequestResume(boolean value, int isolateId) {
+        getIsolateState(isolateId).m_requestResume = value;
+    }
 
-	/**
-	 * Used to determine how much context information should be displayed.
-	 */
-	private static final String LAST_FRAME_DEPTH = "$lastframedepth"; //$NON-NLS-1$
+    private boolean getStepResume(int isolateId) {
+        return getIsolateState(isolateId).m_stepResume;
+    }
 
-	/**
-	 * Used to determine how much context information should be displayed.
-	 */
-	private static final String CURRENT_FRAME_DEPTH = "$currentframedepth"; //$NON-NLS-1$
+    private void setStepResume(boolean value, int isolateId) {
+        getIsolateState(isolateId).m_stepResume = value;
+    }
 
-	/**
-	 * The current frame we are viewing -- controlled by the "up", "down", and "frame" commands.
-	 */
-	public static final String DISPLAY_FRAME_NUMBER = "$displayframenumber"; //$NON-NLS-1$
+    private boolean getRequestHalt(int isolateId) {
+        return getIsolateState(isolateId).m_requestHalt;
+    }
 
-	private static final String FILE_LIST_WRAP = "$filelistwrap"; //$NON-NLS-1$
+    private void setRequestHalt(boolean value, int isolateId) {
+        getIsolateState(isolateId).m_requestHalt = value;
+    }
 
-	private static final String NO_WAITING = "$nowaiting"; //$NON-NLS-1$
+    private InitialPromptState getPromptState(int isolateId) {
+        return getIsolateState(isolateId).m_promptState;
+    }
 
-	/**
-	 * Show this pointer for info stack.
-	 */
-	private static final String INFO_STACK_SHOW_THIS = "$infostackshowthis"; //$NON-NLS-1$
+    private void setPromptState(InitialPromptState value, int isolateId) {
+        getIsolateState(isolateId).m_promptState = value;
+    }
 
-	private static final String PLAYER_FULL_SUPPORT = "$playerfullsupport"; //$NON-NLS-1$
+    /* our current input processing context */
+    LineNumberReader m_in;
+    public LineNumberReader m_keyboardStream;
+    Vector<String> m_keyboardInput;
+    boolean m_keyboardReadRequest;
+    StringTokenizer m_currentTokenizer;
+    String m_currentToken;
+    String m_currentLine;
+    public String m_repeatLine;
+    private boolean m_isIde;
 
-	/**
-	 * Whether the "print" command will display attributes of members.
-	 */
-	public static final String DISPLAY_ATTRIBUTES = "$displayattributes"; //$NON-NLS-1$
-	
-	/* class's static init */
-	static
-	{
+    /**
+     * The module that the next "list" command should display if no
+     * module is explicitly specified.
+     */
+    public static final String LIST_MODULE = "$listmodule"; //$NON-NLS-1$
+
+    /**
+     * The line number at which the next "list" command should begin if no
+     * line number is explicitly specified.
+     */
+    public static final String LIST_LINE = "$listline"; //$NON-NLS-1$
+
+    public static final String LIST_WORKER = "$listworker"; //$NON-NLS-1$
+
+    /**
+     * The number of lines displayed by the "list" command.
+     */
+    private static final String LIST_SIZE = "$listsize"; //$NON-NLS-1$
+
+    private static final String COLUMN_WIDTH = "$columnwidth"; //$NON-NLS-1$
+
+    private static final String UPDATE_DELAY = "$updatedelay"; //$NON-NLS-1$
+
+    private static final String HALT_TIMEOUT = "$halttimeout"; //$NON-NLS-1$
+
+    /**
+     * Current breakpoint number.
+     */
+    private static final String BPNUM = "$bpnum"; //$NON-NLS-1$
+
+    /**
+     * Used to determine how much context information should be displayed.
+     */
+    private static final String LAST_FRAME_DEPTH = "$lastframedepth"; //$NON-NLS-1$
+
+    /**
+     * Used to determine how much context information should be displayed.
+     */
+    private static final String CURRENT_FRAME_DEPTH = "$currentframedepth"; //$NON-NLS-1$
+
+    /**
+     * The current frame we are viewing -- controlled by the "up", "down", and "frame" commands.
+     */
+    public static final String DISPLAY_FRAME_NUMBER = "$displayframenumber"; //$NON-NLS-1$
+
+    private static final String FILE_LIST_WRAP = "$filelistwrap"; //$NON-NLS-1$
+
+    private static final String NO_WAITING = "$nowaiting"; //$NON-NLS-1$
+
+    /**
+     * Show this pointer for info stack.
+     */
+    private static final String INFO_STACK_SHOW_THIS = "$infostackshowthis"; //$NON-NLS-1$
+
+    private static final String PLAYER_FULL_SUPPORT = "$playerfullsupport"; //$NON-NLS-1$
+
+    /**
+     * Whether the "print" command will display attributes of members.
+     */
+    public static final String DISPLAY_ATTRIBUTES = "$displayattributes"; //$NON-NLS-1$
+
+    /* class's static init */
+    static {
         // set up for localizing messages
-        m_localizationManager.addLocalizer( new DebuggerLocalizer("flex.tools.debugger.cli.fdb.") ); //$NON-NLS-1$
-	}
+        m_localizationManager.addLocalizer(new DebuggerLocalizer("flex.tools.debugger.cli.fdb.")); //$NON-NLS-1$
+    }
 
-	public static void main(String[] args)
-	{
-		DebugCLI cli = new DebugCLI();
+    public static void main(String[] args) {
+        DebugCLI cli = new DebugCLI();
 
 		/* attach our 'main' input method and out/err*/
-		cli.m_err = System.err;
-		cli.m_out = System.out;
+        cli.m_err = System.err;
+        cli.m_out = System.out;
 
-		// get the default <application.home>/projects/frameworks/*/src entries into the source path
-		cli.initSourceDirectoriesList();
+        // get the default <application.home>/projects/frameworks/*/src entries into the source path
+        cli.initSourceDirectoriesList();
 
-		// a big of wrangling for our keyboard input stream since its special
-		cli.m_keyboardStream = new LineNumberReader(new InputStreamReader(System.in));
-		cli.pushStream(cli.m_keyboardStream);
+        // a big of wrangling for our keyboard input stream since its special
+        cli.m_keyboardStream = new LineNumberReader(new InputStreamReader(System.in));
+        cli.pushStream(cli.m_keyboardStream);
 
 		/* iterate through the args list */
-		cli.processArgs(args);
+        cli.processArgs(args);
 
 		/* figure out $HOME and the current directory */
-		String userHome = System.getProperty("user.home"); //$NON-NLS-1$
-		String userDir = System.getProperty("user.dir"); //$NON-NLS-1$
+        String userHome = System.getProperty("user.home"); //$NON-NLS-1$
+        String userDir = System.getProperty("user.dir"); //$NON-NLS-1$
 
 		/*
 		 * If the current directory is not $HOME, and a .fdbinit file exists in the current directory,
 		 * then push it onto the stack of files to read.
-		 * 
+		 *
 		 * Note, we want ./.fdbinit to be read AFTER $HOME/.fdbinit, but we push them in reverse
 		 * order, because they're going onto a stack.  If we push them in reverse order, then they
 		 * will be read in the correct order (last one pushed is the first one read).
 		 */
-		if (userDir != null && !userDir.equals(userHome))
-		{
-			try
-			{
-				FileReader sr = new FileReader(new File(userDir, ".fdbinit")); //$NON-NLS-1$
-				cli.pushStream( new LineNumberReader(sr) );
-			}
-			catch(FileNotFoundException fnf) {}
-		}
+        if (userDir != null && !userDir.equals(userHome)) {
+            try {
+                FileReader sr = new FileReader(new File(userDir, ".fdbinit")); //$NON-NLS-1$
+                cli.pushStream(new LineNumberReader(sr));
+            } catch (FileNotFoundException fnf) {
+            }
+        }
 
 		/*
 		 * If a .fdbinit file exists in the $HOME directory, then push it onto the stack of files
 		 * to read.
-		 * 
+		 *
 		 * Note, we want ./.fdbinit to be read AFTER $HOME/.fdbinit, but we push them in reverse
 		 * order, because they're going onto a stack.  If we push them in reverse order, then they
 		 * will be read in the correct order (last one pushed is the first one read).
 		 */
-		if (userHome != null)
-		{
-			try
-			{
-				FileReader sr = new FileReader(new File(userHome, ".fdbinit")); //$NON-NLS-1$
-				cli.pushStream( new LineNumberReader(sr) );
-			}
-			catch(FileNotFoundException fnf) {}
-		}
-
-		cli.execute();
-	}
-
-	public DebugCLI()
-	{
-		m_fullnameOption = false;
-		m_exprCache = new ExpressionCache(this);
-		m_faultTable = new FaultActions();
-		m_breakpoints = new Vector<BreakAction>();
-		m_watchpoints = new Vector<WatchAction>();
-		m_catchpoints = new Vector<CatchAction>();
-		m_displays = new ArrayList<DisplayAction>();
-		m_keyboardInput = new Vector<String>();
-		m_mruURI = null;
-		m_sourceDirectories = new LinkedList<String>();
-
-		initProperties();
-		populateFaultTable();
-	}
-
-	public static LocalizationManager getLocalizationManager() { return m_localizationManager; }
-	public Session				getSession()	{ return m_session; }
-	public FileInfoCache		getFileCache()	{ return m_fileInfo; }
-    public boolean              isIde()         { return m_isIde; }
-
-	/**
-	 * Convert a module to class name.  This is used
-	 * by the ExpressionCache to find variables
-	 * that live at royale package scope.   That
-	 * is variables such as mx.core.Component.
-	 */
-	public String module2ClassName(int moduleId)
-	{
-		String pkg = null;
-		try
-		{
-			SourceFile file = m_fileInfo.getFile(moduleId);
-			pkg = file.getPackageName();
-		}
-		catch(Exception npe)
-		{
-			// didn't work ignore it.
-		}
-		return pkg;
-	}
-
-	LineNumberReader	popStream()						{ return m_readerStack.pop(); }
-	void				pushStream(LineNumberReader r)  { m_readerStack.push(r); }
-	boolean				haveStreams()					{ return !m_readerStack.empty(); }
-
-	void processArgs(String[] args)
-	{
-		for(int i=0; i<args.length; i++)
-		{
-			String arg = args[i];
+        if (userHome != null) {
+            try {
+                FileReader sr = new FileReader(new File(userHome, ".fdbinit")); //$NON-NLS-1$
+                cli.pushStream(new LineNumberReader(sr));
+            } catch (FileNotFoundException fnf) {
+            }
+        }
+
+        cli.execute();
+    }
+
+    public DebugCLI() {
+        m_fullnameOption = false;
+        m_faultTable = faultActionsBuilder.build();
+        m_exprCache = new ExpressionCache(this);
+        m_breakpoints = new Vector<BreakAction>();
+        m_watchpoints = new Vector<WatchAction>();
+        m_catchpoints = new Vector<CatchAction>();
+        m_displays = new ArrayList<DisplayAction>();
+        m_keyboardInput = new Vector<String>();
+        m_mruURI = null;
+        m_sourceDirectories = new LinkedList<String>();
+
+        initProperties();
+        m_mainState = new DebugCLIIsolateState(this);
+        m_lastPromptIsolate = -1;
+        initIsolateState();
+    }
+
+    public static LocalizationManager getLocalizationManager() {
+        return m_localizationManager;
+    }
+
+    public Session getSession() {
+        return m_session;
+    }
+
+    public FileInfoCache getFileCache() {
+        return m_fileInfo;
+    }
+
+    public boolean isIde() {
+        return m_isIde;
+    }
+
+    /**
+     * Convert a module to class name.  This is used
+     * by the ExpressionCache to find variables
+     * that live at royale package scope.   That
+     * is variables such as mx.core.Component.
+     */
+    public String module2ClassName(int moduleId) {
+        String pkg = null;
+        try {
+            SourceFile file = m_fileInfo.getFile(moduleId);
+            pkg = file.getPackageName();
+        } catch (Exception npe) {
+            // didn't work ignore it.
+        }
+        return pkg;
+    }
+
+    LineNumberReader popStream() {
+        return m_readerStack.pop();
+    }
+
+    public void pushStream(LineNumberReader r) {
+        m_readerStack.push(r);
+    }
+
+    boolean haveStreams() {
+        return !m_readerStack.empty();
+    }
+
+    public void processArgs(String[] args) {
+        for (int i = 0; i < args.length; i++) {
+            String arg = args[i];
 //			System.out.println("arg["+i+"]= '"+arg+"'");
-			if (arg.charAt(0) == '-')
-			{
-				// its an option
-				if (arg.equals("-unit")) // unit-testing mode //$NON-NLS-1$
-				{
-					System.setProperty("fdbunit", ""); //$NON-NLS-1$ //$NON-NLS-2$
-				}
-				else if (arg.equals("-fullname") || arg.equals("-f")) //$NON-NLS-1$ //$NON-NLS-2$
-				{
-					m_fullnameOption = true; // emacs mode
-				}
-				else if (arg.equals("-cd")) //$NON-NLS-1$
-				{
-					// consume the path
-					if (i+1 < args.length)
-						m_cdPath = args[i++];
-				}
-                else if (arg.equals("-p")) //$NON-NLS-1$
+            if (arg.charAt(0) == '-') {
+                // its an option
+                if (arg.equals("-unit")) // unit-testing mode //$NON-NLS-1$
+                {
+                    System.setProperty("fdbunit", ""); //$NON-NLS-1$ //$NON-NLS-2$
+                } else if (arg.equals("-fullname") || arg.equals("-f")) //$NON-NLS-1$ //$NON-NLS-2$
+                {
+                    m_fullnameOption = true; // emacs mode
+                } else if (arg.equals("-cd")) //$NON-NLS-1$
+                {
+                    // consume the path
+                    if (i + 1 < args.length)
+                        m_cdPath = args[i++];
+                } else if (arg.equals("-p")) //$NON-NLS-1$
                 {
                     // consume the port
-                    if (i+1 < args.length)
+                    if (i + 1 < args.length)
                         m_connectPort = args[++i];
-                }
-                else if (arg.equals("-ide")) //$NON-NLS-1$
+                } else if (arg.equals("-ide")) //$NON-NLS-1$
                 {
                     m_isIde = true;
+                } else if (arg.equals("-lang")) //$NON-NLS-1$
+                {
+                    if (i + 1 < args.length)
+                        getLocalizationManager().setLocale(LocaleUtility.langToLocale(args[++i]));
+
+                } else {
+                    err("Unknown command-line argument: " + arg); //$NON-NLS-1$
                 }
-				else
-				{
-					err("Unknown command-line argument: " + arg);
-				}
-			}
-			else
-			{
-				// its a URI to run
-				StringReader sr = new StringReader("run "+arg+m_newline); //$NON-NLS-1$
-				pushStream( new LineNumberReader(sr) );
-			}
-		}
-	}
-
-	/**
-	 * Dispose of the current line and read the next from the current stream, if its an empty
-	 * line and we are console then repeat last line.
-	 */
-	String readLine() throws IOException
-	{
-		String line = null;
-		if (haveStreams())
-			line = m_in.readLine();
-		else
-			line = keyboardReadLine();
-
-		setCurrentLine(line);
-		return line;
-	}
-
-	/**
-	 * The reader portion of our keyboard input routine
-	 * Block until input arrives.
-	 */
-	synchronized String keyboardReadLine()
-	{
-		// enable a request then block on the queue
-		m_keyboardReadRequest = true;
-		try { wait(); } catch(InterruptedException ie) {}
-
-		// pull from the front of the queue
-		return m_keyboardInput.remove(0);
-	}
-
-	/**
-	 * A seperate thread collects our input so that we can
-	 * block in the doContinue on the main thread and then
-	 * allow the user to interrupt us via keyboard input
-	 * on this thread.
-	 *
-	 * We built the stupid thing in this manner, since readLine()
-	 * will block no matter what and if we 'quit' we can't
-	 * seem to kill this thread.  .close() doesn't work
-	 * and Thread.stop(), etc. all fail to do the job.
-	 *
-	 * Thus we needed to take a request response approach
-	 * so that we only block when requested to do so.
-	 */
-	public void run()
-	{
-		// while we have this stream
-		while(m_keyboardStream != null)
-		{
-			try
-			{
-				// only if someone is requesting us to read do we do so...
-				if (m_keyboardReadRequest)
-				{
-					// block on keyboard input and put it onto the end of the queue
-					String s = m_keyboardStream.readLine();
-					m_keyboardInput.add(s);
-
-					// fullfilled request, now notify blocking thread.
-					m_keyboardReadRequest = false;
-					synchronized(this) { notifyAll(); }
-				}
-				else
-					try { Thread.sleep(50); } catch(InterruptedException ie) {}
-			}
-			catch(IOException io)
-			{
+            } else {
+                // its a URI to run
+                StringReader sr = new StringReader("run " + arg + m_newline); //$NON-NLS-1$
+                pushStream(new LineNumberReader(sr));
+            }
+        }
+    }
+
+    /**
+     * Dispose of the current line and read the next from the current stream, if its an empty
+     * line and we are console then repeat last line.
+     */
+    protected String readLine() throws IOException {
+        String line = null;
+        if (haveStreams())
+            line = m_in.readLine();
+        else
+            line = keyboardReadLine();
+
+        setCurrentLine(line);
+        return line;
+    }
+
+    /**
+     * The reader portion of our keyboard input routine
+     * Block until input arrives.
+     */
+    synchronized String keyboardReadLine() {
+        // enable a request then block on the queue
+        m_keyboardReadRequest = true;
+        try {
+            wait();
+        } catch (InterruptedException ie) {
+        }
+
+        // pull from the front of the queue
+        return m_keyboardInput.remove(0);
+    }
+
+    /**
+     * A seperate thread collects our input so that we can
+     * block in the doContinue on the main thread and then
+     * allow the user to interrupt us via keyboard input
+     * on this thread.
+     * <p/>
+     * We built the stupid thing in this manner, since readLine()
+     * will block no matter what and if we 'quit' we can't
+     * seem to kill this thread.  .close() doesn't work
+     * and Thread.stop(), etc. all fail to do the job.
+     * <p/>
+     * Thus we needed to take a request response approach
+     * so that we only block when requested to do so.
+     */
+    public void run() {
+        // while we have this stream
+        while (m_keyboardStream != null) {
+            try {
+                // only if someone is requesting us to read do we do so...
+                if (m_keyboardReadRequest) {
+                    // block on keyboard input and put it onto the end of the queue
+                    String s = m_keyboardStream.readLine();
+                    m_keyboardInput.add(s);
+
+                    // fullfilled request, now notify blocking thread.
+                    m_keyboardReadRequest = false;
+                    synchronized (this) {
+                        notifyAll();
+                    }
+                } else
+                    try {
+                        Thread.sleep(50);
+                    } catch (InterruptedException ie) {
+                    }
+            } catch (IOException io) {
 //				io.printStackTrace();
-			}
-		}
-	}
-
-	void setCurrentLine(String s)
-	{
-		m_currentLine = s;
-		if (m_currentLine == null)
-			m_currentTokenizer = null;   /* eof */
-		else
-		{
-			m_currentLine = m_currentLine.trim();
+            }
+        }
+    }
+
+    public void setCurrentLine(String s) {
+        m_currentLine = s;
+        if (m_currentLine == null)
+            m_currentTokenizer = null;   /* eof */
+        else {
+            m_currentLine = m_currentLine.trim();
 
 			/* if nothing provided on this command then pull our 'repeat' command  */
-			if (m_repeatLine != null && !haveStreams() && m_currentLine.length() == 0)
-				m_currentLine = m_repeatLine;
-
-			m_currentTokenizer = new StringTokenizer(m_currentLine, " \n\r\t"); //$NON-NLS-1$
-		}
-	}
-
-	/* Helpers for extracting tokens from the current line */
-	public boolean		hasMoreTokens()									{ return m_currentTokenizer.hasMoreTokens(); }
-	public String		nextToken()										{ m_currentToken = m_currentTokenizer.nextToken(); return m_currentToken; }
-	public int			nextIntToken() throws NumberFormatException		{ nextToken(); return Integer.parseInt(m_currentToken);	}
-	public long			nextLongToken() throws NumberFormatException	{ nextToken(); return Long.parseLong(m_currentToken);	}
-	public String		restOfLine()									{ return m_currentTokenizer.nextToken("").trim(); } //$NON-NLS-1$
-
-	public void execute()
-	{
+            if (m_repeatLine != null && !haveStreams() && m_currentLine.length() == 0)
+                m_currentLine = m_repeatLine;
+
+            m_currentTokenizer = new StringTokenizer(m_currentLine, " \n\r\t"); //$NON-NLS-1$
+        }
+    }
+
+    /* Helpers for extracting tokens from the current line */
+    public boolean hasMoreTokens() {
+        return m_currentTokenizer.hasMoreTokens();
+    }
+
+    public String nextToken() {
+        m_currentToken = m_currentTokenizer.nextToken();
+        return m_currentToken;
+    }
+
+    public int nextIntToken() throws NumberFormatException {
+        nextToken();
+        return Integer.parseInt(m_currentToken);
+    }
+
+    public long nextLongToken() throws NumberFormatException {
+        nextToken();
+        return Long.parseLong(m_currentToken);
+    }
+
+    public String restOfLine() {
+        return m_currentTokenizer.nextToken("").trim();
+    } //$NON-NLS-1$
+
+    public void execute() {
 		/* dump console message */
-		displayStartMessage();
-		
+        displayStartMessage();
+
 		/* now fire our keyboard input thread */
-		Thread t = new Thread(this, "Keyboard input"); //$NON-NLS-1$
-		t.start();
+        Thread t = new Thread(this, "Keyboard input"); //$NON-NLS-1$
+        t.start();
 
 		/* keep processing streams until we have no more to do */
-		while(haveStreams())
-		{
-			try
-			{
-				m_in = popStream();
-				process();
-			}
-			catch(EOFException eof)
-			{
-				; /* quite allright */
-			}
-			catch(IOException io)
-			{
-				Map<String, Object> args = new HashMap<String, Object>();
-				args.put("exceptionMessage", io); //$NON-NLS-1$
-				err(getLocalizationManager().getLocalizedTextString("errorWhileProcessingFile", args)); //$NON-NLS-1$
-			}
-		}
+        while (haveStreams()) {
+            try {
+                m_in = popStream();
+                process();
+            } catch (EOFException eof) {
+                ; /* quite allright */
+            } catch (IOException io) {
+                Map<String, Object> args = new HashMap<String, Object>();
+                args.put("exceptionMessage", io); //$NON-NLS-1$
+                err(getLocalizationManager().getLocalizedTextString("errorWhileProcessingFile", args)); //$NON-NLS-1$
+            }
+        }
 
 		/* we done kill everything */
-		exitSession();
+        exitSession();
 
-		// clear this thing, which also halts our other thread.
-		m_keyboardStream = null;
-	}
+        // clear this thing, which also halts our other thread.
+        m_keyboardStream = null;
+    }
 
-	public PrintStream getOut() { return m_out; }
+    public PrintStream getOut() {
+        return m_out;
+    }
 
-	private void displayStartMessage()
-	{
+    private void displayStartMessage() {
         String build = getLocalizationManager().getLocalizedTextString("defaultBuildName"); //$NON-NLS-1$
 
-        try
-        {
+        try {
             Properties p = new Properties();
             p.load(this.getClass().getResourceAsStream("version.properties")); //$NON-NLS-1$
             String buildString = p.getProperty("build"); //$NON-NLS-1$
-            if ((buildString != null) && (! buildString.equals(""))) //$NON-NLS-1$
+            if ((buildString != null) && (!buildString.equals(""))) //$NON-NLS-1$
             {
                 build = buildString;
             }
-        }
-        catch (Throwable t)
-        {
+        } catch (Throwable t) {
             // ignore
         }
 
-        Map<String, Object> aboutMap = new HashMap<String, Object>(); aboutMap.put("build", build); //$NON-NLS-1$
+        Map<String, Object> aboutMap = new HashMap<String, Object>();
+        aboutMap.put("build", build); //$NON-NLS-1$
         out(getLocalizationManager().getLocalizedTextString("about", aboutMap)); //$NON-NLS-1$
-		out(getLocalizationManager().getLocalizedTextString("copyright")); //$NON-NLS-1$
-	}
-
-	void displayPrompt()
-	{
-		m_out.print("(fdb) "); //$NON-NLS-1$
-	}
-
-	void displayCommandPrompt()
-	{
-		m_out.print(">"); //$NON-NLS-1$
-	}
-
-	// add the given character n times to sb
-	void repeat(StringBuilder sb, char c, int n)
-	{
-		while(n-- > 0)
-			sb.append(c);
-	}
-
-	// Prompt the user to respond to a yes or no type question
-	boolean yesNoQuery(String prompt) throws IOException
-	{
-		boolean result = false;
-		m_out.print(prompt);
-		m_out.print(getLocalizationManager().getLocalizedTextString("yesOrNoAppendedToAllQuestions")); //$NON-NLS-1$
-
-		String in = readLine();
-		if (in != null && in.equals(getLocalizationManager().getLocalizedTextString("singleCharacterUserTypesForYes"))) //$NON-NLS-1$
-			result = true;
-		else if (in != null && in.equals("escape")) //$NON-NLS-1$
-			throw new IllegalArgumentException("escape"); //$NON-NLS-1$
-		else
-			out(getLocalizationManager().getLocalizedTextString("yesNoQueryNotConfirmed")); //$NON-NLS-1$
-		return result;
-	}
-
-	public void err(String s)
-	{
-		// Doesn't make sense to send messages to stderr, because this is
-		// an interactive application; and besides that, sending a combination
-		// of interwoven but related messages to both stdout and stderr causes
-		// the output to be in the wrong order sometimes.
-		out(s);
-	}
-
-	public void out(String s)
-	{
-		if (s.length() > 0 && (s.charAt(s.length()-1) == '\n') )
-			m_out.print(s);
-		else
-			m_out.println(s);
-	}
-
-	static String uft()
-	{
-		Runtime rt = Runtime.getRuntime();
-		long free = rt.freeMemory(), total = rt.totalMemory(), used =  total - free;
+        out(getLocalizationManager().getLocalizedTextString("copyright")); //$NON-NLS-1$
+    }
+
+    void displayPrompt() {
+        m_out.print("(fdb) "); //$NON-NLS-1$
+    }
+
+    void displayCommandPrompt() {
+        m_out.print(">"); //$NON-NLS-1$
+    }
+
+    // add the given character n times to sb
+    void repeat(StringBuilder sb, char c, int n) {
+        while (n-- > 0)
+            sb.append(c);
+    }
+
+    // Prompt the user to respond to a yes or no type question
+    boolean yesNoQuery(String prompt) throws IOException {
+        boolean result = false;
+        m_out.print(prompt);
+        m_out.print(getLocalizationManager().getLocalizedTextString("yesOrNoAppendedToAllQuestions")); //$NON-NLS-1$
+
+        String in = readLine();
+        if (in != null && in.equals(getLocalizationManager().getLocalizedTextString("singleCharacterUserTypesForYes"))) //$NON-NLS-1$
+            result = true;
+        else if (in != null && in.equals("escape")) //$NON-NLS-1$
+            throw new IllegalArgumentException("escape"); //$NON-NLS-1$
+        else
+            out(getLocalizationManager().getLocalizedTextString("yesNoQueryNotConfirmed")); //$NON-NLS-1$
+        return result;
+    }
+
+    public void err(String s) {
+        // Doesn't make sense to send messages to stderr, because this is
+        // an interactive application; and besides that, sending a combination
+        // of interwoven but related messages to both stdout and stderr causes
+        // the output to be in the wrong order sometimes.
+        out(s);
+    }
+
+    public void out(String s) {
+        if (s.length() > 0 && (s.charAt(s.length() - 1) == '\n'))
+            m_out.print(s);
+        else
+            m_out.println(s);
+    }
+
+    static String uft() {
+        Runtime rt = Runtime.getRuntime();
+        long free = rt.freeMemory(), total = rt.totalMemory(), used = total - free;
 //		long max = rt.maxMemory();
-		java.text.NumberFormat nf = java.text.NumberFormat.getInstance() ;
+        java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
 //        System.out.println("used: "+nf.format(used)+" free: "+nf.format(free)+" total: "+nf.format(total)+" max: "+nf.format(max));
-        return "Used "+nf.format(used)+" - free "+nf.format(free)+" - total "+nf.format(total); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        return "Used " + nf.format(used) + " - free " + nf.format(free) + " - total " + nf.format(total); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
     }
 
-	/**
-	 * Add all properties that we know about
-	 */
-	void initProperties()
-	{
-		propertyPut(LIST_SIZE, 10);
-		propertyPut(LIST_LINE, 1);
-		propertyPut(LIST_MODULE, 1);  // default to module #1
-		propertyPut(COLUMN_WIDTH, 70);
-		propertyPut(UPDATE_DELAY, 25);
-		propertyPut(HALT_TIMEOUT, 7000);
-		propertyPut(BPNUM, 0);				// set current breakpoint number as something bad
-		propertyPut(LAST_FRAME_DEPTH, 0);		// used to determine how much context information should be displayed
-		propertyPut(CURRENT_FRAME_DEPTH, 0);   // used to determine how much context information should be displayed
-		propertyPut(DISPLAY_FRAME_NUMBER, 0);  // houses the current frame we are viewing
-		propertyPut(FILE_LIST_WRAP, 999999);   // default 1 file name per line
-		propertyPut(NO_WAITING, 0);
-		propertyPut(INFO_STACK_SHOW_THIS, 1); // show this pointer for info stack
-	}
-
-	// getter/setter for properties; in the expression cache, so that they can be used in expressions!
-	public void propertyPut(String k, int v)  { m_exprCache.put(k,v); }
-	public int  propertyGet(String k)		  { return ((Integer)m_exprCache.get(k)).intValue(); }
-	public Set<String>  propertyKeys()		  { return m_exprCache.keySet(); }
-
-	/**
-	 * Process this reader until its done
-	 */
-	void process() throws IOException
-	{
-		boolean done = false;
-		while(!done)
-		{
-			try
-			{
-				/**
-				 * Now if we are in a session and that session is suspended then we go
-				 * into a state where we wait for some user interaction to get us out
-				 */
-				runningLoop();
+    /**
+     * Add all properties that we know about
+     */
+    void initProperties() {
+        propertyPut(LIST_SIZE, 10);
+        propertyPut(LIST_LINE, 1);
+        propertyPut(LIST_MODULE, 1);  // default to module #1
+        propertyPut(LIST_WORKER, Isolate.DEFAULT_ID);
+        propertyPut(COLUMN_WIDTH, 70);
+        propertyPut(UPDATE_DELAY, 25);
+        propertyPut(HALT_TIMEOUT, 7000);
+        propertyPut(BPNUM, 0);                // set current breakpoint number as something bad
+        propertyPut(LAST_FRAME_DEPTH, 0);        // used to determine how much context information should be displayed
+        propertyPut(CURRENT_FRAME_DEPTH, 0);   // used to determine how much context information should be displayed
+        propertyPut(DISPLAY_FRAME_NUMBER, 0);  // houses the current frame we are viewing
+        propertyPut(FILE_LIST_WRAP, 999999);   // default 1 file name per line
+        propertyPut(NO_WAITING, 0);
+        propertyPut(INFO_STACK_SHOW_THIS, 1); // show this pointer for info stack
+    }
+
+    // getter/setter for properties; in the expression cache, so that they can be used in expressions!
+    public void propertyPut(String k, int v) {
+        m_exprCache.put(k, v);
+    }
+
+    public int propertyGet(String k) {
+        return ((Integer) m_exprCache.get(k)).intValue();
+    }
+
+    public Set<String> propertyKeys() {
+        return m_exprCache.keySet();
+    }
+
+    /**
+     * Process this reader until its done
+     */
+    void process() throws IOException {
+        boolean done = false;
+        while (!done) {
+            try {
+                /**
+                 * Now if we are in a session and that session is suspended then we go
+                 * into a state where we wait for some user interaction to get us out
+                 */
+                runningLoop();
 
 				/* if we are in the stdin then put out a prompt */
-				if (!haveStreams())
-					displayPrompt();
+                if (!haveStreams())
+                    displayPrompt();
 
 				/* now read in the next line */
-				readLine();
-				if (m_currentLine == null)
-					break;
-
-				done = processLine();
-			}
-			catch(NoResponseException nre)
-			{
-				err(getLocalizationManager().getLocalizedTextString("noResponseException")); //$NON-NLS-1$
-			}
-			catch(NotSuspendedException nse)
-			{
-				err(getLocalizationManager().getLocalizedTextString("notSuspendedException")); //$NON-NLS-1$
-			}
-			catch(AmbiguousException ae)
-			{
-				// we already put up a warning for the user
-			}
-			catch(IllegalStateException ise)
-			{
-				err(getLocalizationManager().getLocalizedTextString("illegalStateException")); //$NON-NLS-1$
-			}
-			catch(IllegalMonitorStateException ime)
-			{
-				err(getLocalizationManager().getLocalizedTextString("illegalMonitorStateException")); //$NON-NLS-1$
-			}
-			catch(NoSuchElementException nse)
-			{
-				err(getLocalizationManager().getLocalizedTextString("noSuchElementException")); //$NON-NLS-1$
-			}
-			catch(NumberFormatException nfe)
-			{
-				err(getLocalizationManager().getLocalizedTextString("numberFormatException")); //$NON-NLS-1$
-			}
-			catch(SocketException se)
-			{
-				Map<String, Object> socketArgs = new HashMap<String, Object>();
-				socketArgs.put("message", se.getMessage()); //$NON-NLS-1$
-				err(getLocalizationManager().getLocalizedTextString("socketException", socketArgs)); //$NON-NLS-1$
-			}
-			catch(VersionException ve)
-			{
-				err(getLocalizationManager().getLocalizedTextString("versionException")); //$NON-NLS-1$
-			}
-			catch(NotConnectedException nce)
-			{
-				// handled by isConnectionLost()
-			}
-			catch(Exception e)
-			{
-				err(getLocalizationManager().getLocalizedTextString("unexpectedError")); //$NON-NLS-1$
-				err(getLocalizationManager().getLocalizedTextString("stackTraceFollows")); //$NON-NLS-1$
-				e.printStackTrace();
-			}
-
-			// check for a lost connection and if it is clean-up!
-			if (isConnectionLost())
-			{
-				try
-				{
-					dumpHaltState(false);
-				}
-				catch(PlayerDebugException pde)
-				{
-					err(getLocalizationManager().getLocalizedTextString("sessionEndedAbruptly")); //$NON-NLS-1$
-				}
-			}
-		}
-	}
-
-	// check if we have lost the connect without our help...
-	boolean isConnectionLost()
-	{
-		boolean lost = false;
-
-		if (m_session != null && !m_session.isConnected())
-			lost = true;
-
-		return lost;
-	}
-
-	boolean haveConnection()
-	{
-		boolean have = false;
-
-		if (m_session != null && m_session.isConnected())
-			have = true;
-
-		return have;
-	}
-
-	void doShow() throws AmbiguousException, PlayerDebugException
-	{
+                readLine();
+                if (m_currentLine == null)
+                    break;
+
+                done = processLine();
+            } catch (NoResponseException nre) {
+                err(getLocalizationManager().getLocalizedTextString("noResponseException")); //$NON-NLS-1$
+            } catch (NotSuspendedException nse) {
+                err(getLocalizationManager().getLocalizedTextString("notSuspendedException")); //$NON-NLS-1$
+            } catch (AmbiguousException ae) {
+                // we already put up a warning for the user
+            } catch (IllegalStateException ise) {
+                err(getLocalizationManager().getLocalizedTextString("illegalStateException")); //$NON-NLS-1$
+            } catch (IllegalMonitorStateException ime) {
+                err(getLocalizationManager().getLocalizedTextString("illegalMonitorStateException")); //$NON-NLS-1$
+            } catch (NoSuchElementException nse) {
+                err(getLocalizationManager().getLocalizedTextString("noSuchElementException")); //$NON-NLS-1$
+            } catch (NumberFormatException nfe) {
+                err(getLocalizationManager().getLocalizedTextString("numberFormatException")); //$NON-NLS-1$
+            } catch (SocketException se) {
+                Map<String, Object> socketArgs = new HashMap<String, Object>();
+                socketArgs.put("message", se.getMessage()); //$NON-NLS-1$
+                err(getLocalizationManager().getLocalizedTextString("socketException", socketArgs)); //$NON-NLS-1$
+            } catch (VersionException ve) {
+                err(getLocalizationManager().getLocalizedTextString("versionException")); //$NON-NLS-1$
+            } catch (NotConnectedException nce) {
+                // handled by isConnectionLost()
+            } catch (Exception e) {
+                err(getLocalizationManager().getLocalizedTextString("unexpectedError")); //$NON-NLS-1$
+                err(getLocalizationManager().getLocalizedTextString("stackTraceFollows")); //$NON-NLS-1$
+                e.printStackTrace();
+            }
+
+            // check for a lost connection and if it is clean-up!
+            if (isConnectionLost()) {
+                try {
+                    dumpHaltState(false);
+                } catch (PlayerDebugException pde) {
+                    err(getLocalizationManager().getLocalizedTextString("sessionEndedAbruptly")); //$NON-NLS-1$
+                }
+            }
+        }
+    }
+
+    // check if we have lost the connect without our help...
+    boolean isConnectionLost() {
+        boolean lost = false;
+
+        if (m_session != null && !m_session.isConnected())
+            lost = true;
+
+        return lost;
+    }
+
+    boolean haveConnection() {
+        boolean have = false;
+
+        if (m_session != null && m_session.isConnected())
+            have = true;
+
+        return have;
+    }
+
+    void doShow() throws AmbiguousException, PlayerDebugException {
 		/* show without any args brings up help */
-		if (!hasMoreTokens())
-			out( getHelpTopic("show") ); //$NON-NLS-1$
-		else
-		{
-			/* otherwise we have a boatload of options */
-			String subCmdString = nextToken();
-			int subCmd = showCommandFor(subCmdString);
-			switch(subCmd)
-			{
-				case SHOW_NET_CMD:
-					doShowStats();
-					break;
-
-				case SHOW_FUNC_CMD:
-					doShowFuncs();
-					break;
-
-				case SHOW_URI_CMD:
-					doShowUri();
-					break;
-
-				case SHOW_PROPERTIES_CMD:
-					doShowProperties();
-					break;
-
-				case SHOW_FILES_CMD:
-					doShowFiles();
-					break;
-
-				case SHOW_BREAK_CMD:
-					doShowBreak();
-					break;
-
-				case SHOW_VAR_CMD:
-					doShowVariable();
-					break;
-
-				case SHOW_MEM_CMD:
-					doShowMemory();
-					break;
-
-				case SHOW_LOC_CMD:
-					doShowLocations();
-					break;
-
-				case SHOW_DIRS_CMD:
-					doShowDirectories();
-					break;
-
-				default:
-					doUnknown("show", subCmdString); //$NON-NLS-1$
-					break;
-			}
-		}
-	}
-
-	void doShowUri()
-	{
-		// dump the URI that the player has sent us
-		try
-		{
-			StringBuilder sb = new StringBuilder();
-			sb.append("URI = "); //$NON-NLS-1$
-			sb.append( m_session.getURI() );
-			out( sb.toString() );
-		}
-		catch(Exception e)
-		{
-			err(getLocalizationManager().getLocalizedTextString("noUriReceived")); //$NON-NLS-1$
-		}
-	}
-
-	/**
-	 * Dump the content of files in a raw format
-	 */
-	void doShowFiles()
-	{
-		try
-		{
-			StringBuilder sb = new StringBuilder();
-			Iterator itr = m_fileInfo.getAllFiles();
-
-			while(itr.hasNext())
-			{
-				SourceFile m = (SourceFile) ((Map.Entry)itr.next()).getValue();
-
-				String name = m.getName();
-				int id = m.getId();
-				String path = m.getFullPath();
-
-				sb.append(id);
-				sb.append(' ');
-				sb.append(path);
-				sb.append(", "); //$NON-NLS-1$
-				sb.append(name);
-				sb.append(m_newline);
-			}
-			out( sb.toString() );
-		}
-		catch(NullPointerException npe)
-		{
-			err(getLocalizationManager().getLocalizedTextString("noSourceFilesFound")); //$NON-NLS-1$
-		}
-	}
-
-	void doShowMemory()
-	{
-		out(uft());
-	}
-
-	void doShowLocations()
-	{
-		StringBuilder sb = new StringBuilder();
-		sb.append("Num Type           Disp Enb Address    What"+m_newline);
-
-		// our list of breakpoints
-		int count = breakpointCount();
-		for(int i=0; i<count; i++)
-		{
-			BreakAction b = breakpointAt(i);
-			int num = b.getId();
-
-			FieldFormat.formatLong(sb, num, 3);
-			sb.append(" breakpoint     ");
-
-			if (b.isAutoDisable())
-				sb.append("dis  ");
-			else if (b.isAutoDelete())
-				sb.append("del  ");
-			else
-				sb.append("keep ");
-
-			if (b.isEnabled())
-				sb.append("y   ");
-			else
-				sb.append("n   ");
-
-			Iterator<Location> itr = b.getLocations().iterator();
-			while(itr.hasNext())
-			{
-				Location l = itr.next();
-				SourceFile file = l.getFile();
-				String funcName = (file == null)
-					? getLocalizationManager().getLocalizedTextString("unknownBreakpointLocation") //$NON-NLS-1$
-					: file.getFunctionNameForLine(m_session, l.getLine()) ;
-				int offset = adjustOffsetForUnitTests((file == null) ? 0 : file.getOffsetForLine(l.getLine()));
-
-				sb.append("0x"); //$NON-NLS-1$
-				FieldFormat.formatLongToHex(sb, offset, 8);
-				sb.append(' ');
-
-				if (funcName != null)
-				{
-					Map<String, Object> funcArgs = new HashMap<String, Object>();
-					funcArgs.put("functionName", funcName); //$NON-NLS-1$
-					sb.append(getLocalizationManager().getLocalizedTextString("inFunctionAt", funcArgs)); //$NON-NLS-1$
-				}
-
-				sb.append(file.getName());
-				if (file != null)
-				{
-					sb.append("#"); //$NON-NLS-1$
-					sb.append(file.getId());
-				}
-				sb.append(':');
-				sb.append(l.getLine());
-
-				try
-				{
-					SwfInfo info = m_fileInfo.swfForFile(file);
-					Map<String, Object> swfArgs = new HashMap<String, Object>();
-					swfArgs.put("swf", FileInfoCache.shortNameOfSwf(info)); //$NON-NLS-1$
-					sb.append(getLocalizationManager().getLocalizedTextString("inSwf", swfArgs)); //$NON-NLS-1$
-				}
-				catch(NullPointerException npe)
-				{
-					// can't find the swf
-					sb.append(getLocalizationManager().getLocalizedTextString("nonRestorable")); //$NON-NLS-1$
-				}
-				sb.append(m_newline);
-				if (itr.hasNext())
-					sb.append("                            "); //$NON-NLS-1$
-			}
-		}
-		out(sb.toString());
-	}
-
-	/**
-	 * When running unit tests, we want byte offsets into the file to
-	 * always be displayed as zero, so that the unit test expected
-	 * results will match up with the actual results.  This is just a
-	 * simple helper function that deals with that.
-	 */
-	private int adjustOffsetForUnitTests(int offset)
-	{
-		if (System.getProperty("fdbunit")==null) //$NON-NLS-1$
-			return offset;
-		else
-			return 0;
-	}
-
-	void doShowDirectories()
-	{
-		out(getLocalizationManager().getLocalizedTextString("sourceDirectoriesSearched")); //$NON-NLS-1$
-		Iterator<String> iter = m_sourceDirectories.iterator();
-		while (iter.hasNext())
-		{
-			String dir = iter.next();
-			out("  " + dir); //$NON-NLS-1$
-		}
-	}
-
-	void doHalt() throws SuspendedException, NotConnectedException, NoResponseException
-	{
-		out(getLocalizationManager().getLocalizedTextString("attemptingToSuspend")); //$NON-NLS-1$
-		m_session.suspend();
-		if (m_session.isSuspended())
-			out(getLocalizationManager().getLocalizedTextString("playerStopped")); //$NON-NLS-1$
-		else
-			out(getLocalizationManager().getLocalizedTextString("playerRunning")); //$NON-NLS-1$
-	}
-
-	public void appendReason(StringBuilder sb, int reason)
-	{
-		switch(reason)
-		{
-			case SuspendReason.Unknown:
-				sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_Unknown")); //$NON-NLS-1$
-				break;
-
-			case SuspendReason.Breakpoint:
-				sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_HitBreakpoint")); //$NON-NLS-1$
-				break;
-
-			case SuspendReason.Watch:
-				sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_HitWatchpoint")); //$NON-NLS-1$
-				break;
-
-			case SuspendReason.Fault:
-				sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_ProgramThrewException")); //$NON-NLS-1$
-				break;
-
-			case SuspendReason.StopRequest:
-				sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_StopRequest")); //$NON-NLS-1$
-				break;
-
-			case SuspendReason.Step:
-				sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_ProgramFinishedStepping")); //$NON-NLS-1$
-				break;
-
-			case SuspendReason.HaltOpcode:
-				sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_HaltOpcode")); //$NON-NLS-1$
-				break;
-
-			case SuspendReason.ScriptLoaded:
-				sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_ScriptHasLoadedIntoFlashPlayer")); //$NON-NLS-1$
-				break;
-		}
-	}
-
-	/**
-	 * The big ticket item, where all your questions are answered.
-	 *
-	 */
-	void doInfo() throws AmbiguousException, PlayerDebugException
-	{
-		/* info without any args brings up help */
-		if (!hasMoreTokens())
-			out( getHelpTopic("info") ); //$NON-NLS-1$
-		else
-		{
+        if (!hasMoreTokens())
+            out(getHelpTopic("show")); //$NON-NLS-1$
+        else {
 			/* otherwise we have a boatload of options */
-			String subCmdString = nextToken();
-			int subCmd = infoCommandFor(subCmdString);
-			switch(subCmd)
-			{
-				case INFO_ARGS_CMD:
-					doInfoArgs();
-					break;
-
-				case INFO_BREAK_CMD:
-					doInfoBreak();
-					break;
-
-				case INFO_FILES_CMD:
-					doInfoFiles();
-					break;
-
-				case INFO_FUNCTIONS_CMD:
-					doInfoFuncs();
-					break;
-
-				case INFO_HANDLE_CMD:
-					doInfoHandle();
-					break;
-
-				case INFO_LOCALS_CMD:
-					doInfoLocals();
-					break;
-
-				case INFO_SCOPECHAIN_CMD:
-					doInfoScopeChain();
-					break;
-					
-				case INFO_SOURCES_CMD:
-					doInfoSources();
-					break;
-
-				case INFO_STACK_CMD:
-					doInfoStack();
-					break;
-
-				case INFO_VARIABLES_CMD:
-					doInfoVariables();
-					break;
-
-				case INFO_DISPLAY_CMD:
-					doInfoDisplay();
-					break;
+            String subCmdString = nextToken();
+            int subCmd = showCommandFor(subCmdString);
+            switch (subCmd) {
+                case SHOW_NET_CMD:
+                    doShowStats();
+                    break;
 
-                case INFO_TARGETS_CMD:
-                    doInfoTargets();
+                case SHOW_FUNC_CMD:
+                    doShowFuncs();
                     break;
 
-                case INFO_SWFS_CMD:
-                    doInfoSwfs();
+                case SHOW_URI_CMD:
+                    doShowUri();
                     break;
 
-				default:
-					doUnknown("info", subCmdString); //$NON-NLS-1$
-					break;
-			}
-		}
-	}
-
-	void doInfoStack() throws PlayerDebugException
-	{
-		waitTilHalted();
-
-		StringBuilder sb = new StringBuilder();
-		Frame[] stack = m_session.getFrames();
-		if (stack == null || stack.length == 0)
-			sb.append(getLocalizationManager().getLocalizedTextString("noStackAvailable")); //$NON-NLS-1$
-		else
-		{
-			boolean showThis = propertyGet(INFO_STACK_SHOW_THIS) == 1;
-			for(int i=0; i<stack.length; i++)
-			{
-				// keep spitting out frames until we can't
-				Frame frame = stack[i];
-				boolean valid = appendFrameInfo(sb, frame, i, showThis, true);
-				sb.append(m_newline);
-                if (!valid)
+                case SHOW_PROPERTIES_CMD:
+                    doShowProperties();
                     break;
-			}
-		}
 
-		/* dump it out */
-		out(sb.toString());
-	}
-	
-	/**
-	 * Spit out frame information for a given frame number 
-	 */
-	boolean appendFrameInfo(StringBuilder sb, Frame ctx, int frameNumber, boolean showThis, boolean showFileId) throws PlayerDebugException
-	{
-		boolean validFrame = true;
-
-		// some formatting properties
-		int i = frameNumber;
-
-		Location loc = ctx.getLocation();
-		SourceFile file = loc.getFile();
-		int line = loc.getLine();
-		String name = (file == null) ? "<null>" : file.getName(); //$NON-NLS-1$
-		String sig = ctx.getCallSignature();
-		String func = extractFunctionName(sig);
-
-		// file == null or line < 0 appears to be a terminator for stack info
-		if (file == null && line < 0)
-        {
-            validFrame = false;
-        }
-        else
-		{
-			Variable[] var = ctx.getArguments(m_session);
-			Variable dis = ctx.getThis(m_session);
-			boolean displayArgs = (func != null) || (var != null);
-
-			sb.append('#');
-			FieldFormat.formatLong(sb, i, 3);
-			sb.append(' ');
-
-			if (showThis && dis != null)
-			{
-                m_exprCache.appendVariable(sb, dis);
-				sb.append("."); //$NON-NLS-1$
-			}
-
-			if (func != null)
-				sb.append(func);
-
-			if (displayArgs)
-			{
-				sb.append('(');
-				for (int j=0; j<var.length; j++)
-				{
-					Variable v = var[j];
-					sb.append(v.getName());
-					sb.append('=');
-                    m_exprCache.appendVariableValue(sb, v.getValue());
-					if ((j+1)<var.length)
-						sb.append(", "); //$NON-NLS-1$
-				}
-				sb.append(")"); //$NON-NLS-1$
-				sb.append(getLocalizationManager().getLocalizedTextString("atFilename")); //$NON-NLS-1$
-			}
-
-			sb.append(name);
-
-			// if this file is currently being filtered put the source file id after it
-			if (file != null && (showFileId || !m_fileInfo.inFileList(file)))
-			{
-				sb.append('#');
-				sb.append( file.getId() );
-
-			}
-			sb.append(':');
-			sb.append(line);
-		}
-        return validFrame;
-	}
-
-	/** extract the function name from a signature */
-	public static String extractFunctionName(String sig)
-	{ 
-		// strip everything after the leading ( 
-		int at = sig.indexOf('(');
-		if (at > -1)
-			sig = sig.substring(0, at);
-
-		// trim the leading [object_name::] since it doesn't seem to add much
-		if (sig != null && (at = sig.indexOf("::")) > -1) //$NON-NLS-1$
-			sig = sig.substring(at+2);
-
-		return sig;
-	}
-
-	void doInfoVariables() throws PlayerDebugException
-	{
-		waitTilHalted();
-
-		// dump a set of locals
-		StringBuilder sb = new StringBuilder();
-
-		// use our expression cache formatting routine
-		try
-		{
-			Variable[] vars = m_session.getVariableList();
-			for(int i=0; i<vars.length; i++)
-			{
-				Variable v = vars[i];
-
-				// all non-local and non-arg variables
-				if ( !v.isAttributeSet(VariableAttribute.IS_LOCAL) &&
-					 !v.isAttributeSet(VariableAttribute.IS_ARGUMENT) )
-				{
-					m_exprCache.appendVariable(sb, vars[i]);
-					sb.append(m_newline);
-				}
-			}
-		}
-		catch(NullPointerException npe)
-		{
-			sb.append(getLocalizationManager().getLocalizedTextString("noVariables")); //$NON-NLS-1$
-		}
-
-		out(sb.toString());
-	}
-
-	void doInfoDisplay()
-	{
-		StringBuilder sb = new StringBuilder();
-		sb.append("Num Enb Expression"+m_newline); //$NON-NLS-1$
-
-		// our list of displays
-		int count = displayCount();
-		for(int i=0; i<count; i++)
-		{
-			DisplayAction b = displayAt(i);
-			int num = b.getId();
-			String exp = b.getContent();
-
-			sb.append(':');
-			FieldFormat.formatLong(sb, num, 3);
-
-			if (b.isEnabled())
-				sb.append(" y  "); //$NON-NLS-1$
-			else
-				sb.append(" n  "); //$NON-NLS-1$
-
-			sb.append(exp);
-			sb.append(m_newline);
-		}
-
-		out(sb.toString());
-	}
-
-	void doInfoArgs() throws PlayerDebugException
-	{
-		waitTilHalted();
-
-		// dump a set of locals
-		StringBuilder sb = new StringBuilder();
-
-		// use our expression cache formatting routine
-		try
-		{
-			int num = propertyGet(DISPLAY_FRAME_NUMBER);
-			Frame[] frames = m_session.getFrames();
-			Variable[] vars = frames[num].getArguments(m_session);
-			for(int i=0; i<vars.length; i++)
-			{
-                m_exprCache.appendVariable(sb, vars[i]);
-				sb.append(m_newline);
-			}
-		}
-		catch(NullPointerException npe)
-		{
-			sb.append(getLocalizationManager().getLocalizedTextString("noArguments")); //$NON-NLS-1$
-		}
-        catch(ArrayIndexOutOfBoundsException aix)
-        {
-            sb.append(getLocalizationManager().getLocalizedTextString("notInValidFrame")); //$NON-NLS-1$
+                case SHOW_FILES_CMD:
+                    doShowFiles();
+                    break;
+
+                case SHOW_BREAK_CMD:
+                    doShowBreak();
+                    break;
+
+                case SHOW_VAR_CMD:
+                    doShowVariable();
+                    break;
+
+                case SHOW_MEM_CMD:
+                    doShowMemory();
+                    break;
+
+                case SHOW_LOC_CMD:
+                    doShowLocations();
+                    break;
+
+                case SHOW_DIRS_CMD:
+                    doShowDirectories();
+                    break;
+
+                default:
+                    doUnknown("show", subCmdString); //$NON-NLS-1$
+                    break;
+            }
         }
+    }
 
-		out(sb.toString());
-	}
-
-	void doInfoLocals() throws PlayerDebugException
-	{
-		waitTilHalted();
-
-		// dump a set of locals
-		StringBuilder sb = new StringBuilder();
-
-		// use our expression cache formatting routine
-		try
-		{
-			// get the variables from the requested frame
-			int num = propertyGet(DISPLAY_FRAME_NUMBER);
-			Frame[] ar = m_session.getFrames();
-			Frame ctx = ar[num];
-			Variable[] vars = ctx.getLocals(m_session);
-
-			for(int i=0; i<vars.length; i++)
-			{
-				Variable v = vars[i];
-
-				// see if variable is local
-				if ( v.isAttributeSet(VariableAttribute.IS_LOCAL) )
-				{
-                    m_exprCache.appendVariable(sb, v);
-					sb.append(m_newline);
-				}
-			}
-		}
-		catch(NullPointerException npe)
-		{
-			sb.append(getLocalizationManager().getLocalizedTextString("noLocals")); //$NON-NLS-1$
-		}
-        catch(ArrayIndexOutOfBoundsException aix)
-        {
-            sb.append(getLocalizationManager().getLocalizedTextString("notInValidFrame")); //$NON-NLS-1$
+    void doShowUri() {
+        // dump the URI that the player has sent us
+        try {
+            StringBuilder sb = new StringBuilder();
+            sb.append("URI = "); //$NON-NLS-1$
+            sb.append(m_session.getURI());
+            out(sb.toString());
+        } catch (Exception e) {
+            err(getLocalizationManager().getLocalizedTextString("noUriReceived")); //$NON-NLS-1$
         }
+    }
 
-		out(sb.toString());
-	}
-
-	void doInfoScopeChain() throws PlayerDebugException
-	{
-		waitTilHalted();
-
-		// dump the scope chain
-		StringBuilder sb = new StringBuilder();
-
-		// use our expression cache formatting routine
-		try
-		{
-			// get the scope chainfrom the requested frame
-			int num = propertyGet(DISPLAY_FRAME_NUMBER);
-			Frame[] ar = m_session.getFrames();
-			Frame ctx = ar[num];
-			Variable[] scopes = ctx.getScopeChain(m_session);
-
-			for(int i=0; i<scopes.length; i++)
-			{
-				Variable scope = scopes[i];
-                m_exprCache.appendVariable(sb, scope);
-				sb.append(m_newline);
-			}
-		}
-		catch(NullPointerException npe)
-		{
-			sb.append(getLocalizationManager().getLocalizedTextString("noScopeChain")); //$NON-NLS-1$
-		}
-        catch(ArrayIndexOutOfBoundsException aix)
-        {
-            sb.append(getLocalizationManager().getLocalizedTextString("notInValidFrame")); //$NON-NLS-1$
+    /**
+     * Dump the content of files in a raw format
+     */
+    void doShowFiles() {
+        try {
+            StringBuilder sb = new StringBuilder();
+            for (Isolate isolate : m_session.getWorkers()) {
+
+                Iterator itr = m_fileInfo.getAllFiles(isolate.getId());
+
+                while (itr.hasNext()) {
+                    SourceFile m = (SourceFile) ((Map.Entry) itr.next()).getValue();
+
+                    String name = m.getName();
+                    int id = m.getId();
+                    String path = m.getFullPath();
+
+                    sb.append(id);
+                    sb.append(' ');
+                    sb.append(path);
+                    sb.append(", "); //$NON-NLS-1$
+                    sb.append(name);
+                    sb.append(" ("); //$NON-NLS-1$
+                    if (isolate.getId() == Isolate.DEFAULT_ID) {
+                        sb.append(getLocalizationManager().getLocalizedTextString("mainThread")); //$NON-NLS-1$
+                    } else {
+                        HashMap<String, Object> wArgs = new HashMap<String, Object>();
+                        wArgs.put("worker", isolate.getId() - 1); //$NON-NLS-1$
+                        sb.append(getLocalizationManager().getLocalizedTextString("inWorker", wArgs)); //$NON-NLS-1$
+                    }
+                    sb.append(")"); //$NON-NLS-1$
+                    sb.append(m_newline);
+                }
+            }
+            out(sb.toString());
+        } catch (NullPointerException npe) {
+            err(getLocalizationManager().getLocalizedTextString("noSourceFilesFound")); //$NON-NLS-1$
         }
+    }
 
-		out(sb.toString());
-	}
-	
-	void doInfoTargets()
-    {
-        if (!haveConnection())
-		{
-			out(getLocalizationManager().getLocalizedTextString("noActiveSession")); //$NON-NLS-1$
-			if (m_launchURI != null)
-			{
-				Map<String, Object> args = new HashMap<String, Object>();
-				args.put("uri", m_launchURI); //$NON-NLS-1$
-				out(getLocalizationManager().getLocalizedTextString("runWillLaunchUri", args)); //$NON-NLS-1$
-			}
-		}
-        else
-		{
-			String uri = m_session.getURI();
-			if (uri == null || uri.length() < 1)
-				err(getLocalizationManager().getLocalizedTextString("targetUnknown")); //$NON-NLS-1$
-			else
-				out(uri);
-		}
+    void doShowMemory() {
+        out(uft());
     }
 
-	/**
-	 * Dump some stats about our currently loaded swfs.
-	 */
-    void doInfoSwfs()
-    {
-		try
-		{
-			StringBuilder sb = new StringBuilder();
-			SwfInfo[] swfs = m_fileInfo.getSwfs();
-			for(int i=0; i<swfs.length; i++)
-			{
-				SwfInfo e = swfs[i];
-				if (e == null || e.isUnloaded())
-					continue;
-
-				Map<String, Object> args = new HashMap<String, Object>();
-				args.put("swfName", FileInfoCache.nameOfSwf(e)); //$NON-NLS-1$
-				args.put("size", NumberFormat.getInstance().format(e.getSwfSize())); //$NON-NLS-1$
-
-				try
-				{
-					int size = e.getSwdSize(m_session);
-
-					// our swd is loaded so let's comb through our
-					// list of scripts and locate the range of ids.
-					SourceFile[] files = e.getSourceList(m_session);
-					int max = Integer.MIN_VALUE;
-					int min = Integer.MAX_VALUE;
-					for(int j=0; j<files.length; j++)
-					{
-						SourceFile f = files[j];
-						int id = f.getId();
-						max = (id > max) ? id : max;
-						min = (id < min) ? id : min;
-					}
-
-					args.put("scriptCount", Integer.toString(e.getSourceCount(m_session))); //$NON-NLS-1$
-					args.put("min", Integer.toString(min)); //$NON-NLS-1$
-					args.put("max", Integer.toString(max)); //$NON-NLS-1$
-					args.put("plus", (e.isProcessingComplete()) ? "+" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-					args.put("moreInfo", (size==0) ? getLocalizationManager().getLocalizedTextString("remainingSourceBeingLoaded") : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-				}
-				catch(InProgressException ipe)
-				{
-					sb.append(getLocalizationManager().getLocalizedTextString("debugInfoBeingLoaded")); //$NON-NLS-1$
-				}
-				args.put("url", e.getUrl()); //$NON-NLS-1$
-				sb.append(getLocalizationManager().getLocalizedTextString("swfInfo", args)); //$NON-NLS-1$
-				sb.append(m_newline);
-			}
-			out( sb.toString() );
-		}
-		catch(NullPointerException npe)
-		{
-			err(getLocalizationManager().getLocalizedTextString("noSWFs")); //$NON-NLS-1$
-		}
-    }
-
-	private static final int AUTHORED_FILE = 1;		// a file that was created by the end user, e.g. MyApp.mxml
-	private static final int FRAMEWORK_FILE = 2;	// a file from the Flex framework, e.g. mx.controls.Button.as, see FRAMEWORK_FILE_PACKAGES
-	private static final int SYNTHETIC_FILE = 3;	// e.g. "<set up XML utilities.1>"
-	private static final int ACTIONS_FILE = 4;		// e.g. "Actions for UIComponent: Frame 1 of Layer Name Layer 1"
+    void doShowLocations() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Num Type           Disp Enb Address    What" + m_newline); //$NON-NLS-1$
 
-    private static final String[] FRAMEWORK_FILE_PACKAGES // package prefixes that we consider FRAMEWORK_FILEs
-        = new String[] {"mx","flex","text"}; // 'text' is Vellum (temporary) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        // our list of breakpoints
+        int count = breakpointCount();
+        for (int i = 0; i < count; i++) {
+            BreakAction b = breakpointAt(i);
+            int num = b.getId();
 
-	/**
-	 * Given a file, guesses what type it is -- e.g. a file created by the end user,
-	 * or a file from the Flex framework, etc.
+            FieldFormat.formatLong(sb, num, 3);
+            sb.append(" breakpoint     "); //$NON-NLS-1$
+
+            if (b.isAutoDisable())
+                sb.append("dis  "); //$NON-NLS-1$
+            else if (b.isAutoDelete())
+                sb.append("del  "); //$NON-NLS-1$
+            else
+                sb.append("keep "); //$NON-NLS-1$
+
+            if (b.isEnabled())
+                sb.append("y   "); //$NON-NLS-1$
+            else
+                sb.append("n   "); //$NON-NLS-1$
+
+            Iterator<Location> itr = b.getLocations().iterator();
+            while (itr.hasNext()) {
+                Location l = itr.next();
+                SourceFile file = l.getFile();
+                String funcName = (file == null)
+                        ? getLocalizationManager().getLocalizedTextString("unknownBreakpointLocation") //$NON-NLS-1$
+                        : file.getFunctionNameForLine(m_session, l.getLine());
+                int offset = adjustOffsetForUnitTests((file == null) ? 0 : file.getOffsetForLine(l.getLine()));
+
+                sb.append("0x"); //$NON-NLS-1$
+                FieldFormat.formatLongToHex(sb, offset, 8);
+                sb.append(' ');
+
+                if (funcName != null) {
+                    Map<String, Object> funcArgs = new HashMap<String, Object>();
+                    funcArgs.put("functionName", funcName); //$NON-NLS-1$
+                    sb.append(getLocalizationManager().getLocalizedTextString("inFunctionAt", funcArgs)); //$NON-NLS-1$
+                }
+
+                sb.append(file.getName());
+                if (file != null) {
+                    sb.append("#"); //$NON-NLS-1$
+                    sb.append(file.getId());
+                }
+                sb.append(':');
+                sb.append(l.getLine());
+
+                try {
+                    SwfInfo info = m_fileInfo.swfForFile(file, l.getIsolateId());
+                    Map<String, Object> swfArgs = new HashMap<String, Object>();
+                    swfArgs.put("swf", FileInfoCache.shortNameOfSwf(info)); //$NON-NLS-1$
+                    sb.append(getLocalizationManager().getLocalizedTextString("inSwf", swfArgs)); //$NON-NLS-1$
+                    if (l.getIsolateId() == Isolate.DEFAULT_ID) {
+                        sb.append(" ("); //$NON-NLS-1$
+                        sb.append(getLocalizationManager().getLocalizedTextString("mainThread")); //$NON-NLS-1$
+                        sb.append(")"); //$NON-NLS-1$
+                    } else {
+                        swfArgs = new HashMap<String, Object>();
+                        swfArgs.put("worker", l.getIsolateId() - 1); //$NON-NLS-1$
+                        sb.append(" ("); //$NON-NLS-1$
+                        sb.append(getLocalizationManager().getLocalizedTextString("inWorker", swfArgs)); //$NON-NLS-1$
+                        sb.append(")"); //$NON-NLS-1$
+                    }
+                } catch (NullPointerException npe) {
+                    // can't find the swf
+                    sb.append(getLocalizationManager().getLocalizedTextString("nonRestorable")); //$NON-NLS-1$
+                }
+                sb.append(m_newline);
+                if (itr.hasNext())
+                    sb.append("                            "); //$NON-NLS-1$
+            }
+        }
+        out(sb.toString());
+    }
+
+    /**
+     * When running unit tests, we want byte offsets into the file to
+     * always be displayed as zero, so that the unit test expected
+     * results will match up with the actual results.  This is just a
+     * simple helper function that deals with that.
+     */
+    private int adjustOffsetForUnitTests(int offset) {
+        if (System.getProperty("fdbunit") == null) //$NON-NLS-1$
+            return offset;
+        else
+            return 0;
+    }
+
+    void doShowDirectories() {
+        out(getLocalizationManager().getLocalizedTextString("sourceDirectoriesSearched")); //$NON-NLS-1$
+        Iterator<String> iter = m_sourceDirectories.iterator();
+        while (iter.hasNext()) {
+            String dir = iter.next();
+            out("  " + dir); //$NON-NLS-1$
+        }
+    }
+
+    void doHalt() throws SuspendedException, NotConnectedException, NoResponseException {
+        out(getLocalizationManager().getLocalizedTextString("attemptingToSuspend")); //$NON-NLS-1$
+        IsolateSession session = m_session.getWorkerSession(getActiveIsolateId());
+        if (!session.isSuspended())
+            session.suspend();
+        if (session.isSuspended())
+            out(getLocalizationManager().getLocalizedTextString("playerStopped")); //$NON-NLS-1$
+        else
+            out(getLocalizationManager().getLocalizedTextString("playerRunning")); //$NON-NLS-1$
+    }
+
+    public void appendReason(StringBuilder sb, int reason) {
+        switch (reason) {
+            case SuspendReason.Unknown:
+                sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_Unknown")); //$NON-NLS-1$
+                break;
+
+            case SuspendReason.Breakpoint:
+                sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_HitBreakpoint")); //$NON-NLS-1$
+                break;
+
+            case SuspendReason.Watch:
+                sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_HitWatchpoint")); //$NON-NLS-1$
+                break;
+
+            case SuspendReason.Fault:
+                sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_ProgramThrewException")); //$NON-NLS-1$
+                break;
+
+            case SuspendReason.StopRequest:
+                sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_StopRequest")); //$NON-NLS-1$
+                break;
+
+            case SuspendReason.Step:
+                sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_ProgramFinishedStepping")); //$NON-NLS-1$
+                break;
+
+            case SuspendReason.HaltOpcode:
+                sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_HaltOpcode")); //$NON-NLS-1$
+                break;
+
+            case SuspendReason.ScriptLoaded:
+                sb.append(getLocalizationManager().getLocalizedTextString("suspendReason_ScriptHasLoadedIntoFlashPlayer")); //$NON-NLS-1$
+                break;
+        }
+    }
+
+    /**
+     * The big ticket item, where all your questions are answered.
+     */
+    void doInfo() throws AmbiguousException, PlayerDebugException {
+		/* info without any args brings up help */
+        if (!hasMoreTokens())
+            out(getHelpTopic("info")); //$NON-NLS-1$
+        else {
+			/* otherwise we have a boatload of options */
+            String subCmdString = nextToken();
+            int subCmd = infoCommandFor(subCmdString);
+            switch (subCmd) {
+                case INFO_ARGS_CMD:
+                    doInfoArgs();
+                    break;
+
+                case INFO_BREAK_CMD:
+                    doInfoBreak();
+                    break;
+
+                case INFO_FILES_CMD:
+                    doInfoFiles();
+                    break;
+
+                case INFO_FUNCTIONS_CMD:
+                    doInfoFuncs();
+                    break;
+
+                case INFO_HANDLE_CMD:
+                    doInfoHandle();
+                    break;
+
+                case INFO_LOCALS_CMD:
+                    doInfoLocals();
+                    break;
+
+                case INFO_SCOPECHAIN_CMD:
+                    doInfoScopeChain();
+                    break;
+
+                case INFO_SOURCES_CMD:
+                    doInfoSources();
+                    break;
+
+                case INFO_STACK_CMD:
+                    doInfoStack();
+                    break;
+
+                case INFO_VARIABLES_CMD:
+                    doInfoVariables();
+                    break;
+
+                case INFO_DISPLAY_CMD:
+                    doInfoDisplay();
+                    break;
+
+                case INFO_TARGETS_CMD:
+                    doInfoTargets();
+                    break;
+
+                case INFO_SWFS_CMD:
+                    doInfoSwfs();
+                    break;
+
+                case INFO_WORKERS_CMD:
+                    doInfoWorkers();
+                    break;
+
+                default:
+                    doUnknown("info", subCmdString); //$NON-NLS-1$
+                    break;
+            }
+        }
+    }
+
+    void doInfoWorkers() throws NotConnectedException, NotSupportedException, NotSuspendedException, NoResponseException {
+//		waitTilHalted();
+        Isolate[] isolates = m_session.getWorkers();
+        if (isolates == null || isolates.length == 0) {
+            out(getLocalizationManager().getLocalizedTextString("noWorkersRunning")); //$NON-NLS-1$
+            return;
+        }
+        StringBuilder sb = new StringBuilder();
+        for (Isolate t : isolates) {
+            String status = getLocalizationManager().getLocalizedTextString("workerRunning"); //$NON-NLS-1$
+            if (m_session.getWorkerSession(t.getId()).isSuspended()) {
+                status = getLocalizationManager().getLocalizedTextString("workerSuspended"); //$NON-NLS-1$
+            }
+            if (m_activeIsolate == t.getId()) {
+                status += " " + getLocalizationManager().getLocalizedTextString("workerSelected"); //$NON-NLS-1$ //$NON-NLS-2$
+            }
+            if (t.getId() == Isolate.DEFAULT_ID) {
+                sb.append(getLocalizationManager().getLocalizedTextString("mainThread")); //$NON-NLS-1$
+                sb.append(" "); //$NON-NLS-1$
+                sb.append(Isolate.DEFAULT_ID - 1);
+            } else {
+                HashMap<String, Object> workArgs = new HashMap<String, Object>();
+                workArgs.put("worker", (t.getId() - 1)); //$NON-NLS-1$
+                sb.append(getLocalizationManager().getLocalizedTextString("inWorker", workArgs)); //$NON-NLS-1$
+            }
+            sb.append(" - " + status + m_newline); //$NON-NLS-1$
+        }
+        out(sb.toString());
+    }
+
+
+    void doInfoStack() throws PlayerDebugException {
+        waitTilHalted(m_activeIsolate);
+
+        StringBuilder sb = new StringBuilder();
+        Frame[] stack = m_session.getWorkerSession(m_activeIsolate).getFrames();
+        if (stack == null || stack.length == 0)
+            sb.append(getLocalizationManager().getLocalizedTextString("no

<TRUNCATED>