http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/07f5a7de/debugger/src/main/java/flex/tools/debugger/cli/DebugCLI.java
----------------------------------------------------------------------
diff --git a/debugger/src/main/java/flex/tools/debugger/cli/DebugCLI.java 
b/debugger/src/main/java/flex/tools/debugger/cli/DebugCLI.java
new file mode 100644
index 0000000..58ce94c
--- /dev/null
+++ b/debugger/src/main/java/flex/tools/debugger/cli/DebugCLI.java
@@ -0,0 +1,6878 @@
+/*
+ *
+ *  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 com.sun.org.apache.xml.internal.utils.LocaleUtility;
+import flash.localization.LocalizationManager;
+import flash.tools.debugger.*;
+import flash.tools.debugger.concrete.DProtocol;
+import flash.tools.debugger.concrete.DSwfInfo;
+import flash.tools.debugger.events.*;
+import flash.tools.debugger.expression.ECMA;
+import flash.tools.debugger.expression.NoSuchVariableException;
+import flash.tools.debugger.expression.PlayerFaultException;
+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
+ * Player that exists in flash.tools.debuggger.
+ * <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.
+ */
+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;
+
+       /**
+        * Whether the break command will show it changed workers.
+        * true at the moment because the break function itself does not 
display in
+        * which worker the breakpoint has been set.
+        */
+       public static final boolean WORKER_DISPLAY_INTERNAL_SWAP_INFO = true;
+
+       /* Enum for the state of the initial prompt shown when a swf is loaded 
*/
+       public static enum InitialPromptState {
+               NEVER_SHOWN, SHOWN_ONCE, DONE
+       }
+
+       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;
+       private boolean m_quietMode; // Don't dump out the state of the 
execution when WORKER_DISPLAY_INTERNAL_SWAP_INFO is set to false.
+       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 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;
+       }
+
+       public int getActiveIsolateId() {
+               return m_activeIsolate;
+       }
+
+       private boolean getRequestResume(int isolateId) {
+               return getIsolateState(isolateId).m_requestResume;
+       }
+
+       private void setRequestResume(boolean value, int isolateId) {
+               getIsolateState(isolateId).m_requestResume = value;
+       }
+
+       private boolean getStepResume(int isolateId) {
+               return getIsolateState(isolateId).m_stepResume;
+       }
+
+       private void setStepResume(boolean value, int isolateId) {
+               getIsolateState(isolateId).m_stepResume = value;
+       }
+
+       private boolean getRequestHalt(int isolateId) {
+               return getIsolateState(isolateId).m_requestHalt;
+       }
+
+       private void setRequestHalt(boolean value, int isolateId) {
+               getIsolateState(isolateId).m_requestHalt = value;
+       }
+
+       private InitialPromptState getPromptState(int isolateId) {
+               return getIsolateState(isolateId).m_promptState;
+       }
+
+       private void setPromptState(InitialPromptState value, int isolateId) {
+               getIsolateState(isolateId).m_promptState = value;
+       }
+
+       /* 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;
+
+       /**
+        * 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$
+       }
+
+       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;
+
+               // 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);
+
+               /* iterate through the args list */
+               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$
+
+               /*
+                * 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 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_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$
+                               {
+                                       // consume the port
+                                       if (i + 1 < args.length)
+                                               m_connectPort = args[++i];
+                               } 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 {
+                               // 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.
+        *
+        * 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)
+                       {
+//                             io.printStackTrace();
+                       }
+               }
+       }
+
+       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() {
+               /* dump console message */
+               displayStartMessage();
+
+               /* now fire our keyboard input thread */
+               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$
+                       }
+               }
+
+               /* we done kill everything */
+               exitSession();
+
+               // clear this thing, which also halts our other thread.
+               m_keyboardStream = null;
+       }
+
+       public PrintStream getOut() {
+               return m_out;
+       }
+
+       private void displayStartMessage() {
+               String build = 
getLocalizationManager().getLocalizedTextString("defaultBuildName"); 
//$NON-NLS-1$
+
+               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$
+                       {
+                               build = buildString;
+                       }
+               } catch (Throwable t) {
+                       // ignore
+               }
+
+               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;
+//             long max = rt.maxMemory();
+               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$
+       }
+
+       /**
+        * 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();
+
+                               /* 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 {
+               /* 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();
+                       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$
+               }
+       }
+
+       void doShowMemory() {
+               out(uft());
+       }
+
+       void doShowLocations() {
+               StringBuilder sb = new StringBuilder();
+               sb.append("Num Type           Disp Enb Address    What" + 
m_newline); //$NON-NLS-1$
+
+               // 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     "); //$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("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)
+                                       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, 
ctx.getIsolateId());
+                               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(), ctx.getIsolateId());
+                                       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(m_activeIsolate);
+
+               // dump a set of locals
+               StringBuilder sb = new StringBuilder();
+
+               // use our expression cache formatting routine
+               try {
+                       Variable[] vars = 
m_session.getWorkerSession(m_activeIsolate).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], 
m_activeIsolate);
+                                       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(m_activeIsolate);
+
+               // 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.getWorkerSession(m_activeIsolate).getFrames();
+                       Variable[] vars = frames[num].getArguments(m_session);
+                       for (int i = 0; i < vars.length; i++) {
+                               m_exprCache.appendVariable(sb, vars[i], 
m_activeIsolate);
+                               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$
+               }
+
+               out(sb.toString());
+       }
+
+       void doInfoLocals() throws PlayerDebugException {
+               waitTilHalted(m_activeIsolate);
+
+               // 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.getWorkerSession(m_activeIsolate).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, 
m_activeIsolate);
+                                       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$
+               }
+
+               out(sb.toString());
+       }
+
+       void doInfoScopeChain() throws PlayerDebugException {
+               waitTilHalted(m_activeIsolate);
+
+               // 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.getWorkerSession(m_activeIsolate).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, 
m_activeIsolate);
+                               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$
+               }
+
+               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);
+               }
+       }
+
+       /**
+        * Dump some stats about our currently loaded swfs.
+        */
+       void doInfoSwfs() {
+               try {
+                       StringBuilder sb = new StringBuilder();
+                       SwfInfo[] swfs = m_fileInfo.getSwfs(m_activeIsolate);
+                       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"
+
+       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$
+
+       /**
+        * 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.
+        */
+       private int getFileType(SourceFile sourceFile) {
+               String name = sourceFile.getName();
+               String pkg = sourceFile.getPackageName();
+
+               if (name.startsWith("<") && name.endsWith(">") || 
name.equals("GeneratedLocale")) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                       return SYNTHETIC_FILE;
+
+               for (final String frameworkPkg : FRAMEWORK_FILE_PACKAGES) {
+                       // look for packages starting with pkgName
+                       if (pkg.startsWith(frameworkPkg + '\\') ||
+                                       pkg.startsWith(frameworkPkg + '/') ||
+                                       pkg.equals(frameworkPkg)) {
+                               return FRAMEWORK_FILE;
+                       }
+               }
+
+               if (name.startsWith("Actions for")) //$NON-NLS-1$
+                       return ACTIONS_FILE;
+
+               return AUTHORED_FILE;
+       }
+
+       void buildFileList(StringBuilder sb, boolean authoredFilesOnly) {
+               SourceFile[] ar = m_fileInfo.getFileList(m_activeIsolate);
+               if (ar == null) {
+                       
err(getLocalizationManager().getLocalizedTextString("noSourceFilesFound")); 
//$NON-NLS-1$
+                       return;
+               }
+
+               Vector<String> authoredFiles = new Vector<String>();
+               Vector<String> frameworkFiles = new Vector<String>();
+               Vector<String> syntheticFiles = new Vector<String>();
+               Vector<String> actionsFiles = new Vector<String>();
+
+               for (int i = 0; i < ar.length; i++) {
+                       SourceFile m = ar[i];
+                       int fileType = getFileType(m);
+                       int id = m.getId();
+//                     int fakeId = m_fileInfo.getFakeId(m);
+                       String entry = m.getName() + "#" + id; //$NON-NLS-1$
+
+                       switch (fileType) {
+                               case SYNTHETIC_FILE:
+                                       syntheticFiles.add(entry);
+                                       break;
+                               case FRAMEWORK_FILE:
+                                       frameworkFiles.add(entry);
+                                       break;
+                               case ACTIONS_FILE:
+                                       actionsFiles.add(entry);
+                                       break;
+                               case AUTHORED_FILE:
+                                       authoredFiles.add(entry);
+                                       break;
+                       }
+               }
+
+               int wrapAt = propertyGet(FILE_LIST_WRAP);
+
+               if (!authoredFilesOnly) {
+                       if (actionsFiles.size() > 0) {
+                               appendStrings(sb, actionsFiles, 
(actionsFiles.size() > wrapAt));
+                       }
+
+                       if (frameworkFiles.size() > 0) {
+                               sb.append("---" + m_newline); //$NON-NLS-1$
+                               appendStrings(sb, frameworkFiles, 
(frameworkFiles.size() > wrapAt));
+                       }
+
+                       if (syntheticFiles.size() > 0) {
+                               sb.append("---" + m_newline); //$NON-NLS-1$
+                               appendStrings(sb, syntheticFiles, 
(syntheticFiles.size() > wrapAt));
+                       }
+
+                       sb.append("---" + m_newline); //$NON-NLS-1$
+               }
+
+               appendStrings(sb, authoredFiles, (authoredFiles.size() > 
wrapAt));
+       }
+
+       /**
+        * Dump a list of strings contained a vector
+        * If flow is set then the strings are placed
+        * on a single line and wrapped at $columnwidth
+        */
+       void appendStrings(StringBuilder sb, Vector<String> v, boolean flow) {
+               int count = v.size();
+               int width = 0;
+               int maxCol = propertyGet(COLUMN_WIDTH);
+
+               for (int i = 0; i < count; i++) {
+                       String s = v.get(i);
+                       sb.append(s);
+
+                       // too many of them, then wrap according to columnwidth
+                       if (flow) {
+                               width += (s.length() + 2);
+                               if (width >= maxCol) {
+                                       sb.append(m_newline);
+                                       width = 0;
+                               } else
+                                       sb.append(", "); //$NON-NLS-1$
+                       } else
+                               sb.append(m_newline);
+               }
+
+               // add a line feed for flow based
+               if (flow && width > 0)
+                       sb.append(m_newline);
+       }
+
+       void doInfoFiles() {
+               try {
+                       StringBuilder sb = new StringBuilder();
+                       if (hasMoreTokens()) {
+                               String arg = nextToken();
+                               listFilesMatching(sb, arg);
+                       } else {
+                               buildFileList(sb, false);
+                       }
+                       out(sb.toString());
+               } catch (NullPointerException npe) {
+                       throw new IllegalStateException();
+               }
+       }
+
+       void doInfoHandle() {
+               if (hasMoreTokens()) {
+                       // user specified a fault
+                       String faultName = nextToken();
+
+                       // make sure we know about this one
+                       if (!m_faultTable.exists(faultName))
+                               
err(getLocalizationManager().getLocalizedTextString("unrecognizedFault")); 
//$NON-NLS-1$
+                       else
+                               listFault(faultName);
+               } else {
+                       // dump them all
+                       StringBuilder sb = new StringBuilder();
+
+                       appendFaultTitles(sb);
+
+                       Object names[] = m_faultTable.names();
+                       Arrays.sort(names);
+
+                       for (int i = 0; i < names.length; i++)
+                               appendFault(sb, (String) names[i]);
+
+                       out(sb.toString());
+               }
+       }
+
+       void doInfoFuncs() {
+               StringBuilder sb = new StringBuilder();
+
+               String arg = null;
+
+               // we take an optional single arg which specifies a module
+               try {
+                       if (hasMoreTokens()) {
+                               arg = nextToken();
+                               int id = arg.equals(".") ? 
propertyGet(LIST_MODULE) : parseFileArg(m_activeIsolate, -1, arg); //$NON-NLS-1$
+
+                               SourceFile m = m_fileInfo.getFile(id, 
m_activeIsolate);
+                               listFunctionsFor(sb, m);
+                       } else {
+                               SourceFile[] ar = 
m_fileInfo.getFileList(m_activeIsolate);
+                               if (ar == null)
+                                       
err(getLocalizationManager().getLocalizedTextString("noSourceFilesFound")); 
//$NON-NLS-1$
+                               else {
+                                       for (int i = 0; ar != null && i < 
ar.length; i++) {
+                                               SourceFile m = ar[i];
+                                               listFunctionsFor(sb, m);
+                                       }
+                               }
+                       }
+
+                       out(sb.toString());
+               } catch (NullPointerException npe) {
+                       
err(getLocalizationManager().getLocalizedTextString("noFunctionsFound")); 
//$NON-NLS-1$
+               } catch (ParseException pe) {
+                       err(pe.getMessage());
+               } catch (NoMatchException nme) {
+                       err(nme.getMessage());
+               } catch (AmbiguousException ae) {
+                       err(ae.getMessage());
+               }
+       }
+
+       void listFunctionsFor(StringBuilder sb, SourceFile m) {
+               String[] names = m.getFunctionNames(m_session);
+               if (names == null)
+                       return;
+
+               Arrays.sort(names);
+
+               Map<String, Object> args = new HashMap<String, Object>();
+               args.put("sourceFile", m.getName() + "#" + m.getId()); 
//$NON-NLS-1$ //$NON-NLS-2$
+               
sb.append(getLocalizationManager().getLocalizedTextString("functionsInSourceFile",
 args)); //$NON-NLS-1$
+               sb.append(m_newline);
+
+               for (int j = 0; j < names.length; j++) {
+                       String fname = names[j];
+                       sb.append(' ');
+                       sb.append(fname);
+                       sb.append(' ');
+                       sb.append(m.getLineForFunctionName(m_session, fname));
+                       sb.append(m_newline);
+               }
+       }
+
+       void listFilesMatching(StringBuilder sb, String match) {
+               SourceFile[] sourceFiles = m_fileInfo.getFiles(match);
+
+               for (int j = 0; j < sourceFiles.length; j++) {
+                       SourceFile sourceFile = sourceFiles[j];
+                       sb.append(sourceFile.getName());
+                       sb.append('#');
+                       sb.append(sourceFile.getId());
+                       sb.append(m_newline);
+               }
+       }
+
+       void doInfoSources() {
+               try {
+                       StringBuilder sb = new StringBuilder();
+                       buildFileList(sb, true);
+                       out(sb.toString());
+               } catch (NullPointerException npe) {
+                       throw new IllegalStateException();
+               }
+       }
+
+       void doInfoBreak() throws NotConnectedException {
+//             waitTilHalted();
+
+               StringBuilder sb = new StringBuilder();
+               sb.append("Num Type           Disp Enb Address    What" + 
m_newline); //$NON-NLS-1$
+
+               // our list of breakpoints
+               int count = breakpointCount();
+               for (int i = 0; i < count; i++) {
+                       BreakAction b = breakpointAt(i);
+                       int status = b.getStatus();
+                       boolean isResolved = (status == BreakAction.RESOLVED);
+                       Location l = b.getLocation();
+                       final LocationCollection locations = b.getLocations();
+                       SourceFile file = (l != null) ? l.getFile() : null;
+                       String funcName = (file == null) ? null : 
file.getFunctionNameForLine(m_session, l.getLine());
+                       boolean singleSwf = b.isSingleSwf();
+                       int cmdCount = b.getCommandCount();
+                       int hits = b.getHits();
+                       String cond = b.getConditionString();
+                       boolean silent = b.isSilent();
+                       int offset = adjustOffsetForUnitTests((file == null) ? 
0 : file.getOffsetForLine(l.getLine()));
+
+                       int num = b.getId();
+                       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$
+
+                       sb.append("0x"); //$NON-NLS-1$
+                       FieldFormat.formatLongToHex(sb, offset, 8);
+                       sb.append(' ');
+
+                       if (funcName != null) {
+                               Map<String, Object> args = new HashMap<String, 
Object>();
+                               args.put("functionName", funcName); 
//$NON-NLS-1$
+                               
sb.append(getLocalizationManager().getLocalizedTextString("inFunctionAt", 
args)); //$NON-NLS-1$
+                       }
+
+                       if (file != null) {
+                               sb.append(file.getName());
+                               if (isResolved && singleSwf) {
+                                       sb.append("#"); //$NON-NLS-1$
+                                       sb.append(file.getId());
+                               }
+                               sb.append(':');
+                               sb.append(l.getLine());
+                       } else {
+                               String expr = b.getBreakpointExpression();
+                               if (expr != null)
+                                       sb.append(expr);
+                       }
+
+                       final StringBuilder workerList = new StringBuilder();
+                       if (locations != null) {
+                               for (Iterator<Location> iterator = 
locations.iterator(); iterator.hasNext(); ) {
+                                       Location location = iterator.next();
+                                       
workerList.append(location.getIsolateId() - 1);
+                                       if (iterator.hasNext())
+                                               workerList.append(" / ");
+                               }
+                       }
+
+
+                       if (l != null) {
+                               Map<String, Object> workerArgs = new 
HashMap<String, Object>();
+                               workerArgs.put("worker", 
workerList.toString()); //$NON-NLS-1$
+                               sb.append(" (");
+                               
sb.append(getLocalizationManager().getLocalizedTextString("inWorker", 
workerArgs)); //$NON-NLS-1$
+                               sb.append(") ");
+                       }
+
+                       switch (status) {
+                               case BreakAction.UNRESOLVED:
+                                       
sb.append(getLocalizationManager().getLocalizedTextString("breakpointNotYetResolved"));
 //$NON-NLS-1$
+                                       break;
+                               case BreakAction.AMBIGUOUS:
+                                       
sb.append(getLocalizationManager().getLocalizedTextString("breakpointAmbiguous"));
 //$NON-NLS-1$
+                                       break;
+                               case BreakAction.NOCODE:
+                                       
sb.append(getLocalizationManager().getLocalizedTextString("breakpointNoCode")); 
//$NON-NLS-1$
+                                       break;
+                       }
+
+                       // if a single swf break action then append more info
+                       if (singleSwf && isResolved) {
+                               try {
+                                       SwfInfo info = 
m_fileInfo.swfForFile(file, l.getIsolateId());
+                                       Map<String, Object> swfArgs = new 
HashMap<String, Object>();
+                                       swfArgs.put("swf", 
FileInfoCache.nameOfSwf(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);
+
+                       final String INDENT = "        "; //$NON-NLS-1$
+
+                       // state our condition if we have one
+                       if (cond != null && cond.length() > 0) {
+                               sb.append(INDENT);
+                               Map<String, Object> args = new HashMap<String, 
Object>();
+                               args.put("breakpointCondition", cond); 
//$NON-NLS-1$
+                               
sb.append(getLocalizationManager().getLocalizedTextString(getLocalizationManager().getLocalizedTextString("stopOnlyIfConditionMet",
 args))); //$NON-NLS-1$
+                               sb.append(m_newline);
+                       }
+
+                       // now if its been hit, lets state the fact
+                       if (hits > 0) {
+                               sb.append(INDENT);
+                               Map<String, Object> args = new HashMap<String, 
Object>();
+                               args.put("count", Integer.toString(hits)); 
//$NON-NLS-1$
+                               
sb.append(getLocalizationManager().getLocalizedTextString("breakpointAlreadyHit",
 args)); //$NON-NLS-1$
+                               sb.append(m_newline);
+                       }
+
+                       // silent?
+                       if (silent) {
+                               sb.append(INDENT);
+                               
sb.append(getLocalizationManager().getLocalizedTextString("silentBreakpoint") + 
m_newline); //$NON-NLS-1$
+                       }
+
+                       // now if any commands are trailing then we pump them 
out
+                       for (int j = 0; j < cmdCount; j++) {
+                               sb.append(INDENT);
+                               sb.append(b.commandAt(j));
+                               sb.append(m_newline);
+                       }
+               }
+
+               int wcount = watchpointCount();
+               for (int k = 0; k < wcount; k++) {
+                       WatchAction b = watchpointAt(k);
+                       int id = b.getId();
+                       FieldFormat.formatLong(sb, id, 4);
+
+                       int flags = b.getKind();
+                       switch (flags) {
+                               case WatchKind.READ:
+                                       sb.append("rd watchpoint  "); 
//$NON-NLS-1$
+                                       break;
+                               case WatchKind.WRITE:
+                                       sb.append("wr watchpoint  "); 
//$NON-NLS-1$
+                                       break;
+                               case WatchKind.READWRITE:
+                               default:
+                                       sb.append("watchpoint     "); 
//$NON-NLS-1$
+                                       break;
+                       }
+
+                       sb.append("keep "); //$NON-NLS-1$
+                       sb.append("y   "); //$NON-NLS-1$
+                       sb.append("           "); //$NON-NLS-1$
+                       sb.append(b.getExpr());
+                       sb.append(m_newline);
+               }
+
+               int ccount = catchpointCount();
+               for (int k = 0; k < ccount; k++) {
+                       CatchAction c = catchpointAt(k);
+                       int id = c.getId();
+                       FieldFormat.formatLong(sb, id, 4);
+
+                       String typeToCatch = c.getTypeToCatch();
+                       if (typeToCatch == null)
+                               typeToCatch = "*"; //$NON-NLS-1$
+
+                       sb.append("catch          "); //$NON-NLS-1$
+                       sb.append("keep "); //$NON-NLS-1$
+                       sb.append("y   "); //$NON-NLS-1$
+                       sb.append("           "); //$NON-NLS-1$
+                       sb.append(typeToCatch);
+                       sb.append(m_newline);
+               }
+
+               out(sb.toString());
+       }
+
+       /**
+        * Dump out the state of the execution, either the fact we are running
+        * or the breakpoint we hit.
+        */
+       void dumpHaltState(boolean postStep) throws NotConnectedException, 
SuspendedException, NoResponseException, NotSupportedException, 
NotSuspendedException, IOException {
+               // spit out any event output, if we are to resume after a fault 
and we're not stepping then we're done.
+               processEvents();
+//             System.out.println("processEvents = "+m_requestResume);
+
+               //if (m_requestResume && !postStep)
+               if (hasAnyPendingResumes() != -1 && !postStep)
+                       return;
+
+               if (!m_session.isConnected()) {
+                       // session is kaput
+                       
out(getLocalizationManager().getLocalizedTextString("sessionTerminated")); 
//$NON-NLS-1$
+                       exitSession();
+               } else {
+                       if (!m_quietMode && hasAnythingSuspended()) {
+                               // capture our break location / information
+                               StringBuilder sbLine = new StringBuilder();
+                               dumpBreakLine(postStep, sbLine);
+
+                               // Process our breakpoints.
+                               // Since we can have conditional breakpoints, 
which the
+                               // player always breaks for, but we may not 
want to, the variable
+                               // m_requestResume may be set after this call.  
Additionally,
+                               // silent may be set for one of two reasons; 1) 
m_requestResume
+                               // was set to true in the call or one or more 
breakpoints that
+                               // hit contained the keyword silent in their 
command list.
+                               //
+                               StringBuilder sbBreak = new StringBuilder();
+                               boolean silent = processBreak(postStep, 
sbBreak, m_activeIsolate);
+
+                               StringBuilder sb = new StringBuilder();
+                               if (silent) {
+                                       // silent means we only spit out our 
current location
+                                       dumpBreakLine(postStep, sb);
+                               } else {
+                                       // not silent means we append things 
like normal
+                                       sb.append(sbLine);
+                                       if (sbLine.length() > 0 && 
sbLine.charAt(sbLine.length() - 1) != '\n')
+                                               sb.append(m_newline);
+                                       sb.append(sbBreak);
+                               }
+
+                               // output whatever was generated
+                               if (sb.length() > 0)
+                                       out(sb.toString());
+
+//                             System.out.println("processbreak = 
"+m_requestResume+",silent="+silent+",reason="+m_session.suspendReason());
+                       } else if (!m_quietMode) {
+                               // very bad, set stepping so that we don't 
trigger a continue on a breakpoint or fault
+                               
out(getLocalizationManager().getLocalizedTextString("playerDidNotStop")); 
//$NON-NLS-1$
+                       }
+                       m_quietMode = false;
+               }
+       }
+
+       Location getCurrentLocation() {
+               return getCurrentLocationIsolate(Isolate.DEFAULT_ID);
+       }
+
+       Location getCurrentLocationIsolate(int isolateId) {
+               Location where = null;
+               try {
+                       Frame[] ar = 
m_session.getWorkerSession(isolateId).getFrames();
+                       propertyPut(CURRENT_FRAME_DEPTH, (ar.length > 0) ? 
ar.length : 0);
+                       where = ((ar.length > 0) ? ar[0].getLocation() : null);
+               } catch (PlayerDebugException pde) {
+                       // where == null
+               }
+               return where;
+       }
+
+       void dumpBreakLine(boolean postStep, StringBuilder sb) throws 
NotConnectedException {
+               int bp = -1;
+               String name = 
getLocalizationManager().getLocalizedTextString("unknownFilename"); 
//$NON-NLS-1$
+               int line = -1;
+
+               // clear our current frame display
+               propertyPut(DISPLAY_FRAME_NUMBER, 0);
+
+               int targetIsolate = getLastStoppedIsolate();
+               boolean activeIsolateChanged = (m_activeIsolate != 
targetIsolate);
+               m_activeIsolate = targetIsolate;
+               propertyPut(LIST_WORKER, targetIsolate);
+
+               /* dump a context line to the console */
+               Location l = getCurrentLocationIsolate(targetIsolate);
+
+               // figure out why we stopped
+               int reason = SuspendReason.Unknown;
+               try {
+                       reason = 
m_session.getWorkerSession(targetIsolate).suspendReason();
+               } catch (PlayerDebugException pde) {
+               }
+
+               // then see if it because of a swfloaded event
+               if (reason == SuspendReason.ScriptLoaded) {
+                       m_fileInfo.setDirty();
+                       m_fileInfo.getSwfsIsolate(targetIsolate);
+                       //propertyPut(LIST_MODULE, 
m_fileInfo.getFakeId(m_fileInfo.getFile(1, targetIsolate)));
+                       processEvents();
+                       propagateBreakpoints(targetIsolate);
+                       propertyPut(LIST_LINE, 1);
+                       propertyPut(LIST_WORKER, targetIsolate);
+                       propertyPut(LIST_MODULE, 1);
+                       
sb.append(getLocalizationManager().getLocalizedTextString("additionalCodeLoaded"));
 //$NON-NLS-1$
+                       if (activeIsolateChanged) {
+                               sb.append(m_newline + 
getLocalizationManager().getLocalizedTextString("workerChanged") + " " + 
(targetIsolate - 1) + m_newline); //$NON-NLS-1$ //$NON-NLS-2$
+                       }
+                       sb.append(m_newline);
+
+                       if (resolveBreakpoints(sb))
+                               
sb.append(getLocalizationManager().getLocalizedTextString("setAdditionalBreakpoints")
 + m_newline); //$NON-NLS-1$
+                       else
+                               
sb.append(getLocalizationManager().getLocalizedTextString("fixBreakpoints") + 
m_newline); //$NON-NLS-1$
+
+                       setPromptState(InitialPromptState.SHOWN_ONCE, 
targetIsolate);
+               } else if (l == null || l.getFile() == null) {
+
+                       if (activeIsolateChanged) {
+                               sb.append(m_newline + 
getLocalizationManager().getLocalizedTextString("workerChanged") + " " + 
(targetIsolate - 1) + m_newline);
+                       }
+
+                       // no idea where we are ?!?
+                       propertyPut(LAST_FRAME_DEPTH, 0);
+                       
sb.append(getLocalizationManager().getLocalizedTextString("executionHalted")); 
//$NON-NLS-1$
+                       sb.append(' ');
+
+                       /** disable this line (and enable the one after) if 
implementation Extensions are not provided */
+                       appendBreakInfo(sb, m_activeIsolate);
+                       //sb.append("unknown location");
+               }/* else if (reason == SuspendReason.Breakpoint && 
enabledBreakpointIndexOf(l) == -1) {
+            // Dont output anything
+
+            // That's a edge case when a function breaks often, let's say a 
timer,
+            // if the break action is disabled, the break event are still 
dispatched,
+            // sent to the debugger and outputed, the debugger can't then halt 
the player anymore,
+            // even removing the output, that's the same, I will try to fix 
this better later,
+            // in between, I comment my changes.
+        }*/ else {
+                       if (activeIsolateChanged) {
+                               sb.append(m_newline + 
getLocalizationManager().getLocalizedTextString("workerChanged") + " " + 
(targetIsolate - 1) + m_newline);
+                       }
+
+                       SourceFile file = l.getFile();
+                       name = file.getName();
+                       line = l.getLine();
+                       String funcName = 
file.getFunctionNameForLine(m_session, line);
+
+                       // where were we last time
+                       int lastModule = propertyGet(LIST_MODULE);
+                       int lastDepth = propertyGet(LAST_FRAME_DEPTH);
+
+                       int thisModule = file.getId();
+                       int thisDepth = propertyGet(CURRENT_FRAME_DEPTH);  // 
triggered via getCurrentLocation()
+
+                       // mark where we stopped
+                       propertyPut(LAST_FRAME_DEPTH, thisDepth);
+
+                       // if we have changed our context or we are not 
spitting out source then dump our location
+                       if (!postStep || lastModule != thisModule || lastDepth 
!= thisDepth) {
+                               // is it a fault?
+                               String reasonForHalting;
+                               if (reason == SuspendReason.Fault || reason == 
SuspendReason.StopRequest) {
+                                       StringBuilder s = new StringBuilder();
+                                       appendReason(s, reason);
+                                       reasonForHalting = s.toString();
+                               }
+                               // if its a breakpoint add that information
+                               else if ((bp = enabledBreakpointIndexOf(l)) > 
-1) {
+                                       Map<String, Object> args = new 
HashMap<String, Object>();
+                                       args.put("breakpointNumber", 
Integer.toString(breakpointAt(bp).getId())); //$NON-NLS-1$
+                                       reasonForHalting = 
getLocalizationManager().getLocalizedTextString("hitBreakpoint", args); 
//$NON-NLS-1$
+                               } else {
+                                       reasonForHalting = 
getLocalizationManager().getLocalizedTextString("executionHalted"); 
//$NON-NLS-1$
+                               }
+
+                               Map<String, Object> args = new HashMap<String, 
Object>();
+                               args.put("reasonForHalting", reasonForHalting); 
//$NON-NLS-1$
+                               args.put("fileAndLine", name + ':' + line); 
//$NON-NLS-1$
+                               String formatString;
+                               if (funcName != null) {
+                                       args.put("functionName", funcName); 
//$NON-NLS-1$
+                                       formatString = "haltedInFunction"; 
//$NON-NLS-1$
+                               } else {
+                                       formatString = "haltedInFile"; 
//$NON-NLS-1$
+                               }
+                               
sb.append(getLocalizationManager().getLocalizedTextString(formatString, args));
+
+                               if (!m_fullnameOption)
+                                       sb.append(m_newline);
+                       }
+
+                       // set current listing poistion and emit emacs trigger
+                       setListingPosition(thisModule, line, targetIsolate);
+
+                       // dump our source line if not in emacs mode
+                       if (!m_fullnameOption)
+                               appendSource(sb, file.getId(), line, 
file.getLine(line), false);
+               }
+       }
+
+       private int getLastStoppedIsolate() {
+               int targetIsolate = Isolate.DEFAULT_ID;
+
+               if (m_breakIsolates.size() > 0) {
+                       targetIsolate = 
m_breakIsolates.get(m_breakIsolates.size() - 1);
+               }
+               return targetIsolate;
+       }
+
+       void appendFullnamePosition(StringBuilder sb, SourceFile file, int 
lineNbr) {
+               // fullname option means we dump 'path:line:col?:offset', which 
is used for emacs !
+               String name = file.getFullPath();
+               if (name.startsWith("file:/")) //$NON-NLS-1$
+                       name = name.substring(6);
+
+               // Ctrl-Z Ctrl-Z
+               sb.append('\u001a');
+               sb.append('\u001a');
+
+               sb.append(name);
+               sb.append(':');
+               sb.append(lineNbr);
+               sb.append(':');
+               sb.append('0');
+               sb.append(':');
+               sb.append("beg"); //$NON-NLS-1$
+               sb.append(':');
+               sb.append('0');
+       }
+
+       // pretty print a trace statement to the console
+       void dumpTraceLine(String s) {
+               StringBuilder sb = new StringBuilder();
+               sb.append("[trace] "); //$NON-NLS-1$
+               sb.append(s);
+               out(sb.toString());
+       }
+
+       // pretty print a fault statement to the console
+       void dumpFaultLine(FaultEvent e) {
+               StringBuilder sb = new StringBuilder();
+
+               // use a slightly different format for ConsoleErrorFaults
+               if (e instanceof ConsoleErrorFault) {
+                       
sb.append(getLocalizationManager().getLocalizedTextString("linePrefixWhenDisplayingConsoleError"));
 //$NON-NLS-1$
+                       sb.append(' ');
+                       sb.append(e.information);
+
+                       final String stackTrace = e.stackTrace();
+                       if (stackTrace != null && stackTrace.length() > 0) {
+                               sb.append("\n").append(stackTrace);
+                       }
+               } else {
+                       String name = e.name();
+                       
sb.append(getLocalizationManager().getLocalizedTextString("linePrefixWhenDisplayingFault"));
 //$NON-NLS-1$
+                       sb.append(' ');
+                       sb.append(name);
+                       if (e.information != null && e.information.length() > 
0) {
+                               
sb.append(getLocalizationManager().getLocalizedTextString("informationAboutFault"));
 //$NON-NLS-1$
+                               sb.append(e.information);
+                       }
+
+                       final String stackTrace = e.stackTrace();
+                       if (stackTrace != null && stackTrace.length() > 0) {
+                               sb.append("\n").append(stackTrace);
+                       }
+               }
+               out(sb.toString());
+       }
+
+       /**
+        * Called when a swf has been loaded by the player
+        * @param e event documenting the load
+        */
+       void handleSwfLoadedEvent(SwfLoadedEvent e) {
+               // first we dump out a message that displays we have loaded a 
swf
+               dumpSwfLoadedLine(e);
+       }
+
+       // pretty print a SwfLoaded statement to the console
+       void dumpSwfLoadedLine(SwfLoadedEvent e) {
+               // now rip off any trailing ? options
+               int at = e.path.lastIndexOf('?');
+               String name = (at > -1) ? e.path.substring(0, at) : e.path;
+
+               StringBuilder sb = new StringBuilder();
+               
sb.append(getLocalizationManager().getLocalizedTextString("linePrefixWhenSwfLoaded"));
 //$NON-NLS-1$
+               sb.append(' ');
+               sb.append(name);
+               sb.append(" - "); //$NON-NLS-1$
+
+               Map<String, Object> args = new HashMap<String, Object>();
+               args.put("size", NumberFormat.getInstance().format(e.swfSize)); 
//$NON-NLS-1$
+               
sb.append(getLocalizationManager().getLocalizedTextString("sizeAfterDecompression",
 args)); //$NON-NLS-1$
+               out(sb.toString());
+       }
+
+       /**
+        * Propagate current breakpoints to the newly loaded swf.
+        */
+       void propagateBreakpoints(int isolateId) throws NotConnectedException {
+               // get the newly added swf, which lands at the end list
+               SwfInfo[] swfs = m_fileInfo.getSwfsIsolate(isolateId);
+               SwfInfo swf = (swfs.length > 0) ? swfs[swfs.length - 1] : null;
+
+               // now walk through all breakpoints propagating the
+               // the break for each source and line number we
+               // find in the new swf
+               int size = m_breakpoints.size();
+               for (int i = 0; (swf != null) && i < size; i++) {
+                       // dont do this for single swf breakpoints
+                       BreakAction bp = breakpointAt(i);
+                       if (bp.isSingleSwf())
+                               continue;
+                       if (bp.getStatus() != BreakAction.RESOLVED)
+                               continue;
+                       if (!bp.isPropagable())
+                               continue;
+
+                       try {
+                               Location l = bp.getLocation();
+                               int line = l.getLine();
+                               SourceFile f = l.getFile();
+                               Location newLoc = findAndEnableBreak(swf, f, 
line);
+                               if (newLoc != null)
+                                       bp.addLocation(newLoc);
+                               else newLoc.getFile();
+
+                               dumpAddedBreakpoint(bp);
+
+                       } catch (InProgressException ipe) {
+                               if (breakpointCount() > 0) {
+                                       Map<String, Object> args = new 
HashMap<String, Object>();
+                                       args.put("breakpointNumber", 
Integer.toString(bp.getId())); //$NON-NLS-1$
+                                       
out(getLocalizationManager().getLocalizedTextString("breakpointNotPropagated", 
args)); //$NON-NLS-1$
+                               }
+                       }
+               }
+       }
+
+       private void dumpAddedBreakpoint(BreakAction bp) {
+               Location l = bp.getLocations().last();
+               int which = bp.getId();
+               String name = l.getFile().getName();
+               int offset = 
adjustOffsetForUnitTests(l.getFile().getOffsetForLine(l.getLine()));
+
+               Map<String, Object> args = new HashMap<String, Object>();
+               args.put("breakpointNumber", Integer.toString(which)); 
//$NON-NLS-1$
+               args.put("file", name); //$NON-NLS-1$
+               args.put("line", Integer.toString(l.getLine())); //$NON-NLS-1$
+               String formatString;
+               if (offset != 0) {
+                       args.put("offset", "0x" + Integer.toHexString(offset)); 
//$NON-NLS-1$ //$NON-NLS-2$
+                       formatString = "createdBreakpointWithOffset"; 
//$NON-NLS-1$
+               } else {
+                       formatString = "createdBreakpoint"; //$NON-NLS-1$
+               }
+               
out(getLocalizationManager().getLocalizedTextString(formatString, args));
+       }
+
+       /**
+        * Perform the tasks need for when a swf is unloaded
+        * the player
+        */
+       void handleSwfUnloadedEvent(SwfUnloadedEvent e) {
+               // print out the notification
+               dumpSwfUnloadedLine(e);
+       }
+
+       // pretty print a SwfUnloaded statement to the console
+       void dumpSwfUnloadedLine(SwfUnloadedEvent e) {
+               // now rip off any trailing ? options
+               int at = e.path.lastIndexOf('?');
+               String name = (at > -1) ? e.path.substring(0, at) : e.path;
+
+               StringBuilder sb = new StringBuilder();
+               
sb.append(getLocalizationManager().getLocalizedTextString("linePrefixWhenSwfUnloaded"));
 //$NON-NLS-1$
+               sb.append(' ');
+               sb.append(name);
+               out(sb.toString());
+       }
+
+       void doContinue() throws NotConnectedException {
+               //int stoppedIsolate = getLastStoppedIsolate();
+               int stoppedIsolate = m_activeIsolate;
+               waitTilHalted(stoppedIsolate);
+
+               // this will trigger a resume when we get back to the main loop
+               //m_requestResume = true;
+               setRequestResume(true, stoppedIsolate);
+               m_repeatLine = m_currentLine;
+       }
+
+       boolean hasAnythingSuspended() throws NotConnectedException {
+               boolean hasAnythingSuspended = false;
+               for (Integer id : m_breakIsolates) {
+                       if (m_session.getWorkerSession(id).isSuspended()) {
+                               hasAnythingSuspended = true;
+                               break;
+                       }
+               }
+               return hasAnythingSuspended;
+       }
+
+       int hasAnyPendingResumes() throws NotConnectedException {
+               int rid = -1;
+               if (m_mainState.m_requestResume)
+                       return Isolate.DEFAULT_ID;
+               for (Integer id : m_breakIsolates) {
+                       if (getIsolateState(id).m_requestResume) {
+                               rid = id;
+                               break;
+                       }
+               }
+               return rid;
+       }
+
+       /**
+        * Returns the first isolate's id for which we need to keep showing 
prompts.
+        *
+        * @return The isolate id
+        * @throws NotConnectedException
+        */
+       int hasPendingInitialPrompts() throws NotConnectedException {
+               int rid = -1;
+               for (Integer id : m_breakIsolates) {
+                       if (getPromptState(id) != InitialPromptState.DONE) {
+                               rid = id;
+                               break;
+                       }
+               }
+               return rid;
+       }
+
+       /**
+        * Our main loop when the player is off running
+        */
+       public void runningLoop() throws NoResponseException, 
NotConnectedException, SuspendedException, NotSupportedException, 
NotSuspendedException, IOException {
+               int update = propertyGet(UPDATE_DELAY);
+               boolean nowait = (propertyGet(NO_WAITING) == 1) ? true : false; 
 // DEBUG ONLY; do not document
+               boolean stop = false;
+               boolean noConnection = !haveConnection();
+               boolean hasAnythingSuspended = false;
+               int targetIsolate = Isolate.DEFAULT_ID;
+               if (!noConnection) {
+                       hasAnythingSuspended = hasAnythingSuspended();
+               }
+
+               if (hasAnythingSuspended) {
+                       if (m_breakIsolates.size() > 0) {
+                               targetIsolate = 
m_breakIsolates.get(m_breakIsolates.size() - 1);
+                       }
+               }
+               // not there, not connected or already halted and no pending 
resume requests => we are done
+               //if (noConnection || (hasAnythingSuspended && 
!m_requestResume) )
+               if (noConnection || (hasAnythingSuspended && 
hasAnyPendingResumes() == -1)) {
+                       processEvents();
+                       stop = true;
+
+                       if (!noConnection) {
+                               /** At this point, some isolate is in suspended 
state and will be until a resume
+                                *  is requested via the prompt. We thus check 
for any pending prompts to be displayed
+                                *  for freshly loaded swfs. If any, we switch 
to that worker and prompt the user to set
+                                *  any break points.  */
+                               int pendingPromptIsolate = -1;
+                               if (m_lastPromptIsolate != -1 && 
(getPromptState(m_lastPromptIsolate) != InitialPromptState.DONE)) {
+                                       pendingPromptIsolate = 
m_lastPromptIsolate;
+                               } else {
+                                       pendingPromptIsolate = 
hasPendingInitialPrompts();
+                               }
+                               if (pendingPromptIsolate != -1 && 
pendingPromptIsolate == m_activeIsolate) {
+                                       dumpInitialPrompt(pendingPromptIsolate);
+                               }
+                       }
+               }
+
+               while (!stop) {
+                       // allow keyboard input
+                       if (!nowait)
+                               m_keyboardReadRequest = true;
+                       int pendingResumeId = hasAnyPendingResumes();
+                       if (pendingResumeId != -1) {
+                               // resume execution (request fulfilled) and 
look for keyboard input
+                               try {
+                                       IsolateSession workerSession = 
m_session.getWorkerSession(pendingResumeId);
+                                       //if (m_stepResume)
+                                       if (getStepResume(pendingResumeId))
+                                               workerSession.stepContinue();
+                                       else {
+                                               workerSession.resume();
+                                       }
+                                       /** The user is done setting initial 
breakpoints for this isolate,
+                                        *  clear any pending initial prompts */
+                                       setPromptState(InitialPromptState.DONE, 
pendingResumeId);
+                                       removeBreakIsolate(pendingResumeId);
+                               } catch (NotSuspendedException nse) {
+                                       
err(getLocalizationManager().getLocalizedTextString("playerAlreadyRunning")); 
//$NON-NLS-1$
+                               }
+
+                               setRequestResume(false, pendingResumeId);
+                               setRequestHalt(false, pendingResumeId);
+                               setStepResume(false, pendingResumeId);
+//                             m_requestResume = false;
+//                             m_requestHalt = false;
+//                             m_stepResume = false;
+                       }
+
+                       // sleep for a bit, then process our events.
+                       try {
+                               Thread.sleep(update);
+                       } catch (InterruptedException ie) {
+                       }
+                       processEvents();
+
+                       // lost connection?
+                       if (!haveConnection()) {
+                               stop = true;
+                               dumpHaltState(false);
+                       } else if (hasAnythingSuspended()) {
+                               /**
+                                * We have stopped for some reason.  Now for 
all cases, but conditional
+                                * breakpoints, we should be done.  For 
conditional breakpoints it
+                                * may be that the condition has turned out to 
be false and thus
+                                * we need to continue
+                                */
+
+                               /**
+                                * Now before we do this see, if we have a 
valid break reason, since
+                                * we could be still receiving incoming 
messages, even though we have halted.
+                                * This is definately the case with loading of 
multiple SWFs.  After the load
+                                * we get info on the swf.
+                                */
+                               if (m_breakIsolates.size() > 0) {
+                                       targetIsolate = 
m_breakIsolates.get(m_breakIsolates.size() - 1);
+                               } else {
+                                       targetIsolate = Isolate.DEFAULT_ID;
+                               }
+                               int tries = 3;
+                               IsolateSession workerSession = 
m_session.getWorkerSession(targetIsolate);
+                               while (tries-- > 0 && 
workerSession.suspendReason() == SuspendReason.Unknown)
+                                       try {
+                                               Thread.sleep(100);
+                                               processEvents();
+                                       } catch (InterruptedException ie) {
+                                       }
+
+                               dumpHaltState(false);
+                               //if (!m_requestResume)
+                               if (!getRequestResume(targetIsolate))
+                                       stop = true;
+                       } else if (nowait) {
+                               stop = true;  // for DEBUG only
+                       } else {
+                               /**
+                                * We are still running which is fine.  But 
let's see if the user has
+                                * tried to enter something on the keyboard.  
If so, then we need to
+                                * stop
+                                */
+                               if (!m_keyboardInput.isEmpty() && 
System.getProperty("fdbunit") == null) //$NON-NLS-1$
+                               {
+                                       // flush the queue and prompt the user 
if they want us to halt
+                                       m_keyboardInput.clear();
+                                       try {
+                                               if 
(yesNoQuery(getLocalizationManager().getLocalizedTextString("doYouWantToHalt")))
 //$NON-NLS-1$
+                                               {
+                                                       
out(getLocalizationManager().getLocalizedTextString("attemptingToHalt")); 
//$NON-NLS-1$
+                                                       IsolateSession 
workerSession = m_session.getWorkerSession(m_activeIsolate);
+                                                       workerSession.suspend();
+//                                                     m_session.suspend();
+                                                       
getIsolateState(m_activeIsolate).m_requestHalt = true;
+
+                                                       // no connection => 
dump state and end
+                                                       if (!haveConnection()) {
+                                                               
dumpHaltState(false);
+                                                               stop = true;
+                                                       } else if 
(!workerSession.isSuspended())
+                                                               
err(getLocalizationManager().getLocalizedTextString("couldNotHalt")); 
//$NON-NLS-1$
+                                               }
+                                       } catch (IllegalArgumentException iae) {
+                                               
out(getLocalizationManager().getLocalizedTextString("escapingFromDebuggerPendingLoop"));
 //$NON-NLS-1$
+                                               propertyPut(NO_WAITING, 1);
+                                               stop = true;
+                                       } catch (IOException io) {
+                                               Map<String, Object> args = new 
HashMap<String, Object>();
+                                               args.put("error", 
io.getMessage()); //$NON-NLS-1$
+                                               
err(getLocalizationManager().getLocalizedTextString("continuingDueToError", 
args)); //$NON-NLS-1$
+                                       } catch (SuspendedException se) {
+                                               // lucky us, already stopped
+                                       }
+                               }
+                       }
+//             System.out.println("doContinue 
resume="+m_requestResume+",isSuspended="+m_session.isSuspended());
+               }
+
+               // DEBUG ONLY: if we are not waiting then process some events
+               if (nowait)
+                       processEvents();
+       }
+
+       /**
+        * Does a few of things -
+        * 1) Sets the target worker as 'active'.
+        * 2) Propagates any breakpoints already set which are relevant to the 
target worker.
+        * 3) Outputs messages indicating additional code load and worker 
switch.
+        * 4) Sets {@link DebugCLIIsolateState#m_promptState} as {@link 
InitialPromptState#SHOWN_ONCE} if
+        * the prompt hasn't been shown for this worker before.
+        */
+       private void dumpInitialPrompt(int targetIsolate) throws 
NotConnectedException {
+               boolean activeIsolateChanged = (m_activeIsolate != 
targetIsolate);
+               m_activeIsolate = targetIsolate;
+
+               if (activeIsolateChanged) {
+                       propertyPut(LIST_WORKER, targetIsolate);
+                       propertyPut(LIST_LINE, 1);
+                       propertyPut(LIST_MODULE, 1);
+                       propagateBreakpoints(targetIsolate);
+               }
+
+               StringBuilder sb = new StringBuilder();
+               if (getPromptState(targetIsolate) == 
InitialPromptState.NEVER_SHOWN) {
+                       
sb.append(getLocalizationManager().getLocalizedTextString("additionalCodeLoaded"));
 //$NON-NLS-1$
+                       sb.append(m_newline + 
getLocalizationManager().getLocalizedTextString("workerChanged") + " " + 
(targetIsolate - 1) + m_newline); //$NON-NLS-1$ //$NON-NLS-2$
+                       sb.append(m_newline);
+                       setPromptState(InitialPromptState.SHOWN_ONCE, 
targetIsolate);
+               }
+
+               if (resolveBreakpoints(sb))
+                       
sb.append(getLocalizationManager().getLocalizedTextString("setAdditionalBreakpoints")
 + m_newline); //$NON-NLS-1$
+               else
+                       
sb.append(getLocalizationManager().getLocalizedTextString("fixBreakpoints") + 
m_newline); //$NON-NLS-1$
+
+               // output whatever has to be
+               if (sb.length() > 0)
+                       out(sb.toString());
+
+       }
+
+       private void removeBreakIsolate(int targetIsolate) {
+               for (int i = 0; i < m_breakIsolates.size(); i++) {
+                       int id = m_breakIsolates.get(i);
+                       if (id == targetIsolate) {
+                               m_breakIsolates.remove(i);
+                               break;
+                       }
+               }
+       }
+
+       /**
+        * Bring the listing location back to the current frame
+        */
+       void doHome() {
+               try {
+                       Location l = getCurrentLocationIsolate(m_activeIsolate);
+                       SourceFile file = l.getFile();
+                       int module = file.getId();
+                       int line = l.getLine();
+                       int worker = l.getIsolateId();
+
+                       // now set it
+                       setListingPosition(module, line, worker);
+               } catch (NullPointerException npe) {
+                       
err(getLocalizationManager().getLocalizedTextString("currentLocationUnknown")); 
//$NON-NLS-1$
+               }
+       }
+
+       // Dump a source line of text to the display
+       void dumpStep() throws NotConnectedException, SuspendedException, 
IOException, NotSupportedException, NotSuspendedException, NoResponseException {
+               dumpHaltState(true);
+       }
+
+       /**
+        * Simple interface used with stepWithTimeout().  Implementors of this 
interface
+        * are expected to call one of these function: Session.stepInto(), 
Session.stepOver(),
+        * Session.stepOut(), or Session.stepContinue().
+        */
+       private interface AnyKindOfStep {
+               public void step() throws PlayerDebugException;
+       }
+
+       /**
+        * Helper function to do a stepInto, stepOver, stepOut, or stepContinue,
+        * and then to block (processing events) until either the step has 
completed
+        * or it has timed out.
+        */
+       private void stepWithTimeout(AnyKindOfStep step, int isolateId) throws 
PlayerDebugException {
+               int timeout = 
m_session.getPreference(SessionManager.PREF_RESPONSE_TIMEOUT);
+               long timeoutTime = System.currentTimeMillis() + timeout;
+
+               step.step();
+               IsolateSession workerSession = 
m_session.getWorkerSession(isolateId);
+               while (System.currentTimeMillis() < timeoutTime 

<TRUNCATED>

Reply via email to