Refactory: remove unused classes, imports, fields and methods.
[phpeclipse.git] / net.sourceforge.phpeclipse.debug.core / src / net / sourceforge / phpdt / internal / debug / core / PHPDBGInterface.java
index 9d40c3f..4da1970 100644 (file)
@@ -14,48 +14,48 @@ package net.sourceforge.phpdt.internal.debug.core;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.Vector;
 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.PHPVariable;
 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 java.io.RandomAccessFile;
-
 /**
  * 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;
-       private Vector                  DBGMods          = new Vector ();                       // The module names and their numbers
-       private Vector          stackListOld = new Vector ();
+       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  in;
-       private OutputStream    os;                                                                             // The stream which goes to DBG
-       private boolean                 shouldStop       = false;
-       private String                  evalRet          = new String ("");
-       private String                  serGlobals       = 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;
-       private char[]                  lastCommand      = new char[4];
+       private OutputStream            os;                                                             // 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;
+       private char[]                  lastCommand = new char[4];
+
+       private static final String GlobalVariablesTitle = PHPDebugCorePlugin
+                       .getResourceString("VariablesView.GlobalVariables.title");
 
        /**
         * @param in    The input stream (communication from DBG).
@@ -72,12 +72,14 @@ public class PHPDBGInterface {
 
        /**
         *
-        * @param mod_name The module (source file) to which we add the breakpoint.
-        * @param line     The line where the breakpoint is set.
-        * @return         Breakpoint ID ???.
+        * @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) throws IOException {
-               return setBreakpoint (mod_name, "", line, PHPDBGBase.BPS_ENABLED + PHPDBGBase.BPS_UNRESOLVED, 0, 0, 0, 0, 0);
+       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);
        }
 
        /**
@@ -94,21 +96,21 @@ public class PHPDBGInterface {
         * 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
-       }
+//     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
@@ -138,27 +140,27 @@ public class PHPDBGInterface {
         *
         * @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);
-       }
+//     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.
@@ -178,11 +180,13 @@ public class PHPDBGInterface {
                PHPDBGPacket    DBGPacket;
                PHPDBGFrame     DBGFrame1;
                PHPDBGFrame     DBGFrame2;
+               PHPDBGFrame             DBGFrame3;
                int                     modNo;
 
                DBGPacket       = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);
                DBGFrame1       = new PHPDBGFrame (PHPDBGBase.FRAME_BPS);
                DBGFrame2       = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
+               DBGFrame3       = new PHPDBGFrame (PHPDBGBase.FRAME_RAWDATA);
 
                modNo           = getModByName (mod_name);                                              // Get the module ID by name
 
@@ -201,14 +205,6 @@ public class PHPDBGInterface {
                        DBGFrame1.addInt (rawCounter);                                                  // ID of FRAME_RAWDATA to send file name
                }
 
-               DBGFrame1.addInt (state);                                       // state BPS_*
-               DBGFrame1.addInt (istemp);                                      // istep
-               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) {                                            // 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)
@@ -218,6 +214,29 @@ public class PHPDBGInterface {
                        DBGPacket.addFrame (DBGFrame2);                         // First add file name data
                }
 
+               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
+               }
+
+               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?
@@ -268,7 +287,6 @@ public class PHPDBGInterface {
                if (proxy.getSocket ().isClosed ()) {                                           // Can we communiate with DBG?
                        return;                                                 //  No
                }
-
                DBGPacket.sendPacket (os);                                  // Send the request to DBG
 
                lastCommand = PHPDBGBase.DBGA_CONTINUE;                     // Store the info about the command we sent
@@ -308,10 +326,10 @@ public class PHPDBGInterface {
                return BPUnder;
        }
 
-       public int getLastCmd()
-       {
-               return lastCmd;
-       }
+//     public int getLastCmd()
+//     {
+//             return lastCmd;
+//     }
 
        public int getSID()
        {
@@ -320,7 +338,7 @@ public class PHPDBGInterface {
 
        public void setLastCmd (int cmd)
        {
-               lastCmd = cmd;
+               //lastCmd = cmd;
        }
 
        /**
@@ -380,18 +398,18 @@ public class PHPDBGInterface {
        /**
         *
         */
-       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
-       }
+//     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.
@@ -402,44 +420,126 @@ public class PHPDBGInterface {
         * @param stack The stackframe for which we want the variables.
         * @return      The array of variables
         */
-       public Vector getVariables (PHPStackFrame stack) throws IOException, DebugException  {
-               PHPDBGPacket            DBGPacket;
-               PHPDBGFrame             DBGFrame1;
-               PHPDBGEvalString        evalStr;
+       public synchronized Vector getVariables(PHPStackFrame stack) throws IOException, DebugException {
+               if (DBGStackList.length == 0) {
+                       DBGVarList.clear();
+                       return DBGVarList;
+               }
 
-               DBGPacket = new PHPDBGPacket (PHPDBGBase.DBGA_REQUEST);     //
-           DBGFrame1 = new PHPDBGFrame (PHPDBGBase.FRAME_EVAL);        //
+               // 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);
+               }
 
-               DBGFrame1.addInt (0);                                                                           // istr = raw data ID
-               DBGFrame1.addInt (1);                                                                           // scope_id = -1 means current location, 0 never used, +1 first depth
+               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;
 
-               DBGPacket.addFrame (DBGFrame1);                             // Add command data
+               } else if (scopeID == PHPDBGBase.CURLOC_SCOPE_ID) {
+                       // current stackframe
+                       DBGVarList = getVariables(stack, PHPDBGBase.CURLOC_SCOPE_ID);
 
-               if (proxy.getSocket ().isClosed ()) {                       // Do we have a socket for DBG communication?
-                       return null;                                                                                    //  No, then leave here
+               } else {
+                       // back-trace stackframe
+                       //DBGVarList = getVariables(stack, scopeID);
+                       //removeUnresolvedThisVar(DBGVarList);
+                       // DBG 2.15.5 causes Application Error (on win32) in *some* cases.
+                       DBGVarList.clear();
                }
 
-               DBGPacket.sendPacket (os);                                  // Send the request to DBG
-
-               waitResponse (1000);                                        // Wait for the DBG response (1 second)
-               flushAllPackets ();                                         // Read and process the response from DBG
-
-               evalStr         = new PHPDBGEvalString (stack, serGlobals); // Process serialized variables
-               DBGVarList      = evalStr.getVariables ();
+               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
 
-               PHPVariable var = (PHPVariable) DBGVarList.get (0);
+                       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.
 
-               if (var.getName ().equals ("")) {                                                       // The eclipse variable view cannot handle Variables which have an empty name
+                                                                                                                                       // 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 :.)
-               }                                                                                                                       // TODO the best would be to remove the empty root node, but this would
+                               //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
        }
 
        /**
+        * 
+        */
+       private Vector getVariables(PHPStackFrame stack, int scope_id) throws IOException {
+               PHPDBGPacket DBGPacket = new PHPDBGPacket(PHPDBGBase.DBGA_REQUEST);
+               PHPDBGFrame DBGFrame1 = new PHPDBGFrame(PHPDBGBase.FRAME_EVAL);
+
+               DBGFrame1.addInt(0);
+               DBGFrame1.addInt(scope_id);
+
+               DBGPacket.addFrame(DBGFrame1);
+               evalRet = "";
+
+               if (proxy.getSocket().isClosed()) {
+                       return new Vector();
+               }
+               DBGPacket.sendPacket(os);
+
+               waitResponse(1000);
+               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
         */
@@ -466,21 +566,31 @@ public class PHPDBGInterface {
                // Add command data
                DBGPacket.addFrame(DBGFrame1);
 
-               if(proxy.getSocket().isClosed()) return;
+               if (proxy.getSocket ().isClosed ()) {                   // Do we have a socket for DBG communication?
+                       return;                                                                                         //  No, then leave here
+               }
+
                DBGPacket.sendPacket(os);
 
                waitResponse(1000);
                flushAllPackets();
        }
 
-       public PHPVariable[] evalBlock(PHPStackFrame stack, 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);
 
                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)
@@ -492,16 +602,17 @@ public class PHPDBGInterface {
                // Add command data
                DBGPacket.addFrame(DBGFrame1);
 
-               if(proxy.getSocket().isClosed()) return null;
+               if (proxy.getSocket().isClosed()) {                     // Do we have a socket for DBG communication?
+                       return null;                                                    //  No, then leave here
+               }
                DBGPacket.sendPacket(os);
 
                waitResponse(1000);
                flushAllPackets();
 
-               PHPDBGEvalString evalStr=new PHPDBGEvalString(stack,evalRet);
+               PHPDBGEvalString evalStr=new PHPDBGEvalString(stack, evalRet);
 
                return evalStr.getVars();
-
        }
 
        /**
@@ -582,6 +693,10 @@ public class PHPDBGInterface {
 
                                                toRead = PHPDBGBase.Char4ToInt (framesInfo, nextFrame + 4);     // The size of the string
 
+                                               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
+                                               }
+
                                                return String.copyValueOf (framesInfo, nextFrame + 8, toRead);  // Copy frame content to String and return
                                        }
                                        break;
@@ -594,6 +709,76 @@ public class PHPDBGInterface {
        }
 
        /**
+        * 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);                                     //
+               }
+       }
+
+       /**
+        * 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
+                       }
+               }
+
+               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;
+                       }
+               }
+       }
+
+       /**
         *
         * The stackList contains the currently read stackframes which were sent
         * from DBG. The DBG interface holds a list of the active stack frames.
@@ -603,10 +788,10 @@ public class PHPDBGInterface {
         * <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 the do not appear within the DBG list.
+        *              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' stackfram list has to be sorted by the stackframes
+        * <li> At the end, the 'static' stackframe list has to be sorted by the stackframes
         *              index numbers.
         * </ul>
         *
@@ -623,41 +808,44 @@ public class PHPDBGInterface {
                PHPStackFrame   stackFrameOld;
                PHPStackFrame[] newStackList;
 
+               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 (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ())) { // Did we find the sent stackframe within the list of old stackframes?
+                               if (stackFrameOld.isAvailable ()) {                             // If this stack frame was already found in the new list skip it
+                                       continue;
+                               }
+
+                               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;
                                }
                        }
 
-                       if (n == stackListOld.size ()) {                                    // Did not find the new stackframe within the list
+                       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++) {                                            // For all StackFrames in the StackFrame list
-                       stackFrameOld = (PHPStackFrame) stackListOld.get (n);                           //
-
-                       for (i = 0; i < stackList.size (); i++) {                                                       // For all stackList entries
-                               stackFrameNew = (PHPStackFrame) stackList.get (i);
+               for (n = 0; n < stackListOld.size(); n++) {
+                       stackFrameOld = (PHPStackFrame) stackListOld.get(n);
 
-                               if (stackFrameNew.getDescription ().equals (stackFrameOld.getDescription ())) { // Did we find the sent stackframe within the list of old stackframes?
-                                       break;                                                                  //  Yes, then break;
-                               }
-                       }
-
-                       if (i == stackList.size ()) {                                           // Did not find the old stackframe within the list of new ones
-                                stackListOld.remove (n);                                       //  then remove the old stackframe from list
-                                n -= 1;                                                        // Adjust the stack list index
+                       if (!stackFrameOld.isAvailable()) {
+                               stackListOld.remove(n--);
                        }
                }
 
@@ -718,7 +906,7 @@ public class PHPDBGInterface {
                     return 0;                                                               // We did not read enough bytes, error
                 }
                        }
-
+                       
                        nextFrame = 0;                                                                  // Start with the first frame
 
                        while (nextFrame < bytesToRead) {                                               // As long as we have something within this block
@@ -749,7 +937,8 @@ public class PHPDBGInterface {
                                                                                                                  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[1],                                     // The module number
+                                                                                                                 dbg_stack_new[2]);
                                                        stackList.add (newStack);
                                                }
 
@@ -770,10 +959,6 @@ public class PHPDBGInterface {
 
                                                        fileName = new String (getRawFrameData (entirePack, dbg_src_tree_tmp[3]));      // Get the filename
 
-                                                       if (fileName.length () > 0) {                                               // If we have a filename
-                                                               fileName = fileName.substring (0, fileName.length () - 1);              // Remove '\0' char
-                                                       }
-
                                                        if (dbg_src_tree_tmp[2] != 0) {                                             // If there is a module number
                                                                PHPDBGMod modNew;
 
@@ -811,11 +996,6 @@ public class PHPDBGInterface {
 
                                                error += ": ";
                                                error += new String (getRawFrameData (entirePack, dbg_error_tmp[1]));                   // Add the error string for this error message ID
-
-                                               if (error.length () > 0) {                                                                                                              // If we have a error message
-                                                        error = error.substring (0, error.length () - 1);                                                      //  Remove '\0' char
-                                               }
-
                                                error += "\n";                                                                  // Append a CR
 
                                                PHPDebugCorePlugin.log (new DebugException (new Status (IStatus.WARNING,
@@ -849,16 +1029,15 @@ public class PHPDBGInterface {
                                                break;
 
                                        case PHPDBGBase.FRAME_EVAL:
-                                               String evalString;
+                                               //String evalString;
 
-                                               evalString      = new 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;                                                      //
+                                               //evalString    = getRawFrameData (entirePack, dbg_eval_tmp[0]);                //
                                                break;
 
                                        case PHPDBGBase.FRAME_BPS:                                                          //
@@ -900,10 +1079,6 @@ public class PHPDBGInterface {
 
                                                        fileName = new String (getRawFrameData (entirePack, dbg_bpl_new[2]));
 
-                                                       if (fileName.length () > 0) {                                               // If we have filename
-                                                               fileName = fileName.substring (0, fileName.length () - 1);                              //  Remove '\0' char
-                                                       }
-
                                                        if (dbg_bpl_new[0] != 0) {
                                                                PHPDBGMod modNew;
 
@@ -952,7 +1127,8 @@ public class PHPDBGInterface {
                                        break;
 
                                case PHPDBGBase.DBGC_END:
-                                       sessionEnded = true;
+                                        sessionEnded = true; 
+                                        this.proxy.setTerminated(); 
                                        break;
 
                                case PHPDBGBase.DBGC_BREAKPOINT: