misc changes
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Scanner.java
index 1ae5d16..8a7179b 100644 (file)
@@ -12,6 +12,7 @@ package net.sourceforge.phpdt.internal.compiler.parser;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Stack;
 import net.sourceforge.phpdt.core.compiler.CharOperation;
 import net.sourceforge.phpdt.core.compiler.IScanner;
 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
@@ -32,6 +33,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
   public boolean containsAssertKeyword = false;
   public boolean recordLineSeparator;
   public boolean phpMode = false;
+  public Stack encapsedStringStack = null;
   public char currentCharacter;
   public int startPosition;
   public int currentPosition;
@@ -129,7 +131,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
   public int[][] foundTaskPositions;
   public int foundTaskCount = 0;
   public char[][] taskTags = null;
-  public char[][] taskPriorities = null;
+  public char[][] taskPriorities = null; 
   public static final boolean DEBUG = false;
   public static final boolean TRACE = false;
   public Scanner() {
@@ -815,13 +817,135 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return currentPosition > source.length ? TokenNameEOF : TokenNameRBRACE;
       }
       try {
-        while (true) { //loop for jumping over comments
+        while (true) {
           withoutUnicodePtr = 0;
-          //start with a new token (even comment written with unicode )
+          //start with a new token
+          char encapsedChar = ' ';
+          if (!encapsedStringStack.isEmpty()) {
+            encapsedChar = ((Character) encapsedStringStack.peek()).charValue();
+          }
+          if (encapsedChar != '$' && encapsedChar != ' ') {
+            currentCharacter = source[currentPosition++];
+            if (currentCharacter == encapsedChar) {
+              switch (currentCharacter) {
+                case '`' :
+                  return TokenNameEncapsedString0;
+                case '\'' :
+                  return TokenNameEncapsedString1;
+                case '"' :
+                  return TokenNameEncapsedString2;
+              }
+            }
+            while (currentCharacter != encapsedChar) {
+              /** ** in PHP \r and \n are valid in string literals *** */
+              switch (currentCharacter) {
+                case '\\' :
+                  int escapeSize = currentPosition;
+                  boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
+                  //scanEscapeCharacter make a side effect on this value and
+                  // we need the previous value few lines down this one
+                  scanDoubleQuotedEscapeCharacter();
+                  escapeSize = currentPosition - escapeSize;
+                  if (withoutUnicodePtr == 0) {
+                    //buffer all the entries that have been left aside....
+                    withoutUnicodePtr = currentPosition - escapeSize - 1
+                        - startPosition;
+                    System.arraycopy(source, startPosition,
+                        withoutUnicodeBuffer, 1, withoutUnicodePtr);
+                    withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
+                  } else { //overwrite the / in the buffer
+                    withoutUnicodeBuffer[withoutUnicodePtr] = currentCharacter;
+                    if (backSlashAsUnicodeInString) { //there are TWO \ in
+                      withoutUnicodePtr--;
+                    }
+                  }
+                  break;
+                case '$' :
+                  if (isPHPIdentifierStart(source[currentPosition])
+                      || source[currentPosition] == '{') {
+                    currentPosition--;
+                    encapsedStringStack.push(new Character('$'));
+                    return TokenNameSTRING;
+                  }
+                  break;
+                case '{' :
+                  if (source[currentPosition] == '$') { // CURLY_OPEN
+                    currentPosition--;
+                    encapsedStringStack.push(new Character('$'));
+                    return TokenNameSTRING;
+                  }
+              }
+              // consume next character
+              unicodeAsBackSlash = false;
+              currentCharacter = source[currentPosition++];
+              if (withoutUnicodePtr != 0) {
+                withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
+              }
+              //                  }
+            } // end while
+            currentPosition--;
+            return TokenNameSTRING;
+          }
           // ---------Consume white space and handles startPosition---------
           int whiteStart = currentPosition;
-          boolean isWhiteSpace;
-          do {
+          startPosition = currentPosition;
+          currentCharacter = source[currentPosition++];
+          if (encapsedChar == '$') {
+            switch (currentCharacter) {
+              case '\\' :
+                currentCharacter = source[currentPosition++];
+                return TokenNameSTRING;
+              case '{' :
+                if (encapsedChar == '$') {
+                  if (getNextChar('$'))
+                    return TokenNameCURLY_OPEN;
+                }
+                return TokenNameLBRACE;
+              case '}' :
+                return TokenNameRBRACE;
+              case '[' :
+                return TokenNameLBRACKET;
+              case ']' :
+                return TokenNameRBRACKET;
+              case '\'' :
+                return TokenNameEncapsedString1;
+              case '"' :
+                return TokenNameEncapsedString2;
+              case '`' :
+                return TokenNameEncapsedString0;
+              case '-' :
+                if (getNextChar('>'))
+                  return TokenNameMINUS_GREATER;
+                return TokenNameSTRING;
+              default :
+                if (currentCharacter == '$') {
+                  int oldPosition = currentPosition;
+                  try {
+                    currentCharacter = source[currentPosition++];
+                    if (currentCharacter == '{') {
+                      return TokenNameDOLLAR_LBRACE;
+                    }
+                    if (isPHPIdentifierStart(currentCharacter)) {
+                      return scanIdentifierOrKeyword(true);
+                    } else {
+                      currentPosition = oldPosition;
+                      return TokenNameSTRING;
+                    }
+                  } catch (IndexOutOfBoundsException e) {
+                    currentPosition = oldPosition;
+                    return TokenNameSTRING;
+                  }
+                }
+                if (isPHPIdentifierStart(currentCharacter))
+                  return scanIdentifierOrKeyword(false);
+                if (Character.isDigit(currentCharacter))
+                  return scanNumber(false);
+                return TokenNameERROR;
+            }
+          }
+//          boolean isWhiteSpace;
+          while ((currentCharacter == ' ')
+                  || Character.isWhitespace(currentCharacter)) {
             startPosition = currentPosition;
             currentCharacter = source[currentPosition++];
             //            if (((currentCharacter = source[currentPosition++]) == '\\')
@@ -836,10 +960,10 @@ public class Scanner implements IScanner, ITerminalSymbols {
                 currentLine = null;
               }
             }
-            isWhiteSpace = (currentCharacter == ' ')
-                || Character.isWhitespace(currentCharacter);
+//            isWhiteSpace = (currentCharacter == ' ')
+//                || Character.isWhitespace(currentCharacter);
             //            }
-          } while (isWhiteSpace);
+          } 
           if (tokenizeWhiteSpace && (whiteStart != currentPosition - 1)) {
             // reposition scanner in case we are interested by spaces as tokens
             currentPosition--;
@@ -849,823 +973,559 @@ public class Scanner implements IScanner, ITerminalSymbols {
           //little trick to get out in the middle of a source compuation
           if (currentPosition > eofPosition)
             return TokenNameEOF;
-          // ---------Identify the next token-------------
-          switch (currentCharacter) {
-            case '(' :
-              return getCastOrParen();
-            case ')' :
-              return TokenNameRPAREN;
-            case '{' :
-              return TokenNameLBRACE;
-            case '}' :
-              return TokenNameRBRACE;
-            case '[' :
-              return TokenNameLBRACKET;
-            case ']' :
-              return TokenNameRBRACKET;
-            case ';' :
-              return TokenNameSEMICOLON;
-            case ',' :
-              return TokenNameCOMMA;
-            case '.' :
-              if (getNextChar('='))
-                return TokenNameDOT_EQUAL;
-              if (getNextCharAsDigit())
-                return scanNumber(true);
-              return TokenNameDOT;
-            case '+' :
-              {
-                int test;
-                if ((test = getNextChar('+', '=')) == 0)
-                  return TokenNamePLUS_PLUS;
-                if (test > 0)
-                  return TokenNamePLUS_EQUAL;
-                return TokenNamePLUS;
-              }
-            case '-' :
-              {
-                int test;
-                if ((test = getNextChar('-', '=')) == 0)
-                  return TokenNameMINUS_MINUS;
-                if (test > 0)
-                  return TokenNameMINUS_EQUAL;
-                if (getNextChar('>'))
-                  return TokenNameMINUS_GREATER;
-                return TokenNameMINUS;
-              }
-            case '~' :
-              if (getNextChar('='))
-                return TokenNameTWIDDLE_EQUAL;
-              return TokenNameTWIDDLE;
-            case '!' :
-              if (getNextChar('=')) {
-                if (getNextChar('=')) {
-                  return TokenNameNOT_EQUAL_EQUAL;
+           
+            // ---------Identify the next token-------------
+            switch (currentCharacter) {
+              case '(' :
+                return getCastOrParen();
+              case ')' :
+                return TokenNameRPAREN;
+              case '{' :
+                return TokenNameLBRACE;
+              case '}' :
+                return TokenNameRBRACE;
+              case '[' :
+                return TokenNameLBRACKET;
+              case ']' :
+                return TokenNameRBRACKET;
+              case ';' :
+                return TokenNameSEMICOLON;
+              case ',' :
+                return TokenNameCOMMA;
+              case '.' :
+                if (getNextChar('='))
+                  return TokenNameDOT_EQUAL;
+                if (getNextCharAsDigit())
+                  return scanNumber(true);
+                return TokenNameDOT;
+              case '+' :
+                {
+                  int test;
+                  if ((test = getNextChar('+', '=')) == 0)
+                    return TokenNamePLUS_PLUS;
+                  if (test > 0)
+                    return TokenNamePLUS_EQUAL;
+                  return TokenNamePLUS;
                 }
-                return TokenNameNOT_EQUAL;
-              }
-              return TokenNameNOT;
-            case '*' :
-              if (getNextChar('='))
-                return TokenNameMULTIPLY_EQUAL;
-              return TokenNameMULTIPLY;
-            case '%' :
-              if (getNextChar('='))
-                return TokenNameREMAINDER_EQUAL;
-              return TokenNameREMAINDER;
-            case '<' :
+              case '-' :
               {
-                int oldPosition = currentPosition;
-                try {
-                  currentCharacter = source[currentPosition++];
-                } catch (IndexOutOfBoundsException e) {
-                  currentPosition = oldPosition;
-                  return TokenNameLESS;
+                  int test;
+                  if ((test = getNextChar('-', '=')) == 0)
+                    return TokenNameMINUS_MINUS;
+                  if (test > 0)
+                    return TokenNameMINUS_EQUAL;
+                  if (getNextChar('>'))
+                    return TokenNameMINUS_GREATER;
+                  return TokenNameMINUS;
+              } 
+              case '~' :
+                if (getNextChar('='))
+                  return TokenNameTWIDDLE_EQUAL;
+                return TokenNameTWIDDLE;
+              case '!' :
+                if (getNextChar('=')) {
+                  if (getNextChar('=')) {
+                    return TokenNameNOT_EQUAL_EQUAL;
+                  }
+                  return TokenNameNOT_EQUAL;
                 }
-                switch (currentCharacter) {
-                  case '=' :
-                    return TokenNameLESS_EQUAL;
-                  case '>' :
-                    return TokenNameNOT_EQUAL;
-                  case '<' :
-                    if (getNextChar('='))
-                      return TokenNameLEFT_SHIFT_EQUAL;
-                    if (getNextChar('<')) {
-                      int heredocStart = currentPosition;
-                      int heredocLength = 0;
-                      currentCharacter = source[currentPosition++];
-                      if (isPHPIdentifierStart(currentCharacter)) {
-                        currentCharacter = source[currentPosition++];
-                      } else {
-                        return TokenNameERROR;
-                      }
-                      while (isPHPIdentifierPart(currentCharacter)) {
+                return TokenNameNOT;
+              case '*' :
+                if (getNextChar('='))
+                  return TokenNameMULTIPLY_EQUAL;
+                return TokenNameMULTIPLY;
+              case '%' :
+                if (getNextChar('='))
+                  return TokenNameREMAINDER_EQUAL;
+                return TokenNameREMAINDER;
+              case '<' :
+                {
+                  int oldPosition = currentPosition;
+                  try {
+                    currentCharacter = source[currentPosition++];
+                  } catch (IndexOutOfBoundsException e) {
+                    currentPosition = oldPosition;
+                    return TokenNameLESS;
+                  }
+                  switch (currentCharacter) {
+                    case '=' :
+                      return TokenNameLESS_EQUAL;
+                    case '>' :
+                      return TokenNameNOT_EQUAL;
+                    case '<' :
+                      if (getNextChar('='))
+                        return TokenNameLEFT_SHIFT_EQUAL;
+                      if (getNextChar('<')) {
                         currentCharacter = source[currentPosition++];
-                      }
-                      heredocLength = currentPosition - heredocStart - 1;
-                      // heredoc end-tag determination
-                      boolean endTag = true;
-                      char ch;
-                      do {
-                        ch = source[currentPosition++];
-                        if (ch == '\r' || ch == '\n') {
-                          if (recordLineSeparator) {
-                            pushLineSeparator();
-                          } else {
-                            currentLine = null;
-                          }
-                          for (int i = 0; i < heredocLength; i++) {
-                            if (source[currentPosition + i] != source[heredocStart
-                                + i]) {
-                              endTag = false;
-                              break;
+                        while (Character.isWhitespace(currentCharacter)) {
+                          currentCharacter = source[currentPosition++];
+                        }
+                        int heredocStart = currentPosition - 1;
+                        int heredocLength = 0;
+                        if (isPHPIdentifierStart(currentCharacter)) {
+                          currentCharacter = source[currentPosition++];
+                        } else {
+                          return TokenNameERROR;
+                        }
+                        while (isPHPIdentifierPart(currentCharacter)) {
+                          currentCharacter = source[currentPosition++];
+                        }
+                        heredocLength = currentPosition - heredocStart - 1;
+                        // heredoc end-tag determination
+                        boolean endTag = true;
+                        char ch;
+                        do {
+                          ch = source[currentPosition++];
+                          if (ch == '\r' || ch == '\n') {
+                            if (recordLineSeparator) {
+                              pushLineSeparator();
+                            } else {
+                              currentLine = null;
+                            }
+                            for (int i = 0; i < heredocLength; i++) {
+                              if (source[currentPosition + i] != source[heredocStart
+                                  + i]) {
+                                endTag = false;
+                                break;
+                              }
+                            }
+                            if (endTag) {
+                              currentPosition += heredocLength - 1;
+                              currentCharacter = source[currentPosition++];
+                              break; // do...while loop
+                            } else {
+                              endTag = true;
                             }
                           }
-                          if (endTag) {
-                            currentPosition += heredocLength - 1;
-                            currentCharacter = source[currentPosition++];
-                            break; // do...while loop
-                          } else {
-                            endTag = true;
-                          }
-                        }
-                      } while (true);
-                      return TokenNameHEREDOC;
-                    }
-                    return TokenNameLEFT_SHIFT;
+                        } while (true);
+                        return TokenNameHEREDOC;
+                      }
+                      return TokenNameLEFT_SHIFT;
+                  }
+                  currentPosition = oldPosition;
+                  return TokenNameLESS;
                 }
-                currentPosition = oldPosition;
-                return TokenNameLESS;
-              }
-            case '>' :
-              {
-                int test;
-                if ((test = getNextChar('=', '>')) == 0)
-                  return TokenNameGREATER_EQUAL;
-                if (test > 0) {
+              case '>' :
+                {
+                  int test;
                   if ((test = getNextChar('=', '>')) == 0)
-                    return TokenNameRIGHT_SHIFT_EQUAL;
-                  return TokenNameRIGHT_SHIFT;
+                    return TokenNameGREATER_EQUAL;
+                  if (test > 0) {
+                    if ((test = getNextChar('=', '>')) == 0)
+                      return TokenNameRIGHT_SHIFT_EQUAL;
+                    return TokenNameRIGHT_SHIFT;
+                  }
+                  return TokenNameGREATER;
                 }
-                return TokenNameGREATER;
-              }
-            case '=' :
-              if (getNextChar('=')) {
+              case '=' :
                 if (getNextChar('=')) {
-                  return TokenNameEQUAL_EQUAL_EQUAL;
-                }
-                return TokenNameEQUAL_EQUAL;
-              }
-              if (getNextChar('>'))
-                return TokenNameEQUAL_GREATER;
-              return TokenNameEQUAL;
-            case '&' :
-              {
-                int test;
-                if ((test = getNextChar('&', '=')) == 0)
-                  return TokenNameAND_AND;
-                if (test > 0)
-                  return TokenNameAND_EQUAL;
-                return TokenNameAND;
-              }
-            case '|' :
-              {
-                int test;
-                if ((test = getNextChar('|', '=')) == 0)
-                  return TokenNameOR_OR;
-                if (test > 0)
-                  return TokenNameOR_EQUAL;
-                return TokenNameOR;
-              }
-            case '^' :
-              if (getNextChar('='))
-                return TokenNameXOR_EQUAL;
-              return TokenNameXOR;
-            case '?' :
-              if (getNextChar('>')) {
-                phpMode = false;
-                if (currentPosition==source.length) {
-                  phpMode = true;
-                  return TokenNameINLINE_HTML;
-                }
-                return getInlinedHTML(currentPosition - 2);
-              }
-              return TokenNameQUESTION;
-            case ':' :
-              if (getNextChar(':'))
-                return TokenNamePAAMAYIM_NEKUDOTAYIM;
-              return TokenNameCOLON;
-            case '@' :
-              return TokenNameAT;
-            //                                 case '\'' :
-            //                                         {
-            //                                                 int test;
-            //                                                 if ((test = getNextChar('\n', '\r')) == 0) {
-            //                                                         throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
-            //                                                 }
-            //                                                 if (test > 0) {
-            //                                                         // relocate if finding another quote fairly close: thus unicode
-            // '/u000D' will be fully consumed
-            //                                                         for (int lookAhead = 0;
-            //                                                                 lookAhead < 3;
-            //                                                                 lookAhead++) {
-            //                                                                 if (currentPosition + lookAhead
-            //                                                                         == source.length)
-            //                                                                         break;
-            //                                                                 if (source[currentPosition + lookAhead]
-            //                                                                         == '\n')
-            //                                                                         break;
-            //                                                                 if (source[currentPosition + lookAhead]
-            //                                                                         == '\'') {
-            //                                                                         currentPosition += lookAhead + 1;
-            //                                                                         break;
-            //                                                                 }
-            //                                                         }
-            //                                                         throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
-            //                                                 }
-            //                                         }
-            //                                         if (getNextChar('\'')) {
-            //                                                 // relocate if finding another quote fairly close: thus unicode
-            // '/u000D' will be fully consumed
-            //                                                 for (int lookAhead = 0;
-            //                                                         lookAhead < 3;
-            //                                                         lookAhead++) {
-            //                                                         if (currentPosition + lookAhead
-            //                                                                 == source.length)
-            //                                                                 break;
-            //                                                         if (source[currentPosition + lookAhead]
-            //                                                                 == '\n')
-            //                                                                 break;
-            //                                                         if (source[currentPosition + lookAhead]
-            //                                                                 == '\'') {
-            //                                                                 currentPosition += lookAhead + 1;
-            //                                                                 break;
-            //                                                         }
-            //                                                 }
-            //                                                 throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
-            //                                         }
-            //                                         if (getNextChar('\\'))
-            //                                                 scanEscapeCharacter();
-            //                                         else { // consume next character
-            //                                                 unicodeAsBackSlash = false;
-            //                                                 if (((currentCharacter = source[currentPosition++])
-            //                                                         == '\\')
-            //                                                         && (source[currentPosition] == 'u')) {
-            //                                                         getNextUnicodeChar();
-            //                                                 } else {
-            //                                                         if (withoutUnicodePtr != 0) {
-            //                                                                 withoutUnicodeBuffer[++withoutUnicodePtr] =
-            //                                                                         currentCharacter;
-            //                                                         }
-            //                                                 }
-            //                                         }
-            //                                         // if (getNextChar('\''))
-            //                                         // return TokenNameCharacterLiteral;
-            //                                         // relocate if finding another quote fairly close: thus unicode
-            // '/u000D' will be fully consumed
-            //                                         for (int lookAhead = 0; lookAhead < 20; lookAhead++) {
-            //                                                 if (currentPosition + lookAhead == source.length)
-            //                                                         break;
-            //                                                 if (source[currentPosition + lookAhead] == '\n')
-            //                                                         break;
-            //                                                 if (source[currentPosition + lookAhead] == '\'') {
-            //                                                         currentPosition += lookAhead + 1;
-            //                                                         break;
-            //                                                 }
-            //                                         }
-            //                                         throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
-            case '\'' :
-              try {
-                // consume next character
-                unicodeAsBackSlash = false;
-                currentCharacter = source[currentPosition++];
-                //                if (((currentCharacter = source[currentPosition++]) == '\\')
-                //                  && (source[currentPosition] == 'u')) {
-                //                  getNextUnicodeChar();
-                //                } else {
-                //                  if (withoutUnicodePtr != 0) {
-                //                    withoutUnicodeBuffer[++withoutUnicodePtr] =
-                //                      currentCharacter;
-                //                  }
-                //                }
-                while (currentCharacter != '\'') {
-                  /** ** in PHP \r and \n are valid in string literals *** */
-                  //                  if ((currentCharacter == '\n')
-                  //                    || (currentCharacter == '\r')) {
-                  //                    // relocate if finding another quote fairly close: thus
-                  // unicode '/u000D' will be fully consumed
-                  //                    for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
-                  //                      if (currentPosition + lookAhead == source.length)
-                  //                        break;
-                  //                      if (source[currentPosition + lookAhead] == '\n')
-                  //                        break;
-                  //                      if (source[currentPosition + lookAhead] == '\"') {
-                  //                        currentPosition += lookAhead + 1;
-                  //                        break;
-                  //                      }
-                  //                    }
-                  //                    throw new InvalidInputException(INVALID_CHAR_IN_STRING);
-                  //                  }
-                  if (currentCharacter == '\\') {
-                    int escapeSize = currentPosition;
-                    boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
-                    //scanEscapeCharacter make a side effect on this value and
-                    // we need the previous value few lines down this one
-                    scanSingleQuotedEscapeCharacter();
-                    escapeSize = currentPosition - escapeSize;
-                    if (withoutUnicodePtr == 0) {
-                      //buffer all the entries that have been left aside....
-                      withoutUnicodePtr = currentPosition - escapeSize - 1
-                          - startPosition;
-                      System.arraycopy(source, startPosition,
-                          withoutUnicodeBuffer, 1, withoutUnicodePtr);
-                      withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
-                    } else { //overwrite the / in the buffer
-                      withoutUnicodeBuffer[withoutUnicodePtr] = currentCharacter;
-                      if (backSlashAsUnicodeInString) { //there are TWO \ in
-                        // the stream where
-                        // only one is correct
-                        withoutUnicodePtr--;
-                      }
-                    }
+                  if (getNextChar('=')) {
+                    return TokenNameEQUAL_EQUAL_EQUAL;
                   }
-                  // consume next character
-                  unicodeAsBackSlash = false;
-                  currentCharacter = source[currentPosition++];
-                  //                  if (((currentCharacter = source[currentPosition++]) ==
-                  // '\\')
-                  //                    && (source[currentPosition] == 'u')) {
-                  //                    getNextUnicodeChar();
-                  //                  } else {
-                  if (withoutUnicodePtr != 0) {
-                    withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
-                  }
-                  //                  }
+                  return TokenNameEQUAL_EQUAL;
                 }
-              } catch (IndexOutOfBoundsException e) {
-                throw new InvalidInputException(UNTERMINATED_STRING);
-              } catch (InvalidInputException e) {
-                if (e.getMessage().equals(INVALID_ESCAPE)) {
-                  // relocate if finding another quote fairly close: thus
-                  // unicode '/u000D' will be fully consumed
-                  for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
-                    if (currentPosition + lookAhead == source.length)
-                      break;
-                    if (source[currentPosition + lookAhead] == '\n')
-                      break;
-                    if (source[currentPosition + lookAhead] == '\'') {
-                      currentPosition += lookAhead + 1;
-                      break;
-                    }
-                  }
+                if (getNextChar('>'))
+                  return TokenNameEQUAL_GREATER;
+                return TokenNameEQUAL;
+              case '&' :
+                {
+                  int test;
+                  if ((test = getNextChar('&', '=')) == 0)
+                    return TokenNameAND_AND;
+                  if (test > 0)
+                    return TokenNameAND_EQUAL;
+                  return TokenNameAND;
                 }
-                throw e; // rethrow
-              }
-              if (checkNonExternalizedStringLiterals) { // check for presence
-                // of NLS tags
-                // //$NON-NLS-?$ where
-                // ? is an int.
-                if (currentLine == null) {
-                  currentLine = new NLSLine();
-                  lines.add(currentLine);
+              case '|' :
+                {
+                  int test;
+                  if ((test = getNextChar('|', '=')) == 0)
+                    return TokenNameOR_OR;
+                  if (test > 0)
+                    return TokenNameOR_EQUAL;
+                  return TokenNameOR;
                 }
-                currentLine.add(new StringLiteral(
-                    getCurrentTokenSourceString(), startPosition,
-                    currentPosition - 1));
-              }
-              return TokenNameStringConstant;
-            case '"' :
-              try {
-                // consume next character
-                unicodeAsBackSlash = false;
-                currentCharacter = source[currentPosition++];
-                //                if (((currentCharacter = source[currentPosition++]) == '\\')
-                //                  && (source[currentPosition] == 'u')) {
-                //                  getNextUnicodeChar();
-                //                } else {
-                //                  if (withoutUnicodePtr != 0) {
-                //                    withoutUnicodeBuffer[++withoutUnicodePtr] =
-                //                      currentCharacter;
-                //                  }
-                //                }
-                while (currentCharacter != '"') {
-                  /** ** in PHP \r and \n are valid in string literals *** */
-                  //                  if ((currentCharacter == '\n')
-                  //                    || (currentCharacter == '\r')) {
-                  //                    // relocate if finding another quote fairly close: thus
-                  // unicode '/u000D' will be fully consumed
-                  //                    for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
-                  //                      if (currentPosition + lookAhead == source.length)
-                  //                        break;
-                  //                      if (source[currentPosition + lookAhead] == '\n')
-                  //                        break;
-                  //                      if (source[currentPosition + lookAhead] == '\"') {
-                  //                        currentPosition += lookAhead + 1;
-                  //                        break;
-                  //                      }
-                  //                    }
-                  //                    throw new InvalidInputException(INVALID_CHAR_IN_STRING);
-                  //                  }
-                  if (currentCharacter == '\\') {
-                    int escapeSize = currentPosition;
-                    boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
-                    //scanEscapeCharacter make a side effect on this value and
-                    // we need the previous value few lines down this one
-                    scanDoubleQuotedEscapeCharacter();
-                    escapeSize = currentPosition - escapeSize;
-                    if (withoutUnicodePtr == 0) {
-                      //buffer all the entries that have been left aside....
-                      withoutUnicodePtr = currentPosition - escapeSize - 1
-                          - startPosition;
-                      System.arraycopy(source, startPosition,
-                          withoutUnicodeBuffer, 1, withoutUnicodePtr);
-                      withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
-                    } else { //overwrite the / in the buffer
-                      withoutUnicodeBuffer[withoutUnicodePtr] = currentCharacter;
-                      if (backSlashAsUnicodeInString) { //there are TWO \ in
-                        // the stream where
-                        // only one is correct
-                        withoutUnicodePtr--;
-                      }
-                    }
+              case '^' :
+                if (getNextChar('='))
+                  return TokenNameXOR_EQUAL;
+                return TokenNameXOR;
+              case '?' :
+                if (getNextChar('>')) {
+                  phpMode = false;
+                  if (currentPosition == source.length) {
+                    phpMode = true;
+                    return TokenNameINLINE_HTML;
                   }
+                  return getInlinedHTML(currentPosition - 2);
+                }
+                return TokenNameQUESTION;
+              case ':' :
+                if (getNextChar(':'))
+                  return TokenNamePAAMAYIM_NEKUDOTAYIM;
+                return TokenNameCOLON;
+              case '@' :
+                return TokenNameAT;
+              case '\'' :
+//                return TokenNameEncapsedString1;
+                try {
                   // consume next character
                   unicodeAsBackSlash = false;
                   currentCharacter = source[currentPosition++];
-                  //                  if (((currentCharacter = source[currentPosition++]) ==
-                  // '\\')
-                  //                    && (source[currentPosition] == 'u')) {
-                  //                    getNextUnicodeChar();
-                  //                  } else {
-                  if (withoutUnicodePtr != 0) {
-                    withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
-                  }
+                  //                if (((currentCharacter = source[currentPosition++]) == '\\')
+                  //                  && (source[currentPosition] == 'u')) {
+                  //                  getNextUnicodeChar();
+                  //                } else {
+                  //                  if (withoutUnicodePtr != 0) {
+                  //                    withoutUnicodeBuffer[++withoutUnicodePtr] =
+                  //                      currentCharacter;
                   //                  }
-                }
-              } catch (IndexOutOfBoundsException e) {
-                throw new InvalidInputException(UNTERMINATED_STRING);
-              } catch (InvalidInputException e) {
-                if (e.getMessage().equals(INVALID_ESCAPE)) {
-                  // relocate if finding another quote fairly close: thus
-                  // unicode '/u000D' will be fully consumed
-                  for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
-                    if (currentPosition + lookAhead == source.length)
-                      break;
-                    if (source[currentPosition + lookAhead] == '\n')
-                      break;
-                    if (source[currentPosition + lookAhead] == '\"') {
-                      currentPosition += lookAhead + 1;
-                      break;
-                    }
-                  }
-                }
-                throw e; // rethrow
-              }
-              if (checkNonExternalizedStringLiterals) { // check for presence
-                // of NLS tags
-                // //$NON-NLS-?$ where
-                // ? is an int.
-                if (currentLine == null) {
-                  currentLine = new NLSLine();
-                  lines.add(currentLine);
-                }
-                currentLine.add(new StringLiteral(
-                    getCurrentTokenSourceString(), startPosition,
-                    currentPosition - 1));
-              }
-              return TokenNameStringLiteral;
-            case '`' :
-              try {
-                // consume next character
-                unicodeAsBackSlash = false;
-                currentCharacter = source[currentPosition++];
-                //                if (((currentCharacter = source[currentPosition++]) == '\\')
-                //                  && (source[currentPosition] == 'u')) {
-                //                  getNextUnicodeChar();
-                //                } else {
-                //                  if (withoutUnicodePtr != 0) {
-                //                    withoutUnicodeBuffer[++withoutUnicodePtr] =
-                //                      currentCharacter;
-                //                  }
-                //                }
-                while (currentCharacter != '`') {
-                  /** ** in PHP \r and \n are valid in string literals *** */
-                  //                if ((currentCharacter == '\n')
-                  //                  || (currentCharacter == '\r')) {
-                  //                  // relocate if finding another quote fairly close: thus
-                  // unicode '/u000D' will be fully consumed
-                  //                  for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
-                  //                    if (currentPosition + lookAhead == source.length)
-                  //                      break;
-                  //                    if (source[currentPosition + lookAhead] == '\n')
-                  //                      break;
-                  //                    if (source[currentPosition + lookAhead] == '\"') {
-                  //                      currentPosition += lookAhead + 1;
-                  //                      break;
-                  //                    }
-                  //                  }
-                  //                  throw new InvalidInputException(INVALID_CHAR_IN_STRING);
                   //                }
-                  if (currentCharacter == '\\') {
-                    int escapeSize = currentPosition;
-                    boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
-                    //scanEscapeCharacter make a side effect on this value and
-                    // we need the previous value few lines down this one
-                    scanDoubleQuotedEscapeCharacter();
-                    escapeSize = currentPosition - escapeSize;
-                    if (withoutUnicodePtr == 0) {
-                      //buffer all the entries that have been left aside....
-                      withoutUnicodePtr = currentPosition - escapeSize - 1
-                          - startPosition;
-                      System.arraycopy(source, startPosition,
-                          withoutUnicodeBuffer, 1, withoutUnicodePtr);
-                      withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
-                    } else { //overwrite the / in the buffer
-                      withoutUnicodeBuffer[withoutUnicodePtr] = currentCharacter;
-                      if (backSlashAsUnicodeInString) { //there are TWO \ in
-                        // the stream where
-                        // only one is correct
-                        withoutUnicodePtr--;
+                  while (currentCharacter != '\'') {
+                    /** ** in PHP \r and \n are valid in string literals *** */
+                    //                  if ((currentCharacter == '\n')
+                    //                    || (currentCharacter == '\r')) {
+                    //                    // relocate if finding another quote fairly close: thus
+                    // unicode '/u000D' will be fully consumed
+                    //                    for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+                    //                      if (currentPosition + lookAhead == source.length)
+                    //                        break;
+                    //                      if (source[currentPosition + lookAhead] == '\n')
+                    //                        break;
+                    //                      if (source[currentPosition + lookAhead] == '\"') {
+                    //                        currentPosition += lookAhead + 1;
+                    //                        break;
+                    //                      }
+                    //                    }
+                    //                    throw new InvalidInputException(INVALID_CHAR_IN_STRING);
+                    //                  }
+                    if (currentCharacter == '\\') {
+                      int escapeSize = currentPosition;
+                      boolean backSlashAsUnicodeInString = unicodeAsBackSlash;
+                      //scanEscapeCharacter make a side effect on this value and
+                      // we need the previous value few lines down this one
+                      scanSingleQuotedEscapeCharacter();
+                      escapeSize = currentPosition - escapeSize;
+                      if (withoutUnicodePtr == 0) {
+                        //buffer all the entries that have been left aside....
+                        withoutUnicodePtr = currentPosition - escapeSize - 1
+                            - startPosition;
+                        System.arraycopy(source, startPosition,
+                            withoutUnicodeBuffer, 1, withoutUnicodePtr);
+                        withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
+                      } else { //overwrite the / in the buffer
+                        withoutUnicodeBuffer[withoutUnicodePtr] = currentCharacter;
+                        if (backSlashAsUnicodeInString) { //there are TWO \ in
+                          // the stream where
+                          // only one is correct
+                          withoutUnicodePtr--;
+                        }
                       }
                     }
+                    // consume next character
+                    unicodeAsBackSlash = false;
+                    currentCharacter = source[currentPosition++];
+                    //                  if (((currentCharacter = source[currentPosition++]) ==
+                    // '\\')
+                    //                    && (source[currentPosition] == 'u')) {
+                    //                    getNextUnicodeChar();
+                    //                  } else {
+                    if (withoutUnicodePtr != 0) {
+                      withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
+                    }
+                    //                  }
                   }
-                  // consume next character
-                  unicodeAsBackSlash = false;
-                  currentCharacter = source[currentPosition++];
-                  //                  if (((currentCharacter = source[currentPosition++]) ==
-                  // '\\')
-                  //                    && (source[currentPosition] == 'u')) {
-                  //                    getNextUnicodeChar();
-                  //                  } else {
-                  if (withoutUnicodePtr != 0) {
-                    withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter;
-                  }
-                  //                  }
-                }
-              } catch (IndexOutOfBoundsException e) {
-                throw new InvalidInputException(UNTERMINATED_STRING);
-              } catch (InvalidInputException e) {
-                if (e.getMessage().equals(INVALID_ESCAPE)) {
-                  // relocate if finding another quote fairly close: thus
-                  // unicode '/u000D' will be fully consumed
-                  for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
-                    if (currentPosition + lookAhead == source.length)
-                      break;
-                    if (source[currentPosition + lookAhead] == '\n')
-                      break;
-                    if (source[currentPosition + lookAhead] == '`') {
-                      currentPosition += lookAhead + 1;
-                      break;
+                } catch (IndexOutOfBoundsException e) {
+                  throw new InvalidInputException(UNTERMINATED_STRING);
+                } catch (InvalidInputException e) {
+                  if (e.getMessage().equals(INVALID_ESCAPE)) {
+                    // relocate if finding another quote fairly close: thus
+                    // unicode '/u000D' will be fully consumed
+                    for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+                      if (currentPosition + lookAhead == source.length)
+                        break;
+                      if (source[currentPosition + lookAhead] == '\n')
+                        break;
+                      if (source[currentPosition + lookAhead] == '\'') {
+                        currentPosition += lookAhead + 1;
+                        break;
+                      }
                     }
                   }
+                  throw e; // rethrow
                 }
-                throw e; // rethrow
-              }
-              if (checkNonExternalizedStringLiterals) { // check for presence
-                // of NLS tags
-                // //$NON-NLS-?$ where
-                // ? is an int.
-                if (currentLine == null) {
-                  currentLine = new NLSLine();
-                  lines.add(currentLine);
-                }
-                currentLine.add(new StringLiteral(
-                    getCurrentTokenSourceString(), startPosition,
-                    currentPosition - 1));
-              }
-              return TokenNameStringInterpolated;
-            case '#' :
-            case '/' :
-              {
-                char startChar = currentCharacter;
-                if (getNextChar('=')) {
-                  return TokenNameDIVIDE_EQUAL;
+                if (checkNonExternalizedStringLiterals) { // check for presence
+                  // of NLS tags
+                  // //$NON-NLS-?$ where
+                  // ? is an int.
+                  if (currentLine == null) {
+                    currentLine = new NLSLine();
+                    lines.add(currentLine);
+                  }
+                  currentLine.add(new StringLiteral(
+                      getCurrentTokenSourceString(), startPosition,
+                      currentPosition - 1));
                 }
-                int test;
-                if ((startChar == '#') || (test = getNextChar('/', '*')) == 0) {
-                  //line comment
-                  int endPositionForLineComment = 0;
-                  try { //get the next char
-                    currentCharacter = source[currentPosition++];
-                    //                    if (((currentCharacter = source[currentPosition++])
-                    //                      == '\\')
-                    //                      && (source[currentPosition] == 'u')) {
-                    //                      //-------------unicode traitement ------------
-                    //                      int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-                    //                      currentPosition++;
-                    //                      while (source[currentPosition] == 'u') {
-                    //                        currentPosition++;
-                    //                      }
-                    //                      if ((c1 =
-                    //                        Character.getNumericValue(source[currentPosition++]))
-                    //                        > 15
-                    //                        || c1 < 0
-                    //                        || (c2 =
-                    //                          Character.getNumericValue(source[currentPosition++]))
-                    //                          > 15
-                    //                        || c2 < 0
-                    //                        || (c3 =
-                    //                          Character.getNumericValue(source[currentPosition++]))
-                    //                          > 15
-                    //                        || c3 < 0
-                    //                        || (c4 =
-                    //                          Character.getNumericValue(source[currentPosition++]))
-                    //                          > 15
-                    //                        || c4 < 0) {
-                    //                        throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
-                    //                      } else {
-                    //                        currentCharacter =
-                    //                          (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-                    //                      }
-                    //                    }
-                    //handle the \\u case manually into comment
-                    //                    if (currentCharacter == '\\') {
-                    //                      if (source[currentPosition] == '\\')
-                    //                        currentPosition++;
-                    //                    } //jump over the \\
-                    boolean isUnicode = false;
-                    while (currentCharacter != '\r' && currentCharacter != '\n') {
-                      if (currentCharacter == '?') {
-                        if (getNextChar('>')) {
-                          startPosition = currentPosition - 2;
-                          phpMode = false;
-                          return TokenNameINLINE_HTML;
-                        }
-                      }
-                      //get the next char
-                      isUnicode = false;
+                return TokenNameStringConstant;
+              case '"' :
+                return TokenNameEncapsedString2;
+              case '`' :
+                return TokenNameEncapsedString0;
+              case '#' :
+              case '/' :
+                {
+                  char startChar = currentCharacter;
+                  if (getNextChar('=')) {
+                    return TokenNameDIVIDE_EQUAL;
+                  }
+                  int test;
+                  if ((startChar == '#') || (test = getNextChar('/', '*')) == 0) {
+                    //line comment
+                    int endPositionForLineComment = 0;
+                    try { //get the next char
                       currentCharacter = source[currentPosition++];
-                      //                      if (((currentCharacter = source[currentPosition++])
-                      //                        == '\\')
-                      //                        && (source[currentPosition] == 'u')) {
-                      //                        isUnicode = true;
-                      //                        //-------------unicode traitement ------------
-                      //                        int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+                      //                    if (((currentCharacter = source[currentPosition++])
+                      //                      == '\\')
+                      //                      && (source[currentPosition] == 'u')) {
+                      //                      //-------------unicode traitement ------------
+                      //                      int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+                      //                      currentPosition++;
+                      //                      while (source[currentPosition] == 'u') {
                       //                        currentPosition++;
-                      //                        while (source[currentPosition] == 'u') {
-                      //                          currentPosition++;
-                      //                        }
-                      //                        if ((c1 =
+                      //                      }
+                      //                      if ((c1 =
+                      //                        Character.getNumericValue(source[currentPosition++]))
+                      //                        > 15
+                      //                        || c1 < 0
+                      //                        || (c2 =
+                      //                          Character.getNumericValue(source[currentPosition++]))
+                      //                          > 15
+                      //                        || c2 < 0
+                      //                        || (c3 =
+                      //                          Character.getNumericValue(source[currentPosition++]))
+                      //                          > 15
+                      //                        || c3 < 0
+                      //                        || (c4 =
                       //                          Character.getNumericValue(source[currentPosition++]))
                       //                          > 15
-                      //                          || c1 < 0
-                      //                          || (c2 =
-                      //                            Character.getNumericValue(
-                      //                              source[currentPosition++]))
-                      //                            > 15
-                      //                          || c2 < 0
-                      //                          || (c3 =
-                      //                            Character.getNumericValue(
-                      //                              source[currentPosition++]))
-                      //                            > 15
-                      //                          || c3 < 0
-                      //                          || (c4 =
-                      //                            Character.getNumericValue(
-                      //                              source[currentPosition++]))
-                      //                            > 15
-                      //                          || c4 < 0) {
-                      //                          throw new
+                      //                        || c4 < 0) {
+                      //                        throw new
                       // InvalidInputException(INVALID_UNICODE_ESCAPE);
-                      //                        } else {
-                      //                          currentCharacter =
-                      //                            (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-                      //                        }
+                      //                      } else {
+                      //                        currentCharacter =
+                      //                          (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
                       //                      }
+                      //                    }
                       //handle the \\u case manually into comment
-                      //                      if (currentCharacter == '\\') {
-                      //                        if (source[currentPosition] == '\\')
-                      //                          currentPosition++;
-                      //                      } //jump over the \\
+                      //                    if (currentCharacter == '\\') {
+                      //                      if (source[currentPosition] == '\\')
+                      //                        currentPosition++;
+                      //                    } //jump over the \\
+                      boolean isUnicode = false;
+                      while (currentCharacter != '\r'
+                          && currentCharacter != '\n') {
+                        if (currentCharacter == '?') {
+                          if (getNextChar('>')) {
+                            startPosition = currentPosition - 2;
+                            phpMode = false;
+                            return TokenNameINLINE_HTML;
+                          }
+                        }
+                        //get the next char
+                        isUnicode = false;
+                        currentCharacter = source[currentPosition++];
+                        //                      if (((currentCharacter = source[currentPosition++])
+                        //                        == '\\')
+                        //                        && (source[currentPosition] == 'u')) {
+                        //                        isUnicode = true;
+                        //                        //-------------unicode traitement ------------
+                        //                        int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+                        //                        currentPosition++;
+                        //                        while (source[currentPosition] == 'u') {
+                        //                          currentPosition++;
+                        //                        }
+                        //                        if ((c1 =
+                        //                          Character.getNumericValue(source[currentPosition++]))
+                        //                          > 15
+                        //                          || c1 < 0
+                        //                          || (c2 =
+                        //                            Character.getNumericValue(
+                        //                              source[currentPosition++]))
+                        //                            > 15
+                        //                          || c2 < 0
+                        //                          || (c3 =
+                        //                            Character.getNumericValue(
+                        //                              source[currentPosition++]))
+                        //                            > 15
+                        //                          || c3 < 0
+                        //                          || (c4 =
+                        //                            Character.getNumericValue(
+                        //                              source[currentPosition++]))
+                        //                            > 15
+                        //                          || c4 < 0) {
+                        //                          throw new
+                        // InvalidInputException(INVALID_UNICODE_ESCAPE);
+                        //                        } else {
+                        //                          currentCharacter =
+                        //                            (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+                        //                        }
+                        //                      }
+                        //handle the \\u case manually into comment
+                        //                      if (currentCharacter == '\\') {
+                        //                        if (source[currentPosition] == '\\')
+                        //                          currentPosition++;
+                        //                      } //jump over the \\
+                      }
+                      if (isUnicode) {
+                        endPositionForLineComment = currentPosition - 6;
+                      } else {
+                        endPositionForLineComment = currentPosition - 1;
+                      }
+                      recordComment(false);
+                      if ((currentCharacter == '\r')
+                          || (currentCharacter == '\n')) {
+                        checkNonExternalizeString();
+                        if (recordLineSeparator) {
+                          if (isUnicode) {
+                            pushUnicodeLineSeparator();
+                          } else {
+                            pushLineSeparator();
+                          }
+                        } else {
+                          currentLine = null;
+                        }
+                      }
+                      if (tokenizeComments) {
+                        if (!isUnicode) {
+                          currentPosition = endPositionForLineComment;
+                          // reset one character behind
+                        }
+                        return TokenNameCOMMENT_LINE;
+                      }
+                    } catch (IndexOutOfBoundsException e) { //an eof will them
+                      // be generated
+                      if (tokenizeComments) {
+                        currentPosition--;
+                        // reset one character behind
+                        return TokenNameCOMMENT_LINE;
+                      }
                     }
-                    if (isUnicode) {
-                      endPositionForLineComment = currentPosition - 6;
-                    } else {
-                      endPositionForLineComment = currentPosition - 1;
+                    break;
+                  }
+                  if (test > 0) {
+                    //traditional and annotation comment
+                    boolean isJavadoc = false, star = false;
+                    // consume next character
+                    unicodeAsBackSlash = false;
+                    currentCharacter = source[currentPosition++];
+                    //                  if (((currentCharacter = source[currentPosition++]) ==
+                    // '\\')
+                    //                    && (source[currentPosition] == 'u')) {
+                    //                    getNextUnicodeChar();
+                    //                  } else {
+                    //                    if (withoutUnicodePtr != 0) {
+                    //                      withoutUnicodeBuffer[++withoutUnicodePtr] =
+                    //                        currentCharacter;
+                    //                    }
+                    //                  }
+                    if (currentCharacter == '*') {
+                      isJavadoc = true;
+                      star = true;
                     }
-                    recordComment(false);
                     if ((currentCharacter == '\r')
                         || (currentCharacter == '\n')) {
                       checkNonExternalizeString();
                       if (recordLineSeparator) {
-                        if (isUnicode) {
-                          pushUnicodeLineSeparator();
-                        } else {
-                          pushLineSeparator();
-                        }
+                        pushLineSeparator();
                       } else {
                         currentLine = null;
                       }
                     }
-                    if (tokenizeComments) {
-                      if (!isUnicode) {
-                        currentPosition = endPositionForLineComment;
-                        // reset one character behind
+                    try { //get the next char
+                      currentCharacter = source[currentPosition++];
+                      //                    if (((currentCharacter = source[currentPosition++])
+                      //                      == '\\')
+                      //                      && (source[currentPosition] == 'u')) {
+                      //                      //-------------unicode traitement ------------
+                      //                      getNextUnicodeChar();
+                      //                    }
+                      //handle the \\u case manually into comment
+                      //                    if (currentCharacter == '\\') {
+                      //                      if (source[currentPosition] == '\\')
+                      //                        currentPosition++;
+                      //                      //jump over the \\
+                      //                    }
+                      // empty comment is not a javadoc /**/
+                      if (currentCharacter == '/') {
+                        isJavadoc = false;
                       }
-                      return TokenNameCOMMENT_LINE;
-                    }
-                  } catch (IndexOutOfBoundsException e) { //an eof will them
-                    // be generated
-                    if (tokenizeComments) {
-                      currentPosition--;
-                      // reset one character behind
-                      return TokenNameCOMMENT_LINE;
+                      //loop until end of comment */
+                      while ((currentCharacter != '/') || (!star)) {
+                        if ((currentCharacter == '\r')
+                            || (currentCharacter == '\n')) {
+                          checkNonExternalizeString();
+                          if (recordLineSeparator) {
+                            pushLineSeparator();
+                          } else {
+                            currentLine = null;
+                          }
+                        }
+                        star = currentCharacter == '*';
+                        //get next char
+                        currentCharacter = source[currentPosition++];
+                        //                      if (((currentCharacter = source[currentPosition++])
+                        //                        == '\\')
+                        //                        && (source[currentPosition] == 'u')) {
+                        //                        //-------------unicode traitement ------------
+                        //                        getNextUnicodeChar();
+                        //                      }
+                        //handle the \\u case manually into comment
+                        //                      if (currentCharacter == '\\') {
+                        //                        if (source[currentPosition] == '\\')
+                        //                          currentPosition++;
+                        //                      } //jump over the \\
+                      }
+                      recordComment(isJavadoc);
+                      if (tokenizeComments) {
+                        if (isJavadoc)
+                          return TokenNameCOMMENT_PHPDOC;
+                        return TokenNameCOMMENT_BLOCK;
+                      }
+                    } catch (IndexOutOfBoundsException e) {
+                      throw new InvalidInputException(UNTERMINATED_COMMENT);
                     }
+                    break;
                   }
-                  break;
+                  return TokenNameDIVIDE;
                 }
-                if (test > 0) {
-                  //traditional and annotation comment
-                  boolean isJavadoc = false, star = false;
-                  // consume next character
-                  unicodeAsBackSlash = false;
-                  currentCharacter = source[currentPosition++];
-                  //                  if (((currentCharacter = source[currentPosition++]) ==
-                  // '\\')
-                  //                    && (source[currentPosition] == 'u')) {
-                  //                    getNextUnicodeChar();
-                  //                  } else {
-                  //                    if (withoutUnicodePtr != 0) {
-                  //                      withoutUnicodeBuffer[++withoutUnicodePtr] =
-                  //                        currentCharacter;
-                  //                    }
-                  //                  }
-                  if (currentCharacter == '*') {
-                    isJavadoc = true;
-                    star = true;
-                  }
-                  if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
-                    checkNonExternalizeString();
-                    if (recordLineSeparator) {
-                      pushLineSeparator();
-                    } else {
-                      currentLine = null;
-                    }
-                  }
-                  try { //get the next char
+              case '\u001a' :
+                if (atEnd())
+                  return TokenNameEOF;
+                //the atEnd may not be <currentPosition == source.length> if
+                // source is only some part of a real (external) stream
+                throw new InvalidInputException("Ctrl-Z"); //$NON-NLS-1$
+              default :
+                if (currentCharacter == '$') {
+                  int oldPosition = currentPosition;
+                  try {
                     currentCharacter = source[currentPosition++];
-                    //                    if (((currentCharacter = source[currentPosition++])
-                    //                      == '\\')
-                    //                      && (source[currentPosition] == 'u')) {
-                    //                      //-------------unicode traitement ------------
-                    //                      getNextUnicodeChar();
-                    //                    }
-                    //handle the \\u case manually into comment
-                    //                    if (currentCharacter == '\\') {
-                    //                      if (source[currentPosition] == '\\')
-                    //                        currentPosition++;
-                    //                      //jump over the \\
-                    //                    }
-                    // empty comment is not a javadoc /**/
-                    if (currentCharacter == '/') {
-                      isJavadoc = false;
-                    }
-                    //loop until end of comment */
-                    while ((currentCharacter != '/') || (!star)) {
-                      if ((currentCharacter == '\r')
-                          || (currentCharacter == '\n')) {
-                        checkNonExternalizeString();
-                        if (recordLineSeparator) {
-                          pushLineSeparator();
-                        } else {
-                          currentLine = null;
-                        }
-                      }
-                      star = currentCharacter == '*';
-                      //get next char
-                      currentCharacter = source[currentPosition++];
-                      //                      if (((currentCharacter = source[currentPosition++])
-                      //                        == '\\')
-                      //                        && (source[currentPosition] == 'u')) {
-                      //                        //-------------unicode traitement ------------
-                      //                        getNextUnicodeChar();
-                      //                      }
-                      //handle the \\u case manually into comment
-                      //                      if (currentCharacter == '\\') {
-                      //                        if (source[currentPosition] == '\\')
-                      //                          currentPosition++;
-                      //                      } //jump over the \\
-                    }
-                    recordComment(isJavadoc);
-                    if (tokenizeComments) {
-                      if (isJavadoc)
-                        return TokenNameCOMMENT_PHPDOC;
-                      return TokenNameCOMMENT_BLOCK;
+                    if (isPHPIdentifierStart(currentCharacter)) {
+                      return scanIdentifierOrKeyword(true);
+                    } else {
+                      currentPosition = oldPosition;
+                      return TokenNameDOLLAR;
                     }
                   } catch (IndexOutOfBoundsException e) {
-                    throw new InvalidInputException(UNTERMINATED_COMMENT);
-                  }
-                  break;
-                }
-                return TokenNameDIVIDE;
-              }
-            case '\u001a' :
-              if (atEnd())
-                return TokenNameEOF;
-              //the atEnd may not be <currentPosition == source.length> if
-              // source is only some part of a real (external) stream
-              throw new InvalidInputException("Ctrl-Z"); //$NON-NLS-1$
-            default :
-              if (currentCharacter == '$') {
-                int oldPosition = currentPosition;
-                try {
-                  currentCharacter = source[currentPosition++];
-                  if (isPHPIdentifierStart(currentCharacter)) {
-                    return scanIdentifierOrKeyword(true);
-                  } else {
                     currentPosition = oldPosition;
                     return TokenNameDOLLAR;
                   }
-                } catch (IndexOutOfBoundsException e) {
-                  currentPosition = oldPosition;
-                  return TokenNameDOLLAR;
                 }
-              }
-              if (isPHPIdentifierStart(currentCharacter))
-                return scanIdentifierOrKeyword(false);
-              if (Character.isDigit(currentCharacter))
-                return scanNumber(false);
-              return TokenNameERROR;
-          }
+                if (isPHPIdentifierStart(currentCharacter))
+                  return scanIdentifierOrKeyword(false);
+                if (Character.isDigit(currentCharacter))
+                  return scanNumber(false);
+                return TokenNameERROR;
+            }
+         
         }
       } //-----------------end switch while try--------------------
       catch (IndexOutOfBoundsException e) {
@@ -1679,9 +1539,9 @@ public class Scanner implements IScanner, ITerminalSymbols {
    */
   private int getInlinedHTML(int start) throws InvalidInputException {
     //    int htmlPosition = start;
-    if (currentPosition>source.length) {
-        currentPosition = source.length;
-        return TokenNameEOF;
+    if (currentPosition > source.length) {
+      currentPosition = source.length;
+      return TokenNameEOF;
     }
     startPosition = start;
     try {
@@ -3444,6 +3304,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
     initialPosition = currentPosition = 0;
     containsAssertKeyword = false;
     withoutUnicodeBuffer = new char[this.source.length];
+    encapsedStringStack = new Stack();
   }
   public String toString() {
     if (startPosition == source.length)
@@ -3597,12 +3458,20 @@ public class Scanner implements IScanner, ITerminalSymbols {
       case TokenNameDoubleLiteral :
         return "Double(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
       case TokenNameStringLiteral :
-        return "String(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+        return "StringLiteral(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
       case TokenNameStringConstant :
         return "StringConstant(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
       case TokenNameStringInterpolated :
         return "StringInterpolated(" + new String(getCurrentTokenSource())
             + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+      case TokenNameEncapsedString0 :
+        return "`"; //$NON-NLS-1$  
+      case TokenNameEncapsedString1 :
+        return "\'"; //$NON-NLS-1$  
+      case TokenNameEncapsedString2 :
+        return "\""; //$NON-NLS-1$  
+      case TokenNameSTRING :
+        return "STRING(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
       case TokenNameHEREDOC :
         return "HEREDOC(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$
       case TokenNamePLUS_PLUS :
@@ -3709,8 +3578,8 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return "@";
       case TokenNameDOLLAR :
         return "$";
-      //      case TokenNameDOLLAR_LBRACE :
-      //        return "${";
+      case TokenNameDOLLAR_LBRACE :
+        return "${";
       case TokenNameEOF :
         return "EOF"; //$NON-NLS-1$
       case TokenNameWHITESPACE :
@@ -3721,9 +3590,9 @@ public class Scanner implements IScanner, ITerminalSymbols {
         return "COMMENT_BLOCK(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$
       case TokenNameCOMMENT_PHPDOC :
         return "COMMENT_PHPDOC(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$
-        //      case TokenNameHTML :
-        //        return "HTML(" + new String(getCurrentTokenSource()) + ")";
-        // //$NON-NLS-1$
+      //      case TokenNameHTML :
+      //        return "HTML(" + new String(getCurrentTokenSource()) + ")";
+      // //$NON-NLS-1$
       case TokenNameFILE :
         return "__FILE__"; //$NON-NLS-1$
       case TokenNameLINE :
@@ -3761,6 +3630,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
     this.tokenizeWhiteSpace = tokenizeWhiteSpace;
     this.checkNonExternalizedStringLiterals = checkNonExternalizedStringLiterals;
     this.assertMode = assertMode;
+    this.encapsedStringStack = null;
   }
   private void checkNonExternalizeString() throws InvalidInputException {
     if (currentLine == null)