1) Although dbg will be dropped from being supported or bundled with PHPeclipse,...
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / PHPDBGInterface.java
index 80682b8..d2262ae 100644 (file)
@@ -7,268 +7,674 @@ http://www.eclipse.org/legal/cpl-v10.html
 
 Contributors:
        Vicente Fernando - www.alfersoft.com.ar - Initial implementation
+       Christian Perkonig - remote debug
 **********************************************************************/
 package net.sourceforge.phpdt.internal.debug.core;
 
-import java.io.IOException;
 import java.io.BufferedReader;
+import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Collections;
 import java.util.Vector;
 
+//import net.sourceforge.phpdt.internal.debug.core.PHPDBGProxy.PHPLoop;
+import net.sourceforge.phpdt.internal.debug.core.model.PHPDBGEvalString;
+import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
+import net.sourceforge.phpdt.internal.debug.core.model.PHPValue;
+import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
+
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.debug.core.DebugException;
 
-import net.sourceforge.phpdt.internal.debug.core.model.PHPStackFrame;
-import net.sourceforge.phpdt.internal.debug.core.model.PHPVariable;
-import net.sourceforge.phpdt.internal.debug.core.model.PHPValue;
-
+/**
+ * The interface object are created by the proxy
+ *
+ */
 public class PHPDBGInterface {
+       public boolean                      sessionEnded = false;
+       public int                              sessType     = -1;
+       public int                              BPUnderHit   = 0;
+       public String                           sessID       = new String();
+
+       private int[]                           LastBPRead   = new int[10];
+       private Vector                      DBGBPList    = new Vector();
+       private Vector                      DBGVarList   = new Vector();
+       private PHPStackFrame[]         DBGStackList = new PHPStackFrame[0];
+       private Vector                  DBGMods      = new Vector();                    // The module names and their numbers
+       private Vector                      stackListOld = new Vector();
+       private BufferedReader          dbgInput;
+       private OutputStream            dbgOutput;                                                      // The stream which goes to DBG
+       private boolean                         shouldStop   = false;
+       private String                      evalRet      = new String("");
+       private int                             rawCounter   = 1000;                                    // An rawData frame ID counter
+       private PHPDBGProxy             proxy        = null;
+//  private int                                lastCmd      = -1;
+       private int                             sid          = 0;
+       private boolean                         stopOnError  = false;                                   // If we the debugger should be relaunched after script termination
+       private boolean             bRelaunch    = true;
+       private char[]                  lastCommand  = new char[4];
+       private boolean             bBusy        = false;
+       private boolean             bDebug       = true;                                        // Prints text to console for debugging purposes
+
+       private static final String GlobalVariablesTitle = PHPDebugCorePlugin
+                       .getResourceString("VariablesView.GlobalVariables.title");
+
+       /**
+        * @param in        The input stream (communication from DBG).
+        * @param os        The output stream (communication to DBG).
+        * @param proxy     The proxy to which this interface belongs.
+        * @param bRelaunch The debugger should be relaunched after PHP script termination
+        */
+       public PHPDBGInterface (BufferedReader in, OutputStream os, PHPDBGProxy proxy, boolean bRelaunch) {
+               DBGBPList.clear ();
+
+               this.dbgInput   = in;
+               this.dbgOutput  = os;
+               this.proxy              = proxy;
+               this.bRelaunch  = bRelaunch;
+       }
 
-       // Public
-       public boolean sessionEnded= false;
-       public int sessType= -1;        
-       public int BPUnderHit= 0;
-       public String sessID= new String();
-       
-       // Private
-       private int[] LastBPRead= new int[10];
-       private Vector DBGBPList= new Vector();
-       private PHPStackFrame[] DBGStackList;
-       private PHPVariable[] DBGVariableList;
-       private Vector DBGMods= new Vector();
-       private Vector DBGVars= new Vector();
-       private BufferedReader in;
-       private OutputStream os;
-       private boolean shouldStop= false, isRef= false, hasChildren= false, isObject= false;
-       private String evalRet= new String("");
-       private String serGlobals= new String("");
-       private String typeRead= new String("");
-       private String className= new String("");
-       private int finalPos=0, refCounter=0, rawCounter=1000;
-       private PHPDBGProxy proxy= null;
-       private boolean stopOnError= false;
-       private char[] lastCommand= new char[4];
-        
-       public PHPDBGInterface(BufferedReader in, OutputStream os, PHPDBGProxy proxy) {
-               DBGBPList.clear();
-               this.in= in;
-               this.os= os;
-               this.proxy= proxy;
-       }
-
-       public int addBreakpoint(String mod_name, int line) throws IOException {
-               return setBreakpoint(mod_name, "", line, PHPDBGBase.BPS_ENABLED + PHPDBGBase.BPS_UNRESOLVED, 0, 0, 0, 0, 0);
-       }
-
-       public void removeBreakpoint(String mod_name, int line, int bpNo) throws IOException {
-               setBreakpoint(mod_name, "", line, PHPDBGBase.BPS_DISABLED, 0, 0, 0, bpNo, 0);
-       }
-
-       public void requestDBGVersion() throws IOException {
-               PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
-               PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_VER);
-               
-               DBGPacket.addFrame(DBGFrame);
-
-               if(proxy.getSocket().isClosed()) return;
-               DBGPacket.sendPacket(os);
+       /**
+        *
+        * @param mod_name  The module (source file) to which we add the breakpoint.
+        * @param line      The line where the breakpoint is set.
+        * @param hitCount  The number of hit counts before suspend.
+        * @param condition The break condition
+        * @return          Breakpoint ID ???.
+        */
+       public int addBreakpoint (String mod_name, int line, int hitCount, String condition) throws IOException {
+               return setBreakpoint (mod_name, condition, line, PHPDBGBase.BPS_ENABLED + PHPDBGBase.BPS_UNRESOLVED, 0, hitCount, 0, 0, 0);
        }
 
-       public void getSourceTree() throws IOException {
-               PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
-               PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_SRC_TREE);
-               
-               DBGPacket.addFrame(DBGFrame);
-               
-               if(proxy.getSocket().isClosed()) return;
-               DBGPacket.sendPacket(os);
-
-               // Wait response (1 second) and read response
-               waitResponse(1000);
-               flushAllPackets();
+       /**
+        *
+        * @param mod_name The module (source file) to which we add the breakpoint.
+        * @param line     The line where the breakpoint is set.
+        * @param bpNo     The breakpoint ID ???.
+        */
+       public void removeBreakpoint (String mod_name, int line, int bpNo) throws IOException {
+               setBreakpoint (mod_name, "", line, PHPDBGBase.BPS_DISABLED, 0, 0, 0, bpNo, 0);
        }
 
-       public void addDBGModName(String modName) throws IOException {
-               PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
-               PHPDBGFrame DBGFrame= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
-               
-               rawCounter++;
-               DBGFrame.addInt(rawCounter);                            // FRAME_RAWDATA ID
-               DBGFrame.addInt(modName.length() + 1);          // length of rawdata (+ null char)
-               DBGFrame.addString(modName);                            // file name
-               DBGFrame.addChar('\0');                                         // null char
+       /**
+        * Is this method used anywhere?
+        *
+        */
+//     public void requestDBGVersion () throws IOException {
+//             PHPDBGPacket DBGPacket;                                     // A DBG message packet
+//             PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
+//
+//             DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
+//             DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_VER);         // We want the version of DBG
+//
+//             DBGPacket.addFrame (DBGFrame);                              // Add the 'what we want' to the DBG packet
+//
+//             if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+//                     return;                                                 //  No
+//             }
+//
+//             DBGPacket.sendPacket (os);                                                                      // Send the request to DBG
+//     }
+
+       /**
+        * Called by the proxy
+        *
+        */
+       public void getSourceTree () throws IOException {
+               PHPDBGPacket DBGPacket;                                     // A DBG message packet
+               PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
+
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: getSourceTree");
+               }
+
+               DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
+               DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_SRC_TREE);        // We want a source tree from DBG
 
-               DBGPacket.addFrame(DBGFrame);
-               
-               if(proxy.getSocket().isClosed()) return;
-               DBGPacket.sendPacket(os);
+               DBGPacket.addFrame (DBGFrame);                              // Add the 'what we want' to the DBG packet
+
+               if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+                       bBusy = false;
+                       return;                                                                                                 //  No
+               }
+
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
+
+               waitResponse (1000);                                        // Wait for the DBG response (1 second)
+               flushAllPackets ();                                                                             // Read and process the response from DBG
        }
 
-       // Returns DBG Breakpoint ID
-       private int setBreakpoint(String mod_name, String condition, int line, int state, int istemp, int hitcount, int skiphits, int bpno, int isunderhit) throws IOException {
-               int modNo= 0;
+       /**
+        * Is this method called from anywhere?
+        *
+        * @param modName The modul (filename).
+        */
+//     public void addDBGModName (String modName) throws IOException {
+//             PHPDBGPacket DBGPacket;                                     // A DBG message packet
+//             PHPDBGFrame  DBGFrame;                                      // A frame within a DBG packet
+//
+//             DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     // A request for DBG
+//             DBGFrame  = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);     // We want Module name from DBG
+//
+//             rawCounter++;                                               // Increment the rawData ID counter
+//             DBGFrame.addInt (rawCounter);                                                           // FRAME_RAWDATA ID
+//             DBGFrame.addInt (modName.length () + 1);                                        // The length of rawdata string (incl. null char termination)
+//             DBGFrame.addString (modName);                                                           // The file name (module name)
+//             DBGFrame.addChar ('\0');                                                                        // Add the C-String null termination
+//
+//             DBGPacket.addFrame (DBGFrame);
+//
+//             if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+//                     return;                                                                                                 //  No
+//             }
+//
+//             DBGPacket.sendPacket (os);
+//     }
+
+       /**
+        * This method is called for adding or removing breakpoints.
+        *
+        * @param mod_name      The module name (file name).
+        * @param condition     Info about the condition when to break (not used at the moment).
+        * @param line          The breakpoints line.
+        * @param state         Info whether this breakpoint has to be dis- or enabled.
+        * @param istep         Always 0.
+        * @param hitcount      Always 0.
+        * @param skiphits      Always 0.
+        * @param bpno          The breakpoint ID.
+        * @param isunderhit    ???
+        * @return
+        */
+       private int setBreakpoint (String mod_name, String condition, int line, int state, int istemp, int hitcount, int skiphits, int bpno, int isunderhit) throws IOException {
+               PHPDBGPacket    DBGPacket;
+               PHPDBGFrame     DBGFrame1;
+               PHPDBGFrame     DBGFrame2;
+               PHPDBGFrame             DBGFrame3;
+               int                     modNo;
+
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: setBreakpoint");
+               }
+
+               DBGPacket       = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);
+               DBGFrame1       = new PHPDBGFrame (PHPDBGBase.FRAME_BPS);
+               DBGFrame2       = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
+               DBGFrame3       = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
 
-               PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
-               PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_BPS);
-               PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
+               modNo           = getModByName (mod_name);                                              // Get the module ID by name
 
-               modNo= getModByName(mod_name);
-               
-               if(modNo >= 0) {
-                       DBGFrame1.addInt(modNo);        // mod number
+               if (modNo >= 0) {                                           // Did we find a module ID for the module name?
+                       DBGFrame1.addInt (modNo);                                                               // Add the module ID to frame 1
                } else {
-                       DBGFrame1.addInt(0);            // mod number (0 use file name)
+                       DBGFrame1.addInt (0);                                                                   // mod number (0 use file name)
                }
-               
-               DBGFrame1.addInt(line);                 // line number
-               
-               if(modNo >= 0) {
-                       DBGFrame1.addInt(0);                    // use mod number
+
+               DBGFrame1.addInt (line);                                                                        // line number
+
+               if (modNo >= 0) {                                           // Did we find a module ID for the module name?
+                       DBGFrame1.addInt (0);                                                                   // use mod number
                } else {
                        rawCounter++;
-                       DBGFrame1.addInt(rawCounter);   // ID of FRAME_RAWDATA to send file name
-               }
-
-               DBGFrame1.addInt(state);                // state BPS_*
-               DBGFrame1.addInt(istemp);               // istemp
-               DBGFrame1.addInt(hitcount);             // hit count
-               DBGFrame1.addInt(skiphits);             // skip hits
-               DBGFrame1.addInt(0);                    // ID of condition
-               DBGFrame1.addInt(bpno);                 // breakpoint number
-               DBGFrame1.addInt(isunderhit);   // is under hit
-               
-               if(modNo < 0) {
-                       DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
-                       DBGFrame2.addInt(mod_name.length() + 1);        // length of rawdata (+ null char)
-                       DBGFrame2.addString(mod_name);                          // file name
-                       DBGFrame2.addChar('\0');                                        // null char
-                       // First add file name data
-                       DBGPacket.addFrame(DBGFrame2);
-               }
-
-               // Second add command data
-               DBGPacket.addFrame(DBGFrame1);
+                       DBGFrame1.addInt (rawCounter);                                                  // ID of FRAME_RAWDATA to send file name
+               }
 
-               if(proxy.getSocket().isClosed()) return 0;
-               DBGPacket.sendPacket(os);
+               if (modNo < 0) {                                            // Did we find a module ID for the module name?
+                       DBGFrame2.addInt (rawCounter);                                      // FRAME_RAWDATA ID
+                       DBGFrame2.addInt (mod_name.length() + 1);                   // length of rawdata (+ null char)
+                       DBGFrame2.addString (mod_name);                                     // file name
+                       DBGFrame2.addChar ('\0');                                                   // null char
 
-               clearLastBP();
+                       DBGPacket.addFrame (DBGFrame2);                         // First add file name data
+               }
 
-               // Wait response (1 second) and read response
-               waitResponse(1000);
-               flushAllPackets();
+               DBGFrame1.addInt (state);                                       // state BPS_*
+               DBGFrame1.addInt (istemp);                                      // istemp
+               DBGFrame1.addInt (0);                                               // hit count; this is not supported as one might think
+               DBGFrame1.addInt (hitcount);                                // skip hits is what we think is hit count.
+
+               if (!condition.equals ("")) {                                                           // Do we have a condition for breakpoint
+                       rawCounter++;                                                                                   // Set to new ID
+                       DBGFrame1.addInt (rawCounter);                          // ID of condition
+
+                       DBGFrame3.addInt (rawCounter);                                      // FRAME_RAWDATA ID
+                       DBGFrame3.addInt (condition.length() + 1);                  // length of rawdata (+ null char)
+                       DBGFrame3.addString (condition);                                        // The break condition
+                       DBGFrame3.addChar ('\0');                                                   // null char
+
+                       DBGPacket.addFrame (DBGFrame3);                         // First add break condition
+               }
+               else {
+                       DBGFrame1.addInt (0);                                           // ID of condition is 0, because there is no condition
+               }
 
-               return LastBPRead[8];
+               DBGFrame1.addInt (bpno);                                            // breakpoint number
+               DBGFrame1.addInt (isunderhit);                                  // is under hit
+
+               DBGPacket.addFrame (DBGFrame1);                                                         // Second add command data
+
+               if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+                       bBusy = false;
+                       return 0;                                               //  No
+               }
+
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
+
+               clearLastBP ();
+
+               waitResponse (1000);                                        // Wait for the DBG response (1 second)
+               flushAllPackets ();                                         // Read and process the response from DBG
+
+               return LastBPRead[8];                                                                           // Return what ???
        }
 
-       private void clearLastBP() {
+       /**
+        *
+        */
+       private void clearLastBP () {
                int i;
 
-               for(i=0; i < LastBPRead.length; i++)
-                       LastBPRead[i]= 0;
+               for (i = 0; i < LastBPRead.length; i++) {
+                       LastBPRead[i] = 0;
+               }
        }
 
-       private void copyToLastBP(int[] BPBody) {
+       /**
+        *
+        */
+       private void copyToLastBP (int[] BPBody) {
                int i;
 
-               for(i=0; i < LastBPRead.length; i++)
-                       LastBPRead[i]= BPBody[i];
+               for (i = 0; i < LastBPRead.length; i++) {
+                       LastBPRead[i] = BPBody[i];
+               }
        }
 
-       public void continueExecution() throws IOException {
-               BPUnderHit= 0;
-               PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_CONTINUE);
-               if(proxy.getSocket().isClosed()) return;
-               DBGPacket.sendPacket(os);
-               lastCommand= PHPDBGBase.DBGA_CONTINUE;
+       /**
+        *
+        */
+       public void continueExecution () throws IOException {
+               PHPDBGPacket DBGPacket;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: continueExecution");
+               }
+
+               BPUnderHit = 0;
+               DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_CONTINUE);
+
+               if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+                       return;                                                 //  No
+               }
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
+
+               lastCommand = PHPDBGBase.DBGA_CONTINUE;                     // Store the info about the command we sent
        }
 
-       public void pauseExecution() throws IOException {
-               PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.IntToChar4(PHPDBGBase.DBGC_PAUSE));
-               if(proxy.getSocket().isClosed()) return;
-               DBGPacket.sendPacket(os);
+       /**
+        *
+        */
+       public void pauseExecution () throws IOException {
+               PHPDBGPacket DBGPacket;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: pauseExecution");
+               }
+
+               DBGPacket = new PHPDBGPacket (PHPDBGBase.IntToChar4 (PHPDBGBase.DBGC_PAUSE));
+
+               if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+                        return;                                                //  No
+               }
+
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
        }
 
-       private int getBPUnderHit() {
-               int i, BPUnder=0;
-               int[] dbg_bpl_body= new int[10];
+       /**
+        *
+        */
+       private int getBPUnderHit () {
+               int i;
+               int BPUnder             = 0;
+               int[] dbg_bpl_body      = new int[10];
+
+               for (i = 0; i < DBGBPList.size (); i++) {                               // look for bp under hit
+                       dbg_bpl_body = (int[]) DBGBPList.get (i);
 
-               // look for bp under hit
-               for(i=0; i < DBGBPList.size(); i++) {
-                       dbg_bpl_body= (int[]) DBGBPList.get(i);
-                       if(dbg_bpl_body[9] == 1) {
-                               BPUnder= dbg_bpl_body[8];
+                       if (dbg_bpl_body[9] == 1) {
+                               BPUnder = dbg_bpl_body[8];
                        }
                }
+
                return BPUnder;
        }
 
-       public void stepInto() throws IOException {
-               BPUnderHit= 0;
-               PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPINTO);
-               if(proxy.getSocket().isClosed()) return;
-               DBGPacket.sendPacket(os);
-               lastCommand= PHPDBGBase.DBGA_STEPINTO;
+//     public int getLastCmd()
+//     {
+//             return lastCmd;
+//     }
+
+       public int getSID()
+       {
+         return sid;
+       }
+
+       public void setLastCmd (int cmd)
+       {
+               //lastCmd = cmd;
+       }
+
+       /**
+        *
+        */
+       public boolean stepInto () throws IOException {
+               PHPDBGPacket DBGPacket;
+
+               if (bBusy) {
+                       if (bDebug) {
+                               System.out.println ("PHPDBGInterface: stepOver vetoed");
+                       }
+               }
+
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: stepInto");
+               }
+
+               BPUnderHit = 0;
+               DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPINTO);
+
+               if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+                       return false;                                           //  No
+               }
+
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
+
+               lastCommand = PHPDBGBase.DBGA_STEPINTO;                                         // Store the info about the command we sent
+
+               return true;
        }
 
-       public void stepOver() throws IOException {
-               BPUnderHit= 0;
-               PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOVER);
-               if(proxy.getSocket().isClosed()) return;
-               DBGPacket.sendPacket(os);
-               lastCommand= PHPDBGBase.DBGA_STEPOVER;
+       /**
+        *
+        */
+       public boolean stepOver () throws IOException {
+               PHPDBGPacket DBGPacket;
+
+               if (bBusy) {
+                       if (bDebug) {
+                               System.out.println ("PHPDBGInterface: stepOver vetoed");
+                       }
+               }
+
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: stepOver");
+               }
+
+               BPUnderHit = 0;
+               DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOVER);
+
+               if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+                       return false;                                           //  No
+               }
+
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
+
+               lastCommand = PHPDBGBase.DBGA_STEPOVER;                     // Store the info about the command we sent
+
+               return true;
        }
 
-       public void stepOut() throws IOException {
-               BPUnderHit= 0;
-               PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STEPOUT);
-               if(proxy.getSocket().isClosed()) return;
-               DBGPacket.sendPacket(os);
-               lastCommand= PHPDBGBase.DBGA_STEPOUT;
+       /**
+        *
+        */
+       public boolean stepOut () throws IOException {
+               PHPDBGPacket DBGPacket;
+
+               if (bBusy) {
+                       if (bDebug) {
+                               System.out.println ("PHPDBGInterface: stepOver vetoed");
+                       }
+               }
+
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: stepOut");
+               }
+
+               BPUnderHit = 0;
+               DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STEPOUT);
+
+               if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+                       return false;                                           //  No
+               }
+
+               DBGPacket.sendPacket (dbgOutput);                           // Send the request to DBG
+
+               lastCommand = PHPDBGBase.DBGA_STEPOUT;                      // Store the info about the command we sent
+
+               return true;
        }
 
-       public void stopExecution() throws IOException {
-               BPUnderHit= 0;
-               PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_STOP);
-               if(proxy.getSocket().isClosed()) return;
-               DBGPacket.sendPacket(os);
+       /**
+        *
+        */
+//     public void stopExecution () throws IOException {
+//             PHPDBGPacket DBGPacket;
+//
+//             BPUnderHit = 0;
+//             DBGPacket  = new PHPDBGPacket (PHPDBGBase.DBGA_STOP);
+//
+//             if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
+//                     return;                                                 //  No
+//             }
+//
+//             DBGPacket.sendPacket (os);                                  // Send the request to DBG
+//     }
+
+       /**
+        * This method is called by the proxy.
+        * It sends a request to DBG to get the current variables
+        * with their values. It waits for the response and processes
+        * the input from DBG.
+        *
+        * @param stack The stackframe for which we want the variables.
+        * @return      The array of variables
+        */
+       public synchronized Vector getVariables(PHPStackFrame stack) throws IOException, DebugException {
+               if (DBGStackList.length == 0) {
+                       DBGVarList.clear();
+
+                       return DBGVarList;
+               }
+
+               // get global variables (and assign them to 'main()' stackframe)
+               int global_scope_id = (DBGStackList.length > 1) ? 2 : PHPDBGBase.GLOBAL_SCOPE_ID;
+               // DBG 2.13.1 doesn't return Super Globals with GLOBAL_SCOPE_ID in nested stackframes,
+               // so using 2(most out-standing stack context) instead of GLOBAL_SCOPE_ID.
+               // Also note that 2.13.1 doesn't return $this in class context.
+               // (You can inspect $this in Expressions View. And once it is shown, 2.13.1 comes to return $this.)
+               Vector globalList = getVariables(DBGStackList[DBGStackList.length - 1], global_scope_id);
+
+               if (!globalList.isEmpty()) {
+                       // remove unresolved '$this=?' variable
+                       removeUnresolvedThisVar(globalList);
+
+                       PHPVariable var = (PHPVariable) globalList.get(0);
+                       var.setName(GlobalVariablesTitle);
+                       var.setModifiable(false);
+               }
+
+               int scopeID = stack.getScopeID();
+
+               if (!globalList.isEmpty () &&
+                   ((DBGStackList.length == 1) || (scopeID == PHPDBGBase.CURLOC_SCOPE_ID + 1))) {
+                       // 'main()' stackframe
+                       PHPVariable var = (PHPVariable) globalList.get(0);
+                       PHPValue    val = (PHPValue) var.getValue();
+
+                       DBGVarList      = val.getChildVariables();
+
+                       return DBGVarList;
+               }
+               else if (scopeID == PHPDBGBase.CURLOC_SCOPE_ID) {
+                       // current stackframe
+                       DBGVarList = getVariables(stack, PHPDBGBase.CURLOC_SCOPE_ID);
+               }
+               else {
+                       // back-trace stackframe
+                       //DBGVarList = getVariables(stack, scopeID);
+                       //removeUnresolvedThisVar(DBGVarList);
+                       // DBG 2.15.5 causes Application Error (on win32) in *some* cases.
+                       DBGVarList.clear();
+               }
+
+               if (DBGVarList.size() > 0) {                                                            // Did we get back variables?
+                       PHPVariable var = (PHPVariable) DBGVarList.get(0);              // Yes, then get the first PHPVariable
+                       PHPValue    val = (PHPValue) var.getValue();                    // Get the value
+
+                       if (var.getName().equals("")) {                                                 // Is the root node an empty node (usually it is)
+                               DBGVarList = val.getChildVariables();                           // Then remove the empty node.
+                                                                                                                                       // With removing the empty root node, it wouldn't be necessary to
+                                                                                                                                       // set the name to an empty string. So the code below is just for
+                                                                                                                                       // info or in case the users want to have the empty root node.
+
+                                                                                                                                       // The eclipse variable view cannot handle Variables which have an empty name
+                                                                                                                                       // when it comes to variable tree restore operation. Without a name, no restore!
+                               //var.setName (" ");                                                            // Give a name to the variable root node. Even if it is only a space :-)
+                       }                                                                                                               // TO DO the best would be to remove the empty root node, but this would
+                                                                                                                                       // require a understanding and reworking of the PHPDBGEvalstring class.
+               }
+
+               if (!globalList.isEmpty()) {
+                       DBGVarList.add(globalList.get(0));
+               }
+
+               return DBGVarList;                                                                                      // Return the variables as list
        }
 
-       public PHPVariable[] getVariables(PHPStackFrame stack) throws IOException, DebugException  {
-               PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
-               PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
-       
-               DBGFrame1.addInt(0);                                            // istr = raw data ID
-               DBGFrame1.addInt(1);                                            // scope_id = -1 means current location, 0 never used, +1 first depth
-               
-               // Add command data
+       /**
+        *
+        */
+       private Vector getVariables(PHPStackFrame stack, int scope_id) throws IOException {
+               PHPDBGPacket DBGPacket = new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
+               PHPDBGFrame DBGFrame1 = new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
+
+               if (bBusy) {
+                       if (bDebug) {
+                               System.out.println ("PHPDBGInterface: getVariables vetoed");
+                       }
+               }
+
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: getVariables");
+               }
+
+               DBGFrame1.addInt(0);
+               DBGFrame1.addInt(scope_id);
+
                DBGPacket.addFrame(DBGFrame1);
-               
-               if(proxy.getSocket().isClosed()) return null;
-               DBGPacket.sendPacket(os);
+               evalRet = "";
+
+               if (proxy.getSocket().isClosed()) {
+                       bBusy = false;
+                       return new Vector();
+               }
+
+               DBGPacket.sendPacket(dbgOutput);
 
                waitResponse(1000);
                flushAllPackets();
-               
-               // Process serialized variables
-               DBGVariableList= procVars(stack);
 
-               return DBGVariableList;
+               bBusy = false;                                                          // Already done in flushAllPackets ()
+
+               PHPDBGEvalString evalStr = new PHPDBGEvalString(stack, evalRet);
+               return evalStr.getVariables();
+       }
+
+       /**
+        * Remove unresolved $this variable
+        *
+        * DBG returns $this=? in function's or intermediate stackframes.
+        * (In current method's stackframe, DBG returns $this=classname)
+        *
+        * @param varList
+        */
+       private void removeUnresolvedThisVar(Vector varList) {
+               if (varList.size() > 0) {
+                       PHPVariable var       = (PHPVariable) varList.get(0);
+                       PHPValue    val       = (PHPValue) var.getValue();
+                       Vector      workList  = val.getChildVariables ();
+
+                       for (int i = 0; i < workList.size(); i++) {
+                               PHPVariable workvar = (PHPVariable) workList.get(i);
+
+                               if (workvar.getName().equals ("$this")) {
+                                       String workval = ((PHPValue) workvar.getValue ()).getValueString ();
+
+                                       if (workval.equals ("?") ||
+                                           workval.equals ("NULL")) {
+                                               workList.remove (i);
+                                       }
+                                       break;
+                               }
+                       }
+               }
        }
 
+       /**
+        *
+        * @param logString
+        */
        public void log(String logString) throws IOException, DebugException  {
                PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
                PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_LOG);
                PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
 
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: log");
+               }
+
                rawCounter++;
                DBGFrame1.addInt(rawCounter);                           // ilog
                DBGFrame1.addInt(1);                                            // type
                DBGFrame1.addInt(0);                                            // mod_no
                DBGFrame1.addInt(0);                                            // line_no
                DBGFrame1.addInt(0);                                            // imod_name
-               DBGFrame1.addInt(0);                                            // ext_info             
+               DBGFrame1.addInt(0);                                            // ext_info
 
                DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
                DBGFrame2.addInt(logString.length() + 1);       // length of rawdata (+ null char)
@@ -279,22 +685,42 @@ public class PHPDBGInterface {
                DBGPacket.addFrame(DBGFrame2);
                // Add command data
                DBGPacket.addFrame(DBGFrame1);
-               
-               if(proxy.getSocket().isClosed()) return;
-               DBGPacket.sendPacket(os);
+
+               if (proxy.getSocket ().isClosed ()) {                   // Do we have a socket for DBG communication?
+                       bBusy = false;
+                       return;                                                                                         //  No, then leave here
+               }
+
+               DBGPacket.sendPacket(dbgOutput);
 
                waitResponse(1000);
                flushAllPackets();
        }
 
-       public void evalBlock(String evalString) throws IOException, DebugException  {
+       public synchronized PHPVariable[] evalBlock(PHPStackFrame stack, String evalString) throws IOException, DebugException {
                PHPDBGPacket DBGPacket= new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
                PHPDBGFrame DBGFrame1= new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
                PHPDBGFrame DBGFrame2= new PHPDBGFrame(PHPDBGBase.FRAME_RAWDATA);
 
+               while (bBusy) {
+       }
+
+               bBusy = true;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: evalBlock");
+               }
+
                rawCounter++;
                DBGFrame1.addInt(rawCounter);                           // istr = raw data ID
-               DBGFrame1.addInt(-1);                                           // scope_id = -1 means current location, 0 never used, +1 first depth
+               //DBGFrame1.addInt(1);                                          // scope_id = -1 means current location, 0 never used, +1 first depth
+               int scope_id = stack.getScopeID();
+               /* test code : unnecessary
+               if (DBGStackList.length == 1 || scope_id == (PHPDBGBase.CURLOC_SCOPE_ID + 1)) {
+                       scope_id = PHPDBGBase.GLOBAL_SCOPE_ID;
+               }
+               */
+               DBGFrame1.addInt(scope_id);
 
                DBGFrame2.addInt(rawCounter);                           // FRAME_RAWDATA ID
                DBGFrame2.addInt(evalString.length() + 1);      // length of rawdata (+ null char)
@@ -305,583 +731,719 @@ public class PHPDBGInterface {
                DBGPacket.addFrame(DBGFrame2);
                // Add command data
                DBGPacket.addFrame(DBGFrame1);
-               
-               if(proxy.getSocket().isClosed()) return;
-               DBGPacket.sendPacket(os);
+
+               if (proxy.getSocket().isClosed()) {                     // Do we have a socket for DBG communication?
+                       bBusy = false;
+                       return null;                                                    //  No, then leave here
+               }
+
+               DBGPacket.sendPacket(dbgOutput);
 
                waitResponse(1000);
                flushAllPackets();
-       }
 
-       public void flushAllPackets() throws IOException {
-               while(readResponse() != 0);
+               PHPDBGEvalString evalStr=new PHPDBGEvalString(stack, evalRet);
+
+               return evalStr.getVars();
        }
 
-       public String getModByNo(int modNo) {
-               int i;
-               PHPDBGMod dbg_mod;
+       /**
+        * Read and process everthing we got from DBG
+        */
+       public void flushAllPackets () throws IOException {
+               while (readResponse() != 0);
+       }
 
-               // look for mod
-               for(i=0; i < DBGMods.size(); i++) {
-                       dbg_mod= (PHPDBGMod) DBGMods.get(i);
-                       if(dbg_mod.getNo() == modNo) {
-                               return dbg_mod.getName(); 
+       /**
+        * Get the modules name by its number
+        *
+        * @param modNo The number (id) of the module
+        * @return      The name of the module
+        */
+       public String getModByNo (int modNo) {
+               int             i;
+               PHPDBGMod       dbg_mod;
+
+               for (i = 0; i < DBGMods.size (); i++) {                         // For all the modules we have within the array
+                       dbg_mod = (PHPDBGMod) DBGMods.get (i);                      // Get the module
+
+                       if (dbg_mod.getNo () == modNo) {                            // Is the module from the array the module we want?
+                               return dbg_mod.getName ();                              //  Yes, return the name of the module
                        }
                }
-               return "";
-       }
 
-       private int getModByName(String modName) {
-               int i;
-               PHPDBGMod dbg_mod;
+               return "";                                                      // If nothing was found return emtpy string
+       }
 
-               // look for mod
-               for(i=0; i < DBGMods.size(); i++) {
-                       dbg_mod= (PHPDBGMod) DBGMods.get(i);
-                       if(dbg_mod.getName().equalsIgnoreCase(modName)) {
-                               return dbg_mod.getNo(); 
+       /**
+        *
+        * @param  modName The name of the module for which we want the ID
+        * @return
+        * - The ID of the module
+        * - -1 if nothing was found
+        */
+       private int getModByName (String modName) {
+               int             i;
+               PHPDBGMod       dbg_mod;
+
+               for (i = 0; i < DBGMods.size (); i++) {                         // For all the modules we have within the array
+                       dbg_mod = (PHPDBGMod) DBGMods.get (i);                      // Get the module
+
+                       if (dbg_mod.getName ().equalsIgnoreCase (modName)) {            // Is the module from the array the module we want?
+                               return dbg_mod.getNo ();                                //  Yes, return the name of the module
                        }
                }
-               return -1;
+
+               return -1;                                                      // If nothing was found return -1
        }
 
-       private String getRawFrameData(char[] framesInfo, int frameNo) {
-               int nextFrame= 0;
-               int[] dbg_frame= new int[2];
-               
-               while(nextFrame < framesInfo.length) {
-                       dbg_frame[0] = PHPDBGBase.Char4ToInt(framesInfo, nextFrame);            // frame name
-                       dbg_frame[1] = PHPDBGBase.Char4ToInt(framesInfo, nextFrame + 4);        // frame size
+       /**
+        * Return the string for the given frame number
+        *
+        * @param framesInfo The buffer which is to read
+        * @param frameNo    The frame number
+        * @return
+        */
+       private String getRawFrameData (char[] framesInfo, int frameNo) {
+               int   nextFrame = 0;                                                    // The current read position within the buffer
+               int[] dbg_frame = new int[2];                                           // The two frame header numbers
+
+               while (nextFrame < framesInfo.length) {                                 // As long we have something within the buffer
+                       dbg_frame[0] = PHPDBGBase.Char4ToInt (framesInfo, nextFrame);           // The frame type
+                       dbg_frame[1] = PHPDBGBase.Char4ToInt (framesInfo, nextFrame + 4);       // The frame size
+
+                       nextFrame   += 8;                                                   // The current read position
+
+                       if (dbg_frame[1] == 0) {                                            // If frame size is 0
+                               return "";                                                      //  return an emtpy string
+                       }
+
+                       switch (dbg_frame[0]) {                                                     // Switch for the frame type
+                               case PHPDBGBase.FRAME_RAWDATA:                                                  // The only frame type we are interrested in
+                                       if (frameNo == PHPDBGBase.Char4ToInt (framesInfo, nextFrame)) {         // Is it correct  number of the frame
+                                               int toRead;                                                     //
+
+                                               toRead = PHPDBGBase.Char4ToInt (framesInfo, nextFrame + 4);     // The size of the string
 
-                       nextFrame += 8;
-                       if(dbg_frame[1] == 0) return "";
+                                               if ((int) framesInfo[nextFrame + 8 + toRead - 1] == 0) {                                // Is there a string termination at the end?
+                                                       return String.copyValueOf (framesInfo, nextFrame + 8, toRead - 1);      // Then copy frame content to String without the \0 and return
+                                               }
 
-                       switch(dbg_frame[0]) {
-                               case PHPDBGBase.FRAME_RAWDATA:
-                                       if(frameNo == PHPDBGBase.Char4ToInt(framesInfo, nextFrame)) {
-                                               int toRead= PHPDBGBase.Char4ToInt(framesInfo, nextFrame + 4);
-                                               return String.copyValueOf(framesInfo, nextFrame + 8, toRead);
+                                               return String.copyValueOf (framesInfo, nextFrame + 8, toRead);  // Copy frame content to String and return
                                        }
                                        break;
                        }
-                       // go to next frame
-                       nextFrame += dbg_frame[1];
-               }
-               return "";
-       }
-
-       public PHPVariable[] getInstVars(PHPVariable phpVar) throws DebugException {
-               Vector vecVars= new Vector();
-               PHPVariable localPHPVar;
-               int i=0;
-               
-               // already unserialized
-               for(i=0; i < DBGVars.size(); i++) {
-                       localPHPVar= (PHPVariable)DBGVars.get(i);
-                       if(localPHPVar.getParent() == phpVar) {
-                               vecVars.add(localPHPVar);
-                       }
+
+                       nextFrame += dbg_frame[1];                                                                      // Go for the next frame (add the length of the current one)
+               }
+
+               return "";                                                                                                                                              // We did not found any FRAM_RAWDATA, so return an emtpy strin
+       }
+
+       /**
+        * Reset the availability flag for all stackframes in the list.
+        *
+        * @param list          The list of old stackframes
+        */
+       private void resetAvailability (Vector list) {
+               int             i;
+
+               for (i = 0; i < list.size (); i++) {
+                       ((PHPStackFrame) list.get(i)).setAvailable (false);                                     //
                }
-               PHPVariable[] arrVars= new PHPVariable[vecVars.size()];
-               arrVars= (PHPVariable[]) vecVars.toArray(arrVars);
-
-               return arrVars;
-       }
-       
-       private PHPVariable[] procVars(PHPStackFrame stack) throws DebugException {
-               Vector vecVars= new Vector();
-               
-               // unserialize
-               finalPos= 0;
-               refCounter= 0;
-               doUnserialize(stack, vecVars, null);
-
-               DBGVars= vecVars;
-               
-               return(getInstVars(null));
-       }
-
-       private String readValue(String serialVars) throws DebugException {
-               int startPos=0, endPos=0, lenStr=0, i=0, elements=0;
-               String ret= new String("");
-
-               switch(serialVars.charAt(0)) {
-                       case 'a':       // associative array, a:elements:{[index][value]...}
-                               typeRead= "hash";
-                               startPos= 1;
-                               endPos= serialVars.indexOf(':', startPos + 1);
-                               if(endPos == -1) return "";
-                               finalPos += endPos + 2;
-                               ret= new String(serialVars.substring(startPos + 1, endPos));
-                               
-                               hasChildren= true;
-                               break;
-                       case 'O':       // object, O:name_len:"name":elements:{[attribute][value]...}
-                               typeRead= "object";
-                               
-                               startPos= 1;
-                               endPos= serialVars.indexOf(':', startPos + 1);
-                               if(endPos == -1) return "";
-                               
-                               // get object class
-                               lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos));
-                               startPos= endPos + 2;
-                               endPos= lenStr + startPos;
-                               className= new String(serialVars.substring(startPos, endPos).toString());
-
-                               // get num of elements
-                               startPos= endPos + 1;
-                               endPos= serialVars.indexOf(':', startPos + 1);
-                               if(endPos == -1) return "";
-                               finalPos += endPos + 2;
-                               ret= new String(serialVars.substring(startPos + 1, endPos));
-
-                               isObject= true;
-                               hasChildren= true;                              
-                               break;
-                       case 's':       // string, s:length:"data";
-                               typeRead= "string";
-                               startPos= 1;
-                               endPos= serialVars.indexOf(':', startPos + 1);
-                               if(endPos == -1) return "";
-
-                               lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos));
-                               startPos= endPos + 2;
-                               endPos= lenStr + startPos;
-                               ret= new String(serialVars.substring(startPos, endPos).toString());
-                               finalPos += endPos + 2; 
-                               break;
-                       case 'i':       // integer, i:123;
-                               typeRead= "integer";
-                               startPos= 1;
-                               endPos= serialVars.indexOf(';', startPos + 1);
-                               if(endPos == -1) return "";
-
-                               ret= new String(serialVars.substring(startPos + 1, endPos).toString());
-                               finalPos += endPos + 1;
-                               break;
-                       case 'd':       // double (float), d:1.23;
-                               typeRead= "double";
-                               startPos= 1;
-                               endPos= serialVars.indexOf(';', startPos + 1);
-                               if(endPos == -1) return "";
-       
-                               ret= new String(serialVars.substring(startPos + 1, endPos).toString());
-                               finalPos += endPos + 1;
-                               break;
-                       case 'N':       // NULL, N;
-                               typeRead= "null";
-                               ret= "nil";
-                               finalPos += 2;
-                               break;
-                       case 'b':       // bool, b:0 or 1
-                               typeRead= "boolean";
-                               ret= (serialVars.charAt(2) == '1')?"true":"false";
-                               finalPos += endPos + 4;
-                               break;
-                       case 'z':       // resource, z:typename_len:"typename":valres;
-                               typeRead= "resource";
-                               
-                               startPos= 1;
-                               endPos= serialVars.indexOf(':', startPos + 1);
-                               if(endPos == -1) return "";
-               
-                               // get resource type name
-                               lenStr= Integer.parseInt(serialVars.substring(startPos + 1, endPos));
-                               startPos= endPos + 2;
-                               endPos= lenStr + startPos;
-                               className= new String(serialVars.substring(startPos, endPos).toString());
-
-                               // get resource value
-                               startPos= endPos + 1;
-                               endPos= serialVars.indexOf(';', startPos + 1);
-                               if(endPos == -1) return "";
-                               ret= new String(serialVars.substring(startPos + 1, endPos));
-                               finalPos += endPos + 1;
-                               break;
-                       case 'r':
-                       case 'R':
-                               typeRead= "reference";
-                               startPos= 1;
-                               endPos= serialVars.indexOf(';', startPos + 1);
-                               if(endPos == -1) return "0";
-
-                               ret= new String(serialVars.substring(startPos + 1, endPos));
-                               finalPos += endPos + 1;
-                               isRef= true;
-                               break;
-                       case ';':
-                               typeRead= "unknown";
-                               finalPos+= 1;
-                               break;
-                       case '?':
-                               finalPos+= 1;
-                       default:
-                               finalPos+= 1;
-                               typeRead= "unknown";
-                               break;
-               }
-               return ret;
-       }
-
-       private void doUnserialize(PHPStackFrame stack, Vector vecVars, PHPVariable parent) throws DebugException {
-               int i, elements= 0;
-               PHPVariable newVar= null;
-               String value= new String("");
-               String name= new String("");
-               String tmp= new String("");
-               String[] tmpSplit;
-
-               if(finalPos > serGlobals.length() || serGlobals.equals("") || serGlobals.substring(finalPos).equals("")) return;
-
-               isRef= false;
-               hasChildren= false;
-               isObject= false;
-               name= readValue(serGlobals.substring(finalPos));
-               
-               if(hasChildren) {
-                       // main array
-                       if(refCounter == 0) {
-                               value= name;
-                               name= "";
+       }
+
+       /**
+        * Check whether the new stackframe is in the list of old stackframes.
+        * Test for identical stackframe (identical means same description and same line number).
+        *
+        * @param stackFrameNew The stackframe to check whether he is already within the old stackframe list
+        * @param list          The list of old stackframes
+        * @return
+        *  - true if we have found the identical stackframe within the list
+        *  - false if we did not find the identical stackframe within the list
+        */
+       private boolean isStackFrameInList (PHPStackFrame stackFrameNew, Vector list) {
+               int             i;
+               PHPStackFrame   stackFrameOld;
+
+               for (i = 0; i < list.size (); i++) {
+                       stackFrameOld = (PHPStackFrame) list.get (i);                                           //
+
+                       if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ()) &&
+                               stackFrameNew.getLineNumber () == stackFrameOld.getLineNumber ()) {     // Did we find the sent stackframe within the list of old stackframes?
+                               stackFrameOld.setAvailable (true);                                      // We found the new stackframe in the list of old stack frames
+                stackFrameOld.setIndex (stackFrameNew.getIndex ());
+                stackFrameOld.setScopeID(stackFrameNew.getScopeID());
+
+                               return true;                                                            // The stackframe was found in the list
                        }
-               } else {
-                       hasChildren= false;
-                       isRef= false;
-                       value= readValue(serGlobals.substring(finalPos));
-                       // replaceAll doesn't work, why???
-                       tmpSplit= value.split("\\\\");
-                       value= "";
-                       for(i= 0; i < tmpSplit.length; i++) {
-                               value= value + tmpSplit[i];
-                               if(!tmpSplit[i].equals("")) {
-                                       if(i < (tmpSplit.length - 1)) {
-                                               value= value + "\\";
-                                       }
-                               }
+               }
+
+               return false;
+       }
+
+       /**
+        * Check whether the new stackframe is in the list of old stackframes.
+        * Test for exact stackframe (exact means same description and same line number).
+        *
+        * @param stackFrameNew The stackframe to check whether he is already within the old stackframe list
+        * @param list          The list of old stackframes
+        * @return
+        *  - true if we have exactly this stackframe within the list
+        *  - false if we did not find the exact stackframe within the list
+        */
+       private void markIdenticalStackFrames (Vector oldList, Vector newList) {
+               int             i;
+               PHPStackFrame   stackFrameNew;
+
+               resetAvailability (oldList);                                                    // Reset the availability flag of the old stack frames
+               resetAvailability (newList);                                                    // Reset the availability flag of the old stack frames
+
+               for (i = 0; i < newList.size (); i++) {                                                                                 // For all stackList entries
+                       stackFrameNew = (PHPStackFrame) newList.get (i);
+
+                       if (isStackFrameInList (stackFrameNew, oldList)) {                          // Is this stackframe in the list
+                               stackFrameNew.setAvailable (true);                                                                              //
+                                                                                                                                                                               //
+//                             break;
                        }
                }
-               
-               if(!name.equals("")) {
-                       if(isRef) {
-                               PHPVariable varPHP;
-                               for(i=0; i < vecVars.size(); i++) {
-                                       varPHP= (PHPVariable) vecVars.get(i);
-                                       if(varPHP.getObjectId().equals(value)) {
-                                               newVar= new PHPVariable(stack, name, "local", true, (PHPValue)varPHP.getValue());
-                                               break;                                          
-                                       }
+       }
+
+       /**
+        *
+        * The stackList contains the currently read stackframes which were sent
+        * from DBG. The DBG interface holds a list of the active stack frames.
+        * This method replicates the 'static' stackframe list with the DBG stackframe list
+        * Replication is done in the following way:
+        * <ul>
+        * <li> It looks for new stackframes within the DBG stackframe list and
+        *      adds them to the 'static' list.
+        * <li> It looks for stackframes within the 'static' list, and removes them
+        *              from the 'static' list in case they do not appear within the DBG list.
+        * <li> It looks for stackframes which are already existent and replicates the
+        *              line number and the index number.
+        * <li> At the end, the 'static' stackframe list has to be sorted by the stackframes
+        *              index numbers.
+        * </ul>
+        *
+        * Removes the unused stackframes from the list, or adds stackframes which
+        * are not yet in the list.
+        *
+        *
+        * @param stackList
+        */
+       private void updateStackFrameList (Vector stackList) {
+               int                     i;
+               int             n;
+               PHPStackFrame   stackFrameNew;
+               PHPStackFrame   stackFrameOld;
+               PHPStackFrame[] newStackList;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: updateStackFrameList Start");
+               }
+
+               markIdenticalStackFrames (stackListOld, stackList);                     // Check whether the newly send stack frames can be found in the list
+                                                                                                                                                               // of old stack frames
+
+               for (i = 0; i < stackList.size (); i++) {                                                               // For all stackList entries
+                       stackFrameNew = (PHPStackFrame) stackList.get(i);
+
+                       for (n = 0; n < stackListOld.size (); n++) {                                    // For all StackFrames in the StackFrame list
+                               stackFrameOld = (PHPStackFrame) stackListOld.get (n);                   //
+
+                               if (stackFrameOld.isAvailable ()) {                             // If this stack frame was already found in the new list skip it
+                                       continue;
                                }
-                               if(newVar == null) {
-                                       newVar= new PHPVariable(stack, name, "local", false, null);
+
+                               if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ())) {// Did we find the sent stackframe within the list of old stackframes?
+                                       stackFrameOld.setLineNumber (stackFrameNew.getLineNumber ());
+                                       stackFrameOld.setIndex (stackFrameNew.getIndex ());
+                                       stackFrameOld.setScopeID(stackFrameNew.getScopeID());
+
+                                       stackFrameOld.setAvailable (true);                                                      // And mark this stack frame as available
+                                       stackFrameNew.setAvailable (true);                                                      // And mark this stack frame as available
+
+                                       break;                                                                  //  Yes, then break;
                                }
-                       } else {
-                               refCounter++;
-                               newVar= new PHPVariable(stack, name, "local", value, typeRead, hasChildren, Integer.toString(refCounter), className);
                        }
-                       newVar.setParent(parent);
-                       vecVars.add(newVar);
-               }
-               if(hasChildren) {
-                       elements= Integer.parseInt(value);
-                       for(i=0; i < elements; i++)
-                               doUnserialize(stack, vecVars, newVar);
-
-                       // skip "}"
-                       finalPos += 1;
-               }
-       }
-
-       public int readResponse() throws IOException {
-               int bytesToRead=0, nextFrame=0, i=0, cmdReceived=0, stackIndex=0;
-               boolean errorStack= false;
-               char[] dbg_header_struct_read= new char[16];
-               int[] dbg_header_struct= new int[4];
-               int[] dbg_bpl_tmp= new int[10];
-               int[] dbg_frame= new int[2];
-               int[] dbg_eval_tmp= new int[3];
-               int[] dbg_src_tree_tmp= new int[4];
-               int[] dbg_error_tmp= new int[2];
-               Vector rawList= new Vector();
-               Vector stackList= new Vector();
-               PHPStackFrame[] newStackList;
-               
-               rawList.clear();
-               stackList.clear();
+
+                       if (!stackFrameNew.isAvailable ()) {                                // Did not find the new stackframe within the list?
+                                stackFrameNew.setAvailable (true);                                                             // Mark the stack frame as available and
+                                stackListOld.add (stackFrameNew);                              //  then add the new stackframe
+                       }
+               }
+
+               // And now for removing unused stackframes from list
+
+               for (n = 0; n < stackListOld.size(); n++) {
+                       stackFrameOld = (PHPStackFrame) stackListOld.get(n);
+
+                       if (!stackFrameOld.isAvailable()) {
+                               stackListOld.remove(n--);
+                       }
+               }
+
+               Collections.sort (stackListOld);                                                                                // Sort the 'static' stackframe list by the stackframe index numbers.
+                                                                                                                                                               //
+               newStackList = new PHPStackFrame[stackListOld.size ()];
+               newStackList = (PHPStackFrame[]) stackListOld.toArray (newStackList);
+               DBGStackList = newStackList;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: updateStackFrameList End");
+               }
+       }
+
+    /**
+     * Read the response from DBG and process the frame
+     *
+        * @return
+        * - The received command
+        * - or 0 if something was wrong
+     */
+       public int readResponse () throws IOException {
+        int     bytesToRead            = 0;                         // The number of byte to read for the current DBG block
+        int     nextFrame              = 0;                         // The current read position within entirePack
+        int     i                      = 0;
+        int     cmdReceived            = 0;
+        int     stackIndex             = 0;
+        boolean errorStack             = false;
+        char[]  dbg_header_struct_read = new char[16];              // The buffer for the first 16 bytes of a block
+        int[]   dbg_header_struct      = new int[4];                // The first four numbers (long) of a block
+        int[]   dbg_bpl_tmp            = new int[10];
+        int[]   dbg_frame              = new int[2];
+        int[]   dbg_eval_tmp           = new int[3];
+        int[]   dbg_src_tree_tmp       = new int[4];                //
+        int[]   dbg_error_tmp          = new int[2];
+        Vector  rawList                = new Vector();
+        Vector  stackList              = new Vector();              // Intermediate stacklist which is build up in FRAME_STACK frame
+
+               if (bDebug) {
+               System.out.println ("PHPDBGInterface: readResponse start");
+               }
+
+        rawList.clear ();
+        stackList.clear ();
+
                // Read from input
-               while(readInput(dbg_header_struct_read, 16) != 0) {
-                       dbg_header_struct[0] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 0);
-                       dbg_header_struct[1] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 4);
-                       dbg_header_struct[2] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 8);
-                       dbg_header_struct[3] = PHPDBGBase.Char4ToInt(dbg_header_struct_read, 12);
-                       
-                       // Check DBG sync bytes
-                       if(dbg_header_struct[0] != 0x5953) return 0;
-                       
-                       cmdReceived= dbg_header_struct[1];
-                       bytesToRead= dbg_header_struct[3];
+        while (readInput (dbg_header_struct_read, 16) != 0) {                               // Read 16 byte from input stream
+                       dbg_header_struct[0] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 0);               // Debug sync header
+            dbg_header_struct[1] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 4);                  // Command
+            dbg_header_struct[2] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 8);       //
+            dbg_header_struct[3] = PHPDBGBase.Char4ToInt (dbg_header_struct_read, 12);      // Bytes within this block
+
+            if (dbg_header_struct[0] != 0x5953) {                                           // Check DBG sync bytes
+                       if (bDebug) {
+                       System.out.println ("PHPDBGInterface: readResponse. Wrong sync");
+                       }
+
+               bBusy = false;
+                return 0;                                                                   // Wrong header
+            }
+
+            cmdReceived = dbg_header_struct[1];                                             // Get the command
+            setLastCmd (cmdReceived);                                                                                                          // Store the info about the current command
+            bytesToRead = dbg_header_struct[3];                                                                                        // Get the number of bytes to read for this block
 
                        //System.out.println("Response Received: " + cmdReceived);
-                       char[] entirePack= new char[bytesToRead];
+                       char[] entirePack = new char[bytesToRead];                                      // Store the block data into buffer 'entirePack'
+
+            if (bytesToRead > 0) {                                                          // If there is something within the frame
+                if (readInput (entirePack, bytesToRead) < bytesToRead) {                    // Read the frame into the buffer
+                       if (bDebug) {
+                       System.out.println ("PHPDBGInterface: readResponse. Did not read enough");
+                       }
 
-                       if(bytesToRead > 0) {
-                               if(readInput(entirePack, bytesToRead) < bytesToRead) return 0;
+                   bBusy = false;
+                    return 0;                                                               // We did not read enough bytes, error
+                }
                        }
-                       
-                       // First process frames
-                       nextFrame= 0;
-                       while(nextFrame < bytesToRead) {
-                               dbg_frame[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame);            // frame name
-                               dbg_frame[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);        // frame size
-                               nextFrame += 8;
-                               if(dbg_frame[1] == 0) return 0;
-                               switch(dbg_frame[0]) {
+
+                       nextFrame = 0;                                                                  // Start with the first frame
+
+                       while (nextFrame < bytesToRead) {                                               // As long as we have something within this block
+                               dbg_frame[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame);                           // The name of the frame
+                               dbg_frame[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);               // The size of the frame
+                               nextFrame   += 8;                                                           // The next read position
+
+                               if (dbg_frame[1] == 0) {                                                    // Something within the frame?
+                                       if (bDebug) {
+                                               System.out.println ("PHPDBGInterface: readResponse. Nothing within the frame");
+                                       }
+
+                                       bBusy = false;
+                                       return 0;                                                               //  Nothing to read, error
+                               }
+
+                               switch (dbg_frame[0]) {
                                        case PHPDBGBase.FRAME_STACK:
-                                               int[] dbg_stack_new= new int[4];
-                                               dbg_stack_new[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);    // line no
-                                               dbg_stack_new[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);    // mod no
-                                               dbg_stack_new[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8);    // scope id
-                                               dbg_stack_new[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12);   // id of description string
+                                               int[] dbg_stack_new = new int[4];                                       //
+
+                                               dbg_stack_new[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);   // Source line number
+                                               dbg_stack_new[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);   // Module number
+                                               dbg_stack_new[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);   // Scope id
+                                               dbg_stack_new[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12);  // ID of description string
+
+                                               if ((dbg_stack_new[1] != 0) && !errorStack) {
+                                                       PHPStackFrame newStack;
 
-                                               if(dbg_stack_new[1] != 0 && !errorStack) {
                                                        stackIndex++;
-                                                       PHPStackFrame newStack= new PHPStackFrame(null, getModByNo(dbg_stack_new[1]), dbg_stack_new[0], stackIndex, getRawFrameData(entirePack, dbg_stack_new[3]), dbg_stack_new[1]);
-                                                       stackList.add(newStack);
+                                                       newStack = new PHPStackFrame (null,                                 // The thread
+                                                                                     getModByNo (dbg_stack_new[1]),        // The name of the module (file)
+                                                                                     dbg_stack_new[0],                     // The source line number
+                                                                                                                 stackIndex,
+                                                                                                                 getRawFrameData (entirePack,          // Get the string from this packet
+                                                                                                                                  dbg_stack_new[3]),   // The frame ID for which we want the string
+                                                                                                                 dbg_stack_new[1],                                     // The module number
+                                                                                                                 dbg_stack_new[2]);
+                                                       stackList.add (newStack);
                                                }
-                                               errorStack= false;
-                                               break;
-                                       case PHPDBGBase.FRAME_SOURCE:
+
+                                               errorStack = false;
                                                break;
-                                       case PHPDBGBase.FRAME_SRC_TREE:
-                                               dbg_src_tree_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);         // parent_mod_no
-                                               dbg_src_tree_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);         // parent_line_no               /* NOT USED */
-                                               dbg_src_tree_tmp[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8);         // mod_no
-                                               dbg_src_tree_tmp[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12);        // imod_name
-
-                                               if(getModByNo(dbg_src_tree_tmp[2]).equals("")) {
-                                                       String fileName= new String(getRawFrameData(entirePack, dbg_src_tree_tmp[3]));
-                                                       // Remove '\0' char
-                                                       if(fileName.length() > 0) fileName= fileName.substring(0, fileName.length() - 1);
-
-                                                       if(dbg_src_tree_tmp[2] != 0) {
-                                                               PHPDBGMod modNew= new PHPDBGMod(dbg_src_tree_tmp[2], fileName);
-                                                               DBGMods.add(modNew);
+
+                                       case PHPDBGBase.FRAME_SOURCE:                                                   // Nothing to be done here
+                                               break;                                                                      // TODO: what's with that frame? Something interesting
+
+                                       case PHPDBGBase.FRAME_SRC_TREE:                                                 //
+                                               dbg_src_tree_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);        // The parent module number
+                                               dbg_src_tree_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);        // The parent line number (not used)
+                                               dbg_src_tree_tmp[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);        // The module number
+                                               dbg_src_tree_tmp[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12);       // The filename number
+
+                                               if (getModByNo (dbg_src_tree_tmp[2]).equals ("")) {
+                                                       String fileName;
+
+                                                       fileName = new String (getRawFrameData (entirePack, dbg_src_tree_tmp[3]));      // Get the filename
+
+                                                       if (dbg_src_tree_tmp[2] != 0) {                                             // If there is a module number
+                                                               PHPDBGMod modNew;
+
+                                                               modNew = new PHPDBGMod (dbg_src_tree_tmp[2], fileName);                 // Create a module object
+
+                                                               DBGMods.add (modNew);                                                   // And store it to array
                                                        }
                                                }
                                                break;
-                                       case PHPDBGBase.FRAME_RAWDATA:
-                                               break;
-                                       case PHPDBGBase.FRAME_ERROR:
-                                               errorStack= true;
-                                               dbg_error_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);            // type                 /* type of error */
-                                               dbg_error_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);            // imessage             /* ID of error message */
-                                               
-                                               String error= "\n";
-                                               switch(dbg_error_tmp[0]) {
-                                                       case PHPDBGBase.E_ERROR:
-                                                               error+= "[Error]";
-                                                               break;
-                                                       case PHPDBGBase.E_WARNING:
-                                                               error+= "[Warning]";
-                                                               break;
-                                                       case PHPDBGBase.E_PARSE:
-                                                               error+= "[Parse Error]";
-                                                               break;
-                                                       case PHPDBGBase.E_NOTICE:
-                                                               error+= "[Notice]";
-                                                               break;
-                                                       case PHPDBGBase.E_CORE_ERROR:
-                                                               error+= "[Core Error]";
-                                                               break;
-                                                       case PHPDBGBase.E_CORE_WARNING:
-                                                               error+= "[Core Warning]";
-                                                               break;
-                                                       case PHPDBGBase.E_COMPILE_ERROR:
-                                                               error+= "[Compile Error]";
-                                                               break;
-                                                       case PHPDBGBase.E_COMPILE_WARNING:
-                                                               error+= "[Compile Warning]";
-                                                               break;
-                                                       case PHPDBGBase.E_USER_ERROR:
-                                                               error+= "[User Error]";
-                                                               break;
-                                                       case PHPDBGBase.E_USER_WARNING:
-                                                               error+= "[User Warning]";
-                                                               break;
-                                                       case PHPDBGBase.E_USER_NOTICE:
-                                                               error+= "[User Notice]";
-                                                               break;
-                                                       default:
-                                                               error+= "[Unexpected Error]";
-                                                               break;
+
+                                       case PHPDBGBase.FRAME_RAWDATA:                                                      // Nothing to be done here
+                                               break;                                                                          //  FRAME_RAWDATA are processed within getRawFrameData
+
+                                       case PHPDBGBase.FRAME_ERROR:                                                                                                            // An error frame
+                                               errorStack       = true;                                                                                                                // Yes, we have an error stack
+                                               dbg_error_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);                   // Error type
+                                               dbg_error_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);                   // Error message ID
+
+                                               String error = "\n";                                                            //
+
+                                               switch (dbg_error_tmp[0]) {                                                                                                             // Switch on error type
+                                                       case PHPDBGBase.E_ERROR:                        error += "[Error]";                     break;
+                                                       case PHPDBGBase.E_WARNING:                      error += "[Warning]";                   break;
+                                                       case PHPDBGBase.E_PARSE:                        error += "[Parse Error]";               break;
+                                                       case PHPDBGBase.E_NOTICE:                       error += "[Notice]";                    break;
+                                                       case PHPDBGBase.E_CORE_ERROR:           error += "[Core Error]";                break;
+                                                       case PHPDBGBase.E_CORE_WARNING:         error += "[Core Warning]";              break;
+                                                       case PHPDBGBase.E_COMPILE_ERROR:        error += "[Compile Error]";             break;
+                                                       case PHPDBGBase.E_COMPILE_WARNING:      error += "[Compile Warning]";   break;
+                                                       case PHPDBGBase.E_USER_ERROR:           error += "[User Error]";                break;
+                                                       case PHPDBGBase.E_USER_WARNING:         error += "[User Warning]";              break;
+                                                       case PHPDBGBase.E_USER_NOTICE:          error += "[User Notice]";               break;
+                                                       default:                                                        error += "[Unexpected Error]";  break;
                                                }
-                                               error+= ": ";
-                                               error+= new String(getRawFrameData(entirePack, dbg_error_tmp[1]));
-                                               // Remove '\0' char
-                                               if(error.length() > 0) error= error.substring(0, error.length() - 1);
-                                               error+= "\n";
 
-                                               PHPDebugCorePlugin.log(new DebugException(new Status(IStatus.WARNING, PHPDebugCorePlugin.PLUGIN_ID, IStatus.OK, error, null)));
+                                               error += ": ";
+                                               error += new String (getRawFrameData (entirePack, dbg_error_tmp[1]));                   // Add the error string for this error message ID
+                                               error += "\n";                                                                  // Append a CR
+
+                                               PHPDebugCorePlugin.log (new DebugException (new Status (IStatus.WARNING,
+                                                                                                       PHPDebugCorePlugin.PLUGIN_ID,
+                                                                                                                                                               IStatus.OK,
+                                                                                                                                                               error, null)));
+
                                                // To print errors on the console, I must execute a code in the
                                                // php context, that write the stderr... I didn't found a better way
                                                // TODO: Find a better way????
-                                               String codeExec= "";
-                                               codeExec= "fwrite(fopen('php://stderr', 'w'),\\\"" + error + "\\\");";
-                                               try {
-                                                       evalBlock("eval(\"" + codeExec + "\");");
-                                               } catch (DebugException e) {
-                                                       PHPDebugCorePlugin.log(e);
-                                               }
-                                               if(!stopOnError) {
-                                                       if(lastCommand.equals(PHPDBGBase.DBGA_CONTINUE)) {
-                                                               continueExecution();
-                                                       } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPINTO)) {
-                                                               stepInto();
-                                                       } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPOUT)) {
-                                                               stepOut();
-                                                       } else if(lastCommand.equals(PHPDBGBase.DBGA_STEPOVER)) {
-                                                               stepOver();
+
+//                                             String codeExec= "";
+//                                             codeExec= "fwrite(fopen('php://stderr', 'w'),\\\"" + error + "\\\");";
+//                                             try {
+//                                                     evalBlock("eval(\"" + codeExec + "\");");
+//                                             } catch (DebugException e) {
+//                                                     PHPDebugCorePlugin.log(e);
+//                                             }
+//
+                                               if (!stopOnError) {                                                             // Is always false (Did not see where this is set to true!?)
+                                                       if (lastCommand.equals (PHPDBGBase.DBGA_CONTINUE)) {                        // If last command for PHP was a 'continue',
+                                                               continueExecution ();                                                   //  send continue again
+                                                       } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPINTO)) {                 // If last command for PHP was a 'step into',
+                                                               stepInto ();                                                            //  send 'step into' again
+                                                       } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPOUT)) {                  // If last command for PHP was a 'step out',
+                                                               stepOut ();                                                             //  send 'step out' again
+                                                       } else if (lastCommand.equals (PHPDBGBase.DBGA_STEPOVER)) {                 // If last command for PHP was a 'step over',
+                                                               stepOver ();                                                            //  send 'step over' again
                                                        }
                                                }
                                                break;
+
                                        case PHPDBGBase.FRAME_EVAL:
-                                               String evalString= new String("");
-                                               dbg_eval_tmp[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0); // istr
-                                               dbg_eval_tmp[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4); // iresult
-                                               dbg_eval_tmp[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8); // ierror
-
-                                               evalRet= getRawFrameData(entirePack, dbg_eval_tmp[1]);
-                                               evalString= getRawFrameData(entirePack, dbg_eval_tmp[0]);
-                                               serGlobals= evalRet;
-                                               break;
-                                       case PHPDBGBase.FRAME_BPS:
+                                               //String evalString;
+
+                                               //evalString      = new String ("");
+                                               dbg_eval_tmp[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);                    // istr
+                                               dbg_eval_tmp[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);                    // iresult
+                                               dbg_eval_tmp[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);                    // ierror
+
+                                               evalRet                 = getRawFrameData (entirePack, dbg_eval_tmp[1]);                //
+                                               //evalString    = getRawFrameData (entirePack, dbg_eval_tmp[0]);                //
                                                break;
+
+                                       case PHPDBGBase.FRAME_BPS:                                                          //
+                                               break;                                                                          //
+
                                        case PHPDBGBase.FRAME_BPL:
-                                               int[] dbg_bpl_new= new int[10];
-                                               dbg_bpl_new[0] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);
-                                               dbg_bpl_new[1] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 4);
-                                               dbg_bpl_new[2] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 8);
-                                               dbg_bpl_new[3] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 12);
-                                               dbg_bpl_new[4] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 16);
-                                               dbg_bpl_new[5] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 20);
-                                               dbg_bpl_new[6] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 24);
-                                               dbg_bpl_new[7] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 28);
-                                               dbg_bpl_new[8] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 32);
-                                               dbg_bpl_new[9] = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 36);
-       
+                                               int[] dbg_bpl_new;
+
+                                               dbg_bpl_new        = new int[10];
+                                               dbg_bpl_new[0] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 0);
+                                               dbg_bpl_new[1] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 4);
+                                               dbg_bpl_new[2] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 8);
+                                               dbg_bpl_new[3] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 12);
+                                               dbg_bpl_new[4] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 16);
+                                               dbg_bpl_new[5] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 20);
+                                               dbg_bpl_new[6] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 24);
+                                               dbg_bpl_new[7] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 28);
+                                               dbg_bpl_new[8] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 32);
+                                               dbg_bpl_new[9] = PHPDBGBase.Char4ToInt (entirePack, nextFrame + 36);
+
                                                // look if breakpoint already exists in vector
-                                               for(i=0; i < DBGBPList.size(); i++) {
-                                                       dbg_bpl_tmp= (int[]) DBGBPList.get(i);
-                                                       if(dbg_bpl_tmp[8] == dbg_bpl_new[8]) {
-                                                               DBGBPList.remove(i);
+                                               for (i = 0; i < DBGBPList.size (); i++) {
+                                                       dbg_bpl_tmp = (int[]) DBGBPList.get (i);
+
+                                                       if (dbg_bpl_tmp[8] == dbg_bpl_new[8]) {
+                                                               DBGBPList.remove (i);
+
                                                                break;
                                                        }
                                                }
 
                                                // add breakpoint to vector
-                                               DBGBPList.add(dbg_bpl_new);
-                                               copyToLastBP(dbg_bpl_new);
-                                               
+                                               DBGBPList.add (dbg_bpl_new);
+                                               copyToLastBP (dbg_bpl_new);
+
                                                // mod no returned?
-                                               if(getModByNo(dbg_bpl_new[0]).equals("")) {
-                                                       String fileName= new String(getRawFrameData(entirePack, dbg_bpl_new[2]));
-                                                       // Remove '\0' char
-                                                       if(fileName.length() > 0) fileName= fileName.substring(0, fileName.length() - 1);
-                                                       if(dbg_bpl_new[0] != 0) {
-                                                               PHPDBGMod modNew= new PHPDBGMod(dbg_bpl_new[0], fileName);
-                                                               DBGMods.add(modNew);
+                                               if (getModByNo (dbg_bpl_new[0]).equals ("")) {
+                                                       String fileName;
+
+                                                       fileName = new String (getRawFrameData (entirePack, dbg_bpl_new[2]));
+
+                                                       if (dbg_bpl_new[0] != 0) {
+                                                               PHPDBGMod modNew;
+
+                                                               modNew = new PHPDBGMod (dbg_bpl_new[0], fileName);
+
+                                                               DBGMods.add (modNew);
                                                        }
-                                               }                                                       
+                                               }
                                                break;
+
                                        case PHPDBGBase.FRAME_VER:
                                                break;
+
                                        case PHPDBGBase.FRAME_SID:
+                                               sid = PHPDBGBase.Char4ToInt(entirePack, nextFrame + 0);
                                                break;
+
                                        case PHPDBGBase.FRAME_SRCLINESINFO:
                                                break;
+
                                        case PHPDBGBase.FRAME_SRCCTXINFO:
                                                break;
+
                                        case PHPDBGBase.FRAME_LOG:
                                                break;
+
                                        case PHPDBGBase.FRAME_PROF:
                                                break;
+
                                        case PHPDBGBase.FRAME_PROF_C:
                                                break;
+
                                        case PHPDBGBase.FRAME_SET_OPT:
                                                break;
                                }
-                               // go to next frame
-                               nextFrame += dbg_frame[1];
+
+                               nextFrame += dbg_frame[1];                                                      // go to next frame
                        }
-                       
+
                        // Now process command
                        switch(cmdReceived) {
                                case PHPDBGBase.DBGC_REPLY:
                                        break;
+
                                case PHPDBGBase.DBGC_STARTUP:
                                        break;
+
                                case PHPDBGBase.DBGC_END:
-                                       sessionEnded= true;
+                                       if (bRelaunch) {
+                       continueExecution ();                           // Inform dbg that we want to continue execution
+                       proxy.updateView ();                            // Sent a change event and create thread event to eclipse core
+                       updateStackFrameList (stackList);               // ??? Just a try
+                                       }
+                                       else {
+                                               sessionEnded = true;
+                                               proxy.setTerminated ();
+                                       }
                                        break;
+
                                case PHPDBGBase.DBGC_BREAKPOINT:
-                                       newStackList= new PHPStackFrame[stackList.size()];
-                                       newStackList= (PHPStackFrame[]) stackList.toArray(newStackList);
-                                       DBGStackList= newStackList;
-                                       BPUnderHit= getBPUnderHit();
+                                       BPUnderHit   = getBPUnderHit ();
+                                       updateStackFrameList (stackList);
                                        break;
+
                                case PHPDBGBase.DBGC_STEPINTO_DONE:
                                case PHPDBGBase.DBGC_STEPOVER_DONE:
                                case PHPDBGBase.DBGC_STEPOUT_DONE:
                                case PHPDBGBase.DBGC_EMBEDDED_BREAK:
                                case PHPDBGBase.DBGC_PAUSE:
-                                       BPUnderHit= 1;
-                                       newStackList= new PHPStackFrame[stackList.size()];
-                                       newStackList= (PHPStackFrame[]) stackList.toArray(newStackList);
-                                       DBGStackList= newStackList;
+                                       BPUnderHit   = 1;
+                                       updateStackFrameList (stackList);
                                        break;
+
                                case PHPDBGBase.DBGC_ERROR:
-                                       stackList.clear();
-                                       newStackList= new PHPStackFrame[stackList.size()];
-                                       newStackList= (PHPStackFrame[]) stackList.toArray(newStackList);
-                                       DBGStackList= newStackList;
+                                       stackList.clear ();
+                                       updateStackFrameList (stackList);
                                        break;
+
                                case PHPDBGBase.DBGC_LOG:
                                        break;
+
                                case PHPDBGBase.DBGC_SID:
                                        break;
                        }
                }
-               return cmdReceived;
+
+               if (bDebug) {
+               System.out.println ("PHPDBGInterface: readResponse finish, received: " + cmdReceived);
+               }
+
+        bBusy = false;
+
+               return cmdReceived;                                         // Return the command we received with this block
        }
 
+    /**
+     *
+     */
+
        public PHPStackFrame[] getStackList() {
                return DBGStackList;
        }
 
-       private int readInput(char[] buffer, int bytes) throws IOException {
-               int bytesRead= 0;
+       /**
+        * Reads from input buffer (response sent from DBG) the given number of chars
+        * into frame buffer.
+        *
+        * @param buffer  The frame buffer where to store the read data from DBG.
+        * @param bytes   The number of bytes (chars) which are to read from input stream.
+        * @return        The number of bytes actually read.
+        */
+       private int readInput (char[] buffer, int bytes) throws IOException {
+               int bytesRead = 0;                                                                                      // Reset the bytes read counter
+               int nRetry    = 0;                                          // Retry counter
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: readInput " + bytes);
+               }
+
+               for (int i = 0; i < bytes;) {                               // For the number of bytes we should read
+                       if (dbgInput.ready ()) {                                                                // If input stream is ready for reading
+                               nRetry    = 0;                                      // Reset the retry counter
+                               buffer[i] = (char) (dbgInput.read () & 0x00FF);     // Read a char and store only the least significant 8-bits
+                               bytesRead++;                                        // Increment the bytes read counter
+                               i++;
+                       }
+                       else {                                                  // Input stream is not ready
+                               nRetry++;                                           // Increment the retry counter
+
+                               if (nRetry > 10) {                                  // If nothing received within 100 retries
+                                       if (i > 0) {
+                                               if (bDebug) {
+                                                       System.out.println ("PHPDBGInterface: Too many retries without receiving something");
+                                               }
+                                       }
+                                       break;                                          // we break the loop
+                               }
+
+                               synchronized (dbgInput) {
+                                       if (i > 0) {
+                                               if (bDebug) {
+                                                       System.out.println ("PHPDBGInterface: retry: " + nRetry + " Wait for something to receive, received: " + i + " need " + bytes);
+                                               }
+                                       }
+                               try {
+                                       dbgInput.wait (10);                          // wait 5 ms maximum for something to receive
+                                   } catch (InterruptedException e) {
+                                   }
+                               }
+                       }
+               }
 
-               for(int i=0; i < bytes; i++) {
-                       if(in.ready()) {
-                               buffer[i]= (char) (in.read() & 0x00FF);
-                               bytesRead++;
+               if (bytesRead > 0) {
+                       if (bytes != bytesRead) {
+                               if (bDebug) {
+                                       System.out.println ("PHPDBGInterface: readInput: Possible error: not enough bytes in buffer should read: " + bytes +
+                                                                               " actually read: " + bytesRead);
+                               }
                        }
-                       else
-                               break;                          
                }
-               return bytesRead;
+
+               return bytesRead;                                                                                       // Return the number of bytes actually read
        }
-       
-       public void setShouldStop() {
-               this.shouldStop= true;
+
+       /**
+        * PHPProxy could stop the waiting for a response with this method.
+        *
+        */
+       public void setShouldStop () {
+               this.shouldStop = true;
        }
 
-       public void waitResponse(long milliseconds) throws IOException {
-               long timeout= System.currentTimeMillis() + milliseconds;
-               while(System.currentTimeMillis() < timeout) {
-                       if(in.ready() || shouldStop) {
-                               break;
+       /**
+        * @param milliseconds The maximum time in milliseconds we wait for something
+        *                     to be send from DBG.
+        * @return             - true if something was received from DBG
+        *                                         - false if nothing was send from DBG within the given time
+        *
+        * This method has been a busy wait loop. It was changed to use
+        * a non busy wait to avoid a heavy load after automatic relaunch
+        * after script termination
+        *
+        */
+       public boolean waitResponse (long milliseconds) throws IOException {
+               long timeout;
+
+               if (bDebug) {
+                       System.out.println ("PHPDBGInterface: waitResponse " + milliseconds);
+               }
+
+               timeout = System.currentTimeMillis () + milliseconds;           // Calculate the system time till we wait.
+
+               while (System.currentTimeMillis () < timeout) {             // Is waiting time running out?
+                       synchronized (dbgInput) {
+                       try {
+                               dbgInput.wait (5);                              // wait 5 ms maximum for something to receive
+                           } catch (InterruptedException e) {
+                           }
+                       }
+
+                       if (dbgInput.ready () || shouldStop) {                  //  If something is received of if we should stop now
+                               break;                                              //    break the waiting loop
                        }
                }
+
+               return dbgInput.ready ();                                   // true if we got something from DBG
        }
-}
\ No newline at end of file
+}