no indentation of HTML and phpdocs
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / formatter / CodeFormatter.java
index 516c7de..bfb0e3b 100644 (file)
@@ -23,80 +23,90 @@ import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
 import net.sourceforge.phpdt.internal.compiler.ConfigurableOption;
 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
-
+import net.sourceforge.phpdt.internal.corext.codemanipulation.StubUtility;
+import net.sourceforge.phpdt.internal.corext.util.Strings;
 import net.sourceforge.phpdt.internal.formatter.impl.FormatterOptions;
 import net.sourceforge.phpdt.internal.formatter.impl.SplitLine;
-
-/** <h2>How to format a piece of code ?</h2>
- * <ul><li>Create an instance of <code>CodeFormatter</code>
- * <li>Use the method <code>void format(aString)</code>
- * on this instance to format <code>aString</code>.
- * It will return the formatted string.</ul>
-*/
+import net.sourceforge.phpdt.internal.ui.preferences.CodeFormatterPreferencePage;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.formatter.IContentFormatterExtension;
+import org.eclipse.jface.text.formatter.IFormattingContext;
+
+/**
+ * <h2>How to format a piece of code ?</h2>
+ * <ul>
+ * <li>Create an instance of <code>CodeFormatter</code>
+ * <li>Use the method <code>void format(aString)</code> on this instance to format <code>aString</code>. It will return the
+ * formatted string.
+ * </ul>
+ */
 public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
-
+  // IContentFormatterExtension {
   public FormatterOptions options;
 
-  /** 
+  /**
    * Represents a block in the <code>constructions</code> stack.
    */
   public static final int BLOCK = ITerminalSymbols.TokenNameLBRACE;
 
-  /** 
+  /**
    * Represents a block following a control statement in the <code>constructions</code> stack.
    */
   public static final int NONINDENT_BLOCK = -100;
 
-  /** 
+  /**
    * Contains the formatted output.
    */
   StringBuffer formattedSource;
 
-  /** 
-   * Contains the current line.<br>
+  /**
+   * Contains the current line. <br>
    * Will be dumped at the next "newline"
    */
   StringBuffer currentLineBuffer;
 
-  /** 
+  /**
    * Used during the formatting to get each token.
    */
   Scanner scanner;
 
-  /** 
-   * Contains the tokens responsible for the current indentation level
-   * and the blocks not closed yet.
+  /**
+   * Contains the tokens responsible for the current indentation level and the blocks not closed yet.
    */
   private int[] constructions;
 
-  /** 
+  /**
    * Index in the <code>constructions</code> array.
    */
   private int constructionsCount;
 
-  /** 
+  /**
    * Level of indentation of the current token (number of tab char put in front of it).
    */
   private int indentationLevel;
 
-  /** 
+  /**
    * Regular level of indentation of all the lines
    */
   private int initialIndentationLevel;
 
-  /** 
+  /**
    * Used to split a line.
    */
   Scanner splitScanner;
 
-  /** 
-   * To remember the offset between the beginning of the line and the
-   * beginning of the comment.
+  /**
+   * To remember the offset between the beginning of the line and the beginning of the comment.
    */
   int currentCommentOffset;
+
   int currentLineIndentationLevel;
+
   int maxLineSize = 30;
+
   private boolean containsOpenCloseBraces;
+
   private int indentationLevelForOpenCloseBraces;
 
   /**
@@ -123,7 +133,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
 
   private int multipleLineCommentCounter;
 
-  /** 
+  /**
    * Creates a new instance of Code Formatter using the given settings.
    * 
    * @deprecated backport 1.0 internal functionality
@@ -132,106 +142,94 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     this(convertConfigurableOptions(settings));
   }
 
-  /** 
-   * Creates a new instance of Code Formatter using the FormattingOptions object
-   * given as argument
+  /**
+   * Creates a new instance of Code Formatter using the FormattingOptions object given as argument
+   * 
    * @deprecated Use CodeFormatter(ConfigurableOption[]) instead
    */
   public CodeFormatter() {
     this((Map) null);
   }
-  /** 
+
+  /**
    * Creates a new instance of Code Formatter using the given settings.
    */
   public CodeFormatter(Map settings) {
-
     // initialize internal state
     constructionsCount = 0;
     constructions = new int[10];
     currentLineIndentationLevel = indentationLevel = initialIndentationLevel;
     currentCommentOffset = -1;
-
     // initialize primary and secondary scanners
-    scanner = new Scanner(true /*comment*/
-    , true /*whitespace*/
-    , false /*nls*/
-    , false /*assert*/
-    ); // regular scanner for forming lines
+    scanner = new Scanner(true /* comment */
+    , true /* whitespace */
+    , false /* nls */
+    , false /* assert */
+    , true, /* tokenizeStrings */
+    null, null); // regular scanner for forming lines
     scanner.recordLineSeparator = true;
-
     // to remind of the position of the beginning of the line.
-    splitScanner = new Scanner(true /*comment*/
-    , true /*whitespace*/
-    , false /*nls*/
-    , false /*assert*/
-    );
+    splitScanner = new Scanner(true /* comment */
+    , true /* whitespace */
+    , false /* nls */
+    , false /* assert */
+    , true, /* tokenizeStrings */
+    null, null);
     // secondary scanner to split long lines formed by primary scanning
-
     // initialize current line buffer
     currentLineBuffer = new StringBuffer();
     this.options = new FormatterOptions(settings);
   }
 
   /**
-   * Returns true if a lineSeparator has to be inserted before <code>operator</code>
-   * false otherwise.
+   * Returns true if a lineSeparator has to be inserted before <code>operator</code> false otherwise.
    */
   private static boolean breakLineBeforeOperator(int operator) {
     switch (operator) {
-      case TokenNameCOMMA :
-      case TokenNameSEMICOLON :
-      case TokenNameEQUAL :
-        return false;
-      default :
-        return true;
+    case TokenNameCOMMA:
+    case TokenNameSEMICOLON:
+    case TokenNameEQUAL:
+      return false;
+    default:
+      return true;
     }
   }
 
-  /** 
-  * @deprecated backport 1.0 internal functionality
-  */
+  /**
+   * @deprecated backport 1.0 internal functionality
+   */
   private static Map convertConfigurableOptions(ConfigurableOption[] settings) {
     Hashtable options = new Hashtable(10);
-
     for (int i = 0; i < settings.length; i++) {
       if (settings[i].getComponentName().equals(CodeFormatter.class.getName())) {
         String optionName = settings[i].getOptionName();
         int valueIndex = settings[i].getCurrentValueIndex();
-
         if (optionName.equals("newline.openingBrace")) { //$NON-NLS-1$
           options.put("net.sourceforge.phpdt.core.formatter.newline.openingBrace", valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
         } else if (optionName.equals("newline.controlStatement")) { //$NON-NLS-1$
-          options.put("net.sourceforge.phpdt.core.formatter.newline.controlStatement", valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
+          options
+              .put("net.sourceforge.phpdt.core.formatter.newline.controlStatement", valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         } else if (optionName.equals("newline.clearAll")) { //$NON-NLS-1$
           options.put("net.sourceforge.phpdt.core.formatter.newline.clearAll", valueIndex == 0 ? "clear all" : "preserve one"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
         } else if (optionName.equals("newline.elseIf")) { //$NON-NLS-1$
           options.put("net.sourceforge.phpdt.core.formatter.newline.elseIf", valueIndex == 0 ? "do not insert" : "insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
         } else if (optionName.equals("newline.emptyBlock")) { //$NON-NLS-1$
           options.put("net.sourceforge.phpdt.core.formatter.newline.emptyBlock", valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
         } else if (optionName.equals("lineSplit")) { //$NON-NLS-1$
           options.put("net.sourceforge.phpdt.core.formatter.lineSplit", String.valueOf(valueIndex)); //$NON-NLS-1$ //$NON-NLS-2$
-
         } else if (optionName.equals("style.assignment")) { //$NON-NLS-1$
           options.put("net.sourceforge.phpdt.core.formatter.style.assignment", valueIndex == 0 ? "compact" : "normal"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
         } else if (optionName.equals("tabulation.char")) { //$NON-NLS-1$
           options.put("net.sourceforge.phpdt.core.formatter.tabulation.char", valueIndex == 0 ? "tab" : "space"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
         } else if (optionName.equals("tabulation.size")) { //$NON-NLS-1$
           options.put("net.sourceforge.phpdt.core.formatter.tabulation.size", String.valueOf(valueIndex)); //$NON-NLS-1$ //$NON-NLS-2$
         }
       }
     }
-
     return options;
   }
 
-  /** 
+  /**
    * Returns the end of the source code.
    */
   private final String copyRemainingSource() {
@@ -292,7 +290,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     updateMappedPositions(scanner.startPosition);
   }
 
-  /** 
+  /**
    * Formats the input string.
    */
   private void format() {
@@ -301,7 +299,6 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     int previousCompilableToken = 0;
     int indentationOffset = 0;
     int newLinesInWhitespace = 0;
-
     // number of new lines in the previous whitespace token
     // (used to leave blank lines before comments)
     int pendingNewLines = 0;
@@ -315,53 +312,55 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     boolean inArrayAssignment = false;
     boolean inThrowsClause = false;
     boolean inClassOrInterfaceHeader = false;
-
-    // openBracketCount is used to count the number of open brackets not closed yet.
+    int dollarBraceCount = 0;
+    // openBracketCount is used to count the number of open brackets not closed
+    // yet.
     int openBracketCount = 0;
     int unarySignModifier = 0;
-
-    // openParenthesis[0] is used to count the parenthesis not belonging to a condition
+    // openParenthesis[0] is used to count the parenthesis not belonging to a
+    // condition
     // (eg foo();). parenthesis in for (...) are count elsewhere in the array.
     int openParenthesisCount = 1;
     int[] openParenthesis = new int[10];
-
-    // tokenBeforeColon is used to know what token goes along with the current :
+    // tokenBeforeColon is used to know what token goes along with the current
+    // :
     // it can be case or ?
     int tokenBeforeColonCount = 0;
     int[] tokenBeforeColon = new int[10];
-
     constructionsCount = 0; // initializes the constructions count.
-
     // contains DO if in a DO..WHILE statement, UNITIALIZED otherwise.
     int nlicsToken = 0;
-
-    // fix for 1FF17XY: LFCOM:ALL - Format problem on not matching } and else 
+    // fix for 1FF17XY: LFCOM:ALL - Format problem on not matching } and else
     boolean specialElse = false;
-
     // OPTION (IndentationLevel): initial indentation level may be non-zero.
     currentLineIndentationLevel += constructionsCount;
-
-    // An InvalidInputException exception might cause the termination of this loop.
+    // An InvalidInputException exception might cause the termination of this
+    // loop.
     try {
       while (true) {
-        // Get the next token.  Catch invalid input and output it
+        // Get the next token. Catch invalid input and output it
         // with minimal formatting, also catch end of input and
         // exit the loop.
         try {
           token = scanner.getNextToken();
-
+          if (Scanner.DEBUG) {
+            int currentEndPosition = scanner.getCurrentTokenEndPosition();
+            int currentStartPosition = scanner.getCurrentTokenStartPosition();
+            System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
+            System.out.println(scanner.toStringAction(token));
+          }
           // Patch for line comment
           // See PR http://dev.eclipse.org/bugs/show_bug.cgi?id=23096
           if (token == ITerminalSymbols.TokenNameCOMMENT_LINE) {
             int length = scanner.currentPosition;
-            loop : for (int index = length - 1; index >= 0; index--) {
+            loop: for (int index = length - 1; index >= 0; index--) {
               switch (scanner.source[index]) {
-                case '\r' :
-                case '\n' :
-                  scanner.currentPosition--;
-                  break;
-                default :
-                  break loop;
+              case '\r':
+              case '\n':
+                scanner.currentPosition--;
+                break;
+              default:
+                break loop;
               }
             }
           }
@@ -371,40 +370,53 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           }
           token = 0;
         }
-        if (token == Scanner.TokenNameEOF)
+        if (token == Scanner.TokenNameEOF) {
           break;
-
-        /* ## MODIFYING the indentation level before generating new lines
-        and indentation in the output string
-        */
-
-        // Removes all the indentations made by statements not followed by a block
-        // except if the current token is ELSE, CATCH or if we are in a switch/case
+        } else if (token == Scanner.TokenNameHEREDOC) {
+          // no indentation for heredocs and HTML !
+          outputCurrentTokenWithoutIndent(Scanner.TokenNameHEREDOC, 0);
+          continue;
+        } else if (token == Scanner.TokenNameINLINE_HTML) {
+          // no indentation for heredocs and HTML !
+          int newLineCount = 1;
+          if (scanner.startPosition==0) {
+            newLineCount = 0;
+          }
+          outputCurrentTokenWithoutIndent(Scanner.TokenNameINLINE_HTML, newLineCount);
+          continue;
+        }
+        /*
+         * ## MODIFYING the indentation level before generating new lines and indentation in the output string
+         */
+        // Removes all the indentations made by statements not followed by a
+        // block
+        // except if the current token is ELSE, CATCH or if we are in a
+        // switch/case
         if (clearNonBlockIndents && (token != Scanner.TokenNameWHITESPACE)) {
           switch (token) {
-            case TokenNameelse :
-              if (constructionsCount > 0 && constructions[constructionsCount - 1] == TokenNameelse) {
-                pendingNewLines = 1;
-                specialElse = true;
-              }
-              indentationLevel += popInclusiveUntil(TokenNameif);
+          case TokenNameelse:
+            if (constructionsCount > 0 && constructions[constructionsCount - 1] == TokenNameelse) {
+              pendingNewLines = 1;
+              specialElse = true;
+            }
+            indentationLevel += popInclusiveUntil(TokenNameif);
+            break;
+          //                                           case TokenNamecatch :
+          //                                                   indentationLevel += popInclusiveUntil(TokenNamecatch);
+          //                                                   break;
+          //                                           case TokenNamefinally :
+          //                                                   indentationLevel += popInclusiveUntil(TokenNamecatch);
+          //                                                   break;
+          case TokenNamewhile:
+            if (nlicsToken == TokenNamedo) {
+              indentationLevel += pop(TokenNamedo);
               break;
-              //                                               case TokenNamecatch :
-              //                                                       indentationLevel += popInclusiveUntil(TokenNamecatch);
-              //                                                       break;
-              //                                               case TokenNamefinally :
-              //                                                       indentationLevel += popInclusiveUntil(TokenNamecatch);
-              //                                                       break;
-            case TokenNamewhile :
-              if (nlicsToken == TokenNamedo) {
-                indentationLevel += pop(TokenNamedo);
-                break;
-              }
-            default :
-              indentationLevel += popExclusiveUntilBlockOrCase();
-              // clear until a CASE, DEFAULT or BLOCK is encountered.
-              // Thus, the indentationLevel is correctly cleared either
-              // in a switch/case statement or in any other situation.
+            }
+          default:
+            indentationLevel += popExclusiveUntilBlockOrCase();
+          // clear until a CASE, DEFAULT or BLOCK is encountered.
+          // Thus, the indentationLevel is correctly cleared either
+          // in a switch/case statement or in any other situation.
           }
           clearNonBlockIndents = false;
         }
@@ -416,15 +428,14 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         //                             if (token == Scanner.TokenNamethrows) {
         //                                     inThrowsClause = true;
         //                             }
-        if ((token == Scanner.TokenNameclass // || token == Scanner.TokenNameinterface
-        )
-          && previousToken != Scanner.TokenNameDOT) {
+        if ((token == Scanner.TokenNameclass || token == Scanner.TokenNameinterface) && previousToken != Scanner.TokenNameDOT) {
           inClassOrInterfaceHeader = true;
         }
-
-        /* ## APPEND newlines and indentations to the output string
-        */
-        // Do not add a new line between ELSE and IF, if the option elseIfOnSameLine is true.
+        /*
+         * ## APPEND newlines and indentations to the output string
+         */
+        // Do not add a new line between ELSE and IF, if the option
+        // elseIfOnSameLine is true.
         // Fix for 1ETLWPZ: IVJCOM:ALL - incorrect "else if" formatting
         //        if (pendingNewlineAfterParen
         //          && previousCompilableToken == TokenNameelse
@@ -440,20 +451,19 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         // Add a newline & indent to the formatted source string if
         // a for/if-else/while statement was scanned and there is no block
         // following it.
-        pendingNewlineAfterParen =
-          pendingNewlineAfterParen || (previousCompilableToken == TokenNameRPAREN && token == TokenNameLBRACE);
+        pendingNewlineAfterParen = pendingNewlineAfterParen
+            || (previousCompilableToken == TokenNameRPAREN && token == TokenNameLBRACE);
         if (pendingNewlineAfterParen && token != Scanner.TokenNameWHITESPACE) {
           pendingNewlineAfterParen = false;
-
           // Do to add a newline & indent sequence if the current token is an
-          // open brace or a period or if the current token is a semi-colon and the
+          // open brace or a period or if the current token is a semi-colon and
+          // the
           // previous token is a close paren.
           // add a new line if a parenthesis belonging to a for() statement
           // has been closed and the current token is not an opening brace
-          if (token != TokenNameLBRACE
-            && !isComment(token) // to avoid adding new line between else and a comment
-            && token != TokenNameDOT
-            && !(previousCompilableToken == TokenNameRPAREN && token == TokenNameSEMICOLON)) {
+          if (token != TokenNameLBRACE && !isComment(token)
+          // to avoid adding new line between else and a comment
+              && token != TokenNameDOT && !(previousCompilableToken == TokenNameRPAREN && token == TokenNameSEMICOLON)) {
             newLine(1);
             currentLineIndentationLevel = indentationLevel;
             pendingNewLines = 0;
@@ -461,9 +471,8 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           } else {
             if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode) {
               newLine(1);
-              if (constructionsCount > 0
-                && constructions[constructionsCount - 1] != BLOCK
-                && constructions[constructionsCount - 1] != NONINDENT_BLOCK) {
+              if (constructionsCount > 0 && constructions[constructionsCount - 1] != BLOCK
+                  && constructions[constructionsCount - 1] != NONINDENT_BLOCK) {
                 currentLineIndentationLevel = indentationLevel - 1;
               } else {
                 currentLineIndentationLevel = indentationLevel;
@@ -473,10 +482,8 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
             }
           }
         }
-        if (token == TokenNameLBRACE
-          && options.newLineBeforeOpeningBraceMode
-          && constructionsCount > 0
-          && constructions[constructionsCount - 1] == TokenNamedo) {
+        if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode && constructionsCount > 0
+            && constructions[constructionsCount - 1] == TokenNamedo) {
           newLine(1);
           currentLineIndentationLevel = indentationLevel - 1;
           pendingNewLines = 0;
@@ -505,40 +512,33 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         // Add pending new lines to the formatted source string.
         // Note: pending new lines are not added if the current token
         // is a single line comment or whitespace.
-        // if the comment is between parenthesis, there is no blank line preservation
+        // if the comment is between parenthesis, there is no blank line
+        // preservation
         // (if it's a one-line comment, a blank line is added after it).
         if (((pendingNewLines > 0 && (!isComment(token)))
-          || (newLinesInWhitespace > 0 && (openParenthesisCount <= 1 && isComment(token)))
-          || (previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE))
-          && token != Scanner.TokenNameWHITESPACE) {
-
+            || (newLinesInWhitespace > 0 && (openParenthesisCount <= 1 && isComment(token))) || (previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE))
+            && token != Scanner.TokenNameWHITESPACE) {
           // Do not add newline & indent between an adjoining close brace and
-          // close paren.  Anonymous inner classes may use this form.
+          // close paren. Anonymous inner classes may use this form.
           boolean closeBraceAndCloseParen = previousToken == TokenNameRBRACE && token == TokenNameRPAREN;
-
           // OPTION (NewLineInCompoundStatement): do not add newline & indent
           // between close brace and else, (do) while, catch, and finally if
           // newlineInCompoundStatement is true.
-          boolean nlicsOption =
-            previousToken == TokenNameRBRACE
+          boolean nlicsOption = previousToken == TokenNameRBRACE
               && !options.newlineInControlStatementMode
-              && (token == TokenNameelse || (token == TokenNamewhile && nlicsToken == TokenNamedo));
-          //                                                           || token == TokenNamecatch
-          //                                                           || token == TokenNamefinally);
-
-          // Do not add a newline & indent between a close brace and semi-colon.
+              && (token == TokenNameelse || (token == TokenNamewhile && nlicsToken == TokenNamedo) || token == TokenNamecatch || token == TokenNamefinally);
+          // Do not add a newline & indent between a close brace and
+          // semi-colon.
           boolean semiColonAndCloseBrace = previousToken == TokenNameRBRACE && token == TokenNameSEMICOLON;
-
-          // Do not add a new line & indent between a multiline comment and a opening brace
+          // Do not add a new line & indent between a multiline comment and a
+          // opening brace
           boolean commentAndOpenBrace = previousToken == Scanner.TokenNameCOMMENT_BLOCK && token == TokenNameLBRACE;
-
-          // Do not add a newline & indent between a close brace and a colon (in array assignments, for example).
+          // Do not add a newline & indent between a close brace and a colon
+          // (in array assignments, for example).
           boolean commaAndCloseBrace = previousToken == TokenNameRBRACE && token == TokenNameCOMMA;
-
           // Add a newline and indent, if appropriate.
           if (specialElse
-            || (!commentAndOpenBrace && !closeBraceAndCloseParen && !nlicsOption && !semiColonAndCloseBrace && !commaAndCloseBrace)) {
-
+              || (!commentAndOpenBrace && !closeBraceAndCloseParen && !nlicsOption && !semiColonAndCloseBrace && !commaAndCloseBrace)) {
             // if clearAllBlankLinesMode=false, leaves the blank lines
             // inserted by the user
             // if clearAllBlankLinesMode=true, removes all of then
@@ -554,10 +554,10 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
               if (isComment(previousToken)) {
                 newLine(pendingNewLines);
               } else {
-                /*  if (!(constructionsCount > 1
-                        && constructions[constructionsCount-1] == NONINDENT_BLOCK
-                        && (constructions[constructionsCount-2] == TokenNamefor 
-                         || constructions[constructionsCount-2] == TokenNamewhile))) {*/
+                /*
+                 * if (!(constructionsCount > 1 && constructions[constructionsCount-1] == NONINDENT_BLOCK &&
+                 * (constructions[constructionsCount-2] == TokenNamefor
+                 */
                 if (options.newLineInEmptyBlockMode) {
                   if (inArrayAssignment) {
                     newLine(1); // array assigment with an empty block
@@ -568,17 +568,15 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
                 // }
               }
             } else {
-              // see PR 1FKKC3U: LFCOM:WINNT - Format problem with a comment before the ';'
-              if (!((previousToken == Scanner.TokenNameCOMMENT_BLOCK || previousToken == Scanner.TokenNameCOMMENT_PHPDOC)
-                && token == TokenNameSEMICOLON)) {
+              // see PR 1FKKC3U: LFCOM:WINNT - Format problem with a comment
+              // before the ';'
+              if (!((previousToken == Scanner.TokenNameCOMMENT_BLOCK || previousToken == Scanner.TokenNameCOMMENT_PHPDOC) && token == TokenNameSEMICOLON)) {
                 newLine(pendingNewLines);
               }
             }
-            if (((previousCompilableToken == TokenNameSEMICOLON)
-              || (previousCompilableToken == TokenNameLBRACE)
-              || (previousCompilableToken == TokenNameRBRACE)
-              || (isComment(previousToken)))
-              && (token == TokenNameRBRACE)) {
+            if (((previousCompilableToken == TokenNameSEMICOLON) || (previousCompilableToken == TokenNameLBRACE)
+                || (previousCompilableToken == TokenNameRBRACE) || (isComment(previousToken)))
+                && (token == TokenNameRBRACE)) {
               indentationOffset = -1;
               indentationLevel += popExclusiveUntilBlock();
             }
@@ -594,121 +592,112 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           pendingNewLines = 0;
           newLinesInWhitespace = 0;
           specialElse = false;
-
           if (nlicsToken == TokenNamedo && token == TokenNamewhile) {
             nlicsToken = 0;
           }
         }
+        boolean phpTagAndWhitespace = previousToken == TokenNameINLINE_HTML && token == TokenNameWHITESPACE;
         switch (token) {
-          case TokenNameelse :
-            //                         case TokenNamefinally :
-            expectingOpenBrace = true;
-            pendingNewlineAfterParen = true;
-            indentationLevel += pushControlStatement(token);
-            break;
-          case TokenNamecase :
-          case TokenNamedefault :
-            if (tokenBeforeColonCount == tokenBeforeColon.length) {
-              System.arraycopy(
-                tokenBeforeColon,
-                0,
-                (tokenBeforeColon = new int[tokenBeforeColonCount * 2]),
-                0,
-                tokenBeforeColonCount);
-            }
-            tokenBeforeColon[tokenBeforeColonCount++] = TokenNamecase;
-            indentationLevel += pushControlStatement(TokenNamecase);
-            break;
-          case TokenNameQUESTION :
-            if (tokenBeforeColonCount == tokenBeforeColon.length) {
-              System.arraycopy(
-                tokenBeforeColon,
-                0,
-                (tokenBeforeColon = new int[tokenBeforeColonCount * 2]),
-                0,
-                tokenBeforeColonCount);
-            }
-            tokenBeforeColon[tokenBeforeColonCount++] = token;
-            break;
-          case TokenNameswitch :
-          case TokenNamefor :
-          case TokenNameif :
-          case TokenNamewhile :
-            if (openParenthesisCount == openParenthesis.length) {
-              System.arraycopy(openParenthesis, 0, (openParenthesis = new int[openParenthesisCount * 2]), 0, openParenthesisCount);
-            }
-            openParenthesis[openParenthesisCount++] = 0;
-            expectingOpenBrace = true;
-
-            indentationLevel += pushControlStatement(token);
-            break;
-            //                                 case TokenNametry :
-            //                                         pendingNewlineAfterParen = true;
-            //                                 case TokenNamecatch :
-            //                                         // several CATCH statements can be contiguous.
-            //                                         // a CATCH is encountered pop until first CATCH (if a CATCH follows a TRY it works the same way,
-            //                                         // as CATCH and TRY are the same token in the stack).
-            //                                         expectingOpenBrace = true;
-            //                                         indentationLevel += pushControlStatement(TokenNamecatch);
-            //                                         break;
-
-          case TokenNamedo :
-            expectingOpenBrace = true;
-            indentationLevel += pushControlStatement(token);
-            nlicsToken = token;
-            break;
-          case TokenNamenew :
-            break;
-          case TokenNameLPAREN :
-            //                                         if (previousToken == TokenNamesynchronized) {
-            //                                                 indentationLevel += pushControlStatement(previousToken);
-            //                                         } else {
-            // Put a space between the previous and current token if the
-            // previous token was not a keyword, open paren, logical
-            // compliment (eg: !), semi-colon, open brace, close brace,
-            // super, or this.
-            if (previousCompilableToken != TokenNameLBRACKET
-              && previousToken != TokenNameIdentifier
-              && previousToken != 0
-              && previousToken != TokenNameNOT
-              && previousToken != TokenNameLPAREN
-              && previousToken != TokenNameTWIDDLE
-              && previousToken != TokenNameSEMICOLON
-              && previousToken != TokenNameLBRACE
-              && previousToken != TokenNameRBRACE) {
-              //                                                               && previousToken != TokenNamesuper
-              //                                                               && previousToken != TokenNamethis) {
-              space();
-            }
-            // If in a for/if/while statement, increase the parenthesis count
-            // for the current openParenthesisCount
-            // else increase the count for stand alone parenthesis.
-            if (openParenthesisCount > 0)
-              openParenthesis[openParenthesisCount - 1]++;
-            else
-              openParenthesis[0]++;
-
-            pendingSpace = false;
-            //S                        }
-            break;
-          case TokenNameRPAREN :
-
-            // Decrease the parenthesis count
-            // if there is no more unclosed parenthesis,
-            // a new line and indent may be append (depending on the next token).
-            if ((openParenthesisCount > 1) && (openParenthesis[openParenthesisCount - 1] > 0)) {
-              openParenthesis[openParenthesisCount - 1]--;
-              if (openParenthesis[openParenthesisCount - 1] <= 0) {
-                pendingNewlineAfterParen = true;
-                inAssignment = false;
-                openParenthesisCount--;
-              }
-            } else {
-              openParenthesis[0]--;
+        //          case TokenNameDOLLAR :
+        //            dollarBraceCount++;
+        //            break;
+        case TokenNameelse:
+          //                           case TokenNamefinally :
+          expectingOpenBrace = true;
+          pendingNewlineAfterParen = true;
+          indentationLevel += pushControlStatement(token);
+          break;
+        case TokenNamecase:
+        case TokenNamedefault:
+          if (tokenBeforeColonCount == tokenBeforeColon.length) {
+            System
+                .arraycopy(tokenBeforeColon, 0, (tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 0, tokenBeforeColonCount);
+          }
+          tokenBeforeColon[tokenBeforeColonCount++] = TokenNamecase;
+          indentationLevel += pushControlStatement(TokenNamecase);
+          break;
+        case TokenNameQUESTION:
+          if (tokenBeforeColonCount == tokenBeforeColon.length) {
+            System
+                .arraycopy(tokenBeforeColon, 0, (tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 0, tokenBeforeColonCount);
+          }
+          tokenBeforeColon[tokenBeforeColonCount++] = token;
+          break;
+        case TokenNameswitch:
+        case TokenNamefor:
+        case TokenNameforeach:
+        case TokenNameif:
+        case TokenNamewhile:
+          if (openParenthesisCount == openParenthesis.length) {
+            System.arraycopy(openParenthesis, 0, (openParenthesis = new int[openParenthesisCount * 2]), 0, openParenthesisCount);
+          }
+          openParenthesis[openParenthesisCount++] = 0;
+          expectingOpenBrace = true;
+          indentationLevel += pushControlStatement(token);
+          break;
+        case TokenNametry:
+          pendingNewlineAfterParen = true;
+        case TokenNamecatch:
+          // several CATCH statements can be contiguous.
+          // a CATCH is encountered pop until first CATCH (if a CATCH
+          // follows a TRY it works the same way,
+          // as CATCH and TRY are the same token in the stack).
+          expectingOpenBrace = true;
+          indentationLevel += pushControlStatement(TokenNamecatch);
+          break;
+        case TokenNamedo:
+          expectingOpenBrace = true;
+          indentationLevel += pushControlStatement(token);
+          nlicsToken = token;
+          break;
+        case TokenNamenew:
+          break;
+        case TokenNameLPAREN:
+          //                                           if (previousToken == TokenNamesynchronized) {
+          //                                                   indentationLevel += pushControlStatement(previousToken);
+          //                                           } else {
+          // Put a space between the previous and current token if the
+          // previous token was not a keyword, open paren, logical
+          // compliment (eg: !), semi-colon, open brace, close brace,
+          // super, or this.
+          if (previousCompilableToken != TokenNameLBRACKET && previousToken != TokenNameIdentifier && previousToken != 0
+              && previousToken != TokenNameNOT && previousToken != TokenNameLPAREN && previousToken != TokenNameTWIDDLE
+              && previousToken != TokenNameSEMICOLON && previousToken != TokenNameLBRACE && previousToken != TokenNameRBRACE
+              && previousToken != TokenNamesuper) {
+            //         && previousToken != TokenNamethis) {
+            space();
+          }
+          // If in a for/if/while statement, increase the parenthesis count
+          // for the current openParenthesisCount
+          // else increase the count for stand alone parenthesis.
+          if (openParenthesisCount > 0)
+            openParenthesis[openParenthesisCount - 1]++;
+          else
+            openParenthesis[0]++;
+          pendingSpace = false;
+          //S }
+          break;
+        case TokenNameRPAREN:
+          // Decrease the parenthesis count
+          // if there is no more unclosed parenthesis,
+          // a new line and indent may be append (depending on the next
+          // token).
+          if ((openParenthesisCount > 1) && (openParenthesis[openParenthesisCount - 1] > 0)) {
+            openParenthesis[openParenthesisCount - 1]--;
+            if (openParenthesis[openParenthesisCount - 1] <= 0) {
+              pendingNewlineAfterParen = true;
+              inAssignment = false;
+              openParenthesisCount--;
             }
-            pendingSpace = false;
-            break;
-          case TokenNameLBRACE :
+          } else {
+            openParenthesis[0]--;
+          }
+          pendingSpace = false;
+          break;
+        case TokenNameLBRACE:
+          if (previousCompilableToken == TokenNameDOLLAR) {
+            dollarBraceCount++;
+          } else {
             if ((previousCompilableToken == TokenNameRBRACKET) || (previousCompilableToken == TokenNameEQUAL)) {
               //                  if (previousCompilableToken == TokenNameRBRACKET) {
               inArrayAssignment = true;
@@ -721,120 +710,125 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
               pendingNewLines = 1;
               indentationLevel += pushBlock();
             }
+          }
+          break;
+        case TokenNameRBRACE:
+          if (dollarBraceCount > 0) {
+            dollarBraceCount--;
             break;
-          case TokenNameRBRACE :
+          }
+          if (previousCompilableToken == TokenNameRPAREN) {
+            pendingSpace = false;
+          }
+          if (inArrayAssignment) {
+            inArrayAssignment = false;
+            pendingNewLines = 1;
+            indentationLevel += popInclusiveUntilBlock();
+          } else {
+            pendingNewLines = 1;
+            indentationLevel += popInclusiveUntilBlock();
             if (previousCompilableToken == TokenNameRPAREN) {
-              pendingSpace = false;
-            }
-            if (inArrayAssignment) {
-              inArrayAssignment = false;
-              pendingNewLines = 1;
-              indentationLevel += popInclusiveUntilBlock();
-            } else {
-              pendingNewLines = 1;
-              indentationLevel += popInclusiveUntilBlock();
-
-              if (previousCompilableToken == TokenNameRPAREN) {
-                // fix for 1FGDDV6: LFCOM:WIN98 - Weird splitting on message expression
-                currentLineBuffer.append(options.lineSeparatorSequence);
-                increaseLineDelta(options.lineSeparatorSequence.length);
-              }
-              if (constructionsCount > 0) {
-                switch (constructions[constructionsCount - 1]) {
-                  case TokenNamefor :
-                    //indentationLevel += popExclusiveUntilBlock();
-                    //break;
-                  case TokenNameswitch :
-                  case TokenNameif :
-                  case TokenNameelse :
-                    //                                                                 case TokenNametry :
-                    //                                                                 case TokenNamecatch :
-                    //                                                                 case TokenNamefinally :
-                  case TokenNamewhile :
-                  case TokenNamedo :
-                    //                                                                 case TokenNamesynchronized :
-                    clearNonBlockIndents = true;
-                  default :
-                    break;
-                }
-              }
+              // fix for 1FGDDV6: LFCOM:WIN98 - Weird splitting on message
+              // expression
+              currentLineBuffer.append(options.lineSeparatorSequence);
+              increaseLineDelta(options.lineSeparatorSequence.length);
             }
-            break;
-          case TokenNameLBRACKET :
-            openBracketCount++;
-            pendingSpace = false;
-            break;
-          case TokenNameRBRACKET :
-            openBracketCount -= (openBracketCount > 0) ? 1 : 0;
-            // if there is no left bracket to close, the right bracket is ignored.
-            pendingSpace = false;
-            break;
-          case TokenNameCOMMA :
-          case TokenNameDOT :
-            pendingSpace = false;
-            break;
-          case TokenNameSEMICOLON :
-
-            // Do not generate line terminators in the definition of
-            // the for statement.
-            // if not in this case, jump a line and reduce indentation after the brace
-            // if the block it closes belongs to a conditional statement (if, while, do...).
-            if (openParenthesisCount <= 1) {
-              pendingNewLines = 1;
-              if (expectingOpenBrace) {
+            if (constructionsCount > 0) {
+              switch (constructions[constructionsCount - 1]) {
+              case TokenNamefor:
+              case TokenNameforeach:
+              //indentationLevel += popExclusiveUntilBlock();
+              //break;
+              case TokenNameswitch:
+              case TokenNameif:
+              case TokenNameelse:
+              case TokenNametry:
+              case TokenNamecatch:
+              case TokenNamefinally:
+              case TokenNamewhile:
+              case TokenNamedo:
+                //                                                                     case TokenNamesynchronized :
                 clearNonBlockIndents = true;
-                expectingOpenBrace = false;
+              default:
+                break;
               }
             }
-            inAssignment = false;
-            pendingSpace = false;
-            break;
-          case TokenNamePLUS_PLUS :
-          case TokenNameMINUS_MINUS :
-
-            // Do not put a space between a post-increment/decrement
-            // and the identifier being modified.
-            if (previousToken == TokenNameIdentifier || previousToken == TokenNameRBRACKET) {
-              pendingSpace = false;
+          }
+          break;
+        case TokenNameLBRACKET:
+          openBracketCount++;
+          pendingSpace = false;
+          break;
+        case TokenNameRBRACKET:
+          openBracketCount -= (openBracketCount > 0) ? 1 : 0;
+          // if there is no left bracket to close, the right bracket is
+          // ignored.
+          pendingSpace = false;
+          break;
+        case TokenNameCOMMA:
+        case TokenNameDOT:
+          pendingSpace = false;
+          break;
+        case TokenNameSEMICOLON:
+          // Do not generate line terminators in the definition of
+          // the for statement.
+          // if not in this case, jump a line and reduce indentation after
+          // the brace
+          // if the block it closes belongs to a conditional statement (if,
+          // while, do...).
+          if (openParenthesisCount <= 1) {
+            pendingNewLines = 1;
+            if (expectingOpenBrace) {
+              clearNonBlockIndents = true;
+              expectingOpenBrace = false;
             }
-            break;
-          case TokenNamePLUS : // previously ADDITION
-          case TokenNameMINUS :
-
-            // Handle the unary operators plus and minus via a flag
-            if (!isLiteralToken(previousToken)
-              && previousToken != TokenNameIdentifier
-              && previousToken != TokenNameRPAREN
+          }
+          inAssignment = false;
+          pendingSpace = false;
+          break;
+        case TokenNamePLUS_PLUS:
+        case TokenNameMINUS_MINUS:
+          // Do not put a space between a post-increment/decrement
+          // and the identifier being modified.
+          if (previousToken == TokenNameIdentifier || previousToken == TokenNameRBRACKET) {
+            pendingSpace = false;
+          }
+          break;
+        case TokenNamePLUS:
+        // previously ADDITION
+        case TokenNameMINUS:
+          // Handle the unary operators plus and minus via a flag
+          if (!isLiteralToken(previousToken) && previousToken != TokenNameIdentifier && previousToken != TokenNameRPAREN
               && previousToken != TokenNameRBRACKET) {
-              unarySignModifier = 1;
-            }
-            break;
-          case TokenNameCOLON :
-            // In a switch/case statement, add a newline & indent
-            // when a colon is encountered.
-            if (tokenBeforeColonCount > 0) {
-              if (tokenBeforeColon[tokenBeforeColonCount - 1] == TokenNamecase) {
-                pendingNewLines = 1;
-              }
-              tokenBeforeColonCount--;
-            }
-            break;
-          case TokenNameEQUAL :
-            inAssignment = true;
-            break;
-          case Scanner.TokenNameCOMMENT_LINE :
-            pendingNewLines = 1;
-            if (inAssignment) {
-              currentLineIndentationLevel++;
+            unarySignModifier = 1;
+          }
+          break;
+        case TokenNameCOLON:
+          // In a switch/case statement, add a newline & indent
+          // when a colon is encountered.
+          if (tokenBeforeColonCount > 0) {
+            if (tokenBeforeColon[tokenBeforeColonCount - 1] == TokenNamecase) {
+              pendingNewLines = 1;
             }
-            break; // a line is always inserted after a one-line comment
-          case Scanner.TokenNameCOMMENT_PHPDOC :
-          case Scanner.TokenNameCOMMENT_BLOCK :
-            currentCommentOffset = getCurrentCommentOffset();
-            pendingNewLines = 1;
-            break;
-          case Scanner.TokenNameWHITESPACE :
-
+            tokenBeforeColonCount--;
+          }
+          break;
+        case TokenNameEQUAL:
+          inAssignment = true;
+          break;
+        case Scanner.TokenNameCOMMENT_LINE:
+          pendingNewLines = 1;
+          if (inAssignment) {
+            currentLineIndentationLevel++;
+          }
+          break; // a line is always inserted after a one-line comment
+        case Scanner.TokenNameCOMMENT_PHPDOC:
+        case Scanner.TokenNameCOMMENT_BLOCK:
+          currentCommentOffset = getCurrentCommentOffset();
+          pendingNewLines = 1;
+          break;
+        case Scanner.TokenNameWHITESPACE:
+          if (!phpTagAndWhitespace) {
             // Count the number of line terminators in the whitespace so
             // line spacing can be preserved near comments.
             char[] source = scanner.source;
@@ -856,55 +850,50 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
             }
             increaseLineDelta(scanner.startPosition - scanner.currentPosition);
             break;
-//          case TokenNameHTML :
-//            // Add the next token to the formatted source string.
-//            // outputCurrentToken(token);
-//            int startPosition = scanner.startPosition;
-//            flushBuffer();
-//            for (int i = startPosition, max = scanner.currentPosition; i < max; i++) {
-//              char currentCharacter = scanner.source[i];
-//              updateMappedPositions(i);
-//              currentLineBuffer.append(currentCharacter);
-//            }
-//            break;
-          default :
-            if ((token == TokenNameIdentifier) || isLiteralToken(token)) {
-              //                                                       || token == TokenNamesuper
-              //                                                       || token == TokenNamethis) {
-
-              // Do not put a space between a unary operator
-              // (eg: ++, --, +, -) and the identifier being modified.
-              if (previousToken == TokenNamePLUS_PLUS
-                || previousToken == TokenNameMINUS_MINUS
+          }
+        //          case TokenNameHTML :
+        //            // Add the next token to the formatted source string.
+        //            // outputCurrentToken(token);
+        //            int startPosition = scanner.startPosition;
+        //            flushBuffer();
+        //            for (int i = startPosition, max = scanner.currentPosition; i <
+        // max; i++) {
+        //              char currentCharacter = scanner.source[i];
+        //              updateMappedPositions(i);
+        //              currentLineBuffer.append(currentCharacter);
+        //            }
+        //            break;
+        default:
+          if ((token == TokenNameIdentifier) || isLiteralToken(token) || token == TokenNamesuper) {
+            //                                                 || token == TokenNamethis) {
+            // Do not put a space between a unary operator
+            // (eg: ++, --, +, -) and the identifier being modified.
+            if (previousToken == TokenNamePLUS_PLUS || previousToken == TokenNameMINUS_MINUS
+                || (previousToken == TokenNameMINUS_GREATER && options.compactDereferencingMode) // ->
                 || (previousToken == TokenNamePLUS && unarySignModifier > 0)
                 || (previousToken == TokenNameMINUS && unarySignModifier > 0)) {
-                pendingSpace = false;
-              }
-              unarySignModifier = 0;
+              pendingSpace = false;
             }
-            break;
+            unarySignModifier = 0;
+          }
+          break;
         }
         // Do not output whitespace tokens.
-        if (token != Scanner.TokenNameWHITESPACE) {
-
-          /* Add pending space to the formatted source string.
-          Do not output a space under the following circumstances:
-          1) this is the first pass
-          2) previous token is an open paren
-          3) previous token is a period
-          4) previous token is the logical compliment (eg: !)
-          5) previous token is the bitwise compliment (eg: ~)
-          6) previous token is the open bracket (eg: [)
-          7) in an assignment statement, if the previous token is an 
-          open brace or the current token is a close brace
-          8) previous token is a single line comment
-          */
-          boolean openAndCloseBrace = previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE;
+        if (token != Scanner.TokenNameWHITESPACE || phpTagAndWhitespace) {
+          /*
+           * Add pending space to the formatted source string. Do not output a space under the following circumstances: 1) this is
+           * the first pass 2) previous token is an open paren 3) previous token is a period 4) previous token is the logical
+           * compliment (eg: !) 5) previous token is the bitwise compliment (eg: ~) 6) previous token is the open bracket (eg: [) 7)
+           * in an assignment statement, if the previous token is an open brace or the current token is a close brace 8) previous
+           * token is a single line comment 9) current token is a '->'
+           */
+          if (token == TokenNameMINUS_GREATER && options.compactDereferencingMode)
+            pendingSpace = false;
 
-          if (pendingSpace
-            && insertSpaceAfter(previousToken)
-            && !(inAssignment && (previousToken == TokenNameLBRACE || token == TokenNameRBRACE))
-            && previousToken != Scanner.TokenNameCOMMENT_LINE) {
+          boolean openAndCloseBrace = previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE;
+          if (pendingSpace && insertSpaceAfter(previousToken)
+              && !(inAssignment && (previousToken == TokenNameLBRACE || token == TokenNameRBRACE))
+              && previousToken != Scanner.TokenNameCOMMENT_LINE) {
             if ((!(options.compactAssignmentMode && token == TokenNameEQUAL)) && !openAndCloseBrace)
               space();
           }
@@ -918,11 +907,10 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           pendingSpace = true;
         }
         // Whitespace tokens do not need to be remembered.
-        if (token != Scanner.TokenNameWHITESPACE) {
+        if (token != Scanner.TokenNameWHITESPACE || phpTagAndWhitespace) {
           previousToken = token;
-          if (token != Scanner.TokenNameCOMMENT_BLOCK
-            && token != Scanner.TokenNameCOMMENT_LINE
-            && token != Scanner.TokenNameCOMMENT_PHPDOC) {
+          if (token != Scanner.TokenNameCOMMENT_BLOCK && token != Scanner.TokenNameCOMMENT_LINE
+              && token != Scanner.TokenNameCOMMENT_PHPDOC) {
             previousCompilableToken = token;
           }
         }
@@ -937,9 +925,9 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     }
   }
 
-  /** 
-   * Formats the char array <code>sourceString</code>,
-   * and returns a string containing the formatted version.
+  /**
+   * Formats the char array <code>sourceString</code>, and returns a string containing the formatted version.
+   * 
    * @return the formatted ouput.
    */
   public String formatSourceString(String sourceString) {
@@ -950,24 +938,29 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     return formattedSource.toString();
   }
 
-  /** 
-   * Formats the char array <code>sourceString</code>,
-   * and returns a string containing the formatted version.
-   * @param string the string to format
-   * @param indentationLevel the initial indentation level
+  /**
+   * Formats the char array <code>sourceString</code>, and returns a string containing the formatted version.
+   * 
+   * @param string
+   *          the string to format
+   * @param indentationLevel
+   *          the initial indentation level
    * @return the formatted ouput.
    */
   public String format(String string, int indentationLevel) {
     return format(string, indentationLevel, (int[]) null);
   }
 
-  /** 
-   * Formats the char array <code>sourceString</code>,
-   * and returns a string containing the formatted version.
-   * The positions array is modified to contain the mapped positions.
-   * @param string the string to format
-   * @param indentationLevel the initial indentation level
-   * @param positions the array of positions to map
+  /**
+   * Formats the char array <code>sourceString</code>, and returns a string containing the formatted version. The positions array
+   * is modified to contain the mapped positions.
+   * 
+   * @param string
+   *          the string to format
+   * @param indentationLevel
+   *          the initial indentation level
+   * @param positions
+   *          the array of positions to map
    * @return the formatted ouput.
    */
   public String format(String string, int indentationLevel, int[] positions) {
@@ -990,19 +983,21 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       return this.formatSourceString(string);
     }
   }
-  /** 
-   * Formats the char array <code>sourceString</code>,
-   * and returns a string containing the formatted version. The initial indentation level is 0.
-   * @param string the string to format
+
+  /**
+   * Formats the char array <code>sourceString</code>, and returns a string containing the formatted version. The initial
+   * indentation level is 0.
+   * 
+   * @param string
+   *          the string to format
    * @return the formatted ouput.
    */
   public String format(String string) {
     return this.format(string, 0, (int[]) null);
   }
 
-  /** 
-   * Formats a given source string, starting indenting it at a particular 
-   * depth and using the given options
+  /**
+   * Formats a given source string, starting indenting it at a particular depth and using the given options
    * 
    * @deprecated backport 1.0 internal functionality
    */
@@ -1013,8 +1008,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   }
 
   /**
-   * Returns the number of characters and tab char between the beginning of the line
-   * and the beginning of the comment.
+   * Returns the number of characters and tab char between the beginning of the line and the beginning of the comment.
    */
   private int getCurrentCommentOffset() {
     int linePtr = scanner.linePtr;
@@ -1025,7 +1019,6 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     int beginningOfLine = scanner.lineEnds[linePtr];
     int currentStartPosition = scanner.startPosition;
     char[] source = scanner.source;
-
     // find the position of the beginning of the line containing the comment
     while (beginningOfLine > currentStartPosition) {
       if (linePtr > 0) {
@@ -1038,25 +1031,24 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     for (int i = currentStartPosition - 1; i >= beginningOfLine; i--) {
       char currentCharacter = source[i];
       switch (currentCharacter) {
-        case '\t' :
-          offset += options.tabSize;
-          break;
-        case ' ' :
-          offset++;
-          break;
-        case '\r' :
-        case '\n' :
-          break;
-        default :
-          return offset;
+      case '\t':
+        offset += options.tabSize;
+        break;
+      case ' ':
+        offset++;
+        break;
+      case '\r':
+      case '\n':
+        break;
+      default:
+        return offset;
       }
     }
     return offset;
   }
 
   /**
-   * Returns an array of descriptions for the configurable options.
-   * The descriptions may be changed and passed back to a different
+   * Returns an array of descriptions for the configurable options. The descriptions may be changed and passed back to a different
    * compiler.
    * 
    * @deprecated backport 1.0 internal functionality
@@ -1064,21 +1056,30 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   public static ConfigurableOption[] getDefaultOptions(Locale locale) {
     String componentName = CodeFormatter.class.getName();
     FormatterOptions options = new FormatterOptions();
-    return new ConfigurableOption[] { new ConfigurableOption(componentName, "newline.openingBrace", locale, options.newLineBeforeOpeningBraceMode ? 0 : 1), //$NON-NLS-1$
-      new ConfigurableOption(componentName, "newline.controlStatement", locale, options.newlineInControlStatementMode ? 0 : 1), //$NON-NLS-1$
-      new ConfigurableOption(componentName, "newline.clearAll", locale, options.clearAllBlankLinesMode ? 0 : 1), //$NON-NLS-1$
-      //      new ConfigurableOption(componentName, "newline.elseIf", locale, options.compactElseIfMode ? 0 : 1), //$NON-NLS-1$
-      new ConfigurableOption(componentName, "newline.emptyBlock", locale, options.newLineInEmptyBlockMode ? 0 : 1), //$NON-NLS-1$
-      new ConfigurableOption(componentName, "line.split", locale, options.maxLineLength), //$NON-NLS-1$
-      new ConfigurableOption(componentName, "style.compactAssignment", locale, options.compactAssignmentMode ? 0 : 1), //$NON-NLS-1$
-      new ConfigurableOption(componentName, "tabulation.char", locale, options.indentWithTab ? 0 : 1), //$NON-NLS-1$
-      new ConfigurableOption(componentName, "tabulation.size", locale, options.tabSize) //$NON-NLS-1$
+    return new ConfigurableOption[] {
+        new ConfigurableOption(componentName, "newline.openingBrace", locale, options.newLineBeforeOpeningBraceMode ? 0 : 1),
+        //$NON-NLS-1$
+        new ConfigurableOption(componentName, "newline.controlStatement", locale, options.newlineInControlStatementMode ? 0 : 1),
+        //$NON-NLS-1$
+        new ConfigurableOption(componentName, "newline.clearAll", locale, options.clearAllBlankLinesMode ? 0 : 1),
+        //$NON-NLS-1$
+        //      new ConfigurableOption(componentName, "newline.elseIf", locale,
+        // options.compactElseIfMode ? 0 : 1), //$NON-NLS-1$
+        new ConfigurableOption(componentName, "newline.emptyBlock", locale, options.newLineInEmptyBlockMode ? 0 : 1),
+        //$NON-NLS-1$
+        new ConfigurableOption(componentName, "line.split", locale, options.maxLineLength),
+        //$NON-NLS-1$
+        new ConfigurableOption(componentName, "style.compactAssignment", locale, options.compactAssignmentMode ? 0 : 1),
+        //$NON-NLS-1$
+        new ConfigurableOption(componentName, "tabulation.char", locale, options.indentWithTab ? 0 : 1),
+        //$NON-NLS-1$
+        new ConfigurableOption(componentName, "tabulation.size", locale, options.tabSize) //$NON-NLS-1$
     };
   }
 
   /**
-   * Returns the array of mapped positions.
-   * Returns null is no positions have been set.
+   * Returns the array of mapped positions. Returns null is no positions have been set.
+   * 
    * @return int[]
    * @deprecated There is no need to retrieve the mapped positions anymore.
    */
@@ -1087,80 +1088,121 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   }
 
   /**
-   * Returns the priority of the token given as argument<br>
+   * Returns the priority of the token given as argument <br>
    * The most prioritary the token is, the smallest the return value is.
+   * 
    * @return the priority of <code>token</code>
-   * @param token the token of which the priority is requested
+   * @param token
+   *          the token of which the priority is requested
    */
   private static int getTokenPriority(int token) {
     switch (token) {
-      case TokenNameextends :
-        //                     case TokenNameimplements :
-        //                     case TokenNamethrows :
-        return 10;
-      case TokenNameSEMICOLON : // ;
-        return 20;
-      case TokenNameCOMMA : // ,
-        return 25;
-      case TokenNameEQUAL : // =
-        return 30;
-      case TokenNameAND_AND : // && 
-      case TokenNameOR_OR : // || 
-        return 40;
-      case TokenNameQUESTION : // ? 
-      case TokenNameCOLON : // :
-        return 50; // it's better cutting on ?: than on ;
-      case TokenNameEQUAL_EQUAL : // == 
-      case TokenNameNOT_EQUAL : // != 
-        return 60;
-      case TokenNameLESS : // < 
-      case TokenNameLESS_EQUAL : // <= 
-      case TokenNameGREATER : // > 
-      case TokenNameGREATER_EQUAL : // >= 
-        //                     case TokenNameinstanceof : // instanceof
-        return 70;
-      case TokenNamePLUS : // + 
-      case TokenNameMINUS : // - 
-        return 80;
-      case TokenNameMULTIPLY : // * 
-      case TokenNameDIVIDE : // / 
-      case TokenNameREMAINDER : // % 
-        return 90;
-      case TokenNameLEFT_SHIFT : // << 
-      case TokenNameRIGHT_SHIFT : // >> 
-        //                     case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> 
-        return 100;
-      case TokenNameAND : // &
-      case TokenNameOR : // | 
-      case TokenNameXOR : // ^ 
-        return 110;
-      case TokenNameMULTIPLY_EQUAL : // *= 
-      case TokenNameDIVIDE_EQUAL : // /= 
-      case TokenNameREMAINDER_EQUAL : // %= 
-      case TokenNamePLUS_EQUAL : // += 
-      case TokenNameMINUS_EQUAL : // -= 
-      case TokenNameLEFT_SHIFT_EQUAL : // <<= 
-      case TokenNameRIGHT_SHIFT_EQUAL : // >>= 
-        //                     case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>=
-      case TokenNameAND_EQUAL : // &= 
-      case TokenNameXOR_EQUAL : // ^= 
-      case TokenNameOR_EQUAL : // |= 
-        return 120;
-      case TokenNameDOT : // .
-        return 130;
-      default :
-        return Integer.MAX_VALUE;
+    case TokenNameextends:
+      //                       case TokenNameimplements :
+      //                       case TokenNamethrows :
+      return 10;
+    case TokenNameSEMICOLON:
+      // ;
+      return 20;
+    case TokenNameCOMMA:
+      // ,
+      return 25;
+    case TokenNameEQUAL:
+      // =
+      return 30;
+    case TokenNameAND_AND:
+    // &&
+    case TokenNameOR_OR:
+      // ||
+      return 40;
+    case TokenNameQUESTION:
+    // ?
+    case TokenNameCOLON:
+      // :
+      return 50; // it's better cutting on ?: than on ;
+    case TokenNameEQUAL_EQUAL:
+    // ==
+    case TokenNameEQUAL_EQUAL_EQUAL:
+    // ===
+    case TokenNameNOT_EQUAL:
+    // !=
+    case TokenNameNOT_EQUAL_EQUAL:
+      // !=
+      return 60;
+    case TokenNameLESS:
+    // <
+    case TokenNameLESS_EQUAL:
+    // <=
+    case TokenNameGREATER:
+    // >
+    case TokenNameGREATER_EQUAL:
+      // >=
+      //                       case TokenNameinstanceof : // instanceof
+      return 70;
+    case TokenNamePLUS:
+    // +
+    case TokenNameMINUS:
+      // -
+      return 80;
+    case TokenNameMULTIPLY:
+    // *
+    case TokenNameDIVIDE:
+    // /
+    case TokenNameREMAINDER:
+      // %
+      return 90;
+    case TokenNameLEFT_SHIFT:
+    // <<
+    case TokenNameRIGHT_SHIFT:
+      // >>
+      //                       case TokenNameUNSIGNED_RIGHT_SHIFT : // >>>
+      return 100;
+    case TokenNameAND:
+    // &
+    case TokenNameOR:
+    // |
+    case TokenNameXOR:
+      // ^
+      return 110;
+    case TokenNameMULTIPLY_EQUAL:
+    // *=
+    case TokenNameDIVIDE_EQUAL:
+    // /=
+    case TokenNameREMAINDER_EQUAL:
+    // %=
+    case TokenNamePLUS_EQUAL:
+    // +=
+    case TokenNameMINUS_EQUAL:
+    // -=
+    case TokenNameLEFT_SHIFT_EQUAL:
+    // <<=
+    case TokenNameRIGHT_SHIFT_EQUAL:
+    // >>=
+    //                 case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>=
+    case TokenNameAND_EQUAL:
+    // &=
+    case TokenNameXOR_EQUAL:
+    // ^=
+    case TokenNameOR_EQUAL:
+    // .=
+    case TokenNameDOT_EQUAL:
+      // |=
+      return 120;
+    case TokenNameDOT:
+      // .
+      return 130;
+    default:
+      return Integer.MAX_VALUE;
     }
   }
 
   /**
-   * Handles the exception raised when an invalid token is encountered.
-   * Returns true if the exception has been handled, false otherwise.
+   * Handles the exception raised when an invalid token is encountered. Returns true if the exception has been handled, false
+   * otherwise.
    */
   private boolean handleInvalidToken(Exception e) {
-    if (e.getMessage().equals(Scanner.INVALID_CHARACTER_CONSTANT)
-      || e.getMessage().equals(Scanner.INVALID_CHAR_IN_STRING)
-      || e.getMessage().equals(Scanner.INVALID_ESCAPE)) {
+    if (e.getMessage().equals(Scanner.INVALID_CHARACTER_CONSTANT) || e.getMessage().equals(Scanner.INVALID_CHAR_IN_STRING)
+        || e.getMessage().equals(Scanner.INVALID_ESCAPE)) {
       return true;
     }
     return false;
@@ -1179,62 +1221,63 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   }
 
   /**
-   * Returns true if a space has to be inserted after <code>operator</code>
-   * false otherwise.
+   * Returns true if a space has to be inserted after <code>operator</code> false otherwise.
    */
   private boolean insertSpaceAfter(int token) {
     switch (token) {
-      case TokenNameLPAREN :
-      case TokenNameNOT :
-      case TokenNameTWIDDLE :
-      case TokenNameDOT :
-      case 0 : // no token
-      case TokenNameLBRACKET :
-      case Scanner.TokenNameCOMMENT_LINE :
-        return false;
-      default :
-        return true;
+    case TokenNameLPAREN:
+    case TokenNameNOT:
+    case TokenNameTWIDDLE:
+    case TokenNameDOT:
+    case 0:
+    // no token
+    case TokenNameWHITESPACE:
+    case TokenNameLBRACKET:
+    case TokenNameDOLLAR:
+    case Scanner.TokenNameCOMMENT_LINE:
+      return false;
+    default:
+      return true;
     }
   }
 
   /**
-   * Returns true if a space has to be inserted before <code>operator</code>
-   * false otherwise.<br>
-   * Cannot be static as it uses the code formatter options
-   * (to know if the compact assignment mode is on).
+   * Returns true if a space has to be inserted before <code>operator</code> false otherwise. <br>
+   * Cannot be static as it uses the code formatter options (to know if the compact assignment mode is on).
    */
   private boolean insertSpaceBefore(int token) {
     switch (token) {
-      case TokenNameEQUAL :
-        return (!options.compactAssignmentMode);
-      default :
-        return false;
+    case TokenNameEQUAL:
+      return (!options.compactAssignmentMode);
+    default:
+      return false;
     }
   }
 
   private static boolean isComment(int token) {
-    boolean result =
-      token == Scanner.TokenNameCOMMENT_BLOCK || token == Scanner.TokenNameCOMMENT_LINE || token == Scanner.TokenNameCOMMENT_PHPDOC;
+    boolean result = token == Scanner.TokenNameCOMMENT_BLOCK || token == Scanner.TokenNameCOMMENT_LINE
+        || token == Scanner.TokenNameCOMMENT_PHPDOC;
     return result;
   }
 
   private static boolean isLiteralToken(int token) {
     boolean result = token == TokenNameIntegerLiteral
-      //                       || token == TokenNameLongLiteral
-    //                 || token == TokenNameFloatingPointLiteral
-  || token == TokenNameDoubleLiteral
-      //                       || token == TokenNameCharacterLiteral
-  || token == TokenNameStringLiteral;
+    //                 || token == TokenNameLongLiteral
+        //                     || token == TokenNameFloatingPointLiteral
+        || token == TokenNameDoubleLiteral
+        //                     || token == TokenNameCharacterLiteral
+        || token == TokenNameStringDoubleQuote;
     return result;
   }
 
   /**
-   * If the length of <code>oneLineBuffer</code> exceeds <code>maxLineLength</code>,
-   * it is split and the result is dumped in <code>formattedSource</code>
-   * @param newLineCount the number of new lines to append
+   * If the length of <code>oneLineBuffer</code> exceeds <code>maxLineLength</code>, it is split and the result is dumped in
+   * <code>formattedSource</code>
+   * 
+   * @param newLineCount
+   *          the number of new lines to append
    */
   private void newLine(int newLineCount) {
-
     // format current line
     splitDelta = 0;
     beginningOfLineIndex = formattedSource.length();
@@ -1254,7 +1297,6 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     // reset formatter for next line
     int currentLength = currentLine.length();
     currentLineBuffer = new StringBuffer(currentLength > maxLineSize ? maxLineSize = currentLength : maxLineSize);
-
     increaseGlobalDelta(splitDelta);
     increaseGlobalDelta(lineDelta);
     lineDelta = 0;
@@ -1263,133 +1305,146 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
 
   private String operatorString(int operator) {
     switch (operator) {
-      case TokenNameextends :
-        return "extends"; //$NON-NLS-1$
-
-        //                     case TokenNameimplements :
-        //                             return "implements"; //$NON-NLS-1$
-        //
-        //                     case TokenNamethrows :
-        //                             return "throws"; //$NON-NLS-1$
-
-      case TokenNameSEMICOLON : // ;
-        return ";"; //$NON-NLS-1$
-
-      case TokenNameCOMMA : // ,
-        return ","; //$NON-NLS-1$
-
-      case TokenNameEQUAL : // =
-        return "="; //$NON-NLS-1$
-
-      case TokenNameAND_AND : // && (15.22)
-        return "&&"; //$NON-NLS-1$
-
-      case TokenNameOR_OR : // || (15.23)
-        return "||"; //$NON-NLS-1$
-
-      case TokenNameQUESTION : // ? (15.24)
-        return "?"; //$NON-NLS-1$
-
-      case TokenNameCOLON : // : (15.24)
-        return ":"; //$NON-NLS-1$
-
-      case TokenNameEQUAL_EQUAL : // == (15.20, 15.20.1, 15.20.2, 15.20.3)
-        return "=="; //$NON-NLS-1$
-
-      case TokenNameNOT_EQUAL : // != (15.20, 15.20.1, 15.20.2, 15.20.3)
-        return "!="; //$NON-NLS-1$
-
-      case TokenNameLESS : // < (15.19.1)
-        return "<"; //$NON-NLS-1$
-
-      case TokenNameLESS_EQUAL : // <= (15.19.1)
-        return "<="; //$NON-NLS-1$
-
-      case TokenNameGREATER : // > (15.19.1)
-        return ">"; //$NON-NLS-1$
-
-      case TokenNameGREATER_EQUAL : // >= (15.19.1)
-        return ">="; //$NON-NLS-1$
-
-        //                     case TokenNameinstanceof : // instanceof
-        //                             return "instanceof"; //$NON-NLS-1$
-
-      case TokenNamePLUS : // + (15.17, 15.17.2)
-        return "+"; //$NON-NLS-1$
-
-      case TokenNameMINUS : // - (15.17.2)
-        return "-"; //$NON-NLS-1$
-
-      case TokenNameMULTIPLY : // * (15.16.1)
-        return "*"; //$NON-NLS-1$
-
-      case TokenNameDIVIDE : // / (15.16.2)
-        return "/"; //$NON-NLS-1$
-
-      case TokenNameREMAINDER : // % (15.16.3)
-        return "%"; //$NON-NLS-1$
-
-      case TokenNameLEFT_SHIFT : // << (15.18)
-        return "<<"; //$NON-NLS-1$
-
-      case TokenNameRIGHT_SHIFT : // >> (15.18)
-        return ">>"; //$NON-NLS-1$
-
-        //                     case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
-        //                             return ">>>"; //$NON-NLS-1$
-
-      case TokenNameAND : // & (15.21, 15.21.1, 15.21.2)
-        return "&"; //$NON-NLS-1$
-
-      case TokenNameOR : // | (15.21, 15.21.1, 15.21.2)
-        return "|"; //$NON-NLS-1$
-
-      case TokenNameXOR : // ^ (15.21, 15.21.1, 15.21.2)
-        return "^"; //$NON-NLS-1$
-
-      case TokenNameMULTIPLY_EQUAL : // *= (15.25.2)
-        return "*="; //$NON-NLS-1$
-
-      case TokenNameDIVIDE_EQUAL : // /= (15.25.2)
-        return "/="; //$NON-NLS-1$
-
-      case TokenNameREMAINDER_EQUAL : // %= (15.25.2)
-        return "%="; //$NON-NLS-1$
-
-      case TokenNamePLUS_EQUAL : // += (15.25.2)
-        return "+="; //$NON-NLS-1$
-
-      case TokenNameMINUS_EQUAL : // -= (15.25.2)
-        return "-="; //$NON-NLS-1$
-
-      case TokenNameLEFT_SHIFT_EQUAL : // <<= (15.25.2)
-        return "<<="; //$NON-NLS-1$
-
-      case TokenNameRIGHT_SHIFT_EQUAL : // >>= (15.25.2)
-        return ">>="; //$NON-NLS-1$
-
-        //                     case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
-        //                             return ">>>="; //$NON-NLS-1$
-
-      case TokenNameAND_EQUAL : // &= (15.25.2)
-        return "&="; //$NON-NLS-1$
-
-      case TokenNameXOR_EQUAL : // ^= (15.25.2)
-        return "^="; //$NON-NLS-1$
-
-      case TokenNameOR_EQUAL : // |= (15.25.2)
-        return "|="; //$NON-NLS-1$
-
-      case TokenNameDOT : // .
-        return "."; //$NON-NLS-1$
-
-      default :
-        return ""; //$NON-NLS-1$
+    case TokenNameextends:
+      return "extends"; //$NON-NLS-1$
+    //                 case TokenNameimplements :
+    //                         return "implements"; //$NON-NLS-1$
+    //
+    //                 case TokenNamethrows :
+    //                         return "throws"; //$NON-NLS-1$
+    case TokenNameSEMICOLON:
+      // ;
+      return ";"; //$NON-NLS-1$
+    case TokenNameCOMMA:
+      // ,
+      return ","; //$NON-NLS-1$
+    case TokenNameEQUAL:
+      // =
+      return "="; //$NON-NLS-1$
+    case TokenNameAND_AND:
+      // && (15.22)
+      return "&&"; //$NON-NLS-1$
+    case TokenNameOR_OR:
+      // || (15.23)
+      return "||"; //$NON-NLS-1$
+    case TokenNameQUESTION:
+      // ? (15.24)
+      return "?"; //$NON-NLS-1$
+    case TokenNameCOLON:
+      // : (15.24)
+      return ":"; //$NON-NLS-1$
+    case TokenNamePAAMAYIM_NEKUDOTAYIM:
+      // : (15.24)
+      return "::"; //$NON-NLS-1$
+    case TokenNameEQUAL_EQUAL:
+      // == (15.20, 15.20.1, 15.20.2, 15.20.3)
+      return "=="; //$NON-NLS-1$
+    case TokenNameEQUAL_EQUAL_EQUAL:
+      // == (15.20, 15.20.1, 15.20.2, 15.20.3)
+      return "==="; //$NON-NLS-1$
+    case TokenNameEQUAL_GREATER:
+      // -= (15.25.2)
+      return "=>"; //$NON-NLS-1$                               
+    case TokenNameNOT_EQUAL:
+      // != (15.20, 15.20.1, 15.20.2, 15.20.3)
+      return "!="; //$NON-NLS-1$
+    case TokenNameNOT_EQUAL_EQUAL:
+      // != (15.20, 15.20.1, 15.20.2, 15.20.3)
+      return "!=="; //$NON-NLS-1$
+    case TokenNameLESS:
+      // < (15.19.1)
+      return "<"; //$NON-NLS-1$
+    case TokenNameLESS_EQUAL:
+      // <= (15.19.1)
+      return "<="; //$NON-NLS-1$
+    case TokenNameGREATER:
+      // > (15.19.1)
+      return ">"; //$NON-NLS-1$
+    case TokenNameGREATER_EQUAL:
+      // >= (15.19.1)
+      return ">="; //$NON-NLS-1$
+    //                 case TokenNameinstanceof : // instanceof
+    //                         return "instanceof"; //$NON-NLS-1$
+    case TokenNamePLUS:
+      // + (15.17, 15.17.2)
+      return "+"; //$NON-NLS-1$
+    case TokenNameMINUS:
+      // - (15.17.2)
+      return "-"; //$NON-NLS-1$
+    case TokenNameMULTIPLY:
+      // * (15.16.1)
+      return "*"; //$NON-NLS-1$
+    case TokenNameDIVIDE:
+      // / (15.16.2)
+      return "/"; //$NON-NLS-1$
+    case TokenNameREMAINDER:
+      // % (15.16.3)
+      return "%"; //$NON-NLS-1$
+    case TokenNameLEFT_SHIFT:
+      // << (15.18)
+      return "<<"; //$NON-NLS-1$
+    case TokenNameRIGHT_SHIFT:
+      // >> (15.18)
+      return ">>"; //$NON-NLS-1$
+    //                 case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
+    //                         return ">>>"; //$NON-NLS-1$
+    case TokenNameAND:
+      // & (15.21, 15.21.1, 15.21.2)
+      return "&"; //$NON-NLS-1$
+    case TokenNameOR:
+      // | (15.21, 15.21.1, 15.21.2)
+      return "|"; //$NON-NLS-1$
+    case TokenNameXOR:
+      // ^ (15.21, 15.21.1, 15.21.2)
+      return "^"; //$NON-NLS-1$
+    case TokenNameMULTIPLY_EQUAL:
+      // *= (15.25.2)
+      return "*="; //$NON-NLS-1$
+    case TokenNameDIVIDE_EQUAL:
+      // /= (15.25.2)
+      return "/="; //$NON-NLS-1$
+    case TokenNameREMAINDER_EQUAL:
+      // %= (15.25.2)
+      return "%="; //$NON-NLS-1$
+    case TokenNamePLUS_EQUAL:
+      // += (15.25.2)
+      return "+="; //$NON-NLS-1$
+    case TokenNameMINUS_EQUAL:
+      // -= (15.25.2)
+      return "-="; //$NON-NLS-1$
+    case TokenNameMINUS_GREATER:
+      // -= (15.25.2)
+      return "->"; //$NON-NLS-1$
+    case TokenNameLEFT_SHIFT_EQUAL:
+      // <<= (15.25.2)
+      return "<<="; //$NON-NLS-1$
+    case TokenNameRIGHT_SHIFT_EQUAL:
+      // >>= (15.25.2)
+      return ">>="; //$NON-NLS-1$
+    //                 case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
+    //                         return ">>>="; //$NON-NLS-1$
+    case TokenNameAND_EQUAL:
+      // &= (15.25.2)
+      return "&="; //$NON-NLS-1$
+    case TokenNameXOR_EQUAL:
+      // ^= (15.25.2)
+      return "^="; //$NON-NLS-1$
+    case TokenNameOR_EQUAL:
+      // |= (15.25.2)
+      return "|="; //$NON-NLS-1$
+    case TokenNameDOT_EQUAL:
+      // .=
+      return ".="; //$NON-NLS-1$
+    case TokenNameDOT:
+      // .
+      return "."; //$NON-NLS-1$
+    default:
+      return ""; //$NON-NLS-1$
     }
   }
 
-  /** 
-   * Appends <code>stringToOutput</code> to the formatted output.<br>
+  /**
+   * Appends <code>stringToOutput</code> to the formatted output. <br>
    * If it contains \n, append a LINE_SEPARATOR and indent after it.
    */
   private void output(String stringToOutput) {
@@ -1402,133 +1457,138 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     }
   }
 
-  /** 
-   * Appends <code>token</code> to the formatted output.<br>
+  private void outputCurrentTokenWithoutIndent(int token, int newLineCount) {
+    newLine(newLineCount);
+    formattedSource.append(scanner.source, scanner.startPosition, scanner.currentPosition - scanner.startPosition);
+  }
+
+  /**
+   * Appends <code>token</code> to the formatted output. <br>
    * If it contains <code>\n</code>, append a LINE_SEPARATOR and indent after it.
    */
   private void outputCurrentToken(int token) {
     char[] source = scanner.source;
     int startPosition = scanner.startPosition;
-
     switch (token) {
-      case Scanner.TokenNameCOMMENT_PHPDOC :
-      case Scanner.TokenNameCOMMENT_BLOCK :
-      case Scanner.TokenNameCOMMENT_LINE :
-        boolean endOfLine = false;
-        int currentCommentOffset = getCurrentCommentOffset();
-        int beginningOfLineSpaces = 0;
-        endOfLine = false;
-        currentCommentOffset = getCurrentCommentOffset();
-        beginningOfLineSpaces = 0;
-        boolean pendingCarriageReturn = false;
-        for (int i = startPosition, max = scanner.currentPosition; i < max; i++) {
-          char currentCharacter = source[i];
-          updateMappedPositions(i);
-          switch (currentCharacter) {
-            case '\r' :
-              pendingCarriageReturn = true;
-              endOfLine = true;
-              break;
-            case '\n' :
-              if (pendingCarriageReturn) {
-                increaseGlobalDelta(options.lineSeparatorSequence.length - 2);
-              } else {
-                increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
-              }
-              pendingCarriageReturn = false;
-              currentLineBuffer.append(options.lineSeparatorSequence);
-              beginningOfLineSpaces = 0;
-              endOfLine = true;
-              break;
-            case '\t' :
-              if (pendingCarriageReturn) {
-                pendingCarriageReturn = false;
-                increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
-                currentLineBuffer.append(options.lineSeparatorSequence);
-                beginningOfLineSpaces = 0;
-                endOfLine = true;
-              }
-              if (endOfLine) {
-                // we remove a maximum of currentCommentOffset characters (tabs are converted to space numbers).
-                beginningOfLineSpaces += options.tabSize;
-                if (beginningOfLineSpaces > currentCommentOffset) {
-                  currentLineBuffer.append(currentCharacter);
-                } else {
-                  increaseGlobalDelta(-1);
-                }
-              } else {
-                currentLineBuffer.append(currentCharacter);
-              }
-              break;
-            case ' ' :
-              if (pendingCarriageReturn) {
-                pendingCarriageReturn = false;
-                increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
-                currentLineBuffer.append(options.lineSeparatorSequence);
-                beginningOfLineSpaces = 0;
-                endOfLine = true;
-              }
-              if (endOfLine) {
-                // we remove a maximum of currentCommentOffset characters (tabs are converted to space numbers).
-                beginningOfLineSpaces++;
-                if (beginningOfLineSpaces > currentCommentOffset) {
-                  currentLineBuffer.append(currentCharacter);
-                } else {
-                  increaseGlobalDelta(-1);
-                }
-              } else {
-                currentLineBuffer.append(currentCharacter);
-              }
-              break;
-            default :
-              if (pendingCarriageReturn) {
-                pendingCarriageReturn = false;
-                increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
-                currentLineBuffer.append(options.lineSeparatorSequence);
-                beginningOfLineSpaces = 0;
-                endOfLine = true;
-              } else {
-                beginningOfLineSpaces = 0;
-                currentLineBuffer.append(currentCharacter);
-                endOfLine = false;
-              }
+    case Scanner.TokenNameCOMMENT_PHPDOC:
+    case Scanner.TokenNameCOMMENT_BLOCK:
+    case Scanner.TokenNameCOMMENT_LINE:
+      boolean endOfLine = false;
+      int currentCommentOffset = getCurrentCommentOffset();
+      int beginningOfLineSpaces = 0;
+      endOfLine = false;
+      currentCommentOffset = getCurrentCommentOffset();
+      beginningOfLineSpaces = 0;
+      boolean pendingCarriageReturn = false;
+      for (int i = startPosition, max = scanner.currentPosition; i < max; i++) {
+        char currentCharacter = source[i];
+        updateMappedPositions(i);
+        switch (currentCharacter) {
+        case '\r':
+          pendingCarriageReturn = true;
+          endOfLine = true;
+          break;
+        case '\n':
+          if (pendingCarriageReturn) {
+            increaseGlobalDelta(options.lineSeparatorSequence.length - 2);
+          } else {
+            increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
+          }
+          pendingCarriageReturn = false;
+          currentLineBuffer.append(options.lineSeparatorSequence);
+          beginningOfLineSpaces = 0;
+          endOfLine = true;
+          break;
+        case '\t':
+          if (pendingCarriageReturn) {
+            pendingCarriageReturn = false;
+            increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
+            currentLineBuffer.append(options.lineSeparatorSequence);
+            beginningOfLineSpaces = 0;
+            endOfLine = true;
+          }
+          if (endOfLine) {
+            // we remove a maximum of currentCommentOffset characters (tabs
+            // are converted to space numbers).
+            beginningOfLineSpaces += options.tabSize;
+            if (beginningOfLineSpaces > currentCommentOffset) {
+              currentLineBuffer.append(currentCharacter);
+            } else {
+              increaseGlobalDelta(-1);
+            }
+          } else {
+            currentLineBuffer.append(currentCharacter);
+          }
+          break;
+        case ' ':
+          if (pendingCarriageReturn) {
+            pendingCarriageReturn = false;
+            increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
+            currentLineBuffer.append(options.lineSeparatorSequence);
+            beginningOfLineSpaces = 0;
+            endOfLine = true;
+          }
+          if (endOfLine) {
+            // we remove a maximum of currentCommentOffset characters (tabs
+            // are converted to space numbers).
+            beginningOfLineSpaces++;
+            if (beginningOfLineSpaces > currentCommentOffset) {
+              currentLineBuffer.append(currentCharacter);
+            } else {
+              increaseGlobalDelta(-1);
+            }
+          } else {
+            currentLineBuffer.append(currentCharacter);
+          }
+          break;
+        default:
+          if (pendingCarriageReturn) {
+            pendingCarriageReturn = false;
+            increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
+            currentLineBuffer.append(options.lineSeparatorSequence);
+            beginningOfLineSpaces = 0;
+            endOfLine = true;
+          } else {
+            beginningOfLineSpaces = 0;
+            currentLineBuffer.append(currentCharacter);
+            endOfLine = false;
           }
         }
-        updateMappedPositions(scanner.currentPosition - 1);
-        multipleLineCommentCounter++;
-        break;
-      default :
-        for (int i = startPosition, max = scanner.currentPosition; i < max; i++) {
-          char currentCharacter = source[i];
-          updateMappedPositions(i);
-          currentLineBuffer.append(currentCharacter);
-        }
+      }
+      updateMappedPositions(scanner.currentPosition - 1);
+      multipleLineCommentCounter++;
+      break;
+    default:
+      for (int i = startPosition, max = scanner.currentPosition; i < max; i++) {
+        char currentCharacter = source[i];
+        updateMappedPositions(i);
+        currentLineBuffer.append(currentCharacter);
+      }
     }
   }
 
   /**
    * Outputs <code>currentString</code>:<br>
-   * <ul><li>If its length is < maxLineLength, output
-   * <li>Otherwise it is split.</ul>
-   * @param currentString string to output
-   * @param preIndented whether the string to output was pre-indented
-   * @param depth number of indentation to put in front of <code>currentString</code>
-   * @param operator value of the operator belonging to <code>currentString</code>.
+   * <ul>
+   * <li>If its length is < maxLineLength, output
+   * <li>Otherwise it is split.
+   * </ul>
+   * 
+   * @param currentString
+   *          string to output
+   * @param preIndented
+   *          whether the string to output was pre-indented
+   * @param depth
+   *          number of indentation to put in front of <code>currentString</code>
+   * @param operator
+   *          value of the operator belonging to <code>currentString</code>.
    */
-  private void outputLine(
-    String currentString,
-    boolean preIndented,
-    int depth,
-    int operator,
-    int substringIndex,
-    int[] startSubstringIndexes,
-    int offsetInGlobalLine) {
-
+  private void outputLine(String currentString, boolean preIndented, int depth, int operator, int substringIndex,
+      int[] startSubstringIndexes, int offsetInGlobalLine) {
     boolean emptyFirstSubString = false;
     String operatorString = operatorString(operator);
     boolean placeOperatorBehind = !breakLineBeforeOperator(operator);
     boolean placeOperatorAhead = !placeOperatorBehind;
-
     // dump prefix operator?
     if (placeOperatorAhead) {
       if (!preIndented) {
@@ -1542,9 +1602,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         }
         formattedSource.append(operatorString);
         increaseSplitDelta(operatorString.length());
-
-        if (insertSpaceAfter(operator) //                      && operator != TokenNameimplements
-        && operator != TokenNameextends) {
+        if (insertSpaceAfter(operator) && operator != TokenNameimplements && operator != TokenNameextends) {
           //                   && operator != TokenNamethrows) {
           formattedSource.append(' ');
           increaseSplitDelta(1);
@@ -1552,15 +1610,13 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       }
     }
     SplitLine splitLine = null;
-    if (options.maxLineLength == 0
-      || getLength(currentString, depth) < options.maxLineLength
-      || (splitLine = split(currentString, offsetInGlobalLine)) == null) {
-
-      // depending on the type of operator, outputs new line before of after dumping it
+    if (options.maxLineLength == 0 || getLength(currentString, depth) < options.maxLineLength
+        || (splitLine = split(currentString, offsetInGlobalLine)) == null) {
+      // depending on the type of operator, outputs new line before of after
+      // dumping it
       // indent before postfix operator
       // indent also when the line cannot be split
-      if (operator == TokenNameextends) {
-        //                             || operator == TokenNameimplements
+      if (operator == TokenNameextends || operator == TokenNameimplements) {
         //                             || operator == TokenNamethrows) {
         formattedSource.append(' ');
         increaseSplitDelta(1);
@@ -1576,9 +1632,8 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           BufferedReader reader = new BufferedReader(new StringReader(currentString));
           String line = reader.readLine();
           while (line != null) {
-            updateMappedPositionsWhileSplitting(
-              beginningOfLineIndex,
-              beginningOfLineIndex + line.length() + options.lineSeparatorSequence.length);
+            updateMappedPositionsWhileSplitting(beginningOfLineIndex, beginningOfLineIndex + line.length()
+                + options.lineSeparatorSequence.length);
             formattedSource.append(line);
             beginningOfLineIndex = beginningOfLineIndex + line.length();
             if ((line = reader.readLine()) != null) {
@@ -1596,21 +1651,22 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         for (int i = 0; i < max; i++) {
           char currentChar = currentString.charAt(i);
           switch (currentChar) {
-            case '\r' :
-              break;
-            case '\n' :
-              if (i != max - 1) {
-                // fix for 1FFYL5C: LFCOM:ALL - Incorrect indentation when split with a comment inside a condition
-                // a substring cannot end with a lineSeparatorSequence,
-                // except if it has been added by format() after a one-line comment
-                formattedSource.append(options.lineSeparatorSequence);
-
-                // 1FGDDV6: LFCOM:WIN98 - Weird splitting on message expression
-                dumpTab(depth - 1);
-              }
-              break;
-            default :
-              formattedSource.append(currentChar);
+          case '\r':
+            break;
+          case '\n':
+            if (i != max - 1) {
+              // fix for 1FFYL5C: LFCOM:ALL - Incorrect indentation when
+              // split with a comment inside a condition
+              // a substring cannot end with a lineSeparatorSequence,
+              // except if it has been added by format() after a one-line
+              // comment
+              formattedSource.append(options.lineSeparatorSequence);
+              // 1FGDDV6: LFCOM:WIN98 - Weird splitting on message expression
+              dumpTab(depth - 1);
+            }
+            break;
+          default:
+            formattedSource.append(currentChar);
           }
         }
       }
@@ -1620,7 +1676,6 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           int startPosition = beginningOfLineIndex + startSubstringIndexes[substringIndex];
           updateMappedPositionsWhileSplitting(startPosition, startPosition + max);
         }
-
         // compute the splitDelta resulting with the operator and blank removal
         if (substringIndex + 1 != startSubstringIndexes.length) {
           increaseSplitDelta(startSubstringIndexes[substringIndex] + max - startSubstringIndexes[substringIndex + 1]);
@@ -1660,33 +1715,29 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     // perform actual splitting
     String result[] = splitLine.substrings;
     int[] splitOperators = splitLine.operators;
-
     if (result[0].length() == 0) {
       // when the substring 0 is null, the substring 1 is correctly indented.
       depth--;
       emptyFirstSubString = true;
     }
-    // the operator going in front of the result[0] string is the operator parameter
+    // the operator going in front of the result[0] string is the operator
+    // parameter
     for (int i = 0, max = result.length; i < max; i++) {
       // the new depth is the current one if this is the first substring,
       // the current one + 1 otherwise.
-      // if the substring is a comment, use the current indentation Level instead of the depth
+      // if the substring is a comment, use the current indentation Level
+      // instead of the depth
       // (-1 because the ouputline increases depth).
-      // (fix for 1FFC72R: LFCOM:ALL - Incorrect line split in presence of line comments)
+      // (fix for 1FFC72R: LFCOM:ALL - Incorrect line split in presence of line
+      // comments)
       String currentResult = result[i];
-
       if (currentResult.length() != 0 || splitOperators[i] != 0) {
-          int newDepth = (currentResult.startsWith("/*") //$NON-NLS-1$
-    || currentResult.startsWith("//")) //$NON-NLS-1$ 
-  ? indentationLevel - 1 : depth;
-        outputLine(
-          currentResult,
-          i == 0 || (i == 1 && emptyFirstSubString) ? preIndented : false,
-          i == 0 ? newDepth : newDepth + 1,
-          splitOperators[i],
-          i,
-          splitLine.startSubstringsIndexes,
-          currentString.indexOf(currentResult));
+        int newDepth = (currentResult.startsWith("/*") //$NON-NLS-1$
+        || currentResult.startsWith("//")) //$NON-NLS-1$ 
+            ? indentationLevel - 1 : depth;
+        outputLine(currentResult, i == 0 || (i == 1 && emptyFirstSubString) ? preIndented : false,
+            i == 0 ? newDepth : newDepth + 1, splitOperators[i], i, splitLine.startSubstringsIndexes, currentString
+                .indexOf(currentResult));
         if (i != max - 1) {
           formattedSource.append(options.lineSeparatorSequence);
           increaseSplitDelta(options.lineSeparatorSequence.length);
@@ -1698,7 +1749,6 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       String lastOperatorString = operatorString(lastOperator);
       formattedSource.append(options.lineSeparatorSequence);
       increaseSplitDelta(options.lineSeparatorSequence.length);
-
       if (breakLineBeforeOperator(lastOperator)) {
         dumpTab(depth + 1);
         if (lastOperator != 0) {
@@ -1708,9 +1758,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           }
           formattedSource.append(lastOperatorString);
           increaseSplitDelta(lastOperatorString.length());
-
-          if (insertSpaceAfter(lastOperator) //                                        && lastOperator != TokenNameimplements
-            && lastOperator != TokenNameextends) {
+          if (insertSpaceAfter(lastOperator) && lastOperator != TokenNameimplements && lastOperator != TokenNameextends) {
             //                                 && lastOperator != TokenNamethrows) {
             formattedSource.append(' ');
             increaseSplitDelta(1);
@@ -1746,7 +1794,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   private int popBlock() {
     int delta = 0;
     if ((constructionsCount > 0)
-      && ((constructions[constructionsCount - 1] == BLOCK) || (constructions[constructionsCount - 1] == NONINDENT_BLOCK))) {
+        && ((constructions[constructionsCount - 1] == BLOCK) || (constructions[constructionsCount - 1] == NONINDENT_BLOCK))) {
       if (constructions[constructionsCount - 1] == BLOCK)
         delta--;
       constructionsCount--;
@@ -1757,7 +1805,9 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   /**
    * Pops elements until the stack is empty or the top element is <code>token</code>.<br>
    * Does not remove <code>token</code> from the stack.
-   * @param token the token to be left as the top of the stack
+   * 
+   * @param token
+   *          the token to be left as the top of the stack
    */
   private int popExclusiveUntil(int token) {
     int delta = 0;
@@ -1771,8 +1821,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   }
 
   /**
-   * Pops elements until the stack is empty or the top element is
-   * a <code>BLOCK</code> or a <code>NONINDENT_BLOCK</code>.<br>
+   * Pops elements until the stack is empty or the top element is a <code>BLOCK</code> or a <code>NONINDENT_BLOCK</code>.<br>
    * Does not remove it from the stack.
    */
   private int popExclusiveUntilBlock() {
@@ -1786,16 +1835,15 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   }
 
   /**
-   * Pops elements until the stack is empty or the top element is
-   * a <code>BLOCK</code>, a <code>NONINDENT_BLOCK</code> or a <code>CASE</code>.<br>
+   * Pops elements until the stack is empty or the top element is a <code>BLOCK</code>, a <code>NONINDENT_BLOCK</code> or a
+   * <code>CASE</code>.<br>
    * Does not remove it from the stack.
    */
   private int popExclusiveUntilBlockOrCase() {
     int startCount = constructionsCount;
     int delta = 0;
-    for (int i = startCount - 1;
-      i >= 0 && constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK && constructions[i] != TokenNamecase;
-      i--) {
+    for (int i = startCount - 1; i >= 0 && constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK
+        && constructions[i] != TokenNamecase; i--) {
       constructionsCount--;
       delta--;
     }
@@ -1805,7 +1853,9 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   /**
    * Pops elements until the stack is empty or the top element is <code>token</code>.<br>
    * Removes <code>token</code> from the stack too.
-   * @param token the token to remove from the stack
+   * 
+   * @param token
+   *          the token to remove from the stack
    */
   private int popInclusiveUntil(int token) {
     int startCount = constructionsCount;
@@ -1824,8 +1874,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   }
 
   /**
-   * Pops elements until the stack is empty or the top element is
-   * a <code>BLOCK</code> or a <code>NONINDENT_BLOCK</code>.<br>
+   * Pops elements until the stack is empty or the top element is a <code>BLOCK</code> or a <code>NONINDENT_BLOCK</code>.<br>
    * Does not remove it from the stack.
    */
   private int popInclusiveUntilBlock() {
@@ -1843,21 +1892,17 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     return delta;
   }
 
-  /** 
-   * Pushes a block in the stack.<br>
-   * Pushes a <code>BLOCK</code> if the stack is empty or if the top element is a <code>BLOCK</code>,
-   * pushes <code>NONINDENT_BLOCK</code> otherwise.
-   * Creates a new bigger array if the current one is full.
+  /**
+   * Pushes a block in the stack. <br>
+   * Pushes a <code>BLOCK</code> if the stack is empty or if the top element is a <code>BLOCK</code>, pushes
+   * <code>NONINDENT_BLOCK</code> otherwise. Creates a new bigger array if the current one is full.
    */
   private int pushBlock() {
     int delta = 0;
     if (constructionsCount == constructions.length)
       System.arraycopy(constructions, 0, (constructions = new int[constructionsCount * 2]), 0, constructionsCount);
-
-    if ((constructionsCount == 0)
-      || (constructions[constructionsCount - 1] == BLOCK)
-      || (constructions[constructionsCount - 1] == NONINDENT_BLOCK)
-      || (constructions[constructionsCount - 1] == TokenNamecase)) {
+    if ((constructionsCount == 0) || (constructions[constructionsCount - 1] == BLOCK)
+        || (constructions[constructionsCount - 1] == NONINDENT_BLOCK) || (constructions[constructionsCount - 1] == TokenNamecase)) {
       delta++;
       constructions[constructionsCount++] = BLOCK;
     } else {
@@ -1866,7 +1911,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     return delta;
   }
 
-  /** 
+  /**
    * Pushes <code>token</code>.<br>
    * Creates a new bigger array if the current one is full.
    */
@@ -1878,19 +1923,18 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   }
 
   private static boolean separateFirstArgumentOn(int currentToken) {
-    //return (currentToken == TokenNameCOMMA || currentToken == TokenNameSEMICOLON);
-    return currentToken != TokenNameif
-      && currentToken != TokenNameLPAREN
-      && currentToken != TokenNameNOT
-      && currentToken != TokenNamewhile
-      && currentToken != TokenNamefor
-      && currentToken != TokenNameswitch;
+    //return (currentToken == TokenNameCOMMA || currentToken ==
+    // TokenNameSEMICOLON);
+    return currentToken != TokenNameif && currentToken != TokenNameLPAREN && currentToken != TokenNameNOT
+        && currentToken != TokenNamewhile && currentToken != TokenNamefor && currentToken != TokenNameforeach
+        && currentToken != TokenNameswitch;
   }
 
   /**
-   * Set the positions to map. The mapped positions should be retrieved using the
-   * getMappedPositions() method.
-   * @param positions int[]
+   * Set the positions to map. The mapped positions should be retrieved using the getMappedPositions() method.
+   * 
+   * @param positions
+   *          int[]
    * @deprecated Set the positions to map using the format(String, int, int[]) method.
    * 
    * @see #getMappedPositions()
@@ -1902,7 +1946,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     mappedPositions = new int[positions.length];
   }
 
-  /** 
+  /**
    * Appends a space character to the current line buffer.
    */
   private void space() {
@@ -1911,436 +1955,493 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   }
 
   /**
-   * Splits <code>stringToSplit</code> on the top level token<br>
-   * If there are several identical token at the same level,
-   * the string is cut into many pieces.
-   * @return an object containing the operator and all the substrings
-   * or null if the string cannot be split
+   * Splits <code>stringToSplit</code> on the top level token <br>
+   * If there are several identical token at the same level, the string is cut into many pieces.
+   * 
+   * @return an object containing the operator and all the substrings or null if the string cannot be split
    */
   public SplitLine split(String stringToSplit) {
     return split(stringToSplit, 0);
   }
 
   /**
-   * Splits <code>stringToSplit</code> on the top level token<br>
-   * If there are several identical token at the same level,
-   * the string is cut into many pieces.
-   * @return an object containing the operator and all the substrings
-   * or null if the string cannot be split
+   * Splits <code>stringToSplit</code> on the top level token <br>
+   * If there are several identical token at the same level, the string is cut into many pieces.
+   * 
+   * @return an object containing the operator and all the substrings or null if the string cannot be split
    */
   public SplitLine split(String stringToSplit, int offsetInGlobalLine) {
     /*
-     * See http://dev.eclipse.org/bugs/show_bug.cgi?id=12540 and
-     * http://dev.eclipse.org/bugs/show_bug.cgi?id=14387 
+     * See http://dev.eclipse.org/bugs/show_bug.cgi?id=12540 and http://dev.eclipse.org/bugs/show_bug.cgi?id=14387
      */
     if (stringToSplit.indexOf("//$NON-NLS") != -1) { //$NON-NLS-1$
       return null;
     }
+    // split doesn't work correct for PHP
+    return null;
     // local variables
-    int currentToken = 0;
-    int splitTokenType = 0;
-    int splitTokenDepth = Integer.MAX_VALUE;
-    int splitTokenPriority = Integer.MAX_VALUE;
-
-    int[] substringsStartPositions = new int[10];
-    // contains the start position of substrings
-    int[] substringsEndPositions = new int[10];
-    // contains the start position of substrings
-    int substringsCount = 1; // index in the substringsStartPosition array
-    int[] splitOperators = new int[10];
-    // contains the start position of substrings
-    int splitOperatorsCount = 0; // index in the substringsStartPosition array
-    int[] openParenthesisPosition = new int[10];
-    int openParenthesisPositionCount = 0;
-    int position = 0;
-    int lastOpenParenthesisPosition = -1;
-    // used to remember the position of the 1st open parenthesis
-    // needed for a pattern like: A.B(C); we want formatted like A.B( split C);
-    // setup the scanner with a new source
-    int lastCommentStartPosition = -1;
-    // to remember the start position of the last comment
-    int firstTokenOnLine = -1;
-    // to remember the first token of the line
-    int previousToken = -1;
-    // to remember the previous token.
-    splitScanner.setSource(stringToSplit.toCharArray());
-
-    try {
-      // start the loop
-      while (true) {
-        // takes the next token
-        try {
-          if (currentToken != Scanner.TokenNameWHITESPACE)
-            previousToken = currentToken;
-          currentToken = splitScanner.getNextToken();
-        } catch (InvalidInputException e) {
-          if (!handleInvalidToken(e))
-            throw e;
-          currentToken = 0;
-          // this value is not modify when an exception is raised.
-        }
-        if (currentToken == TokenNameEOF)
-          break;
-
-        if (firstTokenOnLine == -1) {
-          firstTokenOnLine = currentToken;
-        }
-        switch (currentToken) {
-          case TokenNameRBRACE :
-          case TokenNameRPAREN :
-            if (openParenthesisPositionCount > 0) {
-              if (openParenthesisPositionCount == 1 && lastOpenParenthesisPosition < openParenthesisPosition[0]) {
-                lastOpenParenthesisPosition = openParenthesisPosition[0];
-              } else if (
-                (splitTokenDepth == Integer.MAX_VALUE)
-                  || (splitTokenDepth > openParenthesisPositionCount && openParenthesisPositionCount == 1)) {
-                splitTokenType = 0;
-                splitTokenDepth = openParenthesisPositionCount;
-                splitTokenPriority = Integer.MAX_VALUE;
-                substringsStartPositions[0] = 0;
-                // better token means the whole line until now is the first substring
-                substringsCount = 1; // resets the count of substrings
-                substringsEndPositions[0] = openParenthesisPosition[0];
-                // substring ends on operator start
-                position = openParenthesisPosition[0];
-                // the string mustn't be cut before the closing parenthesis but after the opening one.
-                splitOperatorsCount = 1; // resets the count of split operators
-                splitOperators[0] = 0;
-              }
-              openParenthesisPositionCount--;
-            }
-            break;
-          case TokenNameLBRACE :
-          case TokenNameLPAREN :
-            if (openParenthesisPositionCount == openParenthesisPosition.length) {
-              System.arraycopy(
-                openParenthesisPosition,
-                0,
-                (openParenthesisPosition = new int[openParenthesisPositionCount * 2]),
-                0,
-                openParenthesisPositionCount);
-            }
-            openParenthesisPosition[openParenthesisPositionCount++] = splitScanner.currentPosition;
-            if (currentToken == TokenNameLPAREN && previousToken == TokenNameRPAREN) {
-              openParenthesisPosition[openParenthesisPositionCount - 1] = splitScanner.startPosition;
-            }
-            break;
-          case TokenNameSEMICOLON : // ;
-          case TokenNameCOMMA : // ,
-          case TokenNameEQUAL : // =
-            if (openParenthesisPositionCount < splitTokenDepth
-              || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority > getTokenPriority(currentToken))) {
-              // the current token is better than the one we currently have
-              // (in level or in priority if same level)
-              // reset the substringsCount
-              splitTokenDepth = openParenthesisPositionCount;
-              splitTokenType = currentToken;
-              splitTokenPriority = getTokenPriority(currentToken);
-              substringsStartPositions[0] = 0;
-              // better token means the whole line until now is the first substring
-
-              if (separateFirstArgumentOn(firstTokenOnLine) && openParenthesisPositionCount > 0) {
-                substringsCount = 2; // resets the count of substrings
-
-                substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1];
-                substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1];
-                substringsEndPositions[1] = splitScanner.startPosition;
-                splitOperatorsCount = 2; // resets the count of split operators
-                splitOperators[0] = 0;
-                splitOperators[1] = currentToken;
-                position = splitScanner.currentPosition;
-                // next substring will start from operator end
-              } else {
-                substringsCount = 1; // resets the count of substrings
-
-                substringsEndPositions[0] = splitScanner.startPosition;
-                // substring ends on operator start
-                position = splitScanner.currentPosition;
-                // next substring will start from operator end
-                splitOperatorsCount = 1; // resets the count of split operators
-                splitOperators[0] = currentToken;
-              }
-            } else {
-              if ((openParenthesisPositionCount == splitTokenDepth && splitTokenPriority == getTokenPriority(currentToken))
-                && splitTokenType != TokenNameEQUAL
-                && currentToken != TokenNameEQUAL) {
-                // fix for 1FG0BCN: LFCOM:WIN98 - Missing one indentation after split
-                // take only the 1st = into account.
-                // if another token with the same priority is found,
-                // push the start position of the substring and
-                // push the token into the stack.
-                // create a new array object if the current one is full.
-                if (substringsCount == substringsStartPositions.length) {
-                  System.arraycopy(
-                    substringsStartPositions,
-                    0,
-                    (substringsStartPositions = new int[substringsCount * 2]),
-                    0,
-                    substringsCount);
-                  System.arraycopy(
-                    substringsEndPositions,
-                    0,
-                    (substringsEndPositions = new int[substringsCount * 2]),
-                    0,
-                    substringsCount);
-                }
-                if (splitOperatorsCount == splitOperators.length) {
-                  System.arraycopy(splitOperators, 0, (splitOperators = new int[splitOperatorsCount * 2]), 0, splitOperatorsCount);
-                }
-                substringsStartPositions[substringsCount] = position;
-                substringsEndPositions[substringsCount++] = splitScanner.startPosition;
-                // substring ends on operator start
-                position = splitScanner.currentPosition;
-                // next substring will start from operator end
-                splitOperators[splitOperatorsCount++] = currentToken;
-              }
-            }
-            break;
-
-          case TokenNameCOLON : // : (15.24)
-            // see 1FK7C5R, we only split on a colon, when it is associated with a question-mark.
-            // indeed it might appear also behind a case statement, and we do not to break at this point.
-            if ((splitOperatorsCount == 0) || splitOperators[splitOperatorsCount - 1] != TokenNameQUESTION) {
-              break;
-            }
-          case TokenNameextends :
-            //                 case TokenNameimplements :
-            //                 case TokenNamethrows :
-
-          case TokenNameDOT : // .
-          case TokenNameMULTIPLY : // * (15.16.1)
-          case TokenNameDIVIDE : // / (15.16.2)
-          case TokenNameREMAINDER : // % (15.16.3)
-          case TokenNamePLUS : // + (15.17, 15.17.2)
-          case TokenNameMINUS : // - (15.17.2)
-          case TokenNameLEFT_SHIFT : // << (15.18)
-          case TokenNameRIGHT_SHIFT : // >> (15.18)
-            //                         case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
-          case TokenNameLESS : // < (15.19.1)
-          case TokenNameLESS_EQUAL : // <= (15.19.1)
-          case TokenNameGREATER : // > (15.19.1)
-          case TokenNameGREATER_EQUAL : // >= (15.19.1)
-            //                         case TokenNameinstanceof : // instanceof
-          case TokenNameEQUAL_EQUAL : // == (15.20, 15.20.1, 15.20.2, 15.20.3)
-          case TokenNameNOT_EQUAL : // != (15.20, 15.20.1, 15.20.2, 15.20.3)
-          case TokenNameAND : // & (15.21, 15.21.1, 15.21.2)
-          case TokenNameOR : // | (15.21, 15.21.1, 15.21.2)
-          case TokenNameXOR : // ^ (15.21, 15.21.1, 15.21.2)
-          case TokenNameAND_AND : // && (15.22)
-          case TokenNameOR_OR : // || (15.23)
-          case TokenNameQUESTION : // ? (15.24)
-          case TokenNameMULTIPLY_EQUAL : // *= (15.25.2)
-          case TokenNameDIVIDE_EQUAL : // /= (15.25.2)
-          case TokenNameREMAINDER_EQUAL : // %= (15.25.2)
-          case TokenNamePLUS_EQUAL : // += (15.25.2)
-          case TokenNameMINUS_EQUAL : // -= (15.25.2)
-          case TokenNameLEFT_SHIFT_EQUAL : // <<= (15.25.2)
-          case TokenNameRIGHT_SHIFT_EQUAL : // >>= (15.25.2)
-            //                                 case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
-          case TokenNameAND_EQUAL : // &= (15.25.2)
-          case TokenNameXOR_EQUAL : // ^= (15.25.2)
-          case TokenNameOR_EQUAL : // |= (15.25.2)
-
-            if ((openParenthesisPositionCount < splitTokenDepth
-              || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority > getTokenPriority(currentToken)))
-              && !((currentToken == TokenNamePLUS || currentToken == TokenNameMINUS)
-                && (previousToken == TokenNameLBRACE || previousToken == TokenNameLBRACKET || splitScanner.startPosition == 0))) {
-              // the current token is better than the one we currently have
-              // (in level or in priority if same level)
-              // reset the substringsCount
-              splitTokenDepth = openParenthesisPositionCount;
-              splitTokenType = currentToken;
-              splitTokenPriority = getTokenPriority(currentToken);
-              substringsStartPositions[0] = 0;
-              // better token means the whole line until now is the first substring
-
-              if (separateFirstArgumentOn(firstTokenOnLine) && openParenthesisPositionCount > 0) {
-                substringsCount = 2; // resets the count of substrings
-
-                substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1];
-                substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1];
-                substringsEndPositions[1] = splitScanner.startPosition;
-                splitOperatorsCount = 3; // resets the count of split operators
-                splitOperators[0] = 0;
-                splitOperators[1] = 0;
-                splitOperators[2] = currentToken;
-                position = splitScanner.currentPosition;
-                // next substring will start from operator end
-              } else {
-                substringsCount = 1; // resets the count of substrings
-
-                substringsEndPositions[0] = splitScanner.startPosition;
-                // substring ends on operator start
-                position = splitScanner.currentPosition;
-                // next substring will start from operator end
-                splitOperatorsCount = 2; // resets the count of split operators
-                splitOperators[0] = 0;
-                // nothing for first operand since operator will be inserted in front of the second operand
-                splitOperators[1] = currentToken;
-
-              }
-            } else {
-              if (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority == getTokenPriority(currentToken)) {
-                // if another token with the same priority is found,
-                // push the start position of the substring and
-                // push the token into the stack.
-                // create a new array object if the current one is full.
-                if (substringsCount == substringsStartPositions.length) {
-                  System.arraycopy(
-                    substringsStartPositions,
-                    0,
-                    (substringsStartPositions = new int[substringsCount * 2]),
-                    0,
-                    substringsCount);
-                  System.arraycopy(
-                    substringsEndPositions,
-                    0,
-                    (substringsEndPositions = new int[substringsCount * 2]),
-                    0,
-                    substringsCount);
-                }
-                if (splitOperatorsCount == splitOperators.length) {
-                  System.arraycopy(splitOperators, 0, (splitOperators = new int[splitOperatorsCount * 2]), 0, splitOperatorsCount);
-                }
-                substringsStartPositions[substringsCount] = position;
-                substringsEndPositions[substringsCount++] = splitScanner.startPosition;
-                // substring ends on operator start
-                position = splitScanner.currentPosition;
-                // next substring will start from operator end
-                splitOperators[splitOperatorsCount++] = currentToken;
-              }
-            }
-          default :
-            break;
-        }
-        if (isComment(currentToken)) {
-          lastCommentStartPosition = splitScanner.startPosition;
-        } else {
-          lastCommentStartPosition = -1;
-        }
-      }
-    } catch (InvalidInputException e) {
-      return null;
-    }
-    // if the string cannot be split, return null.
-    if (splitOperatorsCount == 0)
-      return null;
-
-    // ## SPECIAL CASES BEGIN
-    if (((splitOperatorsCount == 2
-      && splitOperators[1] == TokenNameDOT
-      && splitTokenDepth == 0
-      && lastOpenParenthesisPosition > -1)
-      || (splitOperatorsCount > 2
-        && splitOperators[1] == TokenNameDOT
-        && splitTokenDepth == 0
-        && lastOpenParenthesisPosition > -1
-        && lastOpenParenthesisPosition <= options.maxLineLength)
-      || (separateFirstArgumentOn(firstTokenOnLine) && splitTokenDepth > 0 && lastOpenParenthesisPosition > -1))
-      && (lastOpenParenthesisPosition < splitScanner.source.length && splitScanner.source[lastOpenParenthesisPosition] != ')')) {
-      // fix for 1FH4J2H: LFCOM:WINNT - Formatter - Empty parenthesis should not be broken on two lines
-      // only one split on a top level .
-      // or more than one split on . and substring before open parenthesis fits one line.
-      // or split inside parenthesis and first token is not a for/while/if
-      SplitLine sl = split(stringToSplit.substring(lastOpenParenthesisPosition), lastOpenParenthesisPosition);
-      if (sl == null || sl.operators[0] != TokenNameCOMMA) {
-        // trim() is used to remove the extra blanks at the end of the substring. See PR 1FGYPI1
-        return new SplitLine(
-          new int[] { 0, 0 },
-          new String[] {
-            stringToSplit.substring(0, lastOpenParenthesisPosition).trim(),
-            stringToSplit.substring(lastOpenParenthesisPosition)},
-          new int[] { offsetInGlobalLine, lastOpenParenthesisPosition + offsetInGlobalLine });
-      } else {
-        // right substring can be split and is split on comma
-        // copy substrings and operators
-        // except if the 1st string is empty.
-        int startIndex = (sl.substrings[0].length() == 0) ? 1 : 0;
-        int subStringsLength = sl.substrings.length + 1 - startIndex;
-        String[] result = new String[subStringsLength];
-        int[] startIndexes = new int[subStringsLength];
-        int operatorsLength = sl.operators.length + 1 - startIndex;
-        int[] operators = new int[operatorsLength];
-
-        result[0] = stringToSplit.substring(0, lastOpenParenthesisPosition);
-        operators[0] = 0;
-
-        System.arraycopy(sl.startSubstringsIndexes, startIndex, startIndexes, 1, subStringsLength - 1);
-        for (int i = subStringsLength - 1; i >= 0; i--) {
-          startIndexes[i] += offsetInGlobalLine;
-        }
-        System.arraycopy(sl.substrings, startIndex, result, 1, subStringsLength - 1);
-        System.arraycopy(sl.operators, startIndex, operators, 1, operatorsLength - 1);
-
-        return new SplitLine(operators, result, startIndexes);
-      }
-    }
-    // if the last token is a comment and the substring before the comment fits on a line,
-    // split before the comment and return the result.
-    if (lastCommentStartPosition > -1 && lastCommentStartPosition < options.maxLineLength && splitTokenPriority > 50) {
-      int end = lastCommentStartPosition;
-      int start = lastCommentStartPosition;
-      if (stringToSplit.charAt(end - 1) == ' ') {
-        end--;
-      }
-      if (start != end && stringToSplit.charAt(start) == ' ') {
-        start++;
-      }
-      return new SplitLine(
-        new int[] { 0, 0 },
-        new String[] { stringToSplit.substring(0, end), stringToSplit.substring(start)},
-        new int[] { 0, start });
-    }
-    if (position != stringToSplit.length()) {
-      if (substringsCount == substringsStartPositions.length) {
-        System.arraycopy(
-          substringsStartPositions,
-          0,
-          (substringsStartPositions = new int[substringsCount * 2]),
-          0,
-          substringsCount);
-        System.arraycopy(substringsEndPositions, 0, (substringsEndPositions = new int[substringsCount * 2]), 0, substringsCount);
-      }
-      // avoid empty extra substring, e.g. line terminated with a semi-colon
-      substringsStartPositions[substringsCount] = position;
-      substringsEndPositions[substringsCount++] = stringToSplit.length();
-    }
-    if (splitOperatorsCount == splitOperators.length) {
-      System.arraycopy(splitOperators, 0, (splitOperators = new int[splitOperatorsCount * 2]), 0, splitOperatorsCount);
-    }
-    splitOperators[splitOperatorsCount] = 0;
-
-    // the last element of the stack is the position of the end of StringToSPlit
-    // +1 because the substring method excludes the last character
-    String[] result = new String[substringsCount];
-    for (int i = 0; i < substringsCount; i++) {
-      int start = substringsStartPositions[i];
-      int end = substringsEndPositions[i];
-      if (stringToSplit.charAt(start) == ' ') {
-        start++;
-        substringsStartPositions[i]++;
-      }
-      if (end != start && stringToSplit.charAt(end - 1) == ' ') {
-        end--;
-      }
-      result[i] = stringToSplit.substring(start, end);
-      substringsStartPositions[i] += offsetInGlobalLine;
-    }
-    if (splitOperatorsCount > substringsCount) {
-      System.arraycopy(substringsStartPositions, 0, (substringsStartPositions = new int[splitOperatorsCount]), 0, substringsCount);
-      System.arraycopy(substringsEndPositions, 0, (substringsEndPositions = new int[splitOperatorsCount]), 0, substringsCount);
-      for (int i = substringsCount; i < splitOperatorsCount; i++) {
-        substringsStartPositions[i] = position;
-        substringsEndPositions[i] = position;
-      }
-      System.arraycopy(splitOperators, 0, (splitOperators = new int[splitOperatorsCount]), 0, splitOperatorsCount);
-    } else {
-      System.arraycopy(substringsStartPositions, 0, (substringsStartPositions = new int[substringsCount]), 0, substringsCount);
-      System.arraycopy(substringsEndPositions, 0, (substringsEndPositions = new int[substringsCount]), 0, substringsCount);
-      System.arraycopy(splitOperators, 0, (splitOperators = new int[substringsCount]), 0, substringsCount);
-    }
-    SplitLine splitLine = new SplitLine(splitOperators, result, substringsStartPositions);
-    return splitLine;
+    //    int currentToken = 0;
+    //    int splitTokenType = 0;
+    //    int splitTokenDepth = Integer.MAX_VALUE;
+    //    int splitTokenPriority = Integer.MAX_VALUE;
+    //    int[] substringsStartPositions = new int[10];
+    //    // contains the start position of substrings
+    //    int[] substringsEndPositions = new int[10];
+    //    // contains the start position of substrings
+    //    int substringsCount = 1; // index in the substringsStartPosition array
+    //    int[] splitOperators = new int[10];
+    //    // contains the start position of substrings
+    //    int splitOperatorsCount = 0; // index in the substringsStartPosition array
+    //    int[] openParenthesisPosition = new int[10];
+    //    int openParenthesisPositionCount = 0;
+    //    int position = 0;
+    //    int lastOpenParenthesisPosition = -1;
+    //    // used to remember the position of the 1st open parenthesis
+    //    // needed for a pattern like: A.B(C); we want formatted like A.B( split C);
+    //    // setup the scanner with a new source
+    //    int lastCommentStartPosition = -1;
+    //    // to remember the start position of the last comment
+    //    int firstTokenOnLine = -1;
+    //    // to remember the first token of the line
+    //    int previousToken = -1;
+    //    // to remember the previous token.
+    //    splitScanner.setSource(stringToSplit.toCharArray());
+    //    try {
+    //      // start the loop
+    //      while (true) {
+    //        // takes the next token
+    //        try {
+    //          if (currentToken != Scanner.TokenNameWHITESPACE)
+    //            previousToken = currentToken;
+    //          currentToken = splitScanner.getNextToken();
+    //          if (Scanner.DEBUG) {
+    //            int currentEndPosition = splitScanner.getCurrentTokenEndPosition();
+    //            int currentStartPosition = splitScanner
+    //                .getCurrentTokenStartPosition();
+    //            System.out.print(currentStartPosition + "," + currentEndPosition
+    //                + ": ");
+    //            System.out.println(scanner.toStringAction(currentToken));
+    //          }
+    //        } catch (InvalidInputException e) {
+    //          if (!handleInvalidToken(e))
+    //            throw e;
+    //          currentToken = 0;
+    //          // this value is not modify when an exception is raised.
+    //        }
+    //        if (currentToken == TokenNameEOF)
+    //          break;
+    //        if (firstTokenOnLine == -1) {
+    //          firstTokenOnLine = currentToken;
+    //        }
+    //        switch (currentToken) {
+    //          case TokenNameRBRACE :
+    //          case TokenNameRPAREN :
+    //            if (openParenthesisPositionCount > 0) {
+    //              if (openParenthesisPositionCount == 1
+    //                  && lastOpenParenthesisPosition < openParenthesisPosition[0]) {
+    //                lastOpenParenthesisPosition = openParenthesisPosition[0];
+    //              } else if ((splitTokenDepth == Integer.MAX_VALUE)
+    //                  || (splitTokenDepth > openParenthesisPositionCount && openParenthesisPositionCount == 1)) {
+    //                splitTokenType = 0;
+    //                splitTokenDepth = openParenthesisPositionCount;
+    //                splitTokenPriority = Integer.MAX_VALUE;
+    //                substringsStartPositions[0] = 0;
+    //                // better token means the whole line until now is the first
+    //                // substring
+    //                substringsCount = 1; // resets the count of substrings
+    //                substringsEndPositions[0] = openParenthesisPosition[0];
+    //                // substring ends on operator start
+    //                position = openParenthesisPosition[0];
+    //                // the string mustn't be cut before the closing parenthesis but
+    //                // after the opening one.
+    //                splitOperatorsCount = 1; // resets the count of split operators
+    //                splitOperators[0] = 0;
+    //              }
+    //              openParenthesisPositionCount--;
+    //            }
+    //            break;
+    //          case TokenNameLBRACE :
+    //          case TokenNameLPAREN :
+    //            if (openParenthesisPositionCount == openParenthesisPosition.length) {
+    //              System
+    //                  .arraycopy(
+    //                      openParenthesisPosition,
+    //                      0,
+    //                      (openParenthesisPosition = new int[openParenthesisPositionCount * 2]),
+    //                      0, openParenthesisPositionCount);
+    //            }
+    //            openParenthesisPosition[openParenthesisPositionCount++] = splitScanner.currentPosition;
+    //            if (currentToken == TokenNameLPAREN
+    //                && previousToken == TokenNameRPAREN) {
+    //              openParenthesisPosition[openParenthesisPositionCount - 1] = splitScanner.startPosition;
+    //            }
+    //            break;
+    //          case TokenNameSEMICOLON :
+    //          // ;
+    //          case TokenNameCOMMA :
+    //          // ,
+    //          case TokenNameEQUAL :
+    //            // =
+    //            if (openParenthesisPositionCount < splitTokenDepth
+    //                || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority > getTokenPriority(currentToken))) {
+    //              // the current token is better than the one we currently have
+    //              // (in level or in priority if same level)
+    //              // reset the substringsCount
+    //              splitTokenDepth = openParenthesisPositionCount;
+    //              splitTokenType = currentToken;
+    //              splitTokenPriority = getTokenPriority(currentToken);
+    //              substringsStartPositions[0] = 0;
+    //              // better token means the whole line until now is the first
+    //              // substring
+    //              if (separateFirstArgumentOn(firstTokenOnLine)
+    //                  && openParenthesisPositionCount > 0) {
+    //                substringsCount = 2; // resets the count of substrings
+    //                substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1];
+    //                substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1];
+    //                substringsEndPositions[1] = splitScanner.startPosition;
+    //                splitOperatorsCount = 2; // resets the count of split operators
+    //                splitOperators[0] = 0;
+    //                splitOperators[1] = currentToken;
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //              } else {
+    //                substringsCount = 1; // resets the count of substrings
+    //                substringsEndPositions[0] = splitScanner.startPosition;
+    //                // substring ends on operator start
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //                splitOperatorsCount = 1; // resets the count of split operators
+    //                splitOperators[0] = currentToken;
+    //              }
+    //            } else {
+    //              if ((openParenthesisPositionCount == splitTokenDepth && splitTokenPriority == getTokenPriority(currentToken))
+    //                  && splitTokenType != TokenNameEQUAL
+    //                  && currentToken != TokenNameEQUAL) {
+    //                // fix for 1FG0BCN: LFCOM:WIN98 - Missing one indentation after
+    //                // split
+    //                // take only the 1st = into account.
+    //                // if another token with the same priority is found,
+    //                // push the start position of the substring and
+    //                // push the token into the stack.
+    //                // create a new array object if the current one is full.
+    //                if (substringsCount == substringsStartPositions.length) {
+    //                  System
+    //                      .arraycopy(
+    //                          substringsStartPositions,
+    //                          0,
+    //                          (substringsStartPositions = new int[substringsCount * 2]),
+    //                          0, substringsCount);
+    //                  System.arraycopy(substringsEndPositions, 0,
+    //                      (substringsEndPositions = new int[substringsCount * 2]),
+    //                      0, substringsCount);
+    //                }
+    //                if (splitOperatorsCount == splitOperators.length) {
+    //                  System.arraycopy(splitOperators, 0,
+    //                      (splitOperators = new int[splitOperatorsCount * 2]), 0,
+    //                      splitOperatorsCount);
+    //                }
+    //                substringsStartPositions[substringsCount] = position;
+    //                substringsEndPositions[substringsCount++] = splitScanner.startPosition;
+    //                // substring ends on operator start
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //                splitOperators[splitOperatorsCount++] = currentToken;
+    //              }
+    //            }
+    //            break;
+    //          case TokenNameCOLON :
+    //            // : (15.24)
+    //            // see 1FK7C5R, we only split on a colon, when it is associated
+    //            // with a question-mark.
+    //            // indeed it might appear also behind a case statement, and we do
+    //            // not to break at this point.
+    //            if ((splitOperatorsCount == 0)
+    //                || splitOperators[splitOperatorsCount - 1] != TokenNameQUESTION) {
+    //              break;
+    //            }
+    //          case TokenNameextends :
+    //          case TokenNameimplements :
+    //          //case TokenNamethrows :
+    //          case TokenNameDOT :
+    //          // .
+    //          case TokenNameMULTIPLY :
+    //          // * (15.16.1)
+    //          case TokenNameDIVIDE :
+    //          // / (15.16.2)
+    //          case TokenNameREMAINDER :
+    //          // % (15.16.3)
+    //          case TokenNamePLUS :
+    //          // + (15.17, 15.17.2)
+    //          case TokenNameMINUS :
+    //          // - (15.17.2)
+    //          case TokenNameLEFT_SHIFT :
+    //          // << (15.18)
+    //          case TokenNameRIGHT_SHIFT :
+    //          // >> (15.18)
+    //          // case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
+    //          case TokenNameLESS :
+    //          // < (15.19.1)
+    //          case TokenNameLESS_EQUAL :
+    //          // <= (15.19.1)
+    //          case TokenNameGREATER :
+    //          // > (15.19.1)
+    //          case TokenNameGREATER_EQUAL :
+    //          // >= (15.19.1)
+    //          // case TokenNameinstanceof : // instanceof
+    //          case TokenNameEQUAL_EQUAL :
+    //          // == (15.20, 15.20.1, 15.20.2, 15.20.3)
+    //          case TokenNameEQUAL_EQUAL_EQUAL :
+    //          // == (15.20, 15.20.1, 15.20.2, 15.20.3)
+    //          case TokenNameNOT_EQUAL :
+    //          // != (15.20, 15.20.1, 15.20.2, 15.20.3)
+    //          case TokenNameNOT_EQUAL_EQUAL :
+    //          // != (15.20, 15.20.1, 15.20.2, 15.20.3)
+    //          case TokenNameAND :
+    //          // & (15.21, 15.21.1, 15.21.2)
+    //          case TokenNameOR :
+    //          // | (15.21, 15.21.1, 15.21.2)
+    //          case TokenNameXOR :
+    //          // ^ (15.21, 15.21.1, 15.21.2)
+    //          case TokenNameAND_AND :
+    //          // && (15.22)
+    //          case TokenNameOR_OR :
+    //          // || (15.23)
+    //          case TokenNameQUESTION :
+    //          // ? (15.24)
+    //          case TokenNameMULTIPLY_EQUAL :
+    //          // *= (15.25.2)
+    //          case TokenNameDIVIDE_EQUAL :
+    //          // /= (15.25.2)
+    //          case TokenNameREMAINDER_EQUAL :
+    //          // %= (15.25.2)
+    //          case TokenNamePLUS_EQUAL :
+    //          // += (15.25.2)
+    //          case TokenNameMINUS_EQUAL :
+    //          // -= (15.25.2)
+    //          case TokenNameLEFT_SHIFT_EQUAL :
+    //          // <<= (15.25.2)
+    //          case TokenNameRIGHT_SHIFT_EQUAL :
+    //          // >>= (15.25.2)
+    //          // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
+    //          case TokenNameAND_EQUAL :
+    //          // &= (15.25.2)
+    //          case TokenNameXOR_EQUAL :
+    //          // ^= (15.25.2)
+    //          case TokenNameOR_EQUAL :
+    //            // |= (15.25.2)
+    //            if ((openParenthesisPositionCount < splitTokenDepth || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority
+    // > getTokenPriority(currentToken)))
+    //                && !((currentToken == TokenNamePLUS || currentToken == TokenNameMINUS) && (previousToken == TokenNameLBRACE
+    //                    || previousToken == TokenNameLBRACKET || splitScanner.startPosition == 0))) {
+    //              // the current token is better than the one we currently have
+    //              // (in level or in priority if same level)
+    //              // reset the substringsCount
+    //              splitTokenDepth = openParenthesisPositionCount;
+    //              splitTokenType = currentToken;
+    //              splitTokenPriority = getTokenPriority(currentToken);
+    //              substringsStartPositions[0] = 0;
+    //              // better token means the whole line until now is the first
+    //              // substring
+    //              if (separateFirstArgumentOn(firstTokenOnLine)
+    //                  && openParenthesisPositionCount > 0) {
+    //                substringsCount = 2; // resets the count of substrings
+    //                substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1];
+    //                substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1];
+    //                substringsEndPositions[1] = splitScanner.startPosition;
+    //                splitOperatorsCount = 3; // resets the count of split operators
+    //                splitOperators[0] = 0;
+    //                splitOperators[1] = 0;
+    //                splitOperators[2] = currentToken;
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //              } else {
+    //                substringsCount = 1; // resets the count of substrings
+    //                substringsEndPositions[0] = splitScanner.startPosition;
+    //                // substring ends on operator start
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //                splitOperatorsCount = 2; // resets the count of split operators
+    //                splitOperators[0] = 0;
+    //                // nothing for first operand since operator will be inserted in
+    //                // front of the second operand
+    //                splitOperators[1] = currentToken;
+    //              }
+    //            } else {
+    //              if (openParenthesisPositionCount == splitTokenDepth
+    //                  && splitTokenPriority == getTokenPriority(currentToken)) {
+    //                // if another token with the same priority is found,
+    //                // push the start position of the substring and
+    //                // push the token into the stack.
+    //                // create a new array object if the current one is full.
+    //                if (substringsCount == substringsStartPositions.length) {
+    //                  System
+    //                      .arraycopy(
+    //                          substringsStartPositions,
+    //                          0,
+    //                          (substringsStartPositions = new int[substringsCount * 2]),
+    //                          0, substringsCount);
+    //                  System.arraycopy(substringsEndPositions, 0,
+    //                      (substringsEndPositions = new int[substringsCount * 2]),
+    //                      0, substringsCount);
+    //                }
+    //                if (splitOperatorsCount == splitOperators.length) {
+    //                  System.arraycopy(splitOperators, 0,
+    //                      (splitOperators = new int[splitOperatorsCount * 2]), 0,
+    //                      splitOperatorsCount);
+    //                }
+    //                substringsStartPositions[substringsCount] = position;
+    //                substringsEndPositions[substringsCount++] = splitScanner.startPosition;
+    //                // substring ends on operator start
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //                splitOperators[splitOperatorsCount++] = currentToken;
+    //              }
+    //            }
+    //          default :
+    //            break;
+    //        }
+    //        if (isComment(currentToken)) {
+    //          lastCommentStartPosition = splitScanner.startPosition;
+    //        } else {
+    //          lastCommentStartPosition = -1;
+    //        }
+    //      }
+    //    } catch (InvalidInputException e) {
+    //      return null;
+    //    }
+    //    // if the string cannot be split, return null.
+    //    if (splitOperatorsCount == 0)
+    //      return null;
+    //    // ## SPECIAL CASES BEGIN
+    //    if (((splitOperatorsCount == 2 && splitOperators[1] == TokenNameDOT
+    //        && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1)
+    //        || (splitOperatorsCount > 2 && splitOperators[1] == TokenNameDOT
+    //            && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1 && lastOpenParenthesisPosition <= options.maxLineLength) ||
+    // (separateFirstArgumentOn(firstTokenOnLine)
+    //        && splitTokenDepth > 0 && lastOpenParenthesisPosition > -1))
+    //        && (lastOpenParenthesisPosition < splitScanner.source.length && splitScanner.source[lastOpenParenthesisPosition] != ')')) {
+    //      // fix for 1FH4J2H: LFCOM:WINNT - Formatter - Empty parenthesis should
+    //      // not be broken on two lines
+    //      // only one split on a top level .
+    //      // or more than one split on . and substring before open parenthesis fits
+    //      // one line.
+    //      // or split inside parenthesis and first token is not a for/while/if
+    //      SplitLine sl = split(
+    //          stringToSplit.substring(lastOpenParenthesisPosition),
+    //          lastOpenParenthesisPosition);
+    //      if (sl == null || sl.operators[0] != TokenNameCOMMA) {
+    //        // trim() is used to remove the extra blanks at the end of the
+    //        // substring. See PR 1FGYPI1
+    //        return new SplitLine(new int[]{0, 0}, new String[]{
+    //            stringToSplit.substring(0, lastOpenParenthesisPosition).trim(),
+    //            stringToSplit.substring(lastOpenParenthesisPosition)}, new int[]{
+    //            offsetInGlobalLine,
+    //            lastOpenParenthesisPosition + offsetInGlobalLine});
+    //      } else {
+    //        // right substring can be split and is split on comma
+    //        // copy substrings and operators
+    //        // except if the 1st string is empty.
+    //        int startIndex = (sl.substrings[0].length() == 0) ? 1 : 0;
+    //        int subStringsLength = sl.substrings.length + 1 - startIndex;
+    //        String[] result = new String[subStringsLength];
+    //        int[] startIndexes = new int[subStringsLength];
+    //        int operatorsLength = sl.operators.length + 1 - startIndex;
+    //        int[] operators = new int[operatorsLength];
+    //        result[0] = stringToSplit.substring(0, lastOpenParenthesisPosition);
+    //        operators[0] = 0;
+    //        System.arraycopy(sl.startSubstringsIndexes, startIndex, startIndexes,
+    //            1, subStringsLength - 1);
+    //        for (int i = subStringsLength - 1; i >= 0; i--) {
+    //          startIndexes[i] += offsetInGlobalLine;
+    //        }
+    //        System.arraycopy(sl.substrings, startIndex, result, 1,
+    //            subStringsLength - 1);
+    //        System.arraycopy(sl.operators, startIndex, operators, 1,
+    //            operatorsLength - 1);
+    //        return new SplitLine(operators, result, startIndexes);
+    //      }
+    //    }
+    //    // if the last token is a comment and the substring before the comment fits
+    //    // on a line,
+    //    // split before the comment and return the result.
+    //    if (lastCommentStartPosition > -1
+    //        && lastCommentStartPosition < options.maxLineLength
+    //        && splitTokenPriority > 50) {
+    //      int end = lastCommentStartPosition;
+    //      int start = lastCommentStartPosition;
+    //      if (stringToSplit.charAt(end - 1) == ' ') {
+    //        end--;
+    //      }
+    //      if (start != end && stringToSplit.charAt(start) == ' ') {
+    //        start++;
+    //      }
+    //      return new SplitLine(new int[]{0, 0}, new String[]{
+    //          stringToSplit.substring(0, end), stringToSplit.substring(start)},
+    //          new int[]{0, start});
+    //    }
+    //    if (position != stringToSplit.length()) {
+    //      if (substringsCount == substringsStartPositions.length) {
+    //        System.arraycopy(substringsStartPositions, 0,
+    //            (substringsStartPositions = new int[substringsCount * 2]), 0,
+    //            substringsCount);
+    //        System.arraycopy(substringsEndPositions, 0,
+    //            (substringsEndPositions = new int[substringsCount * 2]), 0,
+    //            substringsCount);
+    //      }
+    //      // avoid empty extra substring, e.g. line terminated with a semi-colon
+    //      substringsStartPositions[substringsCount] = position;
+    //      substringsEndPositions[substringsCount++] = stringToSplit.length();
+    //    }
+    //    if (splitOperatorsCount == splitOperators.length) {
+    //      System.arraycopy(splitOperators, 0,
+    //          (splitOperators = new int[splitOperatorsCount * 2]), 0,
+    //          splitOperatorsCount);
+    //    }
+    //    splitOperators[splitOperatorsCount] = 0;
+    //    // the last element of the stack is the position of the end of
+    //    // StringToSPlit
+    //    // +1 because the substring method excludes the last character
+    //    String[] result = new String[substringsCount];
+    //    for (int i = 0; i < substringsCount; i++) {
+    //      int start = substringsStartPositions[i];
+    //      int end = substringsEndPositions[i];
+    //      if (stringToSplit.charAt(start) == ' ') {
+    //        start++;
+    //        substringsStartPositions[i]++;
+    //      }
+    //      if (end != start && stringToSplit.charAt(end - 1) == ' ') {
+    //        end--;
+    //      }
+    //      result[i] = stringToSplit.substring(start, end);
+    //      substringsStartPositions[i] += offsetInGlobalLine;
+    //    }
+    //    if (splitOperatorsCount > substringsCount) {
+    //      System.arraycopy(substringsStartPositions, 0,
+    //          (substringsStartPositions = new int[splitOperatorsCount]), 0,
+    //          substringsCount);
+    //      System.arraycopy(substringsEndPositions, 0,
+    //          (substringsEndPositions = new int[splitOperatorsCount]), 0,
+    //          substringsCount);
+    //      for (int i = substringsCount; i < splitOperatorsCount; i++) {
+    //        substringsStartPositions[i] = position;
+    //        substringsEndPositions[i] = position;
+    //      }
+    //      System.arraycopy(splitOperators, 0,
+    //          (splitOperators = new int[splitOperatorsCount]), 0,
+    //          splitOperatorsCount);
+    //    } else {
+    //      System.arraycopy(substringsStartPositions, 0,
+    //          (substringsStartPositions = new int[substringsCount]), 0,
+    //          substringsCount);
+    //      System.arraycopy(substringsEndPositions, 0,
+    //          (substringsEndPositions = new int[substringsCount]), 0,
+    //          substringsCount);
+    //      System.arraycopy(splitOperators, 0,
+    //          (splitOperators = new int[substringsCount]), 0, substringsCount);
+    //    }
+    //    SplitLine splitLine = new SplitLine(splitOperators, result,
+    //        substringsStartPositions);
+    //    return splitLine;
   }
 
   private void updateMappedPositions(int startPosition) {
@@ -2375,11 +2476,8 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   private void updateMappedPositionsWhileSplitting(int startPosition, int endPosition) {
     if (mappedPositions == null || mappedPositions.length == indexInMap)
       return;
-
-    while (indexInMap < mappedPositions.length
-      && startPosition <= mappedPositions[indexInMap]
-      && mappedPositions[indexInMap] < endPosition
-      && indexInMap < indexToMap) {
+    while (indexInMap < mappedPositions.length && startPosition <= mappedPositions[indexInMap]
+        && mappedPositions[indexInMap] < endPosition && indexInMap < indexToMap) {
       mappedPositions[indexInMap] += splitDelta;
       indexInMap++;
     }
@@ -2393,23 +2491,26 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     for (int i = 0, max = s.length(); i < max; i++) {
       char currentChar = s.charAt(i);
       switch (currentChar) {
-        case '\t' :
-          length += options.tabSize;
-          break;
-        default :
-          length++;
+      case '\t':
+        length += options.tabSize;
+        break;
+      default:
+        length++;
       }
     }
     return length;
   }
 
-  /** 
-  * Sets the initial indentation level
-  * @param indentationLevel new indentation level
-  * 
-  * @deprecated
-  */
+  /**
+   * Sets the initial indentation level
+   * 
+   * @param indentationLevel
+   *          new indentation level
+   * 
+   * @deprecated
+   */
   public void setInitialIndentationLevel(int newIndentationLevel) {
     this.initialIndentationLevel = currentLineIndentationLevel = indentationLevel = newIndentationLevel;
   }
+
 }
\ No newline at end of file