fixed bug #1037094 (foreach)
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / formatter / CodeFormatter.java
index 13bbf68..27e8037 100644 (file)
@@ -23,2534 +23,2476 @@ 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>
+   * 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.
+   */
+  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.
+   */
+  int currentCommentOffset;
+
+  int currentLineIndentationLevel;
+
+  int maxLineSize = 30;
+
+  private boolean containsOpenCloseBraces;
+
+  private int indentationLevelForOpenCloseBraces;
+
+  /**
+   * Collections of positions to map
+   */
+  private int[] positionsToMap;
+
+  /**
+   * Collections of mapped positions
+   */
+  private int[] mappedPositions;
+
+  private int indexToMap;
+
+  private int indexInMap;
+
+  private int globalDelta;
+
+  private int lineDelta;
+
+  private int splitDelta;
+
+  private int beginningOfLineIndex;
+
+  private int multipleLineCommentCounter;
+
+  /**
+   * Creates a new instance of Code Formatter using the given settings.
+   * 
+   * @deprecated backport 1.0 internal functionality
+   */
+  public CodeFormatter(ConfigurableOption[] settings) {
+    this(convertConfigurableOptions(settings));
+  }
+
+  /**
+   * 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 */
+    , 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 */
+    , 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.
+   */
+  private static boolean breakLineBeforeOperator(int operator) {
+    switch (operator) {
+    case TokenNameCOMMA:
+    case TokenNameSEMICOLON:
+    case TokenNameEQUAL:
+      return false;
+    default:
+      return true;
+    }
+  }
+
+  /**
+   * @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$
+        } 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() {
+    char str[] = scanner.source;
+    int startPosition = scanner.startPosition;
+    int length = str.length - startPosition;
+    StringBuffer bufr = new StringBuffer(length);
+    if (startPosition < str.length) {
+      bufr.append(str, startPosition, length);
+    }
+    return (bufr.toString());
+  }
+
+  /**
+   * Inserts <code>tabCount</code> tab character or their equivalent number of spaces.
+   */
+  private void dumpTab(int tabCount) {
+    if (options.indentWithTab) {
+      for (int j = 0; j < tabCount; j++) {
+        formattedSource.append('\t');
+        increaseSplitDelta(1);
+      }
+    } else {
+      for (int i = 0, max = options.tabSize * tabCount; i < max; i++) {
+        formattedSource.append(' ');
+        increaseSplitDelta(1);
+      }
+    }
+  }
+
+  /**
+   * Dumps <code>currentLineBuffer</code> into the formatted string.
+   */
+  private void flushBuffer() {
+    String currentString = currentLineBuffer.toString();
+    splitDelta = 0;
+    beginningOfLineIndex = formattedSource.length();
+    if (containsOpenCloseBraces) {
+      containsOpenCloseBraces = false;
+      outputLine(currentString, false, indentationLevelForOpenCloseBraces, 0, -1, null, 0);
+      indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
+    } else {
+      outputLine(currentString, false, currentLineIndentationLevel, 0, -1, null, 0);
+    }
+    int scannerSourceLength = scanner.source.length;
+    if (scannerSourceLength > 2) {
+      if (scanner.source[scannerSourceLength - 1] == '\n' && scanner.source[scannerSourceLength - 2] == '\r') {
+        formattedSource.append(options.lineSeparatorSequence);
+        increaseGlobalDelta(options.lineSeparatorSequence.length - 2);
+      } else if (scanner.source[scannerSourceLength - 1] == '\n') {
+        formattedSource.append(options.lineSeparatorSequence);
+        increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
+      } else if (scanner.source[scannerSourceLength - 1] == '\r') {
+        formattedSource.append(options.lineSeparatorSequence);
+        increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
+      }
+    }
+    updateMappedPositions(scanner.startPosition);
+  }
+
+  /**
+   * Formats the input string.
+   */
+  private void format() {
+    int token = 0;
+    int previousToken = 0;
+    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;
+    boolean expectingOpenBrace = false;
+    boolean clearNonBlockIndents = false;
+    // true if all indentations till the 1st { (usefull after } or ;)
+    boolean pendingSpace = true;
+    boolean pendingNewlineAfterParen = false;
+    // true when a cr is to be put after a ) (in conditional statements)
+    boolean inAssignment = false;
+    boolean inArrayAssignment = false;
+    boolean inThrowsClause = false;
+    boolean inClassOrInterfaceHeader = false;
+    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
+    // (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
+    // :
+    // 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
+    boolean specialElse = false;
+    // OPTION (IndentationLevel): initial indentation level may be non-zero.
+    currentLineIndentationLevel += constructionsCount;
+    // An InvalidInputException exception might cause the termination of this
+    // loop.
+    try {
+      while (true) {
+        // 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--) {
+              switch (scanner.source[index]) {
+              case '\r':
+              case '\n':
+                scanner.currentPosition--;
+                break;
+              default:
+                break loop;
+              }
+            }
+          }
+        } catch (InvalidInputException e) {
+          if (!handleInvalidToken(e)) {
+            throw e;
+          }
+          token = 0;
+        }
+        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
+        if (clearNonBlockIndents && (token != Scanner.TokenNameWHITESPACE)) {
+          switch (token) {
+          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;
+            }
+          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;
+        }
+        // returns to the indentation level created by the SWITCH keyword
+        // if the current token is a CASE or a DEFAULT
+        if (token == TokenNamecase || token == TokenNamedefault) {
+          indentationLevel += pop(TokenNamecase);
+        }
+        //                             if (token == Scanner.TokenNamethrows) {
+        //                                     inThrowsClause = true;
+        //                             }
+        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.
+        // Fix for 1ETLWPZ: IVJCOM:ALL - incorrect "else if" formatting
+        //        if (pendingNewlineAfterParen
+        //          && previousCompilableToken == TokenNameelse
+        //          && token == TokenNameif
+        //          && options.compactElseIfMode) {
+        //          pendingNewlineAfterParen = false;
+        //          pendingNewLines = 0;
+        //          indentationLevel += pop(TokenNameelse);
+        //          // because else if is now one single statement,
+        //          // the indentation level after it is increased by one and not by 2
+        //          // (else = 1 indent, if = 1 indent, but else if = 1 indent, not 2).
+        //        }
+        // 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);
+        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
+          // 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)) {
+            newLine(1);
+            currentLineIndentationLevel = indentationLevel;
+            pendingNewLines = 0;
+            pendingSpace = false;
+          } else {
+            if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode) {
+              newLine(1);
+              if (constructionsCount > 0 && constructions[constructionsCount - 1] != BLOCK
+                  && constructions[constructionsCount - 1] != NONINDENT_BLOCK) {
+                currentLineIndentationLevel = indentationLevel - 1;
+              } else {
+                currentLineIndentationLevel = indentationLevel;
+              }
+              pendingNewLines = 0;
+              pendingSpace = false;
+            }
+          }
+        }
+        if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode && constructionsCount > 0
+            && constructions[constructionsCount - 1] == TokenNamedo) {
+          newLine(1);
+          currentLineIndentationLevel = indentationLevel - 1;
+          pendingNewLines = 0;
+          pendingSpace = false;
+        }
+        // see PR 1G5G8EC
+        if (token == TokenNameLBRACE && inThrowsClause) {
+          inThrowsClause = false;
+          if (options.newLineBeforeOpeningBraceMode) {
+            newLine(1);
+            currentLineIndentationLevel = indentationLevel;
+            pendingNewLines = 0;
+            pendingSpace = false;
+          }
+        }
+        // see PR 1G5G82G
+        if (token == TokenNameLBRACE && inClassOrInterfaceHeader) {
+          inClassOrInterfaceHeader = false;
+          if (options.newLineBeforeOpeningBraceMode) {
+            newLine(1);
+            currentLineIndentationLevel = indentationLevel;
+            pendingNewLines = 0;
+            pendingSpace = false;
+          }
+        }
+        // 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 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) {
+          // Do not add newline & indent between an adjoining close brace and
+          // 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
+              && !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.
+          boolean semiColonAndCloseBrace = previousToken == TokenNameRBRACE && token == TokenNameSEMICOLON;
+          // 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).
+          boolean commaAndCloseBrace = previousToken == TokenNameRBRACE && token == TokenNameCOMMA;
+          // Add a newline and indent, if appropriate.
+          if (specialElse
+              || (!commentAndOpenBrace && !closeBraceAndCloseParen && !nlicsOption && !semiColonAndCloseBrace && !commaAndCloseBrace)) {
+            // if clearAllBlankLinesMode=false, leaves the blank lines
+            // inserted by the user
+            // if clearAllBlankLinesMode=true, removes all of then
+            // and insert only blank lines required by the formatting.
+            if (!options.clearAllBlankLinesMode) {
+              //  (isComment(token))
+              pendingNewLines = (pendingNewLines < newLinesInWhitespace) ? newLinesInWhitespace : pendingNewLines;
+              pendingNewLines = (pendingNewLines > 2) ? 2 : pendingNewLines;
+            }
+            if (previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE) {
+              containsOpenCloseBraces = true;
+              indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
+              if (isComment(previousToken)) {
+                newLine(pendingNewLines);
+              } else {
+                /*
+                 * 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
+                  } else {
+                    newLine(pendingNewLines);
+                  }
+                }
+                // }
+              }
+            } else {
+              // 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)) {
+              indentationOffset = -1;
+              indentationLevel += popExclusiveUntilBlock();
+            }
+            if (previousToken == Scanner.TokenNameCOMMENT_LINE && inAssignment) {
+              // PR 1FI5IPO
+              currentLineIndentationLevel++;
+            } else {
+              currentLineIndentationLevel = indentationLevel + indentationOffset;
+            }
+            pendingSpace = false;
+            indentationOffset = 0;
+          }
+          pendingNewLines = 0;
+          newLinesInWhitespace = 0;
+          specialElse = false;
+          if (nlicsToken == TokenNamedo && token == TokenNamewhile) {
+            nlicsToken = 0;
+          }
+        }
+        boolean phpTagAndWhitespace = previousToken == TokenNameINLINE_HTML && token == TokenNameWHITESPACE;
+        switch (token) {
+        //          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--;
+            }
+          } else {
+            openParenthesis[0]--;
+          }
+          pendingSpace = false;
+          break;
+        case TokenNameLBRACE:
+          if (previousCompilableToken == TokenNameDOLLAR) {
+            dollarBraceCount++;
+          } else {
+            if ((previousCompilableToken == TokenNameRBRACKET) || (previousCompilableToken == TokenNameEQUAL)) {
+              //                  if (previousCompilableToken == TokenNameRBRACKET) {
+              inArrayAssignment = true;
+              inAssignment = false;
+            }
+            if (inArrayAssignment) {
+              indentationLevel += pushBlock();
+            } else {
+              // Add new line and increase indentation level after open brace.
+              pendingNewLines = 1;
+              indentationLevel += pushBlock();
+            }
+          }
+          break;
+        case TokenNameRBRACE:
+          if (dollarBraceCount > 0) {
+            dollarBraceCount--;
+            break;
+          }
+          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:
+              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;
+              default:
+                break;
+              }
+            }
+          }
+          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;
+            }
+          }
+          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++;
+          }
+          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;
+            newLinesInWhitespace = 0;
+            for (int i = scanner.startPosition, max = scanner.currentPosition; i < max; i++) {
+              if (source[i] == '\r') {
+                if (i < max - 1) {
+                  if (source[++i] == '\n') {
+                    newLinesInWhitespace++;
+                  } else {
+                    newLinesInWhitespace++;
+                  }
+                } else {
+                  newLinesInWhitespace++;
+                }
+              } else if (source[i] == '\n') {
+                newLinesInWhitespace++;
+              }
+            }
+            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
+                || (previousToken == TokenNameMINUS_GREATER && options.compactDereferencingMode) // ->
+                || (previousToken == TokenNamePLUS && unarySignModifier > 0)
+                || (previousToken == TokenNameMINUS && unarySignModifier > 0)) {
+              pendingSpace = false;
+            }
+            unarySignModifier = 0;
+          }
+          break;
+        }
+        // Do not output whitespace tokens.
+        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;
+
+          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();
+          }
+          // Add the next token to the formatted source string.
+          outputCurrentToken(token);
+          if (token == Scanner.TokenNameCOMMENT_LINE && openParenthesisCount > 1) {
+            pendingNewLines = 0;
+            currentLineBuffer.append(options.lineSeparatorSequence);
+            increaseLineDelta(options.lineSeparatorSequence.length);
+          }
+          pendingSpace = true;
+        }
+        // Whitespace tokens do not need to be remembered.
+        if (token != Scanner.TokenNameWHITESPACE || phpTagAndWhitespace) {
+          previousToken = token;
+          if (token != Scanner.TokenNameCOMMENT_BLOCK && token != Scanner.TokenNameCOMMENT_LINE
+              && token != Scanner.TokenNameCOMMENT_PHPDOC) {
+            previousCompilableToken = token;
+          }
+        }
+      }
+      output(copyRemainingSource());
+      flushBuffer();
+      // dump the last token of the source in the formatted output.
+    } catch (InvalidInputException e) {
+      output(copyRemainingSource());
+      flushBuffer();
+      // dump the last token of the source in the formatted output.
+    }
+  }
+
+  /**
+   * Formats the char array <code>sourceString</code>, and returns a string containing the formatted version.
+   * 
+   * @return the formatted ouput.
+   */
+  public String formatSourceString(String sourceString) {
+    char[] sourceChars = sourceString.toCharArray();
+    formattedSource = new StringBuffer(sourceChars.length);
+    scanner.setSource(sourceChars);
+    format();
+    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
+   * @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
+   * @return the formatted ouput.
+   */
+  public String format(String string, int indentationLevel, int[] positions) {
+    return this.format(string, indentationLevel, positions, null);
+  }
+
+  public String format(String string, int indentationLevel, int[] positions, String lineSeparator) {
+    if (lineSeparator != null) {
+      this.options.setLineSeparator(lineSeparator);
+    }
+    if (positions != null) {
+      this.setPositionsToMap(positions);
+      this.setInitialIndentationLevel(indentationLevel);
+      String formattedString = this.formatSourceString(string);
+      int[] mappedPositions = this.getMappedPositions();
+      System.arraycopy(mappedPositions, 0, positions, 0, positions.length);
+      return formattedString;
+    } else {
+      this.setInitialIndentationLevel(indentationLevel);
+      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
+   * @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
+   * 
+   * @deprecated backport 1.0 internal functionality
+   */
+  public static String format(String sourceString, int initialIndentationLevel, ConfigurableOption[] options) {
+    CodeFormatter formatter = new CodeFormatter(options);
+    formatter.setInitialIndentationLevel(initialIndentationLevel);
+    return formatter.formatSourceString(sourceString);
+  }
+
+  /**
+   * 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;
+    // if there is no beginning of line, return 0.
+    if (linePtr < 0)
+      return 0;
+    int offset = 0;
+    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) {
+        beginningOfLine = scanner.lineEnds[--linePtr];
+      } else {
+        beginningOfLine = 0;
+        break;
+      }
+    }
+    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;
+      }
+    }
+    return offset;
+  }
+
+  /**
+   * 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
+   */
+  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$
+    };
+  }
+
+  /**
+   * 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.
+   */
+  public int[] getMappedPositions() {
+    return mappedPositions;
+  }
+
+  /**
+   * 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
+   */
+  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 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.
+   */
+  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)) {
+      return true;
+    }
+    return false;
+  }
+
+  private final void increaseGlobalDelta(int offset) {
+    globalDelta += offset;
+  }
+
+  private final void increaseLineDelta(int offset) {
+    lineDelta += offset;
+  }
+
+  private final void increaseSplitDelta(int offset) {
+    splitDelta += offset;
+  }
+
+  /**
+   * 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 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).
+   */
+  private boolean insertSpaceBefore(int token) {
+    switch (token) {
+    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;
+    return result;
+  }
+
+  private static boolean isLiteralToken(int token) {
+    boolean result = token == TokenNameIntegerLiteral
+    //                 || 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
+   */
+  private void newLine(int newLineCount) {
+    // format current line
+    splitDelta = 0;
+    beginningOfLineIndex = formattedSource.length();
+    String currentLine = currentLineBuffer.toString();
+    if (containsOpenCloseBraces) {
+      containsOpenCloseBraces = false;
+      outputLine(currentLine, false, indentationLevelForOpenCloseBraces, 0, -1, null, 0);
+      indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
+    } else {
+      outputLine(currentLine, false, currentLineIndentationLevel, 0, -1, null, 0);
+    }
+    // dump line break(s)
+    for (int i = 0; i < newLineCount; i++) {
+      formattedSource.append(options.lineSeparatorSequence);
+      increaseSplitDelta(options.lineSeparatorSequence.length);
+    }
+    // reset formatter for next line
+    int currentLength = currentLine.length();
+    currentLineBuffer = new StringBuffer(currentLength > maxLineSize ? maxLineSize = currentLength : maxLineSize);
+    increaseGlobalDelta(splitDelta);
+    increaseGlobalDelta(lineDelta);
+    lineDelta = 0;
+    currentLineIndentationLevel = initialIndentationLevel;
+  }
+
+  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 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>
+   * If it contains \n, append a LINE_SEPARATOR and indent after it.
+   */
+  private void output(String stringToOutput) {
+    char currentCharacter;
+    for (int i = 0, max = stringToOutput.length(); i < max; i++) {
+      currentCharacter = stringToOutput.charAt(i);
+      if (currentCharacter != '\t') {
+        currentLineBuffer.append(currentCharacter);
+      }
+    }
+  }
+
+  /**
+   * 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;
+          }
+        }
+      }
+      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>.
+   */
+  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) {
+        dumpTab(depth);
+        preIndented = true;
+      }
+      if (operator != 0) {
+        if (insertSpaceBefore(operator)) {
+          formattedSource.append(' ');
+          increaseSplitDelta(1);
+        }
+        formattedSource.append(operatorString);
+        increaseSplitDelta(operatorString.length());
+        if (insertSpaceAfter(operator) && operator != TokenNameimplements && operator != TokenNameextends) {
+          //                   && operator != TokenNamethrows) {
+          formattedSource.append(' ');
+          increaseSplitDelta(1);
+        }
+      }
+    }
+    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
+      // indent before postfix operator
+      // indent also when the line cannot be split
+      if (operator == TokenNameextends || operator == TokenNameimplements) {
+        //                             || operator == TokenNamethrows) {
+        formattedSource.append(' ');
+        increaseSplitDelta(1);
+      }
+      if (placeOperatorBehind) {
+        if (!preIndented) {
+          dumpTab(depth);
+        }
+      }
+      int max = currentString.length();
+      if (multipleLineCommentCounter != 0) {
+        try {
+          BufferedReader reader = new BufferedReader(new StringReader(currentString));
+          String line = reader.readLine();
+          while (line != null) {
+            updateMappedPositionsWhileSplitting(beginningOfLineIndex, beginningOfLineIndex + line.length()
+                + options.lineSeparatorSequence.length);
+            formattedSource.append(line);
+            beginningOfLineIndex = beginningOfLineIndex + line.length();
+            if ((line = reader.readLine()) != null) {
+              formattedSource.append(options.lineSeparatorSequence);
+              beginningOfLineIndex += options.lineSeparatorSequence.length;
+              dumpTab(currentLineIndentationLevel);
+            }
+          }
+          reader.close();
+        } catch (IOException e) {
+          e.printStackTrace();
+        }
+      } else {
+        updateMappedPositionsWhileSplitting(beginningOfLineIndex, beginningOfLineIndex + max);
+        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);
+          }
+        }
+      }
+      // update positions inside the mappedPositions table
+      if (substringIndex != -1) {
+        if (multipleLineCommentCounter == 0) {
+          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]);
+        }
+      }
+      // dump postfix operator?
+      if (placeOperatorBehind) {
+        if (insertSpaceBefore(operator)) {
+          formattedSource.append(' ');
+          if (operator != 0) {
+            increaseSplitDelta(1);
+          }
+        }
+        formattedSource.append(operatorString);
+        if (operator != 0) {
+          increaseSplitDelta(operatorString.length());
+        }
+      }
+      return;
+    }
+    // fix for 1FG0BA3: LFCOM:WIN98 - Weird splitting on interfaces
+    // extends has to stand alone on a line when currentString has been split.
+    if (options.maxLineLength != 0 && splitLine != null && (operator == TokenNameextends)) {
+      //                               || operator == TokenNameimplements
+      //                               || operator == TokenNamethrows)) {
+      formattedSource.append(options.lineSeparatorSequence);
+      increaseSplitDelta(options.lineSeparatorSequence.length);
+      dumpTab(depth + 1);
+    } else {
+      if (operator == TokenNameextends) {
+        //                             || operator == TokenNameimplements
+        //                             || operator == TokenNamethrows) {
+        formattedSource.append(' ');
+        increaseSplitDelta(1);
+      }
+    }
+    // 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
+    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
+      // (-1 because the ouputline increases depth).
+      // (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));
+        if (i != max - 1) {
+          formattedSource.append(options.lineSeparatorSequence);
+          increaseSplitDelta(options.lineSeparatorSequence.length);
+        }
+      }
+    }
+    if (result.length == splitOperators.length - 1) {
+      int lastOperator = splitOperators[result.length];
+      String lastOperatorString = operatorString(lastOperator);
+      formattedSource.append(options.lineSeparatorSequence);
+      increaseSplitDelta(options.lineSeparatorSequence.length);
+      if (breakLineBeforeOperator(lastOperator)) {
+        dumpTab(depth + 1);
+        if (lastOperator != 0) {
+          if (insertSpaceBefore(lastOperator)) {
+            formattedSource.append(' ');
+            increaseSplitDelta(1);
+          }
+          formattedSource.append(lastOperatorString);
+          increaseSplitDelta(lastOperatorString.length());
+          if (insertSpaceAfter(lastOperator) && lastOperator != TokenNameimplements && lastOperator != TokenNameextends) {
+            //                                 && lastOperator != TokenNamethrows) {
+            formattedSource.append(' ');
+            increaseSplitDelta(1);
+          }
+        }
+      }
+    }
+    if (placeOperatorBehind) {
+      if (insertSpaceBefore(operator)) {
+        formattedSource.append(' ');
+        increaseSplitDelta(1);
+      }
+      formattedSource.append(operatorString);
+      //increaseSplitDelta(operatorString.length());
+    }
+  }
+
+  /**
+   * Pops the top statement of the stack if it is <code>token</code>
+   */
+  private int pop(int token) {
+    int delta = 0;
+    if ((constructionsCount > 0) && (constructions[constructionsCount - 1] == token)) {
+      delta--;
+      constructionsCount--;
+    }
+    return delta;
+  }
+
+  /**
+   * Pops the top statement of the stack if it is a <code>BLOCK</code> or a <code>NONINDENT_BLOCK</code>.
+   */
+  private int popBlock() {
+    int delta = 0;
+    if ((constructionsCount > 0)
+        && ((constructions[constructionsCount - 1] == BLOCK) || (constructions[constructionsCount - 1] == NONINDENT_BLOCK))) {
+      if (constructions[constructionsCount - 1] == BLOCK)
+        delta--;
+      constructionsCount--;
+    }
+    return delta;
+  }
+
+  /**
+   * 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
+   */
+  private int popExclusiveUntil(int token) {
+    int delta = 0;
+    int startCount = constructionsCount;
+    for (int i = startCount - 1; i >= 0 && constructions[i] != token; i--) {
+      if (constructions[i] != NONINDENT_BLOCK)
+        delta--;
+      constructionsCount--;
+    }
+    return delta;
+  }
+
+  /**
+   * 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() {
+    int startCount = constructionsCount;
+    int delta = 0;
+    for (int i = startCount - 1; i >= 0 && constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK; i--) {
+      constructionsCount--;
+      delta--;
+    }
+    return delta;
+  }
+
+  /**
+   * 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--) {
+      constructionsCount--;
+      delta--;
+    }
+    return delta;
+  }
+
+  /**
+   * 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
+   */
+  private int popInclusiveUntil(int token) {
+    int startCount = constructionsCount;
+    int delta = 0;
+    for (int i = startCount - 1; i >= 0 && constructions[i] != token; i--) {
+      if (constructions[i] != NONINDENT_BLOCK)
+        delta--;
+      constructionsCount--;
+    }
+    if (constructionsCount > 0) {
+      if (constructions[constructionsCount - 1] != NONINDENT_BLOCK)
+        delta--;
+      constructionsCount--;
+    }
+    return delta;
+  }
+
+  /**
+   * 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() {
+    int startCount = constructionsCount;
+    int delta = 0;
+    for (int i = startCount - 1; i >= 0 && (constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK); i--) {
+      delta--;
+      constructionsCount--;
+    }
+    if (constructionsCount > 0) {
+      if (constructions[constructionsCount - 1] == BLOCK)
+        delta--;
+      constructionsCount--;
+    }
+    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.
+   */
+  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)) {
+      delta++;
+      constructions[constructionsCount++] = BLOCK;
+    } else {
+      constructions[constructionsCount++] = NONINDENT_BLOCK;
+    }
+    return delta;
+  }
+
+  /**
+   * Pushes <code>token</code>.<br>
+   * Creates a new bigger array if the current one is full.
+   */
+  private int pushControlStatement(int token) {
+    if (constructionsCount == constructions.length)
+      System.arraycopy(constructions, 0, (constructions = new int[constructionsCount * 2]), 0, constructionsCount);
+    constructions[constructionsCount++] = token;
+    return 1;
+  }
+
+  private static boolean separateFirstArgumentOn(int currentToken) {
+    //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[]
+   * @deprecated Set the positions to map using the format(String, int, int[]) method.
+   * 
+   * @see #getMappedPositions()
+   */
+  public void setPositionsToMap(int[] positions) {
+    positionsToMap = positions;
+    lineDelta = 0;
+    globalDelta = 0;
+    mappedPositions = new int[positions.length];
+  }
+
+  /**
+   * Appends a space character to the current line buffer.
+   */
+  private void space() {
+    currentLineBuffer.append(' ');
+    increaseLineDelta(1);
+  }
+
+  /**
+   * 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
+   */
+  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
+     */
+    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();
+    //          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) {
+    if (positionsToMap == null) {
+      return;
+    }
+    char[] source = scanner.source;
+    int sourceLength = source.length;
+    while (indexToMap < positionsToMap.length && positionsToMap[indexToMap] <= startPosition) {
+      int posToMap = positionsToMap[indexToMap];
+      if (posToMap < 0 || posToMap >= sourceLength) {
+        // protection against out of bounds position
+        if (posToMap == sourceLength) {
+          mappedPositions[indexToMap] = formattedSource.length();
+        }
+        indexToMap = positionsToMap.length; // no more mapping
+        return;
+      }
+      if (CharOperation.isWhitespace(source[posToMap])) {
+        mappedPositions[indexToMap] = startPosition + globalDelta + lineDelta;
+      } else {
+        if (posToMap == sourceLength - 1) {
+          mappedPositions[indexToMap] = startPosition + globalDelta + lineDelta;
+        } else {
+          mappedPositions[indexToMap] = posToMap + globalDelta + lineDelta;
+        }
+      }
+      indexToMap++;
+    }
+  }
+
+  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) {
+      mappedPositions[indexInMap] += splitDelta;
+      indexInMap++;
+    }
+  }
+
+  private int getLength(String s, int tabDepth) {
+    int length = 0;
+    for (int i = 0; i < tabDepth; i++) {
+      length += options.tabSize;
+    }
+    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++;
+      }
+    }
+    return length;
+  }
+
+  /**
+   * Sets the initial indentation level
+   * 
+   * @param indentationLevel
+   *          new indentation level
+   * 
+   * @deprecated
+   */
+  public void setInitialIndentationLevel(int newIndentationLevel) {
+    this.initialIndentationLevel = currentLineIndentationLevel = indentationLevel = newIndentationLevel;
+  }
 
-       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>
-        * 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.
-        */
-       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.
-        */
-       int currentCommentOffset;
-       int currentLineIndentationLevel;
-       int maxLineSize = 30;
-       private boolean containsOpenCloseBraces;
-       private int indentationLevelForOpenCloseBraces;
-
-       /**
-        * Collections of positions to map
-        */
-       private int[] positionsToMap;
-
-       /**
-        * Collections of mapped positions
-        */
-       private int[] mappedPositions;
-
-       private int indexToMap;
-
-       private int indexInMap;
-
-       private int globalDelta;
-
-       private int lineDelta;
-
-       private int splitDelta;
-
-       private int beginningOfLineIndex;
-
-       private int multipleLineCommentCounter;
-       
-       /** 
-        * Creates a new instance of Code Formatter using the given settings.
-        * 
-        * @deprecated backport 1.0 internal functionality
-        */
-       public CodeFormatter(ConfigurableOption[] settings) {
-               this(convertConfigurableOptions(settings));
-       }
-       
-       /** 
-        * 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.recordLineSeparator = true;
-
-               // to remind of the position of the beginning of the line.
-               splitScanner = new Scanner(true /*comment*/, true /*whitespace*/, false /*nls*/, false /*assert*/);
-               // 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.
-        */
-       private static boolean breakLineBeforeOperator(int operator) {
-               switch (operator) {
-                       case TokenNameCOMMA :
-                       case TokenNameSEMICOLON :
-                       case TokenNameEQUAL :
-                               return false;
-                       default :
-                               return true;
-               }
-       }
-       
-               /** 
-        * @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("org.phpeclipse.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("org.phpeclipse.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("org.phpeclipse.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("org.phpeclipse.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("org.phpeclipse.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("org.phpeclipse.phpdt.core.formatter.lineSplit", String.valueOf(valueIndex)); //$NON-NLS-1$ //$NON-NLS-2$
-                               
-                               } else if(optionName.equals("style.assignment")) { //$NON-NLS-1$
-                                       options.put("org.phpeclipse.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("org.phpeclipse.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("org.phpeclipse.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() {
-               char str[] = scanner.source;
-               int startPosition = scanner.startPosition;
-               int length = str.length - startPosition;
-               StringBuffer bufr = new StringBuffer(length);
-               if (startPosition < str.length) {
-                       bufr.append(str, startPosition, length);
-               }
-               return (bufr.toString());
-       }
-
-       /**
-        * Inserts <code>tabCount</code> tab character or their equivalent number of spaces.
-        */
-       private void dumpTab(int tabCount) {
-               if (options.indentWithTab) {
-                       for (int j = 0; j < tabCount; j++) {
-                               formattedSource.append('\t');
-                               increaseSplitDelta(1);
-                       }
-               } else {
-                       for (int i = 0, max = options.tabSize * tabCount; i < max; i++) {
-                               formattedSource.append(' ');
-                               increaseSplitDelta(1);
-                       }
-               }
-       }
-
-       /**
-        * Dumps <code>currentLineBuffer</code> into the formatted string.
-        */
-       private void flushBuffer() {
-               String currentString = currentLineBuffer.toString();
-               splitDelta = 0;
-               beginningOfLineIndex = formattedSource.length();
-               if (containsOpenCloseBraces) {
-                       containsOpenCloseBraces = false;
-                       outputLine(
-                               currentString,
-                               false,
-                               indentationLevelForOpenCloseBraces,
-                               0,
-                               -1,
-                               null,
-                               0);
-                       indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
-               } else {
-                       outputLine(currentString, false, currentLineIndentationLevel, 0, -1, null, 0);
-               }
-               int scannerSourceLength = scanner.source.length;
-               if (scannerSourceLength > 2) {
-                       if (scanner.source[scannerSourceLength - 1] == '\n' && 
-                               scanner.source[scannerSourceLength - 2] == '\r') {
-                                       formattedSource.append(options.lineSeparatorSequence);
-                                       increaseGlobalDelta(options.lineSeparatorSequence.length - 2);
-                       } else if (scanner.source[scannerSourceLength - 1] == '\n') {
-                               formattedSource.append(options.lineSeparatorSequence);
-                               increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
-                       } else if (scanner.source[scannerSourceLength - 1] == '\r') {
-                               formattedSource.append(options.lineSeparatorSequence);
-                               increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
-                       }
-               }
-               updateMappedPositions(scanner.startPosition);
-       }
-
-       /** 
-        * Formats the input string.
-        */
-       private void format() {
-               int token = 0;
-               int previousToken = 0;
-               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;
-               boolean expectingOpenBrace = false;
-               boolean clearNonBlockIndents = false;
-               // true if all indentations till the 1st { (usefull after } or ;)
-               boolean pendingSpace = true;
-               boolean pendingNewlineAfterParen = false;
-               // true when a cr is to be put after a ) (in conditional statements)
-               boolean inAssignment = false;
-               boolean inArrayAssignment = false;
-               boolean inThrowsClause = false;
-               boolean inClassOrInterfaceHeader = false;
-
-               // 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
-               // (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 :
-               // 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 
-               boolean specialElse = false;
-
-               // OPTION (IndentationLevel): initial indentation level may be non-zero.
-               currentLineIndentationLevel += constructionsCount;
-
-               // An InvalidInputException exception might cause the termination of this loop.
-               try {
-                       while (true) {
-                               // 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();
-                                       
-                                       // 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--) {
-                                                       switch(scanner.source[index]) {
-                                                               case '\r' :
-                                                               case '\n' :
-                                                                       scanner.currentPosition--;
-                                                                       break;
-                                                               default:
-                                                                       break loop;
-                                                       }
-                                               }
-                                       }
-                               } catch (InvalidInputException e) {
-                                       if (!handleInvalidToken(e)) {
-                                               throw e;
-                                       }
-                                       token = 0;
-                               }
-                               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
-                               if (clearNonBlockIndents && (token != Scanner.TokenNameWHITESPACE)) {
-                                       switch (token) {
-                                               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;
-                                                       }
-                                               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;
-                               }
-                               // returns to the indentation level created by the SWITCH keyword
-                               // if the current token is a CASE or a DEFAULT
-                               if (token == TokenNamecase || token == TokenNamedefault) {
-                                       indentationLevel += pop(TokenNamecase);
-                               }
-//                             if (token == Scanner.TokenNamethrows) {
-//                                     inThrowsClause = true;
-//                             }
-                               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.
-                               // Fix for 1ETLWPZ: IVJCOM:ALL - incorrect "else if" formatting
-                               if (pendingNewlineAfterParen
-                                       && previousCompilableToken == TokenNameelse
-                                       && token == TokenNameif
-                                       && options.compactElseIfMode) {
-                                       pendingNewlineAfterParen = false;
-                                       pendingNewLines = 0;
-                                       indentationLevel += pop(TokenNameelse);
-                                       // because else if is now one single statement,
-                                       // the indentation level after it is increased by one and not by 2
-                                       // (else = 1 indent, if = 1 indent, but else if = 1 indent, not 2).
-                               }
-                               // 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);
-                               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
-                                       // 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)) {
-                                               newLine(1);
-                                               currentLineIndentationLevel = indentationLevel;
-                                               pendingNewLines = 0;
-                                               pendingSpace = false;
-                                       } else {
-                                               if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode) {
-                                                       newLine(1);
-                                                       if (constructionsCount > 0
-                                                               && constructions[constructionsCount - 1] != BLOCK
-                                                               && constructions[constructionsCount - 1] != NONINDENT_BLOCK) {
-                                                               currentLineIndentationLevel = indentationLevel - 1;
-                                                       } else {
-                                                               currentLineIndentationLevel = indentationLevel;
-                                                       }
-                                                       pendingNewLines = 0;
-                                                       pendingSpace = false;
-                                               }
-                                       }
-                               }
-                               if (token == TokenNameLBRACE
-                                       && options.newLineBeforeOpeningBraceMode
-                                       && constructionsCount > 0
-                                       && constructions[constructionsCount - 1] == TokenNamedo) {
-                                       newLine(1);
-                                       currentLineIndentationLevel = indentationLevel - 1;
-                                       pendingNewLines = 0;
-                                       pendingSpace = false;
-                               }
-                               // see PR 1G5G8EC
-                               if (token == TokenNameLBRACE && inThrowsClause) {
-                                       inThrowsClause = false;
-                                       if (options.newLineBeforeOpeningBraceMode) {
-                                               newLine(1);
-                                               currentLineIndentationLevel = indentationLevel;
-                                               pendingNewLines = 0;
-                                               pendingSpace = false;
-                                       }
-                               }
-                               // see PR 1G5G82G
-                               if (token == TokenNameLBRACE && inClassOrInterfaceHeader) {
-                                       inClassOrInterfaceHeader = false;
-                                       if (options.newLineBeforeOpeningBraceMode) {
-                                               newLine(1);
-                                               currentLineIndentationLevel = indentationLevel;
-                                               pendingNewLines = 0;
-                                               pendingSpace = false;
-                                       }
-                               }
-                               // 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 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) {
-
-                                       // Do not add newline & indent between an adjoining close brace and
-                                       // 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
-                                                       && !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.
-                                       boolean semiColonAndCloseBrace =
-                                               previousToken == TokenNameRBRACE && token == TokenNameSEMICOLON;
-
-                                       // 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).
-                                       boolean commaAndCloseBrace =
-                                               previousToken == TokenNameRBRACE && token == TokenNameCOMMA;
-
-                                       // Add a newline and indent, if appropriate.
-                                       if (specialElse
-                                               || (!commentAndOpenBrace
-                                                       && !closeBraceAndCloseParen
-                                                       && !nlicsOption
-                                                       && !semiColonAndCloseBrace
-                                                       && !commaAndCloseBrace)) {
-
-                                               // if clearAllBlankLinesMode=false, leaves the blank lines
-                                               // inserted by the user
-                                               // if clearAllBlankLinesMode=true, removes all of then
-                                               // and insert only blank lines required by the formatting.
-                                               if (!options.clearAllBlankLinesMode) {
-                                                       //  (isComment(token))
-                                                       pendingNewLines =
-                                                               (pendingNewLines < newLinesInWhitespace)
-                                                                       ? newLinesInWhitespace
-                                                                       : pendingNewLines;
-                                                       pendingNewLines = (pendingNewLines > 2) ? 2 : pendingNewLines;
-                                               }
-                                               if (previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE) {
-                                                       containsOpenCloseBraces = true;
-                                                       indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
-                                                       if (isComment(previousToken)) {
-                                                               newLine(pendingNewLines);
-                                                       } else {
-                                                               /*  if (!(constructionsCount > 1
-                                                                       && constructions[constructionsCount-1] == NONINDENT_BLOCK
-                                                                       && (constructions[constructionsCount-2] == TokenNamefor 
-                                                                        || constructions[constructionsCount-2] == TokenNamewhile))) {*/
-                                                               if (options.newLineInEmptyBlockMode) {
-                                                                       if (inArrayAssignment) {
-                                                                               newLine(1); // array assigment with an empty block
-                                                                       } else {
-                                                                               newLine(pendingNewLines);
-                                                                       }
-                                                               }
-                                                               // }
-                                                       }
-                                               } else {
-                                                       // 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)) {
-                                                       indentationOffset = -1;
-                                                       indentationLevel += popExclusiveUntilBlock();
-                                               }
-                                               if (previousToken == Scanner.TokenNameCOMMENT_LINE && inAssignment) {
-                                                       // PR 1FI5IPO
-                                                       currentLineIndentationLevel++;
-                                               } else {
-                                                       currentLineIndentationLevel = indentationLevel + indentationOffset;
-                                               }
-                                               pendingSpace = false;
-                                               indentationOffset = 0;
-                                       }
-                                       pendingNewLines = 0;
-                                       newLinesInWhitespace = 0;
-                                       specialElse = false;
-
-                                       if (nlicsToken == TokenNamedo && token == TokenNamewhile) {
-                                               nlicsToken = 0;
-                                       }
-                               }
-                               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]--;
-                                               }
-                                               pendingSpace = false;
-                                               break;
-                                       case TokenNameLBRACE :
-                                               if ((previousCompilableToken == TokenNameRBRACKET)
-                                                       || (previousCompilableToken == TokenNameEQUAL)) {
-                                                       //                  if (previousCompilableToken == TokenNameRBRACKET) {
-                                                       inArrayAssignment = true;
-                                                       inAssignment = false;
-                                               }
-                                               if (inArrayAssignment) {
-                                                       indentationLevel += pushBlock();
-                                               } else {
-                                                       // Add new line and increase indentation level after open brace.
-                                                       pendingNewLines = 1;
-                                                       indentationLevel += pushBlock();
-                                               }
-                                               break;
-                                       case TokenNameRBRACE :
-                                               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;
-                                                               }
-                                                       }
-                                               }
-                                               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;
-                                                       }
-                                               }
-                                               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++;
-                                               }
-                                               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 :
-
-                                               // Count the number of line terminators in the whitespace so
-                                               // line spacing can be preserved near comments.
-                                               char[] source = scanner.source;
-                                               newLinesInWhitespace = 0;
-                                               for (int i = scanner.startPosition, max = scanner.currentPosition;
-                                                       i < max;
-                                                       i++) {
-                                                       if (source[i] == '\r') {
-                                                               if (i < max - 1) {
-                                                                       if (source[++i] == '\n') {
-                                                                               newLinesInWhitespace++;
-                                                                       } else {
-                                                                               newLinesInWhitespace++;
-                                                                       }
-                                                               } else {
-                                                                       newLinesInWhitespace++;
-                                                               }
-                                                       } else if (source[i] == '\n') {
-                                                                       newLinesInWhitespace++;
-                                                       }
-                                               }
-                                               increaseLineDelta(scanner.startPosition - scanner.currentPosition);
-                                               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 == TokenNamePLUS && unarySignModifier > 0)
-                                                               || (previousToken == TokenNameMINUS && unarySignModifier > 0)) {
-                                                               pendingSpace = false;
-                                                       }
-                                                       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 (pendingSpace
-                                               && insertSpaceAfter(previousToken)
-                                               && !(inAssignment
-                                                       && (previousToken == TokenNameLBRACE || token == TokenNameRBRACE))
-                                               && previousToken != Scanner.TokenNameCOMMENT_LINE) {
-                                               if ((!(options.compactAssignmentMode && token == TokenNameEQUAL))
-                                                       && !openAndCloseBrace)
-                                                       space();
-                                       }
-                                       // Add the next token to the formatted source string.
-                                       outputCurrentToken(token);
-                                       if (token == Scanner.TokenNameCOMMENT_LINE && openParenthesisCount > 1) {
-                                               pendingNewLines = 0;
-                                               currentLineBuffer.append(options.lineSeparatorSequence);
-                                               increaseLineDelta(options.lineSeparatorSequence.length);
-                                       }
-                                       pendingSpace = true;
-                               }
-                               // Whitespace tokens do not need to be remembered.
-                               if (token != Scanner.TokenNameWHITESPACE) {
-                                       previousToken = token;
-                                       if (token != Scanner.TokenNameCOMMENT_BLOCK
-                                               && token != Scanner.TokenNameCOMMENT_LINE
-                                               && token != Scanner.TokenNameCOMMENT_PHPDOC) {
-                                               previousCompilableToken = token;
-                                       }
-                               }
-                       }
-                       output(copyRemainingSource());
-                       flushBuffer(); // dump the last token of the source in the formatted output.
-               } catch (InvalidInputException e) {
-                       output(copyRemainingSource());
-                       flushBuffer(); // dump the last token of the source in the formatted output.
-               }
-       }
-
-       /** 
-        * Formats the char array <code>sourceString</code>,
-        * and returns a string containing the formatted version.
-        * @return the formatted ouput.
-        */
-       public String formatSourceString(String sourceString) {
-               char[] sourceChars = sourceString.toCharArray();
-               formattedSource = new StringBuffer(sourceChars.length);
-               scanner.setSource(sourceChars);
-               format();
-               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
-        * @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
-        * @return the formatted ouput.
-        */
-       public String format(String string, int indentationLevel, int[] positions) {
-               return this.format(string, indentationLevel, positions, null);
-       }
-       
-       public String format(String string, int indentationLevel, int[] positions, String lineSeparator) {
-               if (lineSeparator != null){
-                       this.options.setLineSeparator(lineSeparator);
-               }
-               if (positions != null) {
-                       this.setPositionsToMap(positions);
-                       this.setInitialIndentationLevel(indentationLevel);
-                       String formattedString = this.formatSourceString(string);
-                       int[] mappedPositions = this.getMappedPositions();
-                       System.arraycopy(mappedPositions, 0, positions, 0, positions.length);
-                       return formattedString;
-               } else {
-                       this.setInitialIndentationLevel(indentationLevel);
-                       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
-        * @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
-        * 
-        * @deprecated backport 1.0 internal functionality
-        */
-       public static String format(String sourceString, int initialIndentationLevel, ConfigurableOption[] options) {
-               CodeFormatter formatter = new CodeFormatter(options);
-               formatter.setInitialIndentationLevel(initialIndentationLevel);
-               return formatter.formatSourceString(sourceString);
-       }
-       
-       /**
-        * 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;
-               // if there is no beginning of line, return 0.
-               if (linePtr < 0)
-                       return 0;
-               int offset = 0;
-               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) {
-                               beginningOfLine = scanner.lineEnds[--linePtr];
-                       } else {
-                               beginningOfLine = 0;
-                               break;
-                       }
-               }
-               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;
-                       }
-               }
-               return offset;
-       }
-       
-       /**
-        * 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
-        */
-       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$
-               };
-       }
-
-       /**
-        * 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.
-        */
-       public int[] getMappedPositions() {
-               return mappedPositions;
-       }
-
-       /**
-        * 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
-        */
-       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;
-               }
-       }
-
-       /**
-        * 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)) {
-                       return true;
-               }
-               return false;
-       }
-
-       private final void increaseGlobalDelta(int offset) {
-               globalDelta += offset;
-       }
-
-       private final void increaseLineDelta(int offset) {
-               lineDelta += offset;
-       }
-
-       private final void increaseSplitDelta(int offset) {
-               splitDelta += offset;
-       }
-
-       /**
-        * 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;
-               }
-       }
-
-       /**
-        * 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;
-               }
-       }
-
-       private static boolean isComment(int token) {
-               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;
-               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
-        */
-       private void newLine(int newLineCount) {
-
-               // format current line
-               splitDelta = 0;
-               beginningOfLineIndex = formattedSource.length();
-               String currentLine = currentLineBuffer.toString();
-               if (containsOpenCloseBraces) {
-                       containsOpenCloseBraces = false;
-                       outputLine(
-                               currentLine,
-                               false,
-                               indentationLevelForOpenCloseBraces,
-                               0,
-                               -1,
-                               null,
-                               0);
-                       indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
-               } else {
-                       outputLine(currentLine, false, currentLineIndentationLevel, 0, -1, null, 0);
-               }
-               // dump line break(s)
-               for (int i = 0; i < newLineCount; i++) {
-                       formattedSource.append(options.lineSeparatorSequence);
-                       increaseSplitDelta(options.lineSeparatorSequence.length);
-               }
-               // reset formatter for next line
-               int currentLength = currentLine.length();
-               currentLineBuffer =
-                       new StringBuffer(
-                               currentLength > maxLineSize ? maxLineSize = currentLength : maxLineSize);
-
-               increaseGlobalDelta(splitDelta);
-               increaseGlobalDelta(lineDelta);
-               lineDelta = 0;
-               currentLineIndentationLevel = initialIndentationLevel;
-       }
-
-       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$
-               }
-       }
-
-       /** 
-        * 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) {
-               char currentCharacter;
-               for (int i = 0, max = stringToOutput.length(); i < max; i++) {
-                       currentCharacter = stringToOutput.charAt(i);
-                       if (currentCharacter != '\t') {
-                               currentLineBuffer.append(currentCharacter);
-                       }
-               }
-       }
-
-       /** 
-        * 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;                                                              
-                                                       }
-                                       }
-                               }
-                               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>.
-        */
-       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) {
-                               dumpTab(depth);
-                               preIndented = true;
-                       }
-                       if (operator != 0) {
-                               if (insertSpaceBefore(operator)) {
-                                       formattedSource.append(' ');
-                                       increaseSplitDelta(1);
-                               }
-                               formattedSource.append(operatorString);
-                               increaseSplitDelta(operatorString.length());
-
-                               if (insertSpaceAfter(operator)
-               //                      && operator != TokenNameimplements
-                                       && operator != TokenNameextends) {
-               //                      && operator != TokenNamethrows) {
-                                       formattedSource.append(' ');
-                                       increaseSplitDelta(1);
-                               }
-                       }
-               }
-               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
-                       // indent before postfix operator
-                       // indent also when the line cannot be split
-                       if (operator == TokenNameextends) {
-//                             || operator == TokenNameimplements
-//                             || operator == TokenNamethrows) {
-                               formattedSource.append(' ');
-                               increaseSplitDelta(1);
-                       }
-                       if (placeOperatorBehind) {
-                               if (!preIndented) {
-                                       dumpTab(depth);
-                               }
-                       }
-                       int max = currentString.length();
-                       if (multipleLineCommentCounter != 0) {
-                               try {
-                                       BufferedReader reader = new BufferedReader(new StringReader(currentString));
-                                       String line = reader.readLine();
-                                       while (line != null) {
-                                               updateMappedPositionsWhileSplitting(
-                                                       beginningOfLineIndex,
-                                                       beginningOfLineIndex + line.length() + options.lineSeparatorSequence.length);
-                                               formattedSource.append(line);
-                                               beginningOfLineIndex = beginningOfLineIndex + line.length();
-                                               if ((line = reader.readLine()) != null) {
-                                                       formattedSource.append(options.lineSeparatorSequence);
-                                                       beginningOfLineIndex += options.lineSeparatorSequence.length;
-                                                       dumpTab(currentLineIndentationLevel);
-                                               }
-                                       }
-                                       reader.close();
-                               } catch(IOException e) {
-                                       e.printStackTrace();
-                               }
-                       } else {
-                               updateMappedPositionsWhileSplitting(
-                                       beginningOfLineIndex,
-                                       beginningOfLineIndex + max);
-                               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);
-                                       }
-                               }
-                       }
-                       // update positions inside the mappedPositions table
-                       if (substringIndex != -1) {
-                               if (multipleLineCommentCounter == 0) {
-                                       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]);
-                               }
-                       }
-                       // dump postfix operator?
-                       if (placeOperatorBehind) {
-                               if (insertSpaceBefore(operator)) {
-                                       formattedSource.append(' ');
-                                       if (operator != 0) {
-                                               increaseSplitDelta(1);
-                                       }
-                               }
-                               formattedSource.append(operatorString);
-                               if (operator != 0) {
-                                       increaseSplitDelta(operatorString.length());
-                               }
-                       }
-                       return;
-               }
-               // fix for 1FG0BA3: LFCOM:WIN98 - Weird splitting on interfaces
-               // extends has to stand alone on a line when currentString has been split.
-               if (options.maxLineLength != 0
-                       && splitLine != null
-                       && (operator == TokenNameextends)) {
-//                             || operator == TokenNameimplements
-//                             || operator == TokenNamethrows)) {
-                       formattedSource.append(options.lineSeparatorSequence);
-                       increaseSplitDelta(options.lineSeparatorSequence.length);
-                       dumpTab(depth + 1);
-               } else {
-                       if (operator == TokenNameextends) {
-//                             || operator == TokenNameimplements
-//                             || operator == TokenNamethrows) {
-                               formattedSource.append(' ');
-                               increaseSplitDelta(1);
-                       }
-               }
-               // 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
-               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
-                       // (-1 because the ouputline increases depth).
-                       // (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));
-                               if (i != max - 1) {
-                                       formattedSource.append(options.lineSeparatorSequence);
-                                       increaseSplitDelta(options.lineSeparatorSequence.length);
-                               }
-                       }
-               }
-               if (result.length == splitOperators.length - 1) {
-                       int lastOperator = splitOperators[result.length];
-                       String lastOperatorString = operatorString(lastOperator);
-                       formattedSource.append(options.lineSeparatorSequence);
-                       increaseSplitDelta(options.lineSeparatorSequence.length);
-
-                       if (breakLineBeforeOperator(lastOperator)) {
-                               dumpTab(depth + 1);
-                               if (lastOperator != 0) {
-                                       if (insertSpaceBefore(lastOperator)) {
-                                               formattedSource.append(' ');
-                                               increaseSplitDelta(1);
-                                       }
-                                       formattedSource.append(lastOperatorString);
-                                       increaseSplitDelta(lastOperatorString.length());
-
-                                       if (insertSpaceAfter(lastOperator)
-       //                                      && lastOperator != TokenNameimplements
-                                               && lastOperator != TokenNameextends ) {
-       //                                      && lastOperator != TokenNamethrows) {
-                                               formattedSource.append(' ');
-                                               increaseSplitDelta(1);
-                                       }
-                               }
-                       }
-               }
-               if (placeOperatorBehind) {
-                       if (insertSpaceBefore(operator)) {
-                               formattedSource.append(' ');
-                               increaseSplitDelta(1);
-                       }
-                       formattedSource.append(operatorString);
-                       //increaseSplitDelta(operatorString.length());
-               }
-       }
-       
-       /**
-        * Pops the top statement of the stack if it is <code>token</code>
-        */
-       private int pop(int token) {
-               int delta = 0;
-               if ((constructionsCount > 0)
-                       && (constructions[constructionsCount - 1] == token)) {
-                       delta--;
-                       constructionsCount--;
-               }
-               return delta;
-       }
-       
-       /**
-        * Pops the top statement of the stack if it is a <code>BLOCK</code> or a <code>NONINDENT_BLOCK</code>.
-        */
-       private int popBlock() {
-               int delta = 0;
-               if ((constructionsCount > 0)
-                       && ((constructions[constructionsCount - 1] == BLOCK)
-                               || (constructions[constructionsCount - 1] == NONINDENT_BLOCK))) {
-                       if (constructions[constructionsCount - 1] == BLOCK)
-                               delta--;
-                       constructionsCount--;
-               }
-               return delta;
-       }
-       
-       /**
-        * 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
-        */
-       private int popExclusiveUntil(int token) {
-               int delta = 0;
-               int startCount = constructionsCount;
-               for (int i = startCount - 1; i >= 0 && constructions[i] != token; i--) {
-                       if (constructions[i] != NONINDENT_BLOCK)
-                               delta--;
-                       constructionsCount--;
-               }
-               return delta;
-       }
-       
-       /**
-        * 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() {
-               int startCount = constructionsCount;
-               int delta = 0;
-               for (int i = startCount - 1;
-                       i >= 0 && constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK;
-                       i--) {
-                       constructionsCount--;
-                       delta--;
-               }
-               return delta;
-       }
-       
-       /**
-        * 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--) {
-                       constructionsCount--;
-                       delta--;
-               }
-               return delta;
-       }
-       
-       /**
-        * 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
-        */
-       private int popInclusiveUntil(int token) {
-               int startCount = constructionsCount;
-               int delta = 0;
-               for (int i = startCount - 1; i >= 0 && constructions[i] != token; i--) {
-                       if (constructions[i] != NONINDENT_BLOCK)
-                               delta--;
-                       constructionsCount--;
-               }
-               if (constructionsCount > 0) {
-                       if (constructions[constructionsCount - 1] != NONINDENT_BLOCK)
-                               delta--;
-                       constructionsCount--;
-               }
-               return delta;
-       }
-       
-       /**
-        * 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() {
-               int startCount = constructionsCount;
-               int delta = 0;
-               for (int i = startCount - 1;
-                       i >= 0 && (constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK);
-                       i--) {
-                       delta--;
-                       constructionsCount--;
-               }
-               if (constructionsCount > 0) {
-                       if (constructions[constructionsCount - 1] == BLOCK)
-                               delta--;
-                       constructionsCount--;
-               }
-               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.
-        */
-       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)) {
-                       delta++;
-                       constructions[constructionsCount++] = BLOCK;
-               } else {
-                       constructions[constructionsCount++] = NONINDENT_BLOCK;
-               }
-               return delta;
-       }
-       
-       /** 
-        * Pushes <code>token</code>.<br>
-        * Creates a new bigger array if the current one is full.
-        */
-       private int pushControlStatement(int token) {
-               if (constructionsCount == constructions.length)
-                       System.arraycopy(
-                               constructions,
-                               0,
-                               (constructions = new int[constructionsCount * 2]),
-                               0,
-                               constructionsCount);
-               constructions[constructionsCount++] = token;
-               return 1;
-       }
-       
-       private static boolean separateFirstArgumentOn(int currentToken) {
-               //return (currentToken == TokenNameCOMMA || currentToken == TokenNameSEMICOLON);
-               return currentToken != TokenNameif
-                       && currentToken != TokenNameLPAREN
-                       && currentToken != TokenNameNOT
-                       && currentToken != TokenNamewhile
-                       && currentToken != TokenNamefor
-                       && currentToken != TokenNameswitch;
-       }
-       
-       /**
-        * 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()
-        */
-       public void setPositionsToMap(int[] positions) {
-               positionsToMap = positions;
-               lineDelta = 0;
-               globalDelta = 0;
-               mappedPositions = new int[positions.length];
-       }
-               
-       /** 
-        * Appends a space character to the current line buffer.
-        */
-       private void space() {
-               currentLineBuffer.append(' ');
-               increaseLineDelta(1);
-       }
-       
-       /**
-        * 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
-        */
-       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 
-                */
-               if (stringToSplit.indexOf("//$NON-NLS") != -1) { //$NON-NLS-1$
-                       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;
-       }
-
-       private void updateMappedPositions(int startPosition) {
-               if (positionsToMap == null) {
-                       return;
-               }
-               char[] source = scanner.source;
-               int sourceLength = source.length;
-               while (indexToMap < positionsToMap.length
-                       && positionsToMap[indexToMap] <= startPosition) {
-                       int posToMap = positionsToMap[indexToMap];
-                       if (posToMap < 0
-                               || posToMap >= sourceLength) { // protection against out of bounds position
-                               if (posToMap == sourceLength) {
-                                       mappedPositions[indexToMap] = formattedSource.length();
-                               }
-                               indexToMap = positionsToMap.length; // no more mapping
-                               return;
-                       }
-                       if (CharOperation.isWhitespace(source[posToMap])) {
-                               mappedPositions[indexToMap] = startPosition + globalDelta + lineDelta;
-                       } else {
-                               if (posToMap == sourceLength - 1) {
-                                       mappedPositions[indexToMap] = startPosition + globalDelta + lineDelta;
-                               } else {
-                                       mappedPositions[indexToMap] = posToMap + globalDelta + lineDelta;
-                               }
-                       }
-                       indexToMap++;
-               }
-       }
-       
-       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) {
-                       mappedPositions[indexInMap] += splitDelta;
-                       indexInMap++;
-               }
-       }
-       
-       private int getLength(String s, int tabDepth) {
-               int length = 0;
-               for (int i = 0; i < tabDepth; i++) {
-                       length += options.tabSize;
-               }
-               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++;
-                       }
-               }
-               return length;
-       }
-       
-       /** 
-       * 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