Eclipse3M7 version
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Parser.java
index e3bea19..609a33c 100644 (file)
@@ -11,32 +11,43 @@ Contributors:
 package net.sourceforge.phpdt.internal.compiler.parser;
 
 import java.util.ArrayList;
-import java.util.Hashtable;
 
-import net.sourceforge.phpdt.core.compiler.*;
-import net.sourceforge.phpdt.internal.compiler.parser.*;
+import net.sourceforge.phpdt.core.compiler.CharOperation;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext;
+import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants;
+import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode;
+import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference;
+import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
 import net.sourceforge.phpeclipse.phpeditor.PHPString;
-import net.sourceforge.phpeclipse.phpeditor.php.PHPKeywords;
 
 import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.ui.texteditor.MarkerUtilities;
+
 import test.PHPParserSuperclass;
 
-public class Parser extends PHPParserSuperclass implements PHPKeywords, ITerminalSymbols {
+public class Parser extends PHPParserSuperclass implements ITerminalSymbols, ParserBasicInformation {
+  //internal data for the automat 
+  protected final static int StackIncrement = 255;
+  protected int stateStackTop;
+  protected int[] stack = new int[StackIncrement];
+  public int firstToken; // handle for multiple parsing goals
+  public int lastAct; //handle for multiple parsing goals
+  protected RecoveredElement currentElement;
 
-  public static final int ERROR = 2;
-  public static final int WARNING = 1;
-  public static final int INFO = 0;
+  public static boolean VERBOSE_RECOVERY = false;
+  protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies
 
-  public static final boolean DEBUG = false;
-  //scanner token 
+  //scanner token
   public Scanner scanner;
 
-  private IFile fileToParse;
   private ArrayList phpList;
 
   private int currentPHPString;
@@ -46,7 +57,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   private String str;
 
   // current character
-//  char ch;
+  //  char ch;
   // current token
   int token;
 
@@ -66,7 +77,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   private String stringValue;
 
   /** Contains the current expression. */
- // private StringBuffer expression;
+  // private StringBuffer expression;
 
   private boolean phpMode;
 
@@ -146,12 +157,25 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   //   final static int TokenNameOR = 159;
   //  final static int TokenNameAT = 153; // @
 
-  public Parser() {
+  protected Parser() {
+    this.currentPHPString = 0;
+    //         PHPParserSuperclass.fileToParse = fileToParse;
+    this.phpList = null;
+    this.str = "";
+    this.token = TokenNameEOF;
+    //    this.chIndx = 0;
+    //    this.rowCount = 1;
+    //    this.columnCount = 0;
+    this.phpEnd = false;
+    //   getNextToken();
+
+    this.initializeScanner();
   }
 
+  
   public void setFileToParse(IFile fileToParse) {
     this.currentPHPString = 0;
-    this.fileToParse = fileToParse;
+    PHPParserSuperclass.fileToParse = fileToParse;
     this.phpList = null;
     this.str = "";
     this.token = TokenNameEOF;
@@ -159,27 +183,27 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     this.initializeScanner();
   }
   /**
-   *  Class Constructor.
+   *  ClassDeclaration Constructor.
    *
    *@param  s
    *@param  sess  Description of Parameter
    *@see
    */
   public Parser(IFile fileToParse) {
-//    if (keywordMap == null) {
-//      keywordMap = new HashMap();
-//      for (int i = 0; i < PHP_KEYWORS.length; i++) {
-//        keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
-//      }
-//    }
+    //    if (keywordMap == null) {
+    //      keywordMap = new HashMap();
+    //      for (int i = 0; i < PHP_KEYWORS.length; i++) {
+    //        keywordMap.put(PHP_KEYWORS[i], new Integer(PHP_KEYWORD_TOKEN[i]));
+    //      }
+    //    }
     this.currentPHPString = 0;
-    this.fileToParse = fileToParse;
+    PHPParserSuperclass.fileToParse = fileToParse;
     this.phpList = null;
     this.str = "";
     this.token = TokenNameEOF;
-//    this.chIndx = 0;
-//    this.rowCount = 1;
-//    this.columnCount = 0;
+    //    this.chIndx = 0;
+    //    this.rowCount = 1;
+    //    this.columnCount = 0;
     this.phpEnd = false;
     //   getNextToken();
 
@@ -192,45 +216,10 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   /**
    * Create marker for the parse error
    */
-  private void setMarker(
-    String message,
-    int charStart,
-    int charEnd,
-    int errorLevel)
-    throws CoreException {
+  private void setMarker(String message, int charStart, int charEnd, int errorLevel) throws CoreException {
     setMarker(fileToParse, message, charStart, charEnd, errorLevel);
   }
 
-  public static void setMarker(
-    IFile file,
-    String message,
-    int charStart,
-    int charEnd,
-    int errorLevel)
-    throws CoreException {
-    if (file != null) {
-      Hashtable attributes = new Hashtable();
-      MarkerUtilities.setMessage(attributes, message);
-      switch (errorLevel) {
-        case ERROR :
-          attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
-          break;
-        case WARNING :
-          attributes.put(
-            IMarker.SEVERITY,
-            new Integer(IMarker.SEVERITY_WARNING));
-          break;
-        case INFO :
-          attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_INFO));
-          break;
-      }
-      MarkerUtilities.setCharStart(attributes, charStart);
-      MarkerUtilities.setCharEnd(attributes, charEnd);
-      // setLineNumber(attributes, lineNumber);
-      MarkerUtilities.createMarker(file, attributes, IMarker.PROBLEM);
-    }
-  }
-
   /**
    * This method will throw the SyntaxError.
    * It will add the good lines and columns to the Error
@@ -239,28 +228,24 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
    */
   private void throwSyntaxError(String error) {
 
-//    if (str.length() < chIndx) {
-//      chIndx--;
-//    }
-//    // read until end-of-line
-//    int eol = chIndx;
-//    while (str.length() > eol) {
-//      ch = str.charAt(eol++);
-//      if (ch == '\n') {
-//        eol--;
-//        break;
-//      }
-//    }
-//    throw new SyntaxError(
-//      rowCount,
-//      chIndx - columnCount + 1,
-//      str.substring(columnCount, eol),
-//      error);
-    throw new SyntaxError(
-      1,
-      1,
-      "",
-      error);
+    //    if (str.length() < chIndx) {
+    //      chIndx--;
+    //    }
+    //    // read until end-of-line
+    //    int eol = chIndx;
+    //    while (str.length() > eol) {
+    //      ch = str.charAt(eol++);
+    //      if (ch == '\n') {
+    //        eol--;
+    //        break;
+    //      }
+    //    }
+    //    throw new SyntaxError(
+    //      rowCount,
+    //      chIndx - columnCount + 1,
+    //      str.substring(columnCount, eol),
+    //      error);
+    throw new SyntaxError(1, 1, "", error);
   }
 
   /**
@@ -273,23 +258,27 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     throw new SyntaxError(startRow, 0, " ", error);
   }
 
+  private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) {
+    problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, compilationUnit.compilationResult);
+    throw new SyntaxError(1, 0, " ", error);
+  }
   /**
    *  Method Declaration.
    *
    *@see
    */
-//  private void getChar() {
-//    if (str.length() > chIndx) {
-//      ch = str.charAt(chIndx++);
-//
-//      return;
-//    }
-//
-//    chIndx = str.length() + 1;
-//    ch = ' ';
-//    //  token = TokenNameEOF;
-//    phpEnd = true;
-//  }
+  //  private void getChar() {
+  //    if (str.length() > chIndx) {
+  //      ch = str.charAt(chIndx++);
+  //
+  //      return;
+  //    }
+  //
+  //    chIndx = str.length() + 1;
+  //    ch = ' ';
+  //    //  token = TokenNameEOF;
+  //    phpEnd = true;
+  //  }
 
   /**
    * gets the next token from input
@@ -297,12 +286,11 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   private void getNextToken() throws CoreException {
     try {
       token = scanner.getNextToken();
-      if (DEBUG) {
+      if (Scanner.DEBUG) {
         int currentEndPosition = scanner.getCurrentTokenEndPosition();
         int currentStartPosition = scanner.getCurrentTokenStartPosition();
 
-        System.out.print(
-          currentStartPosition + "," + currentEndPosition + ": ");
+        System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
         System.out.println(scanner.toStringAction(token));
       }
     } catch (InvalidInputException e) {
@@ -310,616 +298,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     }
     return;
 
-    //         boolean phpFound = false;
-    //         char ch2;
-    //
-    //         phpEnd = false;
-    //         try {
-    //                 if (!phpMode) {
-    //
-    //                         while (str.length() > chIndx) {
-    //                                 token = TokenNameERROR;
-    //                                 ch = str.charAt(chIndx++);
-    //
-    //                                 if (ch == '\n') {
-    //                                         rowCount++;
-    //                                 }
-    //                                 if (ch == '<') {
-    //                                         ch2 = str.charAt(chIndx++);
-    //                                         if (ch2 == '?') {
-    //                                                 ch2 = str.charAt(chIndx++);
-    //                                                 if (Character.isWhitespace(ch2)) {
-    //                                                         // php start
-    //                                                         phpMode = true;
-    //                                                         phpFound = true;
-    //                                                         break;
-    //                                                 } else if (ch2 == 'p' || ch2 == 'P') {
-    //                                                         ch2 = str.charAt(chIndx++);
-    //                                                         if (ch2 == 'h' || ch2 == 'H') {
-    //                                                                 ch2 = str.charAt(chIndx++);
-    //                                                                 if (ch2 == 'p' || ch2 == 'P') {
-    //                                                                         phpMode = true;
-    //                                                                         phpFound = true;
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 chIndx--;
-    //                                                         }
-    //                                                         chIndx--;
-    //                                                 }
-    //                                                 chIndx--;
-    //                                         }
-    //                                         chIndx--;
-    //                                 }
-    //                         }
-    //
-    //                 }
-    //
-    //                 if (phpMode) {
-    //                         while (str.length() > chIndx) {
-    //                                 ch = str.charAt(chIndx++);
-    //                                 token = TokenNameERROR;
-    //                                 if (ch == '\n') {
-    //                                         rowCount++;
-    //                                         columnCount = chIndx;
-    //                                         continue; // while loop
-    //                                 }
-    //                                 if (str.length() == chIndx) {
-    //                                         phpEnd = true;
-    //                                 }
-    //                                 if (!Character.isWhitespace(ch)) {
-    //                                         if (ch == '$') {
-    //                                                 if (str.length() > chIndx) {
-    //                                                         if (str.charAt(chIndx) == '{') {
-    //                                                                 chIndx++;
-    //                                                                 token = TokenNameDOLLAROPEN;
-    //                                                                 return;
-    //                                                         }
-    //                                                 }
-    //                                                 getIdentifier();
-    //                                                 return;
-    //                                         }
-    //                                         if ((ch >= 'a' && ch <= 'z')
-    //                                                 || (ch >= 'A' && ch <= 'Z')
-    //                                                 || (ch == '_')
-    //                                                 || (ch == '$')) {
-    //                                                 getIdentifier();
-    //                                                 return;
-    //                                         }
-    //                                         if (ch >= '0' && ch <= '9') {
-    //                                                 getNumber();
-    //                                                 return;
-    //                                         }
-    //                                         if (ch == '/') {
-    //                                                 if (str.length() > chIndx) {
-    //                                                         if (str.charAt(chIndx) == '/') {
-    //                                                                 ch = '/';
-    //                                                                 chIndx++;
-    //                                                                 // read comment until end of line:
-    //                                                                 while ((str.length() > chIndx)
-    //                                                                         && (ch != '\n')) {
-    //                                                                         ch = str.charAt(chIndx++);
-    //                                                                         if (ch == '?') {
-    //                                                                                 ch2 = str.charAt(chIndx);
-    //                                                                                 if (ch2 == '>') {
-    //                                                                                         chIndx++;
-    //                                                                                         token = TokenNameHTML;
-    //                                                                                         // php end
-    //                                                                                         phpMode = false;
-    //                                                                                         phpEnd = true;
-    //                                                                                         return;
-    //                                                                                 }
-    //                                                                         }
-    //                                                                 }
-    //                                                                 rowCount++;
-    //                                                                 continue;
-    //
-    //                                                         } else if (str.charAt(chIndx) == '*') {
-    //                                                                 chIndx++;
-    //                                                                 // multi line comment:
-    //                                                                 while (str.length() > chIndx) {
-    //                                                                         if (str.charAt(chIndx) == '*'
-    //                                                                                 && (str.length() > (chIndx + 1))
-    //                                                                                 && str.charAt(chIndx + 1) == '/') {
-    //                                                                                 chIndx += 2;
-    //                                                                                 break;
-    //                                                                         }
-    //                                                                         ch = str.charAt(chIndx++);
-    //                                                                         if (ch == '\n') {
-    //                                                                                 rowCount++;
-    //                                                                                 columnCount = chIndx;
-    //                                                                         }
-    //                                                                 }
-    //                                                                 continue;
-    //                                                         }
-    //                                                 }
-    //                                         } else if (ch == '#') {
-    //                                                 // read comment until end of line:
-    //                                                 while ((str.length() > chIndx) && (ch != '\n')) {
-    //                                                         ch = str.charAt(chIndx++);
-    //                                                         if (ch == '?') {
-    //                                                                 ch2 = str.charAt(chIndx);
-    //                                                                 if (ch2 == '>') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameHTML;
-    //                                                                         // php end
-    //                                                                         phpMode = false;
-    //                                                                         phpEnd = true;
-    //                                                                         return;
-    //                                                                 }
-    //                                                         }
-    //                                                 }
-    //                                                 rowCount++;
-    //                                                 continue;
-    //
-    //                                         } else if (ch == '"') {
-    //                                                 getString(
-    //                                                         '"',
-    //                                                         TokenNameStringInterpolated,
-    //                                                         "Open string character '\"' at end of file.");
-    //                                                 return;
-    //                                         } else if (ch == '\'') {
-    //                                                 getString(
-    //                                                         '\'',
-    //                                                         TokenNameStringConstant,
-    //                                                         "Open string character \"'\" at end of file.");
-    //                                                 return;
-    //                                         } else if (ch == '`') {
-    //                                                 getString(
-    //                                                         '`',
-    //                                                         TokenNameStringConstant,
-    //                                                         "Open string character \"`\" at end of file.");
-    //                                                 setMarker(
-    //                                                         "Other string delimiters prefered (found \"`\").",
-    //                                                         rowCount,
-    //                                                         PHPParser.INFO);
-    //                                                 return;
-    //                                         }
-    //
-    //                                         switch (ch) {
-    //
-    //                                                 case '(' :
-    //                                                         token = TokenNameLPAREN;
-    //
-    //                                                         break;
-    //                                                 case ')' :
-    //                                                         token = TokenNameRPAREN;
-    //
-    //                                                         break;
-    //                                                 case '{' :
-    //                                                         token = TokenNameLBRACE;
-    //
-    //                                                         break;
-    //                                                 case '}' :
-    //                                                         token = TokenNameRBRACE;
-    //
-    //                                                         break;
-    //                                                 case '[' :
-    //                                                         token = TokenNameLBRACKET;
-    //
-    //                                                         break;
-    //                                                 case ']' :
-    //                                                         token = TokenNameRBRACKET;
-    //
-    //                                                         break;
-    //                                                 case ',' :
-    //                                                         token = TokenNameCOMMA;
-    //
-    //                                                         break;
-    //                                                 case '?' :
-    //                                                         token = TokenNameQUESTION;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '>') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameHTML;
-    //                                                                         // php end
-    //                                                                         phpMode = false;
-    //                                                                         phpEnd = true;
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '@' :
-    //                                                         token = TokenNameAT;
-    //                                                         break;
-    //                                                 case '~' :
-    //                                                         token = TokenNameTWIDDLE;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameTWIDDLE_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //                                                         break;
-    //                                                 case '.' :
-    //                                                         token = TokenNameDOT;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameDOT_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '"' :
-    //                                                         token = TokenNameStringLiteral;
-    //
-    //                                                         break;
-    //                                                 case '%' :
-    //                                                         token = TokenNameREMAINDER;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameREMAINDER_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //                                                         break;
-    //                                                 case ';' :
-    //                                                         token = TokenNameSEMICOLON;
-    //
-    //                                                         break;
-    //                                                 case '^' :
-    //                                                         token = TokenNameXOR;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameXOR_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //                                                         break;
-    //                                                 case '/' :
-    //                                                         token = TokenNameDIVIDE;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameDIVIDE_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '*' :
-    //                                                         token = TokenNameMULTIPLY;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '*') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameXOR;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameMULTIPLY_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '+' :
-    //                                                         token = TokenNamePLUS;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '+') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNamePLUS_PLUS;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNamePLUS_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //                                                         break;
-    //                                                 case '-' :
-    //                                                         token = TokenNameMINUS;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '-') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameMINUS_MINUS;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameMINUS_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '>') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameMINUS_GREATER;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '=' :
-    //                                                         token = TokenNameEQUAL;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 ch = str.charAt(chIndx);
-    //
-    //                                                                 if (ch == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameEQUAL_EQUAL;
-    //                                                                         if (str.length() > chIndx) {
-    //                                                                                 ch = str.charAt(chIndx);
-    //
-    //                                                                                 if (ch == '=') {
-    //                                                                                         chIndx++;
-    //                                                                                         token =
-    //                                                                                                 TokenNameEQUAL_EQUAL_EQUAL;
-    //                                                                                 }
-    //                                                                         }
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (ch == '>') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameEQUAL_GREATER;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '!' :
-    //                                                         token = TokenNameNOT;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameNOT_EQUAL;
-    //                                                                         if (str.length() > chIndx) {
-    //                                                                                 ch = str.charAt(chIndx);
-    //
-    //                                                                                 if (ch == '=') {
-    //                                                                                         chIndx++;
-    //                                                                                         token =
-    //                                                                                                 TokenNameNOT_EQUAL_EQUAL;
-    //                                                                                 }
-    //                                                                         }
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '>' :
-    //                                                         token = TokenNameGREATER;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameGREATER_EQUAL;
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '>') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameRIGHT_SHIFT;
-    //                                                                         if (str.length() > chIndx) {
-    //                                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                                         chIndx++;
-    //                                                                                         token =
-    //                                                                                                 TokenNameRIGHT_SHIFT_EQUAL;
-    //                                                                                         break;
-    //                                                                                 }
-    //                                                                         }
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '<' :
-    //                                                         token = TokenNameLESS;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameLESS_EQUAL;
-    //
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '<') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameLEFT_SHIFT;
-    //                                                                         if (str.charAt(chIndx) == '<') {
-    //                                                                                 // heredoc
-    //                                                                                 int startRow = rowCount;
-    //                                                                                 if (str.length() > chIndx) {
-    //
-    //                                                                                         ch = str.charAt(++chIndx);
-    //                                                                                         if ((ch >= 'a' && ch <= 'z')
-    //                                                                                                 || (ch >= 'A' && ch <= 'Z')
-    //                                                                                                 || (ch == '_')) {
-    //                                                                                                 chIndx++;
-    //                                                                                                 getIdentifier();
-    //                                                                                                 token =
-    //                                                                                                         TokenNameStringConstant;
-    //                                                                                                 while (str.length()
-    //                                                                                                         > chIndx) {
-    //                                                                                                         ch =
-    //                                                                                                                 str.charAt(
-    //                                                                                                                         chIndx++);
-    //                                                                                                         if (ch == '\n') {
-    //                                                                                                                 if (str.length()
-    //                                                                                                                         >= chIndx
-    //                                                                                                                                 + identifier
-    //                                                                                                                                         .length()) {
-    //                                                                                                                         if (str
-    //                                                                                                                                 .substring(
-    //                                                                                                                                         chIndx,
-    //                                                                                                                                         chIndx
-    //                                                                                                                                                 + identifier
-    //                                                                                                                                                         .length())
-    //                                                                                                                                 .equals(identifier)) {
-    //                                                                                                                                 chIndx
-    //                                                                                                                                         += identifier
-    //                                                                                                                                                 .length();
-    //                                                                                                                                 return;
-    //                                                                                                                         }
-    //                                                                                                                 }
-    //                                                                                                         }
-    //                                                                                                 }
-    //                                                                                         }
-    //                                                                                 }
-    //                                                                                 throwSyntaxError(
-    //                                                                                         "Open heredoc syntax after operator '<<<'.",
-    //                                                                                         startRow);
-    //                                                                         } else if (str.charAt(chIndx) == '=') {
-    //                                                                                 chIndx++;
-    //                                                                                 token = TokenNameLEFT_SHIFT_EQUAL;
-    //                                                                                 break;
-    //                                                                         }
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //
-    //                                                 case '|' :
-    //                                                         token = TokenNameOR;
-    //
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '|') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameOR_OR;
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameOR_EQUAL;
-    //                                                                         break;
-    //                                                                 }
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case '&' :
-    //                                                         token = TokenNameAND;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == '&') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameAND_AND;
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 if (str.charAt(chIndx) == '=') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameAND_EQUAL;
-    //                                                                         break;
-    //                                                                 }
-    //                                                                 break;
-    //                                                         }
-    //
-    //                                                         break;
-    //                                                 case ':' :
-    //                                                         token = TokenNameCOLON;
-    //                                                         if (str.length() > chIndx) {
-    //                                                                 if (str.charAt(chIndx) == ':') {
-    //                                                                         chIndx++;
-    //                                                                         token = TokenNameCOLON_COLON;
-    //                                                                 }
-    //                                                         }
-    //                                                         break;
-    //                                                         //              case '#' :
-    //                                                         //                token = TokenNameHASH;
-    //                                                         //
-    //                                                         //                break;
-    //                                                         //          case '@' :
-    //                                                         //            token = TokenNameAT;
-    //                                                         //
-    //                                                         //            break;
-    //                                                 default :
-    //                                                         throwSyntaxError(
-    //                                                                 "unexpected character: '" + ch + "'");
-    //                                         }
-    //
-    //                                         if (token == TokenNameERROR) {
-    //                                                 throwSyntaxError("token not found");
-    //                                         }
-    //
-    //                                         return;
-    //                                 }
-    //                         }
-    //                 }
-    //         } catch (StringIndexOutOfBoundsException e) {
-    //                 // catched from charAt
-    //         }
-    //
-    //         chIndx = str.length() + 1;
-    //         ch = ' ';
-    //         token = TokenNameEOF;
-    //         phpEnd = true;
-    //         //PHPString temp;
-    //         //    if (phpList != null) {
-    //         //      if (currentPHPString < phpList.size()) {
-    //         //        token = TokenNameUNDEFINED;
-    //         //        temp = (PHPString) phpList.get(currentPHPString++);
-    //         //        this.str = temp.getPHPString();
-    //         //        this.token = TokenNameEOF;
-    //         //        this.chIndx = 0;
-    //         //        this.rowCount = temp.getLineNumber();
-    //         //        this.columnCount = 0;
-    //         //        getNextToken();
-    //         //        phpEnd = true;
-    //         //      } else {
-    //         //        token = TokenNameUNDEFINED;
-    //         //        return;
-    //         //      }
-    //         //    }
-  }
-
-  //   /**
-  //    * Get an identifier.
-  //    */
-  //   private void getIdentifier() {
-  //           //  StringBuffer ident = new StringBuffer();
-  //           int startPosition = chIndx - 1;
-  //           //    ident.append(ch);
-  //           if (ch == '$') {
-  //                   getChar();
-  //                   // attention recursive call:
-  //                   getIdentifier();
-  //                   token = TokenNameVariable;
-  //                   return;
-  //           } else {
-  //                   token = TokenNameIdentifier;
-  //           }
-  //
-  //           getChar();
-  //
-  //           //this will read the buffer until the next character is a forbidden character for identifier
-  //           while ((ch >= 'a' && ch <= 'z')
-  //                   || (ch >= 'A' && ch <= 'Z')
-  //                   || (ch >= '0' && ch <= '9')
-  //                   || (ch == '_')) {
-  //                   //    ident.append(ch);
-  //                   getChar();
-  //           }
-  //           int endPosition = chIndx--;
-  //           int length = (--endPosition) - startPosition;
-  //
-  //           identifier = str.substring(startPosition, endPosition);
-  //           // System.out.println(identifier);
-  //
-  //           // determine if this identitfer is a keyword
-  //           // @todo improve this in future version
-  //           Integer i = (Integer) keywordMap.get(identifier.toLowerCase());
-  //           if (i != null) {
-  //                   token = i.intValue();
-  //           }
-  //   }
+  }
 
   /**
    * Get a number.
@@ -928,137 +307,137 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
    * if it's a <code>double</code> the number will be stored in <code>longNumber</code> and the token will have the
    * value {@link Parser#TokenNameINT_NUMBER}
    */
-//  private void getNumber() {
-//    StringBuffer inum = new StringBuffer();
-//    char dFlag = ' ';
-//    int numFormat = 10;
-//
-//    // save first digit
-//    char firstCh = ch;
-//    inum.append(ch);
-//
-//    getChar();
-//    // determine number conversions:
-//    if (firstCh == '0') {
-//      switch (ch) {
-//        case 'b' :
-//          numFormat = 2;
-//          getChar();
-//          break;
-//        case 'B' :
-//          numFormat = 2;
-//          getChar();
-//          break;
-//        case 'o' :
-//          numFormat = 8;
-//          getChar();
-//          break;
-//        case 'O' :
-//          numFormat = 8;
-//          getChar();
-//          break;
-//        case 'x' :
-//          numFormat = 16;
-//          getChar();
-//          break;
-//        case 'X' :
-//          numFormat = 16;
-//          getChar();
-//          break;
-//      }
-//    }
-//
-//    if (numFormat == 16) {
-//      while ((ch >= '0' && ch <= '9')
-//        || (ch >= 'a' && ch <= 'f')
-//        || (ch >= 'A' && ch <= 'F')) {
-//        inum.append(ch);
-//        getChar();
-//      }
-//    } else {
-//      while ((ch >= '0' && ch <= '9')
-//        || (ch == '.')
-//        || (ch == 'E')
-//        || (ch == 'e')) {
-//        if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
-//          if (ch == '.' && dFlag != ' ') {
-//            break;
-//          }
-//          if ((dFlag == 'E') || (dFlag == 'e')) {
-//            break;
-//          }
-//          dFlag = ch;
-//          inum.append(ch);
-//          getChar();
-//          if ((ch == '-') || (ch == '+')) {
-//            inum.append(ch);
-//            getChar();
-//          }
-//        } else {
-//          inum.append(ch);
-//          getChar();
-//        }
-//      }
-//    }
-//    chIndx--;
-//
-//    try {
-//      if (dFlag != ' ') {
-//        doubleNumber = new Double(inum.toString());
-//        token = TokenNameDoubleLiteral;
-//        return;
-//      } else {
-//        longNumber = Long.valueOf(inum.toString(), numFormat);
-//        token = TokenNameIntegerLiteral;
-//        return;
-//      }
-//
-//    } catch (Throwable e) {
-//      throwSyntaxError("Number format error: " + inum.toString());
-//    }
-//  }
-//
-//  /**
-//   * Get a String.
-//   * @param openChar the opening char ('\'', '"', '`')
-//   * @param typeString the type of string {@link #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING}
-//   * @param errorMsg the error message in case of parse error in the string
-//   */
-//  private void getString(
-//    final char openChar,
-//    final int typeString,
-//    final String errorMsg) {
-//    StringBuffer sBuffer = new StringBuffer();
-//    boolean openString = true;
-//    int startRow = rowCount;
-//    while (str.length() > chIndx) {
-//      ch = str.charAt(chIndx++);
-//      if (ch == '\\') {
-//        sBuffer.append(ch);
-//        if (str.length() > chIndx) {
-//          ch = str.charAt(chIndx++);
-//          sBuffer.append(ch);
-//        }
-//      } else if (ch == openChar) {
-//        openString = false;
-//        break;
-//      } else if (ch == '\n') {
-//        rowCount++;
-//        columnCount = chIndx;
-//      } else {
-//        sBuffer.append(ch);
-//      }
-//    }
-//    if (openString) {
-//      if (typeString == TokenNameStringConstant) {
-//        throwSyntaxError(errorMsg, startRow);
-//      } else {
-//        throwSyntaxError(errorMsg);
-//      }
-//    }
-//    token = typeString;
-//    stringValue = sBuffer.toString();
-//  }
+  //  private void getNumber() {
+  //    StringBuffer inum = new StringBuffer();
+  //    char dFlag = ' ';
+  //    int numFormat = 10;
+  //
+  //    // save first digit
+  //    char firstCh = ch;
+  //    inum.append(ch);
+  //
+  //    getChar();
+  //    // determine number conversions:
+  //    if (firstCh == '0') {
+  //      switch (ch) {
+  //        case 'b' :
+  //          numFormat = 2;
+  //          getChar();
+  //          break;
+  //        case 'B' :
+  //          numFormat = 2;
+  //          getChar();
+  //          break;
+  //        case 'o' :
+  //          numFormat = 8;
+  //          getChar();
+  //          break;
+  //        case 'O' :
+  //          numFormat = 8;
+  //          getChar();
+  //          break;
+  //        case 'x' :
+  //          numFormat = 16;
+  //          getChar();
+  //          break;
+  //        case 'X' :
+  //          numFormat = 16;
+  //          getChar();
+  //          break;
+  //      }
+  //    }
+  //
+  //    if (numFormat == 16) {
+  //      while ((ch >= '0' && ch <= '9')
+  //        || (ch >= 'a' && ch <= 'f')
+  //        || (ch >= 'A' && ch <= 'F')) {
+  //        inum.append(ch);
+  //        getChar();
+  //      }
+  //    } else {
+  //      while ((ch >= '0' && ch <= '9')
+  //        || (ch == '.')
+  //        || (ch == 'E')
+  //        || (ch == 'e')) {
+  //        if ((ch == '.') || (ch == 'E') || (ch == 'e')) {
+  //          if (ch == '.' && dFlag != ' ') {
+  //            break;
+  //          }
+  //          if ((dFlag == 'E') || (dFlag == 'e')) {
+  //            break;
+  //          }
+  //          dFlag = ch;
+  //          inum.append(ch);
+  //          getChar();
+  //          if ((ch == '-') || (ch == '+')) {
+  //            inum.append(ch);
+  //            getChar();
+  //          }
+  //        } else {
+  //          inum.append(ch);
+  //          getChar();
+  //        }
+  //      }
+  //    }
+  //    chIndx--;
+  //
+  //    try {
+  //      if (dFlag != ' ') {
+  //        doubleNumber = new Double(inum.toString());
+  //        token = TokenNameDoubleLiteral;
+  //        return;
+  //      } else {
+  //        longNumber = Long.valueOf(inum.toString(), numFormat);
+  //        token = TokenNameIntegerLiteral;
+  //        return;
+  //      }
+  //
+  //    } catch (Throwable e) {
+  //      throwSyntaxError("Number format error: " + inum.toString());
+  //    }
+  //  }
+  //
+  //  /**
+  //   * Get a String.
+  //   * @param openChar the opening char ('\'', '"', '`')
+  //   * @param typeString the type of string {@link #TokenNameSTRING_CONSTANT},{@link #TokenNameINTERPOLATED_STRING}
+  //   * @param errorMsg the error message in case of parse error in the string
+  //   */
+  //  private void getString(
+  //    final char openChar,
+  //    final int typeString,
+  //    final String errorMsg) {
+  //    StringBuffer sBuffer = new StringBuffer();
+  //    boolean openString = true;
+  //    int startRow = rowCount;
+  //    while (str.length() > chIndx) {
+  //      ch = str.charAt(chIndx++);
+  //      if (ch == '\\') {
+  //        sBuffer.append(ch);
+  //        if (str.length() > chIndx) {
+  //          ch = str.charAt(chIndx++);
+  //          sBuffer.append(ch);
+  //        }
+  //      } else if (ch == openChar) {
+  //        openString = false;
+  //        break;
+  //      } else if (ch == '\n') {
+  //        rowCount++;
+  //        columnCount = chIndx;
+  //      } else {
+  //        sBuffer.append(ch);
+  //      }
+  //    }
+  //    if (openString) {
+  //      if (typeString == TokenNameStringConstant) {
+  //        throwSyntaxError(errorMsg, startRow);
+  //      } else {
+  //        throwSyntaxError(errorMsg);
+  //      }
+  //    }
+  //    token = typeString;
+  //    stringValue = sBuffer.toString();
+  //  }
 
   //   public void htmlParserTester(String input) {
   //           int lineNumber = 1;
@@ -1278,9 +657,9 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
       }
     }
     this.token = TokenNameEOF;
-//    this.chIndx = 0;
-//    this.rowCount = rowCount;
-//    this.columnCount = 0;
+    //    this.chIndx = 0;
+    //    this.rowCount = rowCount;
+    //    this.columnCount = 0;
     this.phpEnd = false;
     this.phpMode = true;
     scanner.setSource(s.toCharArray());
@@ -1291,7 +670,10 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
         if (token != TokenNameEOF && token != TokenNameERROR) {
           statementList();
         }
-        if (token != TokenNameEOF && token != TokenNameERROR) {
+        if (token != TokenNameEOF) {
+          if (token == TokenNameERROR) {
+            throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")");
+          }
           if (token == TokenNameRPAREN) {
             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
           }
@@ -1320,11 +702,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           throw err;
         } else {
           //   setMarker(err.getMessage(), err.getLine(), ERROR);
-          setMarker(
-            err.getMessage(),
-            scanner.getCurrentTokenStartPosition(),
-            scanner.getCurrentTokenEndPosition(),
-            ERROR);
+          setMarker(err.getMessage(), scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), ERROR);
         }
         // if an error occured,
         // try to find keywords 'class' or 'function'
@@ -1342,29 +720,55 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     }
     while (true);
   }
-
-  /**
-   * Parses a string with php tags
-   * i.e. '&lt;body&gt; &lt;?php phpinfo() ?&gt; &lt;/body&gt;'
-   */
-  public void parse(String s) throws CoreException {
+  public void init(String s) {
     this.str = s;
     this.token = TokenNameEOF;
-//    this.chIndx = 0;
-//    this.rowCount = 1;
-//    this.columnCount = 0;
+    //    this.chIndx = 0;
+    //    this.rowCount = 1;
+    //    this.columnCount = 0;
     this.phpEnd = false;
     this.phpMode = false;
     /* scanner initialization */
     scanner.setSource(s.toCharArray());
     scanner.setPHPMode(false);
+  }
+
+  protected void initialize(boolean phpMode) {
+    compilationUnit = null;
+    referenceContext = null;
+    this.str = "";
+    this.token = TokenNameEOF;
+    //    this.chIndx = 0;
+    //    this.rowCount = 1;
+    //    this.columnCount = 0;
+    this.phpEnd = false;
+    this.phpMode = phpMode;
+    scanner.setPHPMode(phpMode);
+  }
+  /**
+   * Parses a string with php tags
+   * i.e. '&lt;body&gt; &lt;?php phpinfo() ?&gt; &lt;/body&gt;'
+   */
+  public void parse(String s) throws CoreException {
+    init(s);
+    parse();
+  }
+
+  /**
+        * Parses a string with php tags
+        * i.e. '&lt;body&gt; &lt;?php phpinfo() ?&gt; &lt;/body&gt;'
+        */
+  protected void parse() throws CoreException {
     getNextToken();
     do {
       try {
         if (token != TokenNameEOF && token != TokenNameERROR) {
           statementList();
         }
-        if (token != TokenNameEOF && token != TokenNameERROR) {
+        if (token != TokenNameEOF) {
+          if (token == TokenNameERROR) {
+            throwSyntaxError("Scanner error (Found unknown token: " + scanner.toStringAction(token) + ")");
+          }
           if (token == TokenNameRPAREN) {
             throwSyntaxError("Too many closing ')'; end-of-file not reached.");
           }
@@ -1390,11 +794,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
         return;
       } catch (SyntaxError sytaxErr1) {
         // setMarker(sytaxErr1.getMessage(), sytaxErr1.getLine(), ERROR);
-        setMarker(
-          sytaxErr1.getMessage(),
-          scanner.getCurrentTokenStartPosition(),
-          scanner.getCurrentTokenEndPosition(),
-          ERROR);
+        setMarker(sytaxErr1.getMessage(), scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), ERROR);
         try {
           // if an error occured,
           // try to find keywords 'class' or 'function'
@@ -1410,11 +810,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           }
         } catch (SyntaxError sytaxErr2) {
           //    setMarker(sytaxErr2.getMessage(), sytaxErr2.getLine(), ERROR);
-          setMarker(
-            sytaxErr2.getMessage(),
-            scanner.getCurrentTokenStartPosition(),
-            scanner.getCurrentTokenEndPosition(),
-            ERROR);
+          setMarker(sytaxErr2.getMessage(), scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), ERROR);
           return;
         }
       }
@@ -1429,9 +825,9 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
 
     this.str = s;
     this.token = TokenNameEOF;
-//    this.chIndx = 0;
-//    this.rowCount = 1;
-//    this.columnCount = 0;
+    //    this.chIndx = 0;
+    //    this.rowCount = 1;
+    //    this.columnCount = 0;
     this.phpEnd = false;
     this.phpMode = false;
     scanner.setSource(s.toCharArray());
@@ -1445,15 +841,16 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     return outlineInfo;
   }
 
-  private void parseDeclarations(
-    PHPOutlineInfo outlineInfo,
-    PHPSegmentWithChildren current,
-    boolean goBack) {
+  private boolean isVariable() {
+    return token == TokenNameVariable || token == TokenNamethis;
+  }
+
+  private void parseDeclarations(PHPOutlineInfo outlineInfo, OutlineableWithChildren current, boolean goBack) {
     char[] ident;
     //   PHPClassDeclaration current = (PHPClassDeclaration) stack.peek();
     PHPSegmentWithChildren temp;
     int counter = 0;
-    
+
     IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
     try {
       while (token != TokenNameEOF && token != TokenNameERROR) {
@@ -1463,14 +860,14 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           getNextToken();
         } else if (token == TokenNamevar) {
           getNextToken();
-          if (token == TokenNameVariable
-            && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
+          if (token == TokenNameVariable && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_VAR)) {
             ident = scanner.getCurrentIdentifierSource();
-            String variableName = new String(ident);
+            //substring(1) added because PHPVarDeclaration doesn't need the $ anymore
+            String variableName = new String(ident).substring(1);
             outlineInfo.addVariable(variableName);
             getNextToken();
             if (token != TokenNameSEMICOLON) {
-              
+
               getNextToken();
               ident = scanner.getCurrentTokenSource();
               if (token > TokenNameKEYWORD) {
@@ -1480,6 +877,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
               } else {
                 switch (token) {
                   case TokenNameVariable :
+                  case TokenNamethis :
                     current.add(new PHPVarDeclaration(current, variableName,
                     //                      chIndx - ident.length,
                     scanner.getCurrentTokenStartPosition(), new String(ident)));
@@ -1490,10 +888,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
                     scanner.getCurrentTokenStartPosition(), new String(ident)));
                     break;
                   case TokenNameDoubleLiteral :
-                    current
-                      .add(new PHPVarDeclaration(
-                        current,
-                        variableName + doubleNumber,
+                    current.add(new PHPVarDeclaration(current, variableName + doubleNumber,
                     //   chIndx - ident.length,
                     scanner.getCurrentTokenStartPosition(), new String(ident)));
                     break;
@@ -1534,8 +929,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           if (token == TokenNameAND) {
             getNextToken();
           }
-          if (token == TokenNameIdentifier
-            && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
+          if (token == TokenNameIdentifier && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_FUNC)) {
             ident = scanner.getCurrentIdentifierSource();
             outlineInfo.addVariable(new String(ident));
             temp = new PHPFunctionDeclaration(current, new String(ident),
@@ -1547,8 +941,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           }
         } else if (token == TokenNameclass) {
           getNextToken();
-          if (token == TokenNameIdentifier
-            && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
+          if (token == TokenNameIdentifier && store.getBoolean(PHPeclipsePlugin.PHP_OUTLINE_CLASS)) {
             ident = scanner.getCurrentIdentifierSource();
             outlineInfo.addVariable(new String(ident));
             temp = new PHPClassDeclaration(current, new String(ident),
@@ -1559,15 +952,13 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
             getNextToken();
 
             //skip tokens for classname, extends and others until we have the opening '{'
-            while (token != TokenNameLBRACE
-              && token != TokenNameEOF
-              && token != TokenNameERROR) {
+            while (token != TokenNameLBRACE && token != TokenNameEOF && token != TokenNameERROR) {
               getNextToken();
             }
             parseDeclarations(outlineInfo, temp, true);
             //        stack.pop();
           }
-        } else if (token == TokenNameLBRACE) {
+        } else if ((token == TokenNameLBRACE) || (token == TokenNameDOLLAR_LBRACE)) {
           getNextToken();
           counter++;
         } else if (token == TokenNameRBRACE) {
@@ -1576,17 +967,13 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           if (counter == 0 && goBack) {
             return;
           }
-        } else if (
-          token == TokenNamerequire
-            || token == TokenNamerequire_once
-            || token == TokenNameinclude
-            || token == TokenNameinclude_once) {
-          ident =   scanner.getCurrentTokenSource(); 
-         
+        } else if (token == TokenNamerequire || token == TokenNamerequire_once || token == TokenNameinclude || token == TokenNameinclude_once) {
+          ident = scanner.getCurrentTokenSource();
+
           getNextToken();
           int startPosition = scanner.getCurrentTokenStartPosition();
           expression();
-          char[] expr =   scanner.getCurrentTokenSource(startPosition); 
+          char[] expr = scanner.getCurrentTokenSource(startPosition);
           outlineInfo.addVariable(new String(ident));
           current.add(new PHPReqIncDeclaration(current, new String(ident),
           //    chIndx - ident.length,
@@ -1600,11 +987,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     } catch (SyntaxError sytaxErr) {
       try {
         //  setMarker(sytaxErr.getMessage(), sytaxErr.getLine(), ERROR);
-        setMarker(
-          sytaxErr.getMessage(),
-          scanner.getCurrentTokenStartPosition(),
-          scanner.getCurrentTokenEndPosition(),
-          ERROR);
+        setMarker(sytaxErr.getMessage(), scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), ERROR);
       } catch (CoreException e) {
       }
     }
@@ -1612,10 +995,11 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
 
   private void statementList() throws CoreException {
     do {
-      statement();
+      statement(TokenNameEOF);
       if ((token == TokenNameRBRACE)
         || (token == TokenNamecase)
         || (token == TokenNamedefault)
+        || (token == TokenNameelse)
         || (token == TokenNameelseif)
         || (token == TokenNameendif)
         || (token == TokenNameendfor)
@@ -1629,7 +1013,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     } while (true);
   }
 
-  private void compoundStatement() throws CoreException {
+  private void functionBody(MethodDeclaration methodDecl) throws CoreException {
     // '{' [statement-list] '}'
     if (token == TokenNameLBRACE) {
       getNextToken();
@@ -1640,39 +1024,62 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
       statementList();
     }
     if (token == TokenNameRBRACE) {
+      methodDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
       getNextToken();
     } else {
       throwSyntaxError("'}' expected in compound-statement.");
     }
   }
 
-  private void statement() throws CoreException {
+  private void statement(int previousToken) throws CoreException {
     //   if (token > TokenNameKEYWORD && token != TokenNamelist && token != TokenNamenew) {
     //  char[] ident = scanner.getCurrentIdentifierSource();
     //  String keyword = new String(ident);
+       if (token == TokenNameAT) {
+               getNextToken();
+               if (token != TokenNamerequire
+                               && token != TokenNamerequire_once
+                               && token != TokenNameinclude
+                               && token != TokenNameinclude_once
+                               && token != TokenNameIdentifier
+                               && token != TokenNameVariable
+                               && token != TokenNamethis
+                               && token != TokenNameStringInterpolated) {
+                       throwSyntaxError("identifier expected after '@'.");
+               }
+       }
     if (token == TokenNameinclude || token == TokenNameinclude_once) {
       getNextToken();
-      expression();
-      if (token == TokenNameSEMICOLON) {
-        getNextToken();
-      } else {
-        if (token != TokenNameStopPHP) {
-          throwSyntaxError("';' character after 'include' or 'include_once' expected.");
+      if (token == TokenNameLPAREN) {
+        expression();
+        if (token == TokenNameSEMICOLON) {
+          getNextToken();
+        } else {
+          if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
+            throwSyntaxError("';' expected after 'include' or 'include_once'.");
+          }
+          //        getNextToken();
         }
-        getNextToken();
+      } else {
+        concatenationExpression();
       }
+
       return;
     } else if (token == TokenNamerequire || token == TokenNamerequire_once) {
       getNextToken();
       //constant();
-      expression();
-      if (token == TokenNameSEMICOLON) {
-        getNextToken();
-      } else {
-        if (token != TokenNameStopPHP) {
-          throwSyntaxError("';' character after 'require' or 'require_once' expected.");
+      if (token == TokenNameLPAREN) {
+        expression();
+        if (token == TokenNameSEMICOLON) {
+          getNextToken();
+        } else {
+          if (previousToken != TokenNameAT && token != TokenNameStopPHP) {
+            throwSyntaxError("';' expected after 'require' or 'require_once'.");
+          }
+          //        getNextToken();
         }
-        getNextToken();
+      } else {
+        concatenationExpression();
       }
       return;
     } else if (token == TokenNameif) {
@@ -1826,10 +1233,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
       foreachStatement();
       return;
 
-    } else if (
-      token == TokenNamecontinue
-        || token == TokenNamebreak
-        || token == TokenNamereturn) {
+    } else if (token == TokenNamecontinue || token == TokenNamebreak || token == TokenNamereturn) {
       getNextToken();
       if (token != TokenNameSEMICOLON) {
         expression();
@@ -1953,18 +1357,30 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
       }
       return;
     } else if (token == TokenNamefunction) {
+      MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
+      methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
       getNextToken();
-      functionDefinition();
+      functionDefinition(methodDecl);
       return;
     } else if (token == TokenNameclass) {
-      getNextToken();
-      classDeclarator();
-      classBody();
+      TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
+      typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
+      // default super class
+      typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
+      compilationUnit.types.add(typeDecl);
+      try {
+        pushOnAstStack(typeDecl);
+        getNextToken();
+        classDeclarator(typeDecl);
+        classBody(typeDecl);
+      } finally {
+        astPtr--;
+        astLengthPtr--;
+      }
       return;
       //      } else {
       //        throwSyntaxError("Unexpected keyword '" + keyword + "'");
     } else if (token == TokenNameLBRACE) {
-      // compoundStatement
       getNextToken();
       if (token != TokenNameRBRACE) {
         statementList();
@@ -1984,35 +1400,52 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
         return;
       } else {
         if (token != TokenNameStopPHP && token != TokenNameEOF) {
-          throwSyntaxError(
-            "';' expected after expression (Found token: "
-              + scanner.toStringAction(token)
-              + ")");
+          throwSyntaxError("';' expected after expression (Found token: " + scanner.toStringAction(token) + ")");
         }
         getNextToken();
       }
     }
   }
 
-  private void classDeclarator() throws CoreException {
+  private void classDeclarator(TypeDeclaration typeDecl) throws CoreException {
     //identifier
     //identifier 'extends' identifier
+
     if (token == TokenNameIdentifier) {
+      typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
+      typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
+      typeDecl.name = scanner.getCurrentIdentifierSource();
       getNextToken();
       if (token == TokenNameextends) {
-        getNextToken();
-        if (token == TokenNameIdentifier) {
+        do {
           getNextToken();
-        } else {
-          throwSyntaxError("Class name expected after keyword 'extends'.");
-        }
-      }
+          if (token == TokenNameIdentifier) {
+            getNextToken();
+          } else {
+            reportSyntaxError("Class name expected after keyword 'extends'.", scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition());
+            //            throwSyntaxError("ClassDeclaration name expected after keyword 'extends'.");
+          }
+        } while (token == TokenNameCOMMA);
+      } 
     } else {
-      throwSyntaxError("Class name expected after keyword 'class'.");
+      typeDecl.sourceStart = scanner.getCurrentTokenStartPosition();
+      typeDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
+
+      if (token > TokenNameKEYWORD) {
+        typeDecl.name = scanner.getCurrentIdentifierSource();
+        reportSyntaxError(
+          "Don't use keyword for class declaration [" + scanner.toStringAction(token) + "].",
+                                 typeDecl.sourceStart,
+                                 typeDecl.sourceEnd);
+        //        throwSyntaxError("Don't use keyword for class declaration [" + token + "].");
+      }
+      typeDecl.name = new char[] { ' ' };
+      reportSyntaxError("Class name expected after keyword 'class'.", typeDecl.sourceStart, typeDecl.sourceEnd);
+      //      throwSyntaxError("ClassDeclaration name expected after keyword 'class'.");
     }
   }
 
-  private void classBody() throws CoreException {
+  private void classBody(TypeDeclaration typeDecl) throws CoreException {
     //'{' [class-element-list] '}'
     if (token == TokenNameLBRACE) {
       getNextToken();
@@ -2020,6 +1453,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
         classElementList();
       }
       if (token == TokenNameRBRACE) {
+        typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
         getNextToken();
       } else {
         throwSyntaxError("'}' expected at end of class body.");
@@ -2039,8 +1473,10 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     //class-property
     //function-definition
     if (token == TokenNamefunction) {
+      MethodDeclaration methodDecl = new MethodDeclaration(this.compilationUnit.compilationResult);
+      methodDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
       getNextToken();
-      functionDefinition();
+      functionDefinition(methodDecl);
     } else if (token == TokenNamevar) {
       getNextToken();
       classProperty();
@@ -2060,6 +1496,9 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           constant();
         }
       } else {
+        if (token == TokenNamethis) {
+          throwSyntaxError("Reserved word '$this' not allowed after keyword 'var'.");
+        }
         throwSyntaxError("Variable expected after keyword 'var'.");
       }
       if (token != TokenNameCOMMA) {
@@ -2074,17 +1513,36 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     }
   }
 
-  private void functionDefinition() throws CoreException {
-    functionDeclarator();
-    compoundStatement();
+  private void functionDefinition(MethodDeclaration methodDecl) throws CoreException {
+    if (astPtr == 0) {
+      compilationUnit.types.add(methodDecl);
+    } else {
+      AstNode node = astStack[astPtr];
+      if (node instanceof TypeDeclaration) {
+        TypeDeclaration typeDecl = ((TypeDeclaration) node);
+        if (typeDecl.methods == null) {
+          typeDecl.methods = new AbstractMethodDeclaration[] { methodDecl };
+        } else {
+          AbstractMethodDeclaration[] newMethods;
+          System.arraycopy(typeDecl.methods, 0, newMethods = new AbstractMethodDeclaration[typeDecl.methods.length + 1], 1, typeDecl.methods.length);
+          newMethods[0] = methodDecl;
+          typeDecl.methods = newMethods;
+        }
+      }
+    }
+    functionDeclarator(methodDecl);
+    functionBody(methodDecl);
   }
 
-  private void functionDeclarator() throws CoreException {
+  private void functionDeclarator(MethodDeclaration methodDecl) throws CoreException {
     //identifier '(' [parameter-list] ')'
     if (token == TokenNameAND) {
       getNextToken();
     }
     if (token == TokenNameIdentifier) {
+      methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
+      methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
+      methodDecl.selector = scanner.getCurrentIdentifierSource();
       getNextToken();
       if (token == TokenNameLPAREN) {
         getNextToken();
@@ -2097,8 +1555,14 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
       if (token != TokenNameRPAREN) {
         throwSyntaxError("')' expected in function declaration.");
       } else {
+        methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
         getNextToken();
       }
+    } else {
+      if (token > TokenNameKEYWORD) {
+        throwSyntaxError("Don't use keyword for function declaration [" + token + "].");
+      }
+      throwSyntaxError("Function name expected after keyword 'function'.");
     }
   }
   //
@@ -2119,7 +1583,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     //variable-reference
     if (token == TokenNameAND) {
       getNextToken();
-      if (token == TokenNameVariable) {
+      if (isVariable()) {
         getNextToken();
       } else {
         throwSyntaxError("Variable expected after reference operator '&'.");
@@ -2134,6 +1598,9 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
       }
       return;
     }
+    if (token == TokenNamethis) {
+      throwSyntaxError("Reserved word '$this' not allowed in parameter declaration.");
+    }
   }
 
   private void labeledStatementList() throws CoreException {
@@ -2143,11 +1610,10 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     do {
       if (token == TokenNamecase) {
         getNextToken();
-        constant();
+        expression(); //constant();
         if (token == TokenNameCOLON) {
           getNextToken();
-          if (token == TokenNamecase
-            || token == TokenNamedefault) { // empty case statement ?
+          if (token == TokenNamecase || token == TokenNamedefault) { // empty case statement ?
             continue;
           }
           statementList();
@@ -2159,9 +1625,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           //            rowCount,
           //            PHPParser.INFO);
           setMarker(
-            "':' expected after 'case' keyword (Found token: "
-              + scanner.toStringAction(token)
-              + ")",
+            "':' expected after 'case' keyword (Found token: " + scanner.toStringAction(token) + ")",
             scanner.getCurrentTokenStartPosition(),
             scanner.getCurrentTokenEndPosition(),
             INFO);
@@ -2171,10 +1635,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           }
           statementList();
         } else {
-          throwSyntaxError(
-            "':' character after 'case' constant expected (Found token: "
-              + scanner.toStringAction(token)
-              + ")");
+          throwSyntaxError("':' character after 'case' constant expected (Found token: " + scanner.toStringAction(token) + ")");
         }
       } else { // TokenNamedefault
         getNextToken();
@@ -2245,26 +1706,30 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     // ':' statement-list [elseif-list] [else-colon-statement] 'endif' ';'
     if (token == TokenNameCOLON) {
       getNextToken();
-      statementList();
-      switch (token) {
-        case TokenNameelse :
-          getNextToken();
-          if (token == TokenNameCOLON) {
+      if (token != TokenNameendif) {
+        statementList();
+        switch (token) {
+          case TokenNameelse :
             getNextToken();
-            statementList();
-          } else {
-            if (token == TokenNameif) { //'else if'
+            if (token == TokenNameCOLON) {
               getNextToken();
-              elseifStatementList();
+              if (token != TokenNameendif) {
+                statementList();
+              }
             } else {
-              throwSyntaxError("':' expected after 'else'.");
+              if (token == TokenNameif) { //'else if'
+                getNextToken();
+                elseifStatementList();
+              } else {
+                throwSyntaxError("':' expected after 'else'.");
+              }
             }
-          }
-          break;
-        case TokenNameelseif :
-          getNextToken();
-          elseifStatementList();
-          break;
+            break;
+          case TokenNameelseif :
+            getNextToken();
+            elseifStatementList();
+            break;
+        }
       }
 
       if (token != TokenNameendif) {
@@ -2277,7 +1742,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
       getNextToken();
     } else {
       // statement [else-statement]
-      statement();
+      statement(TokenNameEOF);
       if (token == TokenNameelseif) {
         getNextToken();
         if (token == TokenNameLPAREN) {
@@ -2294,7 +1759,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
         ifStatement();
       } else if (token == TokenNameelse) {
         getNextToken();
-        statement();
+        statement(TokenNameEOF);
       }
     }
   }
@@ -2307,7 +1772,9 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           getNextToken();
           if (token == TokenNameCOLON) {
             getNextToken();
-            statementList();
+            if (token != TokenNameendif) {
+              statementList();
+            }
             return;
           } else {
             if (token == TokenNameif) { //'else if'
@@ -2330,7 +1797,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     if (token == TokenNameLPAREN) {
       getNextToken();
       expression();
-      if (token != TokenNameLPAREN) {
+      if (token != TokenNameRPAREN) {
         throwSyntaxError("')' expected in else-if-statement.");
       }
       getNextToken();
@@ -2338,7 +1805,9 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
         throwSyntaxError("':' expected in else-if-statement.");
       }
       getNextToken();
-      statementList();
+      if (token != TokenNameendif) {
+        statementList();
+      }
     }
   }
 
@@ -2385,7 +1854,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
       }
       getNextToken();
     } else {
-      statement();
+      statement(TokenNameEOF);
     }
   }
 
@@ -2403,7 +1872,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
       }
       getNextToken();
     } else {
-      statement();
+      statement(TokenNameEOF);
     }
   }
 
@@ -2420,7 +1889,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
       }
       getNextToken();
     } else {
-      statement();
+      statement(TokenNameEOF);
     }
   }
 
@@ -2453,14 +1922,14 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
 
   private void expression() throws CoreException {
     //todo: find a better way to get the expression
-//    expression = new StringBuffer();
-//    for (int i = chIndx; i < str.length(); i++) {
-//      if (str.charAt(i) == ';') {
-//        break;
-//      }
-//      expression.append(str.charAt(i));
-//    }
-    
+    //    expression = new StringBuffer();
+    //    for (int i = chIndx; i < str.length(); i++) {
+    //      if (str.charAt(i) == ';') {
+    //        break;
+    //      }
+    //      expression.append(str.charAt(i));
+    //    }
+
     //    if (token == TokenNameSTRING_CONSTANT || token == TokenNameINTERPOLATED_STRING) {
     //      getNextToken();
     //    } else {
@@ -2475,6 +1944,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     // String ident;
     char[] ident;
     boolean castFlag = false;
+    boolean arrayFlag = false;
     switch (token) {
       case TokenNamenew :
         getNextToken();
@@ -2499,6 +1969,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
         break;
       case TokenNameLPAREN :
         getNextToken();
+
         if (token == TokenNameIdentifier) {
           // check if identifier is a type:
           //   ident = identifier;
@@ -2507,20 +1978,34 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           for (int i = 0; i < PHP_TYPES.length; i++) {
             if (PHP_TYPES[i].equals(str)) {
               castFlag = true;
+              if (PHP_TYPES[i].equals("array")) {
+                arrayFlag = true;
+              }
               break;
             }
           }
-          if (castFlag) {
+        }
+
+        if (castFlag) {
+          getNextToken();
+          if (arrayFlag && token == TokenNameLPAREN) {
             getNextToken();
-            if (token != TokenNameRPAREN) {
-              throwSyntaxError(") expected after cast-type '" + str + "'.");
+            if (token == TokenNameRPAREN) {
+              getNextToken();
+            } else {
+              expression();
+              if (token != TokenNameRPAREN) {
+                throwSyntaxError(") expected after 'array('.");
+              }
             }
-            getNextToken();
-            expression();
-            break;
           }
-        }
-        if (!castFlag) {
+          if (token != TokenNameRPAREN) {
+            throwSyntaxError(") expected after cast-type '" + str + "'.");
+          }
+          getNextToken();
+          expression();
+          break;
+        } else {
           expression();
         }
         if (token != TokenNameRPAREN) {
@@ -2543,16 +2028,14 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
         getNextToken();
         break;
       case TokenNameVariable :
+      case TokenNamethis :
         ident = scanner.getCurrentIdentifierSource();
         getNextToken();
         if (token == TokenNameLBRACE) {
           getNextToken();
           expression();
           if (token != TokenNameRBRACE) {
-            throwSyntaxError(
-              "'}' expected after variable '"
-                + new String(ident)
-                + "' in variable-expression.");
+            throwSyntaxError("'}' expected after variable '" + new String(ident) + "' in variable-expression.");
           }
           getNextToken();
         } else if (token == TokenNameLPAREN) {
@@ -2560,10 +2043,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           if (token != TokenNameRPAREN) {
             expressionList();
             if (token != TokenNameRPAREN) {
-              throwSyntaxError(
-                "')' expected after variable '"
-                  + new String(ident)
-                  + "' in postfix-expression.");
+              throwSyntaxError("')' expected after variable '" + new String(ident) + "' in postfix-expression.");
             }
           }
           getNextToken();
@@ -2578,12 +2058,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
             expressionList();
             if (token != TokenNameRPAREN) {
               throwSyntaxError(
-                "')' expected after identifier '"
-                  + new String(ident)
-                  + "' in postfix-expression."
-                  + "(Found token: "
-                  + scanner.toStringAction(token)
-                  + ")");
+                "')' expected after identifier '" + new String(ident) + "' in postfix-expression." + "(Found token: " + scanner.toStringAction(token) + ")");
             }
           }
           getNextToken();
@@ -2693,9 +2168,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
             //              rowCount,
             //              PHPParser.INFO);
             setMarker(
-              "Avoid using keyword '"
-                + new String(ident)
-                + "' as variable name.",
+              "Avoid using keyword '" + new String(ident) + "' as variable name.",
               scanner.getCurrentTokenStartPosition(),
               scanner.getCurrentTokenEndPosition(),
               INFO);
@@ -2727,10 +2200,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
               break;
             default :
               throwSyntaxError("Syntax error after '->' token.");
-          } while (
-            token == TokenNameLBRACKET
-              || token == TokenNameLPAREN
-              || token == TokenNameLBRACE) {
+          } while (token == TokenNameLBRACKET || token == TokenNameLPAREN || token == TokenNameLBRACE) {
               if (token == TokenNameLBRACKET) {
                 getNextToken();
                 expressionList();
@@ -2738,16 +2208,14 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
                   throwSyntaxError("] expected after '->'.");
                 }
                 getNextToken();
-              }
-              if (token == TokenNameLPAREN) {
+              } else if (token == TokenNameLPAREN) {
                 getNextToken();
                 expressionList();
                 if (token != TokenNameRPAREN) {
                   throwSyntaxError(") expected after '->'.");
                 }
                 getNextToken();
-              }
-              if (token == TokenNameLBRACE) {
+              } else if (token == TokenNameLBRACE) {
                 getNextToken();
                 expression();
                 if (token != TokenNameRBRACE) {
@@ -2784,7 +2252,11 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
         // '@' '&' '*' '+' '-' '~' '!'
       case TokenNameAT :
         getNextToken();
-        castExpression();
+        if (token == TokenNameinclude || token == TokenNameinclude_once || token == TokenNamerequire || token == TokenNamerequire_once) {
+          statement(TokenNameAT);
+        } else {
+          postfixExpression(); //  castExpression();
+        }
         break;
       case TokenNameAND :
         getNextToken();
@@ -2827,27 +2299,6 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     unaryExpression();
   }
 
-  private void typeName() throws CoreException {
-    //'string' 'unset' 'array' 'object'
-    //'bool' 'boolean'
-    //'real' 'double' 'float'
-    //'int' 'integer'
-    String identifier = "";
-    if (token == TokenNameIdentifier) {
-      char[] ident = scanner.getCurrentIdentifierSource();
-      identifier = new String(ident);
-      String str = identifier.toLowerCase();
-      getNextToken();
-      for (int i = 0; i < PHP_TYPES.length; i++) {
-        if (PHP_TYPES[i].equals(str)) {
-          return;
-        }
-      }
-    }
-    throwSyntaxError(
-      "Expected type cast '( <type-name> )'; Got '" + identifier + "'.");
-  }
-
   private void assignExpression() throws CoreException {
     castExpression();
     if (token == TokenNameEQUAL) { // =
@@ -2898,9 +2349,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   private void multiplicativeExpression() throws CoreException {
     do {
       assignExpression();
-      if (token != TokenNameMULTIPLY
-        && token != TokenNameDIVIDE
-        && token != TokenNameREMAINDER) {
+      if (token != TokenNameMULTIPLY && token != TokenNameDIVIDE && token != TokenNameREMAINDER) {
         return;
       }
       getNextToken();
@@ -2940,10 +2389,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   private void relationalExpression() throws CoreException {
     do {
       shiftExpression();
-      if (token != TokenNameLESS
-        && token != TokenNameGREATER
-        && token != TokenNameLESS_EQUAL
-        && token != TokenNameGREATER_EQUAL) {
+      if (token != TokenNameLESS && token != TokenNameGREATER && token != TokenNameLESS_EQUAL && token != TokenNameGREATER_EQUAL) {
         return;
       }
       getNextToken();
@@ -2953,8 +2399,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
   private void identicalExpression() throws CoreException {
     do {
       relationalExpression();
-      if (token != TokenNameEQUAL_EQUAL_EQUAL
-        && token != TokenNameNOT_EQUAL_EQUAL) {
+      if (token != TokenNameEQUAL_EQUAL_EQUAL && token != TokenNameNOT_EQUAL_EQUAL) {
         return;
       }
       getNextToken();
@@ -3168,10 +2613,7 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
           if (token != TokenNameRPAREN) {
             expressionList();
             if (token != TokenNameRPAREN) {
-              throwSyntaxError(
-                "')' expected after identifier '"
-                  + new String(ident)
-                  + "' in postfix-expression.");
+              throwSyntaxError("')' expected after identifier '" + new String(ident) + "' in postfix-expression.");
             }
           }
           getNextToken();
@@ -3197,4 +2639,546 @@ public class Parser extends PHPParserSuperclass implements PHPKeywords, ITermina
     }
   }
 
+  public void reportSyntaxError() { //int act, int currentKind, int stateStackTop) {
+
+    /* remember current scanner position */
+    int startPos = scanner.startPosition;
+    int currentPos = scanner.currentPosition;
+
+    //         String[] expectings;
+    //         String tokenName = name[symbol_index[currentKind]];
+
+    //fetch all "accurate" possible terminals that could recover the error
+    //         int start, end = start = asi(stack[stateStackTop]);
+    //         while (asr[end] != 0)
+    //                 end++;
+    //         int length = end - start;
+    //         expectings = new String[length];
+    //         if (length != 0) {
+    //                 char[] indexes = new char[length];
+    //                 System.arraycopy(asr, start, indexes, 0, length);
+    //                 for (int i = 0; i < length; i++) {
+    //                         expectings[i] = name[symbol_index[indexes[i]]];
+    //                 }
+    //         }
+
+    //if the pb is an EOF, try to tell the user that they are some 
+    //         if (tokenName.equals(UNEXPECTED_EOF)) {
+    //                 if (!this.checkAndReportBracketAnomalies(problemReporter())) {
+    //                         char[] tokenSource;
+    //                         try {
+    //                                 tokenSource = this.scanner.getCurrentTokenSource();
+    //                         } catch (Exception e) {
+    //                                 tokenSource = new char[] {};
+    //                         }
+    //                         problemReporter().parseError(
+    //                                 this.scanner.startPosition, 
+    //                                 this.scanner.currentPosition - 1, 
+    //                                 tokenSource, 
+    //                                 tokenName, 
+    //                                 expectings); 
+    //                 }
+    //         } else { //the next test is HEAVILY grammar DEPENDENT.
+    //                 if ((length == 14)
+    //                         && (expectings[0] == "=") //$NON-NLS-1$
+    //                         && (expectings[1] == "*=") //$NON-NLS-1$
+    //                         && (expressionPtr > -1)) {
+    //                                 switch(currentKind) {
+    //                                         case TokenNameSEMICOLON:
+    //                                         case TokenNamePLUS:
+    //                                         case TokenNameMINUS:
+    //                                         case TokenNameDIVIDE:
+    //                                         case TokenNameREMAINDER:
+    //                                         case TokenNameMULTIPLY:
+    //                                         case TokenNameLEFT_SHIFT:
+    //                                         case TokenNameRIGHT_SHIFT:
+    ////                                               case TokenNameUNSIGNED_RIGHT_SHIFT:
+    //                                         case TokenNameLESS:
+    //                                         case TokenNameGREATER:
+    //                                         case TokenNameLESS_EQUAL:
+    //                                         case TokenNameGREATER_EQUAL:
+    //                                         case TokenNameEQUAL_EQUAL:
+    //                                         case TokenNameNOT_EQUAL:
+    //                                         case TokenNameXOR:
+    //                                         case TokenNameAND:
+    //                                         case TokenNameOR:
+    //                                         case TokenNameOR_OR:
+    //                                         case TokenNameAND_AND:
+    //                                                 // the ; is not the expected token ==> it ends a statement when an expression is not ended
+    //                                                 problemReporter().invalidExpressionAsStatement(expressionStack[expressionPtr]);
+    //                                                 break;
+    //                                         case TokenNameRBRACE :
+    //                                                 problemReporter().missingSemiColon(expressionStack[expressionPtr]);
+    //                                                 break;
+    //                                         default:
+    //                                                 char[] tokenSource;
+    //                                                 try {
+    //                                                         tokenSource = this.scanner.getCurrentTokenSource();
+    //                                                 } catch (Exception e) {
+    //                                                         tokenSource = new char[] {};
+    //                                                 }
+    //                                                 problemReporter().parseError(
+    //                                                         this.scanner.startPosition, 
+    //                                                         this.scanner.currentPosition - 1, 
+    //                                                         tokenSource, 
+    //                                                         tokenName, 
+    //                                                         expectings); 
+    //                                                 this.checkAndReportBracketAnomalies(problemReporter());
+    //                                 }
+    //                 } else {
+    char[] tokenSource;
+    try {
+      tokenSource = this.scanner.getCurrentTokenSource();
+    } catch (Exception e) {
+      tokenSource = new char[] {
+      };
+    }
+    //                         problemReporter().parseError(
+    //                                 this.scanner.startPosition, 
+    //                                 this.scanner.currentPosition - 1, 
+    //                                 tokenSource, 
+    //                                 tokenName, 
+    //                                 expectings); 
+    this.checkAndReportBracketAnomalies(problemReporter());
+    //                 }
+    //         }
+    /* reset scanner where it was */
+    scanner.startPosition = startPos;
+    scanner.currentPosition = currentPos;
+  }
+  public static final int RoundBracket = 0;
+  public static final int SquareBracket = 1;
+  public static final int CurlyBracket = 2;
+  public static final int BracketKinds = 3;
+
+  protected int[] nestedMethod; //the ptr is nestedType
+  protected int nestedType, dimensions;
+  //ast stack
+  final static int AstStackIncrement = 100;
+  protected int astPtr;
+  protected AstNode[] astStack = new AstNode[AstStackIncrement];
+  protected int astLengthPtr;
+  protected int[] astLengthStack;
+  AstNode[] noAstNodes = new AstNode[AstStackIncrement];
+
+  public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/
+  protected ReferenceContext referenceContext;
+  protected ProblemReporter problemReporter;
+  //  protected CompilationResult compilationResult;
+
+  /**
+   * Returns this parser's problem reporter initialized with its reference context.
+   * Also it is assumed that a problem is going to be reported, so initializes
+   * the compilation result's line positions.
+   */
+  public ProblemReporter problemReporter() {
+    if (scanner.recordLineSeparator) {
+      compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
+    }
+    problemReporter.referenceContext = referenceContext;
+    return problemReporter;
+  }
+  /*
+   * Reconsider the entire source looking for inconsistencies in {} () []
+   */
+  public boolean checkAndReportBracketAnomalies(ProblemReporter problemReporter) {
+
+    scanner.wasAcr = false;
+    boolean anomaliesDetected = false;
+    try {
+      char[] source = scanner.source;
+      int[] leftCount = { 0, 0, 0 };
+      int[] rightCount = { 0, 0, 0 };
+      int[] depths = { 0, 0, 0 };
+      int[][] leftPositions = new int[][] { new int[10], new int[10], new int[10] };
+      int[][] leftDepths = new int[][] { new int[10], new int[10], new int[10] };
+      int[][] rightPositions = new int[][] { new int[10], new int[10], new int[10] };
+      int[][] rightDepths = new int[][] { new int[10], new int[10], new int[10] };
+      scanner.currentPosition = scanner.initialPosition; //starting point (first-zero-based char)
+      while (scanner.currentPosition < scanner.eofPosition) { //loop for jumping over comments
+        try {
+          // ---------Consume white space and handles startPosition---------
+          boolean isWhiteSpace;
+          do {
+            scanner.startPosition = scanner.currentPosition;
+            //                                         if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
+            //                                                 isWhiteSpace = scanner.jumpOverUnicodeWhiteSpace();
+            //                                         } else {
+            if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
+              if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
+                // only record line positions we have not recorded yet
+                scanner.pushLineSeparator();
+              }
+            }
+            isWhiteSpace = CharOperation.isWhitespace(scanner.currentCharacter);
+            //                                         }
+          } while (isWhiteSpace && (scanner.currentPosition < scanner.eofPosition));
+
+          // -------consume token until } is found---------
+
+          switch (scanner.currentCharacter) {
+            case '{' :
+              {
+                int index = leftCount[CurlyBracket]++;
+                if (index == leftPositions[CurlyBracket].length) {
+                  System.arraycopy(leftPositions[CurlyBracket], 0, (leftPositions[CurlyBracket] = new int[index * 2]), 0, index);
+                  System.arraycopy(leftDepths[CurlyBracket], 0, (leftDepths[CurlyBracket] = new int[index * 2]), 0, index);
+                }
+                leftPositions[CurlyBracket][index] = scanner.startPosition;
+                leftDepths[CurlyBracket][index] = depths[CurlyBracket]++;
+              }
+              break;
+            case '}' :
+              {
+                int index = rightCount[CurlyBracket]++;
+                if (index == rightPositions[CurlyBracket].length) {
+                  System.arraycopy(rightPositions[CurlyBracket], 0, (rightPositions[CurlyBracket] = new int[index * 2]), 0, index);
+                  System.arraycopy(rightDepths[CurlyBracket], 0, (rightDepths[CurlyBracket] = new int[index * 2]), 0, index);
+                }
+                rightPositions[CurlyBracket][index] = scanner.startPosition;
+                rightDepths[CurlyBracket][index] = --depths[CurlyBracket];
+              }
+              break;
+            case '(' :
+              {
+                int index = leftCount[RoundBracket]++;
+                if (index == leftPositions[RoundBracket].length) {
+                  System.arraycopy(leftPositions[RoundBracket], 0, (leftPositions[RoundBracket] = new int[index * 2]), 0, index);
+                  System.arraycopy(leftDepths[RoundBracket], 0, (leftDepths[RoundBracket] = new int[index * 2]), 0, index);
+                }
+                leftPositions[RoundBracket][index] = scanner.startPosition;
+                leftDepths[RoundBracket][index] = depths[RoundBracket]++;
+              }
+              break;
+            case ')' :
+              {
+                int index = rightCount[RoundBracket]++;
+                if (index == rightPositions[RoundBracket].length) {
+                  System.arraycopy(rightPositions[RoundBracket], 0, (rightPositions[RoundBracket] = new int[index * 2]), 0, index);
+                  System.arraycopy(rightDepths[RoundBracket], 0, (rightDepths[RoundBracket] = new int[index * 2]), 0, index);
+                }
+                rightPositions[RoundBracket][index] = scanner.startPosition;
+                rightDepths[RoundBracket][index] = --depths[RoundBracket];
+              }
+              break;
+            case '[' :
+              {
+                int index = leftCount[SquareBracket]++;
+                if (index == leftPositions[SquareBracket].length) {
+                  System.arraycopy(leftPositions[SquareBracket], 0, (leftPositions[SquareBracket] = new int[index * 2]), 0, index);
+                  System.arraycopy(leftDepths[SquareBracket], 0, (leftDepths[SquareBracket] = new int[index * 2]), 0, index);
+                }
+                leftPositions[SquareBracket][index] = scanner.startPosition;
+                leftDepths[SquareBracket][index] = depths[SquareBracket]++;
+              }
+              break;
+            case ']' :
+              {
+                int index = rightCount[SquareBracket]++;
+                if (index == rightPositions[SquareBracket].length) {
+                  System.arraycopy(rightPositions[SquareBracket], 0, (rightPositions[SquareBracket] = new int[index * 2]), 0, index);
+                  System.arraycopy(rightDepths[SquareBracket], 0, (rightDepths[SquareBracket] = new int[index * 2]), 0, index);
+                }
+                rightPositions[SquareBracket][index] = scanner.startPosition;
+                rightDepths[SquareBracket][index] = --depths[SquareBracket];
+              }
+              break;
+            case '\'' :
+              {
+                if (scanner.getNextChar('\\')) {
+                  scanner.scanEscapeCharacter();
+                } else { // consume next character
+                  scanner.unicodeAsBackSlash = false;
+                  //                                                                   if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
+                  //                                                                           scanner.getNextUnicodeChar();
+                  //                                                                   } else {
+                  if (scanner.withoutUnicodePtr != 0) {
+                    scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
+                  }
+                  //                                                                   }
+                }
+                scanner.getNextChar('\'');
+                break;
+              }
+            case '"' : // consume next character
+              scanner.unicodeAsBackSlash = false;
+              //                                                       if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
+              //                                                               scanner.getNextUnicodeChar();
+              //                                                       } else {
+              if (scanner.withoutUnicodePtr != 0) {
+                scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
+              }
+              //                                                       }
+              while (scanner.currentCharacter != '"') {
+                if (scanner.currentCharacter == '\r') {
+                  if (source[scanner.currentPosition] == '\n')
+                    scanner.currentPosition++;
+                  break; // the string cannot go further that the line
+                }
+                if (scanner.currentCharacter == '\n') {
+                  break; // the string cannot go further that the line
+                }
+                if (scanner.currentCharacter == '\\') {
+                  scanner.scanEscapeCharacter();
+                }
+                // consume next character
+                scanner.unicodeAsBackSlash = false;
+                //                                                             if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
+                //                                                                     scanner.getNextUnicodeChar();
+                //                                                             } else {
+                if (scanner.withoutUnicodePtr != 0) {
+                  scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
+                }
+                //                                                             }
+              }
+              break;
+            case '/' :
+              {
+                int test;
+                if ((test = scanner.getNextChar('/', '*')) == 0) { //line comment 
+                  //get the next char 
+                  if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
+                    //-------------unicode traitement ------------
+                    int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+                    scanner.currentPosition++;
+                    while (source[scanner.currentPosition] == 'u') {
+                      scanner.currentPosition++;
+                    }
+                    if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                      || c1 < 0
+                      || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                      || c2 < 0
+                      || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                      || c3 < 0
+                      || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                      || c4 < 0) { //error don't care of the value
+                      scanner.currentCharacter = 'A';
+                    } //something different from \n and \r
+                    else {
+                      scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+                    }
+                  }
+                  while (scanner.currentCharacter != '\r' && scanner.currentCharacter != '\n') {
+                    //get the next char
+                    scanner.startPosition = scanner.currentPosition;
+                    if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
+                      //-------------unicode traitement ------------
+                      int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+                      scanner.currentPosition++;
+                      while (source[scanner.currentPosition] == 'u') {
+                        scanner.currentPosition++;
+                      }
+                      if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                        || c1 < 0
+                        || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                        || c2 < 0
+                        || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                        || c3 < 0
+                        || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                        || c4 < 0) { //error don't care of the value
+                        scanner.currentCharacter = 'A';
+                      } //something different from \n and \r
+                      else {
+                        scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+                      }
+                    }
+                  }
+                  if (scanner.recordLineSeparator && ((scanner.currentCharacter == '\r') || (scanner.currentCharacter == '\n'))) {
+                    if (scanner.lineEnds[scanner.linePtr] < scanner.startPosition) {
+                      // only record line positions we have not recorded yet
+                      scanner.pushLineSeparator();
+                      if (this.scanner.taskTags != null) {
+                        this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
+                      }
+                    }
+                  }
+                  break;
+                }
+                if (test > 0) { //traditional and annotation comment
+                  boolean star = false;
+                  // consume next character
+                  scanner.unicodeAsBackSlash = false;
+                  //                                                                   if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
+                  //                                                                           scanner.getNextUnicodeChar();
+                  //                                                                   } else {
+                  if (scanner.withoutUnicodePtr != 0) {
+                    scanner.withoutUnicodeBuffer[++scanner.withoutUnicodePtr] = scanner.currentCharacter;
+                  }
+                  //                                                                   }
+                  if (scanner.currentCharacter == '*') {
+                    star = true;
+                  }
+                  //get the next char 
+                  if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
+                    //-------------unicode traitement ------------
+                    int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+                    scanner.currentPosition++;
+                    while (source[scanner.currentPosition] == 'u') {
+                      scanner.currentPosition++;
+                    }
+                    if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                      || c1 < 0
+                      || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                      || c2 < 0
+                      || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                      || c3 < 0
+                      || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                      || c4 < 0) { //error don't care of the value
+                      scanner.currentCharacter = 'A';
+                    } //something different from * and /
+                    else {
+                      scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+                    }
+                  }
+                  //loop until end of comment */ 
+                  while ((scanner.currentCharacter != '/') || (!star)) {
+                    star = scanner.currentCharacter == '*';
+                    //get next char
+                    if (((scanner.currentCharacter = source[scanner.currentPosition++]) == '\\') && (source[scanner.currentPosition] == 'u')) {
+                      //-------------unicode traitement ------------
+                      int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+                      scanner.currentPosition++;
+                      while (source[scanner.currentPosition] == 'u') {
+                        scanner.currentPosition++;
+                      }
+                      if ((c1 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                        || c1 < 0
+                        || (c2 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                        || c2 < 0
+                        || (c3 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                        || c3 < 0
+                        || (c4 = Character.getNumericValue(source[scanner.currentPosition++])) > 15
+                        || c4 < 0) { //error don't care of the value
+                        scanner.currentCharacter = 'A';
+                      } //something different from * and /
+                      else {
+                        scanner.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+                      }
+                    }
+                  }
+                  if (this.scanner.taskTags != null) {
+                    this.scanner.checkTaskTag(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
+                  }
+                  break;
+                }
+                break;
+              }
+            default :
+              if (Scanner.isPHPIdentifierStart(scanner.currentCharacter)) {
+                scanner.scanIdentifierOrKeyword(false);
+                break;
+              }
+              if (Character.isDigit(scanner.currentCharacter)) {
+                scanner.scanNumber(false);
+                break;
+              }
+          }
+          //-----------------end switch while try--------------------
+        } catch (IndexOutOfBoundsException e) {
+          break; // read until EOF
+        } catch (InvalidInputException e) {
+          return false; // no clue
+        }
+      }
+      if (scanner.recordLineSeparator) {
+        //                             compilationUnit.compilationResult.lineSeparatorPositions = scanner.getLineEnds();
+      }
+
+      // check placement anomalies against other kinds of brackets
+      for (int kind = 0; kind < BracketKinds; kind++) {
+        for (int leftIndex = leftCount[kind] - 1; leftIndex >= 0; leftIndex--) {
+          int start = leftPositions[kind][leftIndex]; // deepest first
+          // find matching closing bracket
+          int depth = leftDepths[kind][leftIndex];
+          int end = -1;
+          for (int i = 0; i < rightCount[kind]; i++) {
+            int pos = rightPositions[kind][i];
+            // want matching bracket further in source with same depth
+            if ((pos > start) && (depth == rightDepths[kind][i])) {
+              end = pos;
+              break;
+            }
+          }
+          if (end < 0) { // did not find a good closing match
+            problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult);
+            return true;
+          }
+          // check if even number of opening/closing other brackets in between this pair of brackets
+          int balance = 0;
+          for (int otherKind = 0;(balance == 0) && (otherKind < BracketKinds); otherKind++) {
+            for (int i = 0; i < leftCount[otherKind]; i++) {
+              int pos = leftPositions[otherKind][i];
+              if ((pos > start) && (pos < end))
+                balance++;
+            }
+            for (int i = 0; i < rightCount[otherKind]; i++) {
+              int pos = rightPositions[otherKind][i];
+              if ((pos > start) && (pos < end))
+                balance--;
+            }
+            if (balance != 0) {
+              problemReporter.unmatchedBracket(start, referenceContext, compilationUnit.compilationResult); //bracket anomaly
+              return true;
+            }
+          }
+        }
+        // too many opening brackets ?
+        for (int i = rightCount[kind]; i < leftCount[kind]; i++) {
+          anomaliesDetected = true;
+          problemReporter.unmatchedBracket(leftPositions[kind][leftCount[kind] - i - 1], referenceContext, compilationUnit.compilationResult);
+        }
+        // too many closing brackets ?
+        for (int i = leftCount[kind]; i < rightCount[kind]; i++) {
+          anomaliesDetected = true;
+          problemReporter.unmatchedBracket(rightPositions[kind][i], referenceContext, compilationUnit.compilationResult);
+        }
+        if (anomaliesDetected)
+          return true;
+      }
+
+      return anomaliesDetected;
+    } catch (ArrayStoreException e) { // jdk1.2.2 jit bug
+      return anomaliesDetected;
+    } catch (NullPointerException e) { // jdk1.2.2 jit bug
+      return anomaliesDetected;
+    }
+  }
+
+  protected void pushOnAstLengthStack(int pos) {
+    try {
+      astLengthStack[++astLengthPtr] = pos;
+    } catch (IndexOutOfBoundsException e) {
+      int oldStackLength = astLengthStack.length;
+      int[] oldPos = astLengthStack;
+      astLengthStack = new int[oldStackLength + StackIncrement];
+      System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
+      astLengthStack[astLengthPtr] = pos;
+    }
+  }
+
+  protected void pushOnAstStack(AstNode node) {
+    /*add a new obj on top of the ast stack
+    astPtr points on the top*/
+
+    try {
+      astStack[++astPtr] = node;
+    } catch (IndexOutOfBoundsException e) {
+      int oldStackLength = astStack.length;
+      AstNode[] oldStack = astStack;
+      astStack = new AstNode[oldStackLength + AstStackIncrement];
+      System.arraycopy(oldStack, 0, astStack, 0, oldStackLength);
+      astPtr = oldStackLength;
+      astStack[astPtr] = node;
+    }
+
+    try {
+      astLengthStack[++astLengthPtr] = 1;
+    } catch (IndexOutOfBoundsException e) {
+      int oldStackLength = astLengthStack.length;
+      int[] oldPos = astLengthStack;
+      astLengthStack = new int[oldStackLength + AstStackIncrement];
+      System.arraycopy(oldPos, 0, astLengthStack, 0, oldStackLength);
+      astLengthStack[astLengthPtr] = 1;
+    }
+  }
 }
\ No newline at end of file