GotoMatchingBracket implementiert
authorkhartlage <khartlage>
Sun, 30 Mar 2003 20:04:07 +0000 (20:04 +0000)
committerkhartlage <khartlage>
Sun, 30 Mar 2003 20:04:07 +0000 (20:04 +0000)
19 files changed:
net.sourceforge.phpeclipse/plugin.xml
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/SingleCharReader.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/CodeFormatter.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/impl/FormatterOptions.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/impl/SplitLine.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/PHPCodeReader.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/PHPPairMatcher.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/IViewPartInputProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/GenerateActionGroup.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/GotoMatchingBracketAction.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/PHPEditorActionDefinitionIds.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/PHPdtActionConstants.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPActionContributor.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorActionDefinitionIds.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.properties
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java

index 0dd2df1..8533507 100644 (file)
@@ -232,17 +232,16 @@ Temporarily replaced until errors can be ironed out...
             description="%CodingActionSet.description"
             visible="false"
             id="net.sourceforge.phpeclipse.ui.CodingActionSet">
-<!-- =========================================================================== -->
-<!-- Source Menu                                                                 -->
-<!-- =========================================================================== -->
+         <!-- =========================================================================== -->
+         <!-- Source Menu                                                                 -->
+         <!-- =========================================================================== -->
          <menu
                label="%SourceMenu.label"
                path="edit"
                id="net.sourceforge.phpeclipse.ui.source.menu">
-            <separator
-                  name="editGroup">
-            </separator>
-         </menu>
+            <separator name="editGroup"/>
+         </menu>       
+       
          <action 
                        definitionId="net.sourceforge.phpeclipse.phpeditor.format"
                        label="%FormatAction.label"
@@ -317,15 +316,17 @@ Temporarily replaced until errors can be ironed out...
             extensions="php"
             contributorClass="net.sourceforge.phpeclipse.phpeditor.PHPActionContributor"
             class="net.sourceforge.phpeclipse.phpeditor.PHPEditor"
-            id="net.sourceforge.phpeclipse.PHPEditor">
-      </editor>
+            id="net.sourceforge.phpeclipse.PHPEditor"
+            default="true">
+      </editor>  
       <editor
             name="%phpEditorName"
             icon="icons/obj16/phpedit.gif"
             extensions="php3"
             contributorClass="net.sourceforge.phpeclipse.phpeditor.PHPActionContributor"
             class="net.sourceforge.phpeclipse.phpeditor.PHPEditor"
-            id="net.sourceforge.phpeclipse.PHPEditor">
+            id="net.sourceforge.phpeclipse.PHPEditor"
+            default="true">
       </editor>
       <editor
             name="%phpEditorName"
@@ -333,7 +334,8 @@ Temporarily replaced until errors can be ironed out...
             extensions="php4"
             contributorClass="net.sourceforge.phpeclipse.phpeditor.PHPActionContributor"
             class="net.sourceforge.phpeclipse.phpeditor.PHPEditor"
-            id="net.sourceforge.phpeclipse.PHPEditor">
+            id="net.sourceforge.phpeclipse.PHPEditor"
+            default="true">
       </editor>
       <editor
             name="%phpEditorName"
@@ -341,7 +343,8 @@ Temporarily replaced until errors can be ironed out...
             extensions="inc"
             contributorClass="net.sourceforge.phpeclipse.phpeditor.PHPActionContributor"
             class="net.sourceforge.phpeclipse.phpeditor.PHPEditor"
-            id="net.sourceforge.phpeclipse.PHPEditor">
+            id="net.sourceforge.phpeclipse.PHPEditor"
+            default="true">
       </editor>
       <editor
             name="%phpEditorName"
@@ -349,7 +352,8 @@ Temporarily replaced until errors can be ironed out...
             extensions="phtml"
             contributorClass="net.sourceforge.phpeclipse.phpeditor.PHPActionContributor"
             class="net.sourceforge.phpeclipse.phpeditor.PHPEditor"
-            id="net.sourceforge.phpeclipse.PHPEditor">
+            id="net.sourceforge.phpeclipse.PHPEditor"
+            default="true">
       </editor>
       <editor
             name="%phpEditorName"
@@ -357,7 +361,8 @@ Temporarily replaced until errors can be ironed out...
             extensions="htm"
             contributorClass="net.sourceforge.phpeclipse.phpeditor.PHPActionContributor"
             class="net.sourceforge.phpeclipse.phpeditor.PHPEditor"
-            id="net.sourceforge.phpeclipse.PHPEditor">
+            id="net.sourceforge.phpeclipse.PHPEditor"
+            default="true">
       </editor>
       <editor
             name="%phpEditorName"
@@ -365,7 +370,8 @@ Temporarily replaced until errors can be ironed out...
             extensions="html"
             contributorClass="net.sourceforge.phpeclipse.phpeditor.PHPActionContributor"
             class="net.sourceforge.phpeclipse.phpeditor.PHPEditor"
-            id="net.sourceforge.phpeclipse.PHPEditor">
+            id="net.sourceforge.phpeclipse.PHPEditor"
+            default="true">
       </editor>
       <editor
             name="%phpEditorName"
@@ -373,7 +379,8 @@ Temporarily replaced until errors can be ironed out...
             extensions="xml"
             contributorClass="net.sourceforge.phpeclipse.phpeditor.PHPActionContributor"
             class="net.sourceforge.phpeclipse.phpeditor.PHPEditor"
-            id="net.sourceforge.phpeclipse.PHPEditor">
+            id="net.sourceforge.phpeclipse.PHPEditor"
+            default="true">
       </editor>
    </extension>
    <extension
@@ -643,6 +650,8 @@ Temporarily replaced until errors can be ironed out...
             scopeId="org.eclipse.ui.textEditorScope"
             configurationId="org.eclipse.ui.emacsAcceleratorConfiguration">
 <!-- edit -->
+                <accelerator key="Ctrl+Shift+P" id="net.sourceforge.phpeclipse.ui.edit.text.php.goto.matching.bracket" />
+
          <accelerator
                key="Ctrl+1"
                id="net.sourceforge.phpeclipse.ui.edit.text.php.content.assist.proposals">
@@ -665,6 +674,7 @@ Temporarily replaced until errors can be ironed out...
             scopeId="org.eclipse.ui.textEditorScope"
             configurationId="org.eclipse.ui.defaultAcceleratorConfiguration">
 <!-- edit -->
+         <accelerator key="Ctrl+Shift+P" id="net.sourceforge.phpeclipse.ui.edit.text.php.goto.matching.bracket" />
          <accelerator
                key="Ctrl+Space"
                id="net.sourceforge.phpeclipse.ui.edit.text.php.content.assist.proposals">
@@ -687,6 +697,8 @@ Temporarily replaced until errors can be ironed out...
             scopeId="org.eclipse.ui.textEditorScope"
             configurationId="org.eclipse.ui.defaultAcceleratorConfiguration">
 <!-- edit -->
+         <accelerator key="Command+Shift+P" id="net.sourceforge.phpeclipse.ui.edit.text.php.goto.matching.bracket" platform="carbon" /> 
+               
          <accelerator
                platform="carbon"
                key="Command+1"
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/SingleCharReader.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/SingleCharReader.java
new file mode 100644 (file)
index 0000000..2507032
--- /dev/null
@@ -0,0 +1,55 @@
+package net.sourceforge.phpdt.internal.corext.phpdoc;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.IOException;
+import java.io.Reader;
+
+public abstract class SingleCharReader extends Reader {
+       
+       /**
+        * @see Reader#read()
+        */
+       public abstract int read() throws IOException;
+
+       /**
+        * @see Reader#read(char[],int,int)
+        */
+       public int read(char cbuf[], int off, int len) throws IOException {
+               int end= off + len;
+               for (int i= off; i < end; i++) {
+                       int ch= read();
+                       if (ch == -1) {
+                               if (i == off) {
+                                       return -1;
+                               } else {
+                                       return i - off;
+                               }
+                       }
+                       cbuf[i]= (char)ch;
+               }
+               return len;
+       }               
+       
+       /**
+        * @see Reader#ready()
+        */             
+    public boolean ready() throws IOException {
+               return true;
+       }
+       
+       /**
+        * Gets the content as a String
+        */
+       public String getString() throws IOException {
+               StringBuffer buf= new StringBuffer();
+               int ch;
+               while ((ch= read()) != -1) {
+                       buf.append((char)ch);
+               }
+               return buf.toString();
+       }
+}
\ No newline at end of file
index 13bbf68..98f4f2c 100644 (file)
@@ -35,2522 +35,2602 @@ import net.sourceforge.phpdt.internal.formatter.impl.SplitLine;
 */
 public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
 
-       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;
-       }
+  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("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;
+
+    // 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
index 5684b81..ba4127f 100644 (file)
@@ -12,190 +12,198 @@ package net.sourceforge.phpdt.internal.formatter.impl;
 
 import java.util.Map;
 
-public class FormatterOptions {        
-
-       /**
-        * Option IDs
-        */
-       public static final String OPTION_InsertNewlineBeforeOpeningBrace = "org.phpeclipse.phpdt.core.formatter.newline.openingBrace"; //$NON-NLS-1$
-       public static final String OPTION_InsertNewlineInControlStatement = "org.phpeclipse.phpdt.core.formatter.newline.controlStatement"; //$NON-NLS-1$
-       public static final String OPTION_InsertNewLineBetweenElseAndIf = "org.phpeclipse.phpdt.core.formatter.newline.elseIf"; //$NON-NLS-1$
-       public static final String OPTION_InsertNewLineInEmptyBlock = "org.phpeclipse.phpdt.core.formatter.newline.emptyBlock"; //$NON-NLS-1$
-       public static final String OPTION_ClearAllBlankLines = "org.phpeclipse.phpdt.core.formatter.newline.clearAll"; //$NON-NLS-1$
-       public static final String OPTION_SplitLineExceedingLength = "org.phpeclipse.phpdt.core.formatter.lineSplit"; //$NON-NLS-1$
-       public static final String OPTION_CompactAssignment = "org.phpeclipse.phpdt.core.formatter.style.assignment"; //$NON-NLS-1$
-       public static final String OPTION_TabulationChar = "org.phpeclipse.phpdt.core.formatter.tabulation.char"; //$NON-NLS-1$
-       public static final String OPTION_TabulationSize = "org.phpeclipse.phpdt.core.formatter.tabulation.size"; //$NON-NLS-1$
-       
-       public static final String INSERT = "insert"; //$NON-NLS-1$
-       public static final String DO_NOT_INSERT = "do not insert"; //$NON-NLS-1$
-       public static final String PRESERVE_ONE = "preserve one"; //$NON-NLS-1$
-       public static final String CLEAR_ALL = "clear all"; //$NON-NLS-1$
-       public static final String NORMAL = "normal"; //$NON-NLS-1$
-       public static final String COMPACT = "compact"; //$NON-NLS-1$
-       public static final String TAB = "tab"; //$NON-NLS-1$
-       public static final String SPACE = "space"; //$NON-NLS-1$
-       
-       // by default, do not insert blank line before opening brace
-       public boolean newLineBeforeOpeningBraceMode = false;
-
-       // by default, do not insert blank line behind keywords (ELSE, CATCH, FINALLY,...) in control statements
-       public boolean newlineInControlStatementMode = false;
-
-       // by default, preserve one blank line per sequence of blank lines
-       public boolean clearAllBlankLinesMode = false;
-       
-       // line splitting will occur when line exceeds this length
-       public int maxLineLength = 80;
-
-       public boolean compactAssignmentMode = false; // if isTrue, assignments look like x= 12 (not like x = 12);
-
-       //number of consecutive spaces used to replace the tab char
-       public int tabSize = 4; // n spaces for one tab
-       public boolean indentWithTab = true;
-
-       public boolean compactElseIfMode = true; // if true, else and if are kept on the same line.
-       public boolean newLineInEmptyBlockMode = true; // if false, no new line in {} if it's empty.
-       
-       public char[] lineSeparatorSequence = System.getProperty("line.separator").toCharArray(); //$NON-NLS-1$
-/** 
- * Initializing the formatter options with default settings
- */
-public FormatterOptions(){
-}
-/** 
- * Initializing the formatter options with external settings
- */
-public FormatterOptions(Map settings){
-       if (settings == null) return;
-
-       // filter options which are related to the assist component
-       Object[] entries = settings.entrySet().toArray();
-       for (int i = 0, max = entries.length; i < max; i++){
-               Map.Entry entry = (Map.Entry)entries[i];
-               if (!(entry.getKey() instanceof String)) continue;
-               if (!(entry.getValue() instanceof String)) continue;
-               String optionID = (String) entry.getKey();
-               String optionValue = (String) entry.getValue();
-               
-               if(optionID.equals(OPTION_InsertNewlineBeforeOpeningBrace)){
-                       if (optionValue.equals(INSERT)){
-                               this.newLineBeforeOpeningBraceMode = true;
-                       } else if (optionValue.equals(DO_NOT_INSERT)){
-                               this.newLineBeforeOpeningBraceMode = false;
-                       }
-                       continue;
-               }
-               if(optionID.equals(OPTION_InsertNewlineInControlStatement)){
-                       if (optionValue.equals(INSERT)){
-                               this.newlineInControlStatementMode = true;
-                       } else if (optionValue.equals(DO_NOT_INSERT)){
-                               this.newlineInControlStatementMode = false;
-                       }
-                       continue;
-               }
-               if(optionID.equals(OPTION_ClearAllBlankLines)){
-                       if (optionValue.equals(CLEAR_ALL)){
-                               this.clearAllBlankLinesMode = true;
-                       } else if (optionValue.equals(PRESERVE_ONE)){
-                               this.clearAllBlankLinesMode = false;
-                       }
-                       continue;
-               }
-               if(optionID.equals(OPTION_InsertNewLineBetweenElseAndIf)){
-                       if (optionValue.equals(INSERT)){
-                               this.compactElseIfMode = false;
-                       } else if (optionValue.equals(DO_NOT_INSERT)){
-                               this.compactElseIfMode = true;
-                       }
-                       continue;
-               }
-               if(optionID.equals(OPTION_InsertNewLineInEmptyBlock)){
-                       if (optionValue.equals(INSERT)){
-                               this.newLineInEmptyBlockMode = true;
-                       } else if (optionValue.equals(DO_NOT_INSERT)){
-                               this.newLineInEmptyBlockMode = false;
-                       }
-                       continue;
-               }
-               if(optionID.equals(OPTION_SplitLineExceedingLength)){
-                       try {
-                               int val = Integer.parseInt(optionValue);
-                               if (val >= 0) this.maxLineLength = val;
-                       } catch(NumberFormatException e){
-                       }
-               }
-               if(optionID.equals(OPTION_CompactAssignment)){
-                       if (optionValue.equals(COMPACT)){
-                               this.compactAssignmentMode = true;
-                       } else if (optionValue.equals(NORMAL)){
-                               this.compactAssignmentMode = false;
-                       }
-                       continue;
-               }
-               if(optionID.equals(OPTION_TabulationChar)){
-                       if (optionValue.equals(TAB)){
-                               this.indentWithTab = true;
-                       } else if (optionValue.equals(SPACE)){
-                               this.indentWithTab = false;
-                       }
-                       continue;
-               }
-               if(optionID.equals(OPTION_TabulationSize)){
-                       try {
-                               int val = Integer.parseInt(optionValue);
-                               if (val > 0) this.tabSize = val;
-                       } catch(NumberFormatException e){
-                       }
-               }
-       }
-}
+public class FormatterOptions {
 
-/**
- * 
- * @return int
- */
-public int getMaxLineLength() {
-       return maxLineLength;
-}
-public int getTabSize() {
-       return tabSize;
-}
-public boolean isAddingNewLineBeforeOpeningBrace() {
-       return newLineBeforeOpeningBraceMode;
-}
-public boolean isAddingNewLineInControlStatement() {
-       return newlineInControlStatementMode;
-}
-public boolean isAddingNewLineInEmptyBlock() {
-       return newLineInEmptyBlockMode;
-}
-public boolean isClearingAllBlankLines() {
-       return clearAllBlankLinesMode;
-}
-public boolean isCompactingAssignment() {
-       return compactAssignmentMode;
-}
-public boolean isCompactingElseIf() {
-       return compactElseIfMode;
-}
-public boolean isUsingTabForIndenting() {
-       return indentWithTab;
-}
-public void setLineSeparator(String lineSeparator) {
-       lineSeparatorSequence = lineSeparator.toCharArray();
-}
-/**
- * @deprecated - should use a Map when creating the options.
- */
-public void setMaxLineLength(int maxLineLength) {
-       this.maxLineLength = maxLineLength;
-}
-/**
- * @deprecated - should use a Map when creating the options.
- */
-public void setCompactElseIfMode(boolean flag) {
-       compactElseIfMode = flag;
-}
+  /**
+   * Option IDs
+   */
+  public static final String OPTION_InsertNewlineBeforeOpeningBrace = "net.sourceforge.phpdt.core.formatter.newline.openingBrace"; //$NON-NLS-1$
+  public static final String OPTION_InsertNewlineInControlStatement = "net.sourceforge.phpdt.core.formatter.newline.controlStatement"; //$NON-NLS-1$
+  public static final String OPTION_InsertNewLineBetweenElseAndIf = "net.sourceforge.phpdt.core.formatter.newline.elseIf"; //$NON-NLS-1$
+  public static final String OPTION_InsertNewLineInEmptyBlock = "net.sourceforge.phpdt.core.formatter.newline.emptyBlock"; //$NON-NLS-1$
+  public static final String OPTION_ClearAllBlankLines = "net.sourceforge.phpdt.core.formatter.newline.clearAll"; //$NON-NLS-1$
+  public static final String OPTION_SplitLineExceedingLength = "net.sourceforge.phpdt.core.formatter.lineSplit"; //$NON-NLS-1$
+  public static final String OPTION_CompactAssignment = "net.sourceforge.phpdt.core.formatter.style.assignment"; //$NON-NLS-1$
+  public static final String OPTION_TabulationChar = "net.sourceforge.phpdt.core.formatter.tabulation.char"; //$NON-NLS-1$
+  public static final String OPTION_TabulationSize = "net.sourceforge.phpdt.core.formatter.tabulation.size"; //$NON-NLS-1$
+
+  public static final String INSERT = "insert"; //$NON-NLS-1$
+  public static final String DO_NOT_INSERT = "do not insert"; //$NON-NLS-1$
+  public static final String PRESERVE_ONE = "preserve one"; //$NON-NLS-1$
+  public static final String CLEAR_ALL = "clear all"; //$NON-NLS-1$
+  public static final String NORMAL = "normal"; //$NON-NLS-1$
+  public static final String COMPACT = "compact"; //$NON-NLS-1$
+  public static final String TAB = "tab"; //$NON-NLS-1$
+  public static final String SPACE = "space"; //$NON-NLS-1$
+
+  // by default, do not insert blank line before opening brace
+  public boolean newLineBeforeOpeningBraceMode = false;
+
+  // by default, do not insert blank line behind keywords (ELSE, CATCH, FINALLY,...) in control statements
+  public boolean newlineInControlStatementMode = false;
+
+  // by default, preserve one blank line per sequence of blank lines
+  public boolean clearAllBlankLinesMode = false;
+
+  // line splitting will occur when line exceeds this length
+  public int maxLineLength = 80;
+
+  public boolean compactAssignmentMode = false;
+  // if isTrue, assignments look like x= 12 (not like x = 12);
+
+  //number of consecutive spaces used to replace the tab char
+  public int tabSize = 4; // n spaces for one tab
+  public boolean indentWithTab = true;
+
+  public boolean compactElseIfMode = true;
+  // if true, else and if are kept on the same line.
+  public boolean newLineInEmptyBlockMode = true;
+  // if false, no new line in {} if it's empty.
+
+  public char[] lineSeparatorSequence = System.getProperty("line.separator").toCharArray(); //$NON-NLS-1$
+  /** 
+   * Initializing the formatter options with default settings
+   */
+  public FormatterOptions() {
+  }
+  /** 
+   * Initializing the formatter options with external settings
+   */
+  public FormatterOptions(Map settings) {
+    if (settings == null)
+      return;
+
+    // filter options which are related to the assist component
+    Object[] entries = settings.entrySet().toArray();
+    for (int i = 0, max = entries.length; i < max; i++) {
+      Map.Entry entry = (Map.Entry) entries[i];
+      if (!(entry.getKey() instanceof String))
+        continue;
+      if (!(entry.getValue() instanceof String))
+        continue;
+      String optionID = (String) entry.getKey();
+      String optionValue = (String) entry.getValue();
+
+      if (optionID.equals(OPTION_InsertNewlineBeforeOpeningBrace)) {
+        if (optionValue.equals(INSERT)) {
+          this.newLineBeforeOpeningBraceMode = true;
+        } else if (optionValue.equals(DO_NOT_INSERT)) {
+          this.newLineBeforeOpeningBraceMode = false;
+        }
+        continue;
+      }
+      if (optionID.equals(OPTION_InsertNewlineInControlStatement)) {
+        if (optionValue.equals(INSERT)) {
+          this.newlineInControlStatementMode = true;
+        } else if (optionValue.equals(DO_NOT_INSERT)) {
+          this.newlineInControlStatementMode = false;
+        }
+        continue;
+      }
+      if (optionID.equals(OPTION_ClearAllBlankLines)) {
+        if (optionValue.equals(CLEAR_ALL)) {
+          this.clearAllBlankLinesMode = true;
+        } else if (optionValue.equals(PRESERVE_ONE)) {
+          this.clearAllBlankLinesMode = false;
+        }
+        continue;
+      }
+      if (optionID.equals(OPTION_InsertNewLineBetweenElseAndIf)) {
+        if (optionValue.equals(INSERT)) {
+          this.compactElseIfMode = false;
+        } else if (optionValue.equals(DO_NOT_INSERT)) {
+          this.compactElseIfMode = true;
+        }
+        continue;
+      }
+      if (optionID.equals(OPTION_InsertNewLineInEmptyBlock)) {
+        if (optionValue.equals(INSERT)) {
+          this.newLineInEmptyBlockMode = true;
+        } else if (optionValue.equals(DO_NOT_INSERT)) {
+          this.newLineInEmptyBlockMode = false;
+        }
+        continue;
+      }
+      if (optionID.equals(OPTION_SplitLineExceedingLength)) {
+        try {
+          int val = Integer.parseInt(optionValue);
+          if (val >= 0)
+            this.maxLineLength = val;
+        } catch (NumberFormatException e) {
+        }
+      }
+      if (optionID.equals(OPTION_CompactAssignment)) {
+        if (optionValue.equals(COMPACT)) {
+          this.compactAssignmentMode = true;
+        } else if (optionValue.equals(NORMAL)) {
+          this.compactAssignmentMode = false;
+        }
+        continue;
+      }
+      if (optionID.equals(OPTION_TabulationChar)) {
+        if (optionValue.equals(TAB)) {
+          this.indentWithTab = true;
+        } else if (optionValue.equals(SPACE)) {
+          this.indentWithTab = false;
+        }
+        continue;
+      }
+      if (optionID.equals(OPTION_TabulationSize)) {
+        try {
+          int val = Integer.parseInt(optionValue);
+          if (val > 0)
+            this.tabSize = val;
+        } catch (NumberFormatException e) {
+        }
+      }
+    }
+  }
+
+  /**
+   * 
+   * @return int
+   */
+  public int getMaxLineLength() {
+    return maxLineLength;
+  }
+  public int getTabSize() {
+    return tabSize;
+  }
+  public boolean isAddingNewLineBeforeOpeningBrace() {
+    return newLineBeforeOpeningBraceMode;
+  }
+  public boolean isAddingNewLineInControlStatement() {
+    return newlineInControlStatementMode;
+  }
+  public boolean isAddingNewLineInEmptyBlock() {
+    return newLineInEmptyBlockMode;
+  }
+  public boolean isClearingAllBlankLines() {
+    return clearAllBlankLinesMode;
+  }
+  public boolean isCompactingAssignment() {
+    return compactAssignmentMode;
+  }
+  public boolean isCompactingElseIf() {
+    return compactElseIfMode;
+  }
+  public boolean isUsingTabForIndenting() {
+    return indentWithTab;
+  }
+  public void setLineSeparator(String lineSeparator) {
+    lineSeparatorSequence = lineSeparator.toCharArray();
+  }
+  /**
+   * @deprecated - should use a Map when creating the options.
+   */
+  public void setMaxLineLength(int maxLineLength) {
+    this.maxLineLength = maxLineLength;
+  }
+  /**
+   * @deprecated - should use a Map when creating the options.
+   */
+  public void setCompactElseIfMode(boolean flag) {
+    compactElseIfMode = flag;
+  }
 
 }
index b17a73d..049c220 100644 (file)
@@ -14,198 +14,200 @@ import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
 
 /** Represents a split line: contains an operator and all substrings
 */
-public class SplitLine implements ITerminalSymbols{
-       public int[] operators; // the operator on which the string was split.
-       public String[] substrings;
-       public int[] startSubstringsIndexes;
-/**
- * SplitLine constructor comment.
- */
-public SplitLine(int[] operators, String[] substrings) {
-       this(operators, substrings, null);
-}
-/**
- * SplitLine constructor comment.
- */
-public SplitLine(int[] operators, String[] substrings, int[] startIndexes) {
-       super();
-       this.operators=operators;
-       this.substrings=substrings;
-       this.startSubstringsIndexes = startIndexes;
-}
-/**
- * Prints a nice representation of the receiver
- * @return java.lang.String
- */
-public String toString() {
-       StringBuffer result=new StringBuffer();
-       String operatorString = new String();
-               
-       for (int i=0,max=substrings.length;i<max;i++){
-               int currentOperator = operators[i];
-               String currentString = substrings[i];
-               boolean placeOperatorAhead = currentOperator != TokenNameCOMMA && currentOperator != TokenNameSEMICOLON;
-               boolean placeOperatorBehind = currentOperator == TokenNameCOMMA || currentOperator == TokenNameSEMICOLON;
-               
-
-
-       switch (currentOperator){
-               case TokenNameextends:
-                       operatorString="extends"; //$NON-NLS-1$
-                       break;
-//             case TokenNameimplements:
-//                     operatorString="implements"; //$NON-NLS-1$
-//                     break;
-//             case TokenNamethrows:
-//                     operatorString="throws"; //$NON-NLS-1$
-//                     break;
-               case TokenNameSEMICOLON : // ;
-                       operatorString=";"; //$NON-NLS-1$
-                       break;
-               case TokenNameCOMMA : // ,
-                       operatorString=","; //$NON-NLS-1$
-                       break;
-               case TokenNameEQUAL : // =
-                       operatorString="="; //$NON-NLS-1$
-                       break;
-               case TokenNameAND_AND : // && (15.22)
-                       operatorString="&&"; //$NON-NLS-1$
-                       break;
-               case TokenNameOR_OR : // || (15.23)
-                       operatorString="||"; //$NON-NLS-1$
-                       break;
-               case TokenNameQUESTION : // ? (15.24)
-                       operatorString="?"; //$NON-NLS-1$
-                       break;
-
-               case TokenNameCOLON : // : (15.24)
-                       operatorString=":"; //$NON-NLS-1$
-                       break;
-               case TokenNameEQUAL_EQUAL : // == (15.20, 15.20.1, 15.20.2, 15.20.3)
-                       operatorString="=="; //$NON-NLS-1$
-                       break;
-
-               case TokenNameNOT_EQUAL : // != (15.20, 15.20.1, 15.20.2, 15.20.3)
-                       operatorString="!="; //$NON-NLS-1$
-                       break;
-
-               case TokenNameLESS : // < (15.19.1)
-                       operatorString="<"; //$NON-NLS-1$
-                       break;
-
-               case TokenNameLESS_EQUAL : // <= (15.19.1)
-                       operatorString="<="; //$NON-NLS-1$
-                       break;
-
-               case TokenNameGREATER : // > (15.19.1)
-                       operatorString=">"; //$NON-NLS-1$
-                       break;
-
-               case TokenNameGREATER_EQUAL : // >= (15.19.1)
-                       operatorString=">="; //$NON-NLS-1$
-                       break;
-
-//             case TokenNameinstanceof : // instanceof
-//                     operatorString="instanceof"; //$NON-NLS-1$
-//                     break;
-               case TokenNamePLUS : // + (15.17, 15.17.2)
-                       operatorString="+"; //$NON-NLS-1$
-                       break;
-
-               case TokenNameMINUS : // - (15.17.2)
-                       operatorString="-"; //$NON-NLS-1$
-                       break;
-               case TokenNameMULTIPLY : // * (15.16.1)
-                       operatorString="*"; //$NON-NLS-1$
-                       break;
-
-               case TokenNameDIVIDE : // / (15.16.2)
-                       operatorString="/"; //$NON-NLS-1$
-                       break;
-
-               case TokenNameREMAINDER : // % (15.16.3)
-                       operatorString="%"; //$NON-NLS-1$
-                       break;
-               case TokenNameLEFT_SHIFT : // << (15.18)
-                       operatorString="<<"; //$NON-NLS-1$
-                       break;
-
-               case TokenNameRIGHT_SHIFT : // >> (15.18)
-                       operatorString=">>"; //$NON-NLS-1$
-                       break;
-
-//             case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
-//                     operatorString=">>>"; //$NON-NLS-1$
-//                     break;
-               case TokenNameAND : // & (15.21, 15.21.1, 15.21.2)
-                       operatorString="&"; //$NON-NLS-1$
-                       break;
-
-               case TokenNameOR : // | (15.21, 15.21.1, 15.21.2)
-                       operatorString="|"; //$NON-NLS-1$
-                       break;
-
-               case TokenNameXOR : // ^ (15.21, 15.21.1, 15.21.2)
-                       operatorString="^"; //$NON-NLS-1$
-                       break;
-               case TokenNameMULTIPLY_EQUAL : // *= (15.25.2)
-                       operatorString="*="; //$NON-NLS-1$
-                       break;
-
-               case TokenNameDIVIDE_EQUAL : // /= (15.25.2)
-                       operatorString="/="; //$NON-NLS-1$
-                       break;
-               case TokenNameREMAINDER_EQUAL : // %= (15.25.2)
-                       operatorString="%="; //$NON-NLS-1$
-                       break;
-
-               case TokenNamePLUS_EQUAL : // += (15.25.2)
-                       operatorString="+="; //$NON-NLS-1$
-                       break;
-
-               case TokenNameMINUS_EQUAL : // -= (15.25.2)
-                       operatorString="-="; //$NON-NLS-1$
-                       break;
-
-               case TokenNameLEFT_SHIFT_EQUAL : // <<= (15.25.2)
-                       operatorString="<<="; //$NON-NLS-1$
-                       break;
-
-               case TokenNameRIGHT_SHIFT_EQUAL : // >>= (15.25.2)
-                       operatorString=">>="; //$NON-NLS-1$
-                       break;
-
-//             case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
-//                     operatorString=">>>="; //$NON-NLS-1$
-//                     break;
-
-               case TokenNameAND_EQUAL : // &= (15.25.2)
-                       operatorString="&="; //$NON-NLS-1$
-                       break;
-
-               case TokenNameXOR_EQUAL : // ^= (15.25.2)
-                       operatorString="^="; //$NON-NLS-1$
-                       break;
-
-               case TokenNameOR_EQUAL : // |= (15.25.2)
-                       operatorString="|="; //$NON-NLS-1$
-                       break;
-               case TokenNameDOT : // .
-                       operatorString="."; //$NON-NLS-1$
-                       break;
-
-               default:
-                       operatorString=""; //$NON-NLS-1$
-       }
-               if (placeOperatorAhead){
-                       result.append(operatorString);
-               }
-               result.append(currentString);
-               if (placeOperatorBehind){
-                       result.append(operatorString);
-               }
-               result.append('\n');
-       }
-       return ""; //$NON-NLS-1$
-}
+public class SplitLine implements ITerminalSymbols {
+  public int[] operators; // the operator on which the string was split.
+  public String[] substrings;
+  public int[] startSubstringsIndexes;
+  /**
+   * SplitLine constructor comment.
+   */
+  public SplitLine(int[] operators, String[] substrings) {
+    this(operators, substrings, null);
+  }
+  /**
+   * SplitLine constructor comment.
+   */
+  public SplitLine(int[] operators, String[] substrings, int[] startIndexes) {
+    super();
+    this.operators = operators;
+    this.substrings = substrings;
+    this.startSubstringsIndexes = startIndexes;
+  }
+  /**
+   * Prints a nice representation of the receiver
+   * @return java.lang.String
+   */
+  public String toString() {
+    StringBuffer result = new StringBuffer();
+    String operatorString = new String();
+
+    for (int i = 0, max = substrings.length; i < max; i++) {
+      int currentOperator = operators[i];
+      String currentString = substrings[i];
+      boolean placeOperatorAhead =
+        currentOperator != TokenNameCOMMA
+          && currentOperator != TokenNameSEMICOLON;
+      boolean placeOperatorBehind =
+        currentOperator == TokenNameCOMMA
+          || currentOperator == TokenNameSEMICOLON;
+
+      switch (currentOperator) {
+        case TokenNameextends :
+          operatorString = "extends"; //$NON-NLS-1$
+          break;
+          //           case TokenNameimplements:
+          //                   operatorString="implements"; //$NON-NLS-1$
+          //                   break;
+          //           case TokenNamethrows:
+          //                   operatorString="throws"; //$NON-NLS-1$
+          //                   break;
+        case TokenNameSEMICOLON : // ;
+          operatorString = ";"; //$NON-NLS-1$
+          break;
+        case TokenNameCOMMA : // ,
+          operatorString = ","; //$NON-NLS-1$
+          break;
+        case TokenNameEQUAL : // =
+          operatorString = "="; //$NON-NLS-1$
+          break;
+        case TokenNameAND_AND : // && (15.22)
+          operatorString = "&&"; //$NON-NLS-1$
+          break;
+        case TokenNameOR_OR : // || (15.23)
+          operatorString = "||"; //$NON-NLS-1$
+          break;
+        case TokenNameQUESTION : // ? (15.24)
+          operatorString = "?"; //$NON-NLS-1$
+          break;
+
+        case TokenNameCOLON : // : (15.24)
+          operatorString = ":"; //$NON-NLS-1$
+          break;
+        case TokenNameEQUAL_EQUAL : // == (15.20, 15.20.1, 15.20.2, 15.20.3)
+          operatorString = "=="; //$NON-NLS-1$
+          break;
+
+        case TokenNameNOT_EQUAL : // != (15.20, 15.20.1, 15.20.2, 15.20.3)
+          operatorString = "!="; //$NON-NLS-1$
+          break;
+
+        case TokenNameLESS : // < (15.19.1)
+          operatorString = "<"; //$NON-NLS-1$
+          break;
+
+        case TokenNameLESS_EQUAL : // <= (15.19.1)
+          operatorString = "<="; //$NON-NLS-1$
+          break;
+
+        case TokenNameGREATER : // > (15.19.1)
+          operatorString = ">"; //$NON-NLS-1$
+          break;
+
+        case TokenNameGREATER_EQUAL : // >= (15.19.1)
+          operatorString = ">="; //$NON-NLS-1$
+          break;
+
+          //           case TokenNameinstanceof : // instanceof
+          //                   operatorString="instanceof"; //$NON-NLS-1$
+          //                   break;
+        case TokenNamePLUS : // + (15.17, 15.17.2)
+          operatorString = "+"; //$NON-NLS-1$
+          break;
+
+        case TokenNameMINUS : // - (15.17.2)
+          operatorString = "-"; //$NON-NLS-1$
+          break;
+        case TokenNameMULTIPLY : // * (15.16.1)
+          operatorString = "*"; //$NON-NLS-1$
+          break;
+
+        case TokenNameDIVIDE : // / (15.16.2)
+          operatorString = "/"; //$NON-NLS-1$
+          break;
+
+        case TokenNameREMAINDER : // % (15.16.3)
+          operatorString = "%"; //$NON-NLS-1$
+          break;
+        case TokenNameLEFT_SHIFT : // << (15.18)
+          operatorString = "<<"; //$NON-NLS-1$
+          break;
+
+        case TokenNameRIGHT_SHIFT : // >> (15.18)
+          operatorString = ">>"; //$NON-NLS-1$
+          break;
+
+          //           case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
+          //                   operatorString=">>>"; //$NON-NLS-1$
+          //                   break;
+        case TokenNameAND : // & (15.21, 15.21.1, 15.21.2)
+          operatorString = "&"; //$NON-NLS-1$
+          break;
+
+        case TokenNameOR : // | (15.21, 15.21.1, 15.21.2)
+          operatorString = "|"; //$NON-NLS-1$
+          break;
+
+        case TokenNameXOR : // ^ (15.21, 15.21.1, 15.21.2)
+          operatorString = "^"; //$NON-NLS-1$
+          break;
+        case TokenNameMULTIPLY_EQUAL : // *= (15.25.2)
+          operatorString = "*="; //$NON-NLS-1$
+          break;
+
+        case TokenNameDIVIDE_EQUAL : // /= (15.25.2)
+          operatorString = "/="; //$NON-NLS-1$
+          break;
+        case TokenNameREMAINDER_EQUAL : // %= (15.25.2)
+          operatorString = "%="; //$NON-NLS-1$
+          break;
+
+        case TokenNamePLUS_EQUAL : // += (15.25.2)
+          operatorString = "+="; //$NON-NLS-1$
+          break;
+
+        case TokenNameMINUS_EQUAL : // -= (15.25.2)
+          operatorString = "-="; //$NON-NLS-1$
+          break;
+
+        case TokenNameLEFT_SHIFT_EQUAL : // <<= (15.25.2)
+          operatorString = "<<="; //$NON-NLS-1$
+          break;
+
+        case TokenNameRIGHT_SHIFT_EQUAL : // >>= (15.25.2)
+          operatorString = ">>="; //$NON-NLS-1$
+          break;
+
+          //           case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
+          //                   operatorString=">>>="; //$NON-NLS-1$
+          //                   break;
+
+        case TokenNameAND_EQUAL : // &= (15.25.2)
+          operatorString = "&="; //$NON-NLS-1$
+          break;
+
+        case TokenNameXOR_EQUAL : // ^= (15.25.2)
+          operatorString = "^="; //$NON-NLS-1$
+          break;
+
+        case TokenNameOR_EQUAL : // |= (15.25.2)
+          operatorString = "|="; //$NON-NLS-1$
+          break;
+        case TokenNameDOT : // .
+          operatorString = "."; //$NON-NLS-1$
+          break;
+
+        default :
+          operatorString = ""; //$NON-NLS-1$
+      }
+      if (placeOperatorAhead) {
+        result.append(operatorString);
+      }
+      result.append(currentString);
+      if (placeOperatorBehind) {
+        result.append(operatorString);
+      }
+      result.append('\n');
+    }
+    return ""; //$NON-NLS-1$
+  }
 }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.java
new file mode 100644 (file)
index 0000000..120b578
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.actions;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Class that gives access to the action messages resource bundle.
+ */
+public class ActionMessages {
+
+       private static final String BUNDLE_NAME= "net.sourceforge.phpdt.internal.ui.actions.ActionMessages"; //$NON-NLS-1$
+
+       private static final ResourceBundle RESOURCE_BUNDLE= ResourceBundle.getBundle(BUNDLE_NAME);
+
+       private ActionMessages() {
+               // no instance
+       }
+
+       /**
+        * Returns the resource string associated with the given key in the resource bundle. If there isn't 
+        * any value under the given key, the key is returned.
+        *
+        * @param key the resource key
+        * @return the string
+        */     
+       public static String getString(String key) {
+               try {
+                       return RESOURCE_BUNDLE.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+       
+       /**
+        * Returns the formatted resource string associated with the given key in the resource bundle. 
+        * <code>MessageFormat</code> is used to format the message. If there isn't  any value 
+        * under the given key, the key is returned.
+        *
+        * @param key the resource key
+        * @param arg the message argument
+        * @return the string
+        */     
+       public static String getFormattedString(String key, Object arg) {
+               return getFormattedString(key, new Object[] { arg });
+       }
+       
+       /**
+        * Returns the formatted resource string associated with the given key in the resource bundle. 
+        * <code>MessageFormat</code> is used to format the message. If there isn't  any value 
+        * under the given key, the key is returned.
+        *
+        * @param key the resource key
+        * @param args the message arguments
+        * @return the string
+        */     
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);      
+       }       
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/ActionMessages.properties
new file mode 100644 (file)
index 0000000..b51f21d
--- /dev/null
@@ -0,0 +1,237 @@
+################################################################################
+# Copyright (c) 2002 International Business Machines Corp. and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v0.5 
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v05.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+################################################################################
+
+OpenWithMenu.label=Open Wit&h
+RefactorMenu.label=Re&factor
+SourceMenu.label=&Source
+NavigateMenu.label=&Navigate
+
+BuildAction.label=&Build Project
+RebuildAction.label=Rebuild Pro&ject
+
+SelectionConverter.codeResolveOrInput_failed=Couldn't convert text selection into a PHP element
+SelectionConverter.codeResolve_failed=Couldn't convert text selection into a PHP element
+
+OpenAction.label=&Open
+OpenAction.tooltip=Open an editor on the selected element
+OpenAction.description=Open an editor on the selected element
+OpenAction.declaration.label=&Open Declaration@F3
+OpenAction.select_element=&Select or enter the element to open:
+
+OpenAction.error.title=Open
+OpenAction.error.message=Cannot open default editor.
+OpenAction.error.messageArgs=Cannot open default editor on {0}. {1}
+OpenAction.error.messageProblems=Problems Opening Editor
+OpenAction.error.messageBadSelection=Current text selection doesn't resolve to a PHP element
+
+OpenSuperImplementationAction.label=Open S&uper Implementation
+OpenSuperImplementationAction.tooltip=Open the Implementation in the Super Type
+OpenSuperImplementationAction.description=Open the Implementation in the Super Type
+OpenSuperImplementationAction.error.title=Open Super Implementation
+OpenSuperImplementationAction.error.message=Opening failed. Check log for details.
+OpenSuperImplementationAction.not_applicable=Operation not applicable to current text selection. Please position the cursor inside a method.
+OpenSuperImplementationAction.no_super_implementation=There isn''t any super implementation for method ''{0}''.
+
+OpenTypeHierarchyAction.label=Open Type Hie&rarchy
+OpenTypeHierarchyAction.tooltip=Open a type hierarchy on the selected element
+OpenTypeHierarchyAction.description=Open a type hierarchy on the selected element
+OpenTypeHierarchyAction.dialog.title=Open Type Hierarchy
+OpenTypeHierarchyAction.messages.title=Can\'t create type hierarchy
+OpenTypeHierarchyAction.messages.no_php_element=No PHP element selected.
+OpenTypeHierarchyAction.messages.no_php_resources=Selected package fragment doesn\'t contain any PHP resource.
+OpenTypeHierarchyAction.messages.no_types=Selected compilation unit doesn\'t contain a type.
+OpenTypeHierarchyAction.messages.no_valid_php_element=No valid PHP element selected.
+
+ShowInPackageViewAction.label=Show in Pac&kage Explorer
+ShowInPackageViewAction.description=Show the selected element in Package Explorer
+ShowInPackageViewAction.tooltip=Show in Package Explorer
+ShowInPackageViewAction.select_name=&Select or enter the element to reveal:
+ShowInPackageViewAction.dialog.title=Show In Package Explorer
+ShowInPackageViewAction.error.message=Internal error. Please see log for details.
+ShowInPackageViewAction.not_found=Couldn\'t reveal the selected element in Package Explorer. May be the element is filtered out.
+
+ShowInNavigatorView.label=Show in &Navigator View
+ShowInNavigatorView.dialog.title=Show in Navigator View
+ShowInNavigatorView.dialog.message=Select the element to be opened in the navigator view:
+ShowInNavigatorView.error.activation_failed=Unable to activate Resource Navigator
+ShowInNavigatorView.error.conversion_failed=Unable to convert PHP element into a resource
+
+OverrideMethodsAction.label=O&verride/Implement Methods...
+OverrideMethodsAction.description=Override or Implement Methods from super types.
+OverrideMethodsAction.tooltip=Override/Implement Methods
+
+OverrideMethodsAction.error.title=Override/Implement Methods
+OverrideMethodsAction.error.nothing_found=No methods to override found for this type.
+OverrideMethodsAction.error.type_removed_in_editor=Input type has been removed in editor.
+OverrideMethodsAction.not_applicable=Operation not applicable to current text selection. Please position the cursor inside a type.
+
+AddGetterSetterAction.label=Gene&rate Getter and Setter...
+AddGetterSetterAction.description=Generate Getter and Setter methods for the field
+AddGetterSetterAction.tooltip=Generate Getter and Setter methods for the Field
+
+AddGetterSetterAction.error.title=Generate Getter and Setter
+AddGetterSetterAction.error.actionfailed=Generating Getter and Setter Failed.
+AddGetterSetterAction.error.fieldNotExisting=The field ''{0}'' has been removed in the editor.
+AddGetterSetterAction.not_applicable=Operation not applicable to current text selection. Please select a field or a type that declares some fields.
+AddGetterSetterAction.read_only=The compilation unit in which the field ''{0}'' is declared is read only.
+
+AddGetterSetterAction.QueryDialog.title=Generate Getter and Setter
+AddGetterSetterAction.SkipSetterForFinalDialog.message=Field ''{0}'' is final.\nOK to skip creation of the setter method?
+AddGetterSetterAction.SkipExistingDialog.message=Method ''{0}'' already exists.\nSkip creation?
+AddGetterSetterAction.SkipExistingDialog.skip.label=&Skip
+AddGetterSetterAction.SkipExistingDialog.replace.label=&Replace
+AddGetterSetterAction.SkipExistingDialog.skipAll.label=Skip &All
+
+AddUnimplementedConstructorsAction.label=Add &Constructors from Superclass
+AddUnimplementedConstructorsAction.description=Evaluate and add constructors from superclass
+AddUnimplementedConstructorsAction.tooltip=Add Constructors from Superclass
+
+AddUnimplementedConstructorsAction.error.title=Add Constructors from Superclass
+AddUnimplementedConstructorsAction.error.nothing_found=No unimplemented constructors found.
+AddUnimplementedConstructorsAction.error.type_removed_in_editor=Input type has been removed in editor.
+AddUnimplementedConstructorsAction.not_applicable=Operation not applicable to current text selection. Please position the cursor inside a type.
+
+AddJavaDocStubAction.label=Add &Javadoc Comment
+AddJavaDocStubAction.description=Add a Javadoc comment stub to the member element
+AddJavaDocStubAction.tooltip=Add a Javadoc comment stub to the member element
+
+AddJavaDocStubsAction.error.dialogTitle=Add Javadoc Comment
+AddJavaDocStubsAction.error.noWorkingCopy=Could not find working copy.
+AddJavaDocStubsAction.error.memberNotExisting=Member has been removed in editor.
+AddJavaDocStubsAction.error.actionFailed=Error while adding Javadoc comment
+AddJavaDocStubsAction.not_applicable=Operation not applicable to current text selection. Please position the cursor inside a type or method.
+
+ExternalizeStringsAction.label= &Externalize Strings...
+ExternalizeStringsAction.dialog.title= Externalize Strings
+ExternalizeStringsAction.dialog.message=Couldn't open Externalize String Wizard
+
+FindStringsToExternalizeAction.label= &Find Strings to Externalize...
+FindStringsToExternalizeAction.dialog.title= Find Strings to Externalize
+FindStringsToExternalizeAction.error.message=Unexpected Exception. See log.
+FindStringsToExternalizeAction.foundStrings= {0} in {1}
+FindStringsToExternalizeAction.noStrings= No strings to externalize were found.
+FindStringsToExternalizeAction.not_externalized= {0} &not externalized string(s) found.
+FindStringsToExternalizeAction.button.label= &Externalize...
+FindStringsToExternalizeAction.hide= &Hide compilation units with no strings to externalize
+FindStringsToExternalizeAction.find_strings=Finding not externalized strings...
+
+OpenExternalJavadocAction.label=Open E&xternal Javadoc
+OpenExternalJavadocAction.description=Opens the Javadoc of the selected element in an external browser
+OpenExternalJavadocAction.tooltip=Opens the Javadoc of the selected element in an external browser
+OpenExternalJavadocAction.help_not_available=Help support not available
+OpenExternalJavadocAction.select_element=&Select or enter the element to open:
+OpenExternalJavadocAction.libraries.no_location=The documentation location for ''{0}'' has not been configured. For elements from libraries specify the Javadoc location URL on the property page of the parent JAR (''{1}'')
+OpenExternalJavadocAction.source.no_location=The documentation location for ''{0}'' has not been configured. For elements from source specify the Javadoc location URL on the property page of the parent project (''{1}'')
+OpenExternalJavadocAction.no_entry=The documentation does not contain an entry for ''{0}''.\n(File ''{1}'' does not exist.)
+OpenExternalJavadocAction.opening_failed=Opening Javadoc failed. See log for details
+OpenExternalJavadocAction.dialog.title=Open External Javadoc
+OpenExternalJavadocAction.code_resolve_failed=Couldn't convert text selection into a PHP element
+
+SelfEncapsulateFieldAction.label=&Self Encapsulate...
+SelfEncapsulateFieldAction.dialog.title=Self Encapsulate Field
+SelfEncapsulateFieldAction.dialog.unavailable=Operation unavailable on the current selection. Select a field.
+SelfEncapsulateFieldAction.dialog.cannot_perform=Cannot perform refactoring. See log for more details.
+SelfEncapsulateFieldAction.dialog.field_doesnot_exit=Field {0} doesn't exist in editor buffer anymore.
+
+OrganizeImportsAction.label=Or&ganize Imports@Ctrl+Shift+O
+OrganizeImportsAction.tooltip=Evaluate All Required Imports and Replace the Current Imports
+OrganizeImportsAction.description=Evaluate all required imports and replace the current imports
+
+OrganizeImportsAction.multi.op.description=Organizing imports...
+OrganizeImportsAction.multi.error.parse={0}: Compilation unit has parse errors. No changes applied.
+OrganizeImportsAction.multi.error.readonly={0}: Compilation unit is read-only. No changes applied.
+OrganizeImportsAction.multi.error.unresolvable={0}: Compilation unit contains ambiguous references. User interaction required.
+OrganizeImportsAction.multi.error.unexpected={0}: Unexpected error. See log for details.
+
+OrganizeImportsAction.selectiondialog.title=Organize Imports
+OrganizeImportsAction.selectiondialog.message=&Choose type to import:
+
+OrganizeImportsAction.error.title=Organize Imports
+OrganizeImportsAction.error.message=Unexpected error in organize imports. See log for details.
+
+OrganizeImportsAction.single.error.parse=Compilation unit has parse errors. No changes applied.
+
+OrganizeImportsAction.summary_added={0} import(s) added.
+OrganizeImportsAction.summary_removed={0} import(s) removed.
+
+OrganizeImportsAction.multi.status.title=Organize Imports
+OrganizeImportsAction.multi.status.description=Problems while organizing imports on some compilation units. See 'Details' for more information.
+
+OpenBrowserUtil.help_not_available=Help support not available
+
+MemberFilterActionGroup.hide_fields.label=Hide Fields
+MemberFilterActionGroup.hide_fields.tooltip=Hide Fields
+MemberFilterActionGroup.hide_fields.description=Toggles the visibility of fields
+
+MemberFilterActionGroup.hide_static.label=Hide Static Members
+MemberFilterActionGroup.hide_static.tooltip=Hide Static Members
+MemberFilterActionGroup.hide_static.description=Toggles the visibility of static members
+
+MemberFilterActionGroup.hide_nonpublic.label=Hide Non-Public Members
+MemberFilterActionGroup.hide_nonpublic.tooltip=Hide Non-Public Members
+MemberFilterActionGroup.hide_nonpublic.description=Toggles the visibility of non-public members
+
+NewWizardsActionGroup.new=Ne&w
+
+OpenProjectAction.dialog.title=Open Project
+OpenProjectAction.dialog.message=Select project(s) to be opened
+OpenProjectAction.error.message=Problems while opening projects
+OpenProjectAction.no_php_nature.one=The following project doesn't have a PHP nature and is therefore not present in the Package Explorer:
+OpenProjectAction.no_php_nature.multiple=The following projects don't have a PHP nature and are therefore not present in the Package Explorer:
+
+AddGetterSetterAction.dialog.title=&Select Methods to Create in Type ''{0}'':
+AddGetterSetterAction.one_selected=1 method selected
+AddGetterSetterAction.methods_selected={0} methods selected
+AddGettSetterAction.typeContainsNoFields.message=The type contains no fields or all fields have getters/setters already.
+
+OpenJavaPerspectiveAction.dialog.title=Open PHP Perspective
+OpenJavaPerspectiveAction.error.open_failed=Couldn\'t open PHP perspective
+
+OpenJavaBrowsingPerspectiveAction.dialog.title=Open PHP Browsing Perspective
+OpenJavaBrowsingPerspectiveAction.error.open_failed=Couldn\'t open PHP browsing perspective
+
+OpenTypeInHierarchyAction.label=Open Type in Hierarchy...@Ctrl+Shift+H
+OpenTypeInHierarchyAction.description=Open a type a the type hierarchy
+OpenTypeInHierarchyAction.tooltip=Open a type in a type hierarchy
+OpenTypeInHierarchyAction.dialogMessage=&Choose a type (? = any character, * = any string):
+OpenTypeInHierarchyAction.dialogTitle=Open Type in Hierarchy
+
+RefreshAction.label= Re&fresh
+RefreshAction.toolTip= Refresh
+RefreshAction.progressMessage= Refreshing...
+RefreshAction.error.title= Refresh Problems
+RefreshAction.error.message= Problems occurred refreshing the selected resources.
+RefreshAction.locationDeleted.title= Project location has been deleted
+RefreshAction.locationDeleted.message= The location for project {0} ({1}) has been deleted.\n Delete {0} from the workspace?
+
+ModifyParameterAction.problem.title=Refactoring
+ModifyParameterAction.problem.message=Operation not possible.
+
+PullUpAction.problem.title=Refactoring
+PullUpAction.problem.message=Operation not possible.
+
+OverrideMethodQuery.groupMethodsByTypes=Group methods by &types
+OverrideMethodQuery.dialog.title=Override/Implement Methods
+OverrideMethodQuery.dialog.description=&Select methods to override or implement:
+OverrideMethodQuery.selectioninfo.one={0} method selected.
+OverrideMethodQuery.selectioninfo.more={0} methods selected.
+
+ActionUtil.notOnBuildPath.title=Operation Cannot be Performed
+ActionUtil.notOnBuildPath.message=The resource is not on the build path of a PHP project.
+
+SelectAllAction.label= Select A&ll
+SelectAllAction.tooltip= Select All
+
+AddJARToClasspathAction.label=Add to Build Path
+AddJARToClasspathAction.toolTip=Add JAR to the PHP build path
+AddJARToClasspathAction.progressMessage=Adding to build path...
+AddJARToClasspathAction.error.title=Add To Build Path
+AddJARToClasspathAction.error.message=Problems occurred while adding to the build path.
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/PHPCodeReader.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/PHPCodeReader.java
new file mode 100644 (file)
index 0000000..41db8c4
--- /dev/null
@@ -0,0 +1,233 @@
+package net.sourceforge.phpdt.internal.ui.text;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.IOException;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+import net.sourceforge.phpdt.internal.corext.phpdoc.SingleCharReader;
+
+/**
+ * Reads from a document either forwards or backwards. May be configured to
+ * skip comments and strings.
+ */
+public class PHPCodeReader extends SingleCharReader {
+       
+       /** The EOF character */
+       public static final int EOF= -1;
+       
+       private boolean fSkipComments= false;
+       private boolean fSkipStrings= false;
+       private boolean fForward= false;
+       
+       private IDocument fDocument;
+       private int fOffset;
+       
+       private int fEnd= -1;
+       private int fCachedLineNumber= -1;
+       private int fCachedLineOffset= -1;
+       
+       
+       public PHPCodeReader() {
+       }
+       
+       /**
+        * Returns the offset of the last read character. Should only be called after read has been called.
+        */
+       public int getOffset() {
+               return fForward ? fOffset -1 : fOffset;
+       }
+       
+       public void configureForwardReader(IDocument document, int offset, int length, boolean skipComments, boolean skipStrings) throws IOException {
+               fDocument= document;
+               fOffset= offset;
+               fSkipComments= skipComments;
+               fSkipStrings= skipStrings;
+               
+               fForward= true;
+               fEnd= Math.min(fDocument.getLength(), fOffset + length);                
+       }
+       
+       public void configureBackwardReader(IDocument document, int offset, boolean skipComments, boolean skipStrings) throws IOException {
+               fDocument= document;
+               fOffset= offset;
+               fSkipComments= skipComments;
+               fSkipStrings= skipStrings;
+               
+               fForward= false;
+               try {
+                       fCachedLineNumber= fDocument.getLineOfOffset(fOffset);
+               } catch (BadLocationException x) {
+                       throw new IOException(x.getMessage());
+               }
+       }
+       
+       /*
+        * @see Reader#close()
+        */
+       public void close() throws IOException {
+               fDocument= null;
+       }
+       
+       /*
+        * @see SingleCharReader#read()
+        */
+       public int read() throws IOException {
+               try {
+                       return fForward ? readForwards() : readBackwards();
+               } catch (BadLocationException x) {
+                       throw new IOException(x.getMessage());
+               }
+       }
+       
+       private void gotoCommentEnd() throws BadLocationException {
+               while (fOffset < fEnd) {
+                       char current= fDocument.getChar(fOffset++);
+                       if (current == '*') {
+                               if (fOffset < fEnd && fDocument.getChar(fOffset) == '/') {
+                                       ++ fOffset;
+                                       return;
+                               }
+                       }
+               }
+       }
+       
+       private void gotoStringEnd(char delimiter) throws BadLocationException {
+               while (fOffset < fEnd) {
+                       char current= fDocument.getChar(fOffset++);
+                       if (current == '\\') {
+                               // ignore escaped characters
+                               ++ fOffset;
+                       } else if (current == delimiter) {
+                               return;
+                       }
+               }
+       }
+       
+       private void gotoLineEnd() throws BadLocationException {
+               int line= fDocument.getLineOfOffset(fOffset);
+               fOffset= fDocument.getLineOffset(line + 1);
+       }
+       
+       private int readForwards() throws BadLocationException {
+               while (fOffset < fEnd) {
+                       char current= fDocument.getChar(fOffset++);
+                       
+                       switch (current) {
+                               case '/':
+                                       
+                                       if (fSkipComments && fOffset < fEnd) {
+                                               char next= fDocument.getChar(fOffset);
+                                               if (next == '*') {
+                                                       // a comment starts, advance to the comment end
+                                                       ++ fOffset;
+                                                       gotoCommentEnd();
+                                                       continue;
+                                               } else if (next == '/') {
+                                                       // '//'-comment starts, advance to the line end
+                                                       gotoLineEnd();
+                                                       continue;
+                                               }
+                                       }
+                                       
+                                       return current;
+                                       
+                               case '"':
+                               case '\'':
+                               
+                                       if (fSkipStrings) {
+                                               gotoStringEnd(current);
+                                               continue;
+                                       }
+                                       
+                                       return current;
+                       }
+                       
+                       return current;
+               }
+               
+               return EOF;
+       }
+       
+       private void handleSingleLineComment() throws BadLocationException {
+               int line= fDocument.getLineOfOffset(fOffset);
+               if (line < fCachedLineNumber) {
+                       fCachedLineNumber= line;
+                       fCachedLineOffset= fDocument.getLineOffset(line);
+                       int offset= fOffset;
+                       while (fCachedLineOffset < offset) {
+                               char current= fDocument.getChar(offset--);
+                               if (current == '/' && fCachedLineOffset <= offset && fDocument.getChar(offset) == '/') {
+                                       fOffset= offset;
+                                       return;
+                               }
+                       }
+               }
+       }
+       
+       private void gotoCommentStart() throws BadLocationException {
+               while (0 < fOffset) {
+                       char current= fDocument.getChar(fOffset--);
+                       if (current == '*' && 0 <= fOffset && fDocument.getChar(fOffset) == '/')
+                               return;
+               }
+       }
+       
+       private void gotoStringStart(char delimiter) throws BadLocationException {
+               while (0 < fOffset) {
+                       char current= fDocument.getChar(fOffset);
+                       if (current == delimiter) {
+                               if ( !(0 <= fOffset && fDocument.getChar(fOffset -1) == '\\'))
+                                       return;
+                       }
+                       -- fOffset;
+               }
+       }
+               
+       private int readBackwards() throws BadLocationException {
+               
+               while (0 < fOffset) {
+                       -- fOffset;
+                       
+                       handleSingleLineComment();
+                       
+                       char current= fDocument.getChar(fOffset);
+                       switch (current) {
+                               case '/':
+                                       
+                                       if (fSkipComments && fOffset > 1) {
+                                               char next= fDocument.getChar(fOffset - 1);
+                                               if (next == '*') {
+                                                       // a comment ends, advance to the comment start
+                                                       fOffset -= 2;
+                                                       gotoCommentStart();
+                                                       continue;
+                                               }
+                                       }
+                                       
+                                       return current;
+                                       
+                               case '"':
+                               case '\'':
+                               
+                                       if (fSkipStrings) {
+                                               -- fOffset;
+                                               gotoStringStart(current);
+                                               continue;
+                                       }
+                                       
+                                       return current;
+                       }
+                       
+                       return current;
+               }
+               
+               return EOF;
+       }
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/PHPPairMatcher.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/PHPPairMatcher.java
new file mode 100644 (file)
index 0000000..97a0edd
--- /dev/null
@@ -0,0 +1,172 @@
+package net.sourceforge.phpdt.internal.ui.text;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import java.io.IOException;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+
+/**
+ * Helper class for match pairs of characters.
+ */
+public class PHPPairMatcher {
+       
+       
+       public static final int LEFT=      1;
+       public static final int RIGHT= 2;
+
+       
+       protected char[] fPairs;
+       protected IDocument fDocument;
+       protected int fOffset;
+       
+       protected int fStartPos;
+       protected int fEndPos;
+       protected int fAnchor;
+       
+       protected PHPCodeReader fReader= new PHPCodeReader();
+       
+       
+       public PHPPairMatcher(char[] pairs) {
+               fPairs= pairs;
+       }
+       
+       public IRegion match(IDocument document, int offset) {
+
+               fOffset= offset;
+
+               if (fOffset < 0)
+                       return null;
+
+               fDocument= document;
+
+               if (matchPairsAt() && fStartPos != fEndPos)
+                       return new Region(fStartPos, fEndPos - fStartPos + 1);
+                       
+               return null;
+       }
+       
+       public int getAnchor() {
+               return fAnchor;
+       }
+       
+       public void dispose() {
+               fDocument= null;
+               if (fReader != null) {
+                       try {
+                               fReader.close();
+                       } catch (IOException x) {
+                               // ignore
+                       }
+                       fReader= null;
+               }
+       }
+       
+       protected boolean matchPairsAt() {
+
+               int i;
+               int pairIndex1= fPairs.length;
+               int pairIndex2= fPairs.length;
+
+               fStartPos= -1;
+               fEndPos= -1;
+
+               // get the chars preceding and following the start position
+               try {
+
+                       char prevChar= fDocument.getChar(Math.max(fOffset - 1, 0));
+                       char nextChar= fDocument.getChar(fOffset);
+
+                       // search for opening peer character next to the activation point
+                       for (i= 0; i < fPairs.length; i= i + 2) {
+                               if (nextChar == fPairs[i]) {
+                                       fStartPos= fOffset;
+                                       pairIndex1= i;
+                               } else if (prevChar == fPairs[i]) {
+                                       fStartPos= fOffset - 1;
+                                       pairIndex1= i;
+                               }
+                       }
+                       
+                       // search for closing peer character next to the activation point
+                       for (i= 1; i < fPairs.length; i= i + 2) {
+                               if (prevChar == fPairs[i]) {
+                                       fEndPos= fOffset - 1;
+                                       pairIndex2= i;
+                               } else if (nextChar == fPairs[i]) {
+                                       fEndPos= fOffset;
+                                       pairIndex2= i;
+                               }
+                       }
+
+                       if (fEndPos > -1) {
+                               fAnchor= RIGHT;
+                               fStartPos= searchForOpeningPeer(fEndPos, fPairs[pairIndex2 - 1], fPairs[pairIndex2], fDocument);
+                               if (fStartPos > -1)
+                                       return true;
+                               else
+                                       fEndPos= -1;
+                       }       else if (fStartPos > -1) {
+                               fAnchor= LEFT;
+                               fEndPos= searchForClosingPeer(fStartPos, fPairs[pairIndex1], fPairs[pairIndex1 + 1], fDocument);
+                               if (fEndPos > -1)
+                                       return true;
+                               else
+                                       fStartPos= -1;
+                       }
+
+               } catch (BadLocationException x) {
+               } catch (IOException x) {
+               }
+
+               return false;
+       }
+       
+       protected int searchForClosingPeer(int offset, int openingPeer, int closingPeer, IDocument document) throws IOException {
+               
+               fReader.configureForwardReader(document, offset + 1, document.getLength(), true, true);
+               
+               int stack= 1;
+               int c= fReader.read();
+               while (c != PHPCodeReader.EOF) {
+                       if (c == openingPeer && c != closingPeer)
+                               stack++;
+                       else if (c == closingPeer)
+                               stack--;
+                               
+                       if (stack == 0)
+                               return fReader.getOffset();
+                               
+                       c= fReader.read();
+               }
+               
+               return  -1;
+       }
+       
+       protected int searchForOpeningPeer(int offset, int openingPeer, int closingPeer, IDocument document) throws IOException {
+               
+               fReader.configureBackwardReader(document, offset, true, true);
+               
+               int stack= 1;
+               int c= fReader.read();
+               while (c != PHPCodeReader.EOF) {
+                       if (c == closingPeer && c != openingPeer)
+                               stack++;
+                       else if (c == openingPeer)
+                               stack--;
+                               
+                       if (stack == 0)
+                               return fReader.getOffset();
+                               
+                       c= fReader.read();
+               }
+               
+               return -1;
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/IViewPartInputProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/IViewPartInputProvider.java
new file mode 100644 (file)
index 0000000..54764c8
--- /dev/null
@@ -0,0 +1,15 @@
+package net.sourceforge.phpdt.internal.ui.viewsupport;
+
+/**
+ * Interface common to all view parts that provide an input.
+ */
+public interface IViewPartInputProvider {
+       
+       /**
+        * Returns the input.
+        *
+        * @return the input object
+        */
+       public Object getViewPartInput();
+
+}
index 8f68e78..0607a3e 100644 (file)
@@ -22,6 +22,7 @@ import org.eclipse.debug.internal.ui.actions.ActionMessages;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
 import org.eclipse.jface.util.Assert;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -36,6 +37,7 @@ import org.eclipse.ui.actions.AddBookmarkAction;
 import org.eclipse.ui.part.Page;
 import org.eclipse.ui.texteditor.ConvertLineDelimitersAction;
 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.IUpdate;
 
 /**
  * Action group that adds the source and generate actions to a part's context
@@ -49,6 +51,7 @@ import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
  */
 public class GenerateActionGroup extends ActionGroup {
        
+  private PHPEditor fEditor;
        private boolean fEditorIsOwner;
        private IWorkbenchSite fSite;
        private String fGroupName= IContextMenuConstants.GROUP_SOURCE;
@@ -76,6 +79,7 @@ public class GenerateActionGroup extends ActionGroup {
         */
        public GenerateActionGroup(PHPEditor editor, String groupName) {
                fSite= editor.getSite();
+    fEditor= editor;
                fEditorIsOwner= true;
                fGroupName= groupName;
                ISelectionProvider provider= fSite.getSelectionProvider();
@@ -213,14 +217,6 @@ public class GenerateActionGroup extends ActionGroup {
         */
        public void editorStateChanged() {
                Assert.isTrue(fEditorIsOwner);
-//             fAddImport.update();
-//             fExternalizeStrings.editorStateChanged();
-//             fOrganizeImports.editorStateChanged();
-//             fOverrideMethods.editorStateChanged();
-//             fAddUnimplementedConstructors.editorStateChanged();
-//             fAddJavaDocStub.editorStateChanged();
-//             fSurroundWithTryCatch.editorStateChanged();
-//             fAddGetterSetter.editorStateChanged();
                
                // http://dev.eclipse.org/bugs/show_bug.cgi?id=17709
                fConvertToMac.update();
@@ -255,25 +251,27 @@ public class GenerateActionGroup extends ActionGroup {
                }
        }
        
-       private IMenuManager createEditorSubMenu(IMenuManager mainMenu) {
-               IMenuManager result= new MenuManager(ActionMessages.getString("SourceMenu.label")); //$NON-NLS-1$
-               int added= 0;
-//             added+= addAction(result, fOrganizeImports);
-//             added+= addAction(result, fAddImport);
-//             result.add(new Separator());
-//             added+= addAction(result, fOverrideMethods);
-//             added+= addAction(result, fAddGetterSetter);
-//             added+= addAction(result, fAddUnimplementedConstructors);
-//             added+= addAction(result, fAddJavaDocStub);
-               added+= addAction(result, fAddBookmark);
-//             result.add(new Separator());            
-//             added+= addAction(result, fSurroundWithTryCatch);
-//             added+= addAction(result, fExternalizeStrings);
-               if (added == 0)
-                       result= null;
-               return result;
-       }
-
+  private IMenuManager createEditorSubMenu(IMenuManager mainMenu) {
+    IMenuManager result= new MenuManager(ActionMessages.getString("SourceMenu.label")); //$NON-NLS-1$
+    int added= 0;
+    added+= addEditorAction(result, "Comment"); //$NON-NLS-1$
+    added+= addEditorAction(result, "Uncomment"); //$NON-NLS-1$
+//    result.add(new Separator());
+//    added+= addAction(result, fOrganizeImports);
+//    added+= addAction(result, fAddImport);
+    result.add(new Separator());
+//    added+= addAction(result, fOverrideMethods);
+//    added+= addAction(result, fAddGetterSetter);
+//    added+= addAction(result, fAddUnimplementedConstructors);
+//    added+= addAction(result, fAddJavaDocStub);
+    added+= addAction(result, fAddBookmark);
+//    result.add(new Separator());             
+//    added+= addAction(result, fSurroundWithTryCatch);
+//    added+= addAction(result, fExternalizeStrings);
+    if (added == 0)
+      result= null;
+    return result;
+  }
        /* (non-Javadoc)
         * Method declared in ActionGroup
         */
@@ -285,6 +283,7 @@ public class GenerateActionGroup extends ActionGroup {
                                provider.removeSelectionChangedListener(listener);
                        }
                }
+    fEditor= null;
                super.dispose();
        }
        
@@ -298,9 +297,9 @@ public class GenerateActionGroup extends ActionGroup {
 //             actionBar.setGlobalActionHandler(JdtActionConstants.EXTERNALIZE_STRINGS, fExternalizeStrings);
 //             actionBar.setGlobalActionHandler(JdtActionConstants.FIND_STRINGS_TO_EXTERNALIZE, fFindStringsToExternalize);
 //             actionBar.setGlobalActionHandler(JdtActionConstants.ORGANIZE_IMPORTS, fOrganizeImports);
-//             actionBar.setGlobalActionHandler(JdtActionConstants.CONVERT_LINE_DELIMITERS_TO_WINDOWS, fConvertToWindows);
-//             actionBar.setGlobalActionHandler(JdtActionConstants.CONVERT_LINE_DELIMITERS_TO_UNIX, fConvertToUNIX);
-//             actionBar.setGlobalActionHandler(JdtActionConstants.CONVERT_LINE_DELIMITERS_TO_MAC, fConvertToMac);
+               actionBar.setGlobalActionHandler(PHPdtActionConstants.CONVERT_LINE_DELIMITERS_TO_WINDOWS, fConvertToWindows);
+               actionBar.setGlobalActionHandler(PHPdtActionConstants.CONVERT_LINE_DELIMITERS_TO_UNIX, fConvertToUNIX);
+               actionBar.setGlobalActionHandler(PHPdtActionConstants.CONVERT_LINE_DELIMITERS_TO_MAC, fConvertToMac);
                if (!fEditorIsOwner) {
                        // editor provides its own implementation of these actions.
                        actionBar.setGlobalActionHandler(IWorkbenchActionConstants.BOOKMARK, fAddBookmark);
@@ -323,4 +322,23 @@ public class GenerateActionGroup extends ActionGroup {
                }
                return 0;
        }       
+       
+  private int addEditorAction(IMenuManager menu, String actionID) {
+    if (fEditor == null)
+      return 0;
+    IAction action= fEditor.getAction(actionID);
+    if (action == null)
+      return 0;
+    if (action instanceof IUpdate)
+      ((IUpdate)action).update();
+    if (action.isEnabled()) {
+      menu.add(action);
+      return 1;
+    }
+    return 0;
+  }
+  
+  private boolean isEditorOwner() {
+    return fEditor != null;
+  }    
 }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/GotoMatchingBracketAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/GotoMatchingBracketAction.java
new file mode 100644 (file)
index 0000000..4bd636d
--- /dev/null
@@ -0,0 +1,32 @@
+package net.sourceforge.phpdt.ui.actions;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+import net.sourceforge.phpdt.internal.corext.Assert;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditorMessages;
+
+import org.eclipse.jface.action.Action;
+
+
+public class GotoMatchingBracketAction extends Action {
+
+       public final static String GOTO_MATCHING_BRACKET= "GotoMatchingBracket"; //$NON-NLS-1$
+       
+       private final PHPEditor fEditor;
+       
+       public GotoMatchingBracketAction(PHPEditor editor) {
+               super(PHPEditorMessages.getString("GotoMatchingBracket.label"));
+               Assert.isNotNull(editor);
+               fEditor= editor;
+               setEnabled(null != fEditor);
+       }
+       
+       public void run() {
+               fEditor.gotoMatchingBracket();
+       }
+       
+}
\ No newline at end of file
index aab8e47..72fc67e 100644 (file)
@@ -9,4 +9,13 @@ public interface PHPEditorActionDefinitionIds {
         * Value: net.sourceforge.phpeclipse.phpeditor.uncomment
         */
        public static final String UNCOMMENT = "net.sourceforge.phpdt.ui.actions.uncomment";
+       
+  // navigate
+       
+  /**
+   * Action definition ID of the navigate -> open action
+   * (value <code>"org.phpeclipse.phpdt.ui.edit.text.php.open.editor"</code>).
+   */
+  public static final String OPEN_EDITOR= "net.sourceforge.phpeclipse.ui.edit.text.php.open.editor"; //$NON-NLS-1$
+
 }
index 0709883..0b9bf6b 100644 (file)
@@ -49,5 +49,29 @@ public class PHPdtActionConstants {
    * phpeclipse.phpdt.ui.actions.Format"</code>).
    */
   public static final String FORMAT = "net.sourceforge.phpeclipse.phpeditor.Format"; //$NON-NLS-1$
+  
+  /**
+   * Source menu: name of standard Convert Line Delimiters To Windows global action
+   * (value <code>"org.phpeclipse.phpdt.ui.actions.ConvertLineDelimitersToWindows"</code>).
+   */
+  public static String CONVERT_LINE_DELIMITERS_TO_WINDOWS= "net.sourceforge.phpeclipse.ui.actions.ConvertLineDelimitersToWindows"; //$NON-NLS-1$
+
+  /**
+   * Source menu: name of standard Convert Line Delimiters To UNIX global action
+   * (value <code>"org.phpeclipse.phpdt.ui.actions.ConvertLineDelimitersToUNIX"</code>).
+   */
+  public static String CONVERT_LINE_DELIMITERS_TO_UNIX= "net.sourceforge.phpeclipse.ui.actions.ConvertLineDelimitersToUNIX"; //$NON-NLS-1$
+
+  /**
+   * Source menu: name of standardConvert Line Delimiters ToMac global action
+   * (value <code>"org.phpeclipse.phpdt.ui.actions.ConvertLineDelimitersToMac"</code>).
+   */
+  public static String CONVERT_LINE_DELIMITERS_TO_MAC= "net.sourceforge.phpeclipse.ui.actions.ConvertLineDelimitersToMac"; //$NON-NLS-1$
+
+  /**
+   * Navigate menu: name of standard Open global action
+   * (value <code>"org.phpeclipse.phpdt.ui.actions.Open"</code>).
+   */
+  public static final String OPEN= "net.sourceforge.phpeclipse.ui.actions.Open"; //$NON-NLS-1$
 
 }
index 587bc9d..999ec19 100644 (file)
@@ -12,10 +12,17 @@ Contributors:
     Klaus Hartlage - www.eclipseproject.de
 **********************************************************************/
 
-import net.sourceforge.phpdt.ui.IContextMenuConstants;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction;
 import net.sourceforge.phpdt.ui.actions.PHPdtActionConstants;
 
+import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
 import org.eclipse.jface.action.Separator;
 import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.IEditorPart;
@@ -24,19 +31,22 @@ import org.eclipse.ui.actions.ActionGroup;
 import org.eclipse.ui.actions.RetargetAction;
 import org.eclipse.ui.texteditor.BasicTextEditorActionContributor;
 import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
 import org.eclipse.ui.texteditor.RetargetTextEditorAction;
 
 /**
  * Contributes interesting PHP actions to the desktop's Edit menu and the toolbar.
  */
-public class PHPActionContributor extends BasicTextEditorActionContributor   {
+public class PHPActionContributor extends BasicTextEditorActionContributor {
 
   // protected RetargetTextEditorAction fContentAssistTip;
   // protected TextEditorAction fTogglePresentation;
   protected RetargetAction fRetargetContentAssist;
-       
+
   protected RetargetTextEditorAction fContentAssist;
-  
+  private RetargetTextEditorAction fGotoMatchingBracket;
+  private List fRetargetToolbarActions = new ArrayList();
+
   protected PHPParserAction parserAction;
 
   /**
@@ -44,40 +54,77 @@ public class PHPActionContributor extends BasicTextEditorActionContributor   {
    */
   public PHPActionContributor() {
     super();
-    
-       fRetargetContentAssist= new RetargetAction(PHPdtActionConstants.CONTENT_ASSIST,  PHPEditorMessages.getString("ContentAssistProposal.label")); //$NON-NLS-1$
-       fRetargetContentAssist.setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
-               
-       fContentAssist= new RetargetTextEditorAction(PHPEditorMessages.getResourceBundle(), "ContentAssistProposal."); //$NON-NLS-1$
-       fContentAssist.setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); 
-//     fContentAssist.setImageDescriptor(JavaPluginImages.DESC_CLCL_CODE_ASSIST);
-//     fContentAssist.setDisabledImageDescriptor(JavaPluginImages.DESC_DLCL_CODE_ASSIST);
-
-    
+
+    ResourceBundle b = PHPEditorMessages.getResourceBundle();
+
+    fRetargetContentAssist = new RetargetAction(PHPdtActionConstants.CONTENT_ASSIST, PHPEditorMessages.getString("ContentAssistProposal.label")); //$NON-NLS-1$
+    fRetargetContentAssist.setActionDefinitionId(
+      PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+
+    fContentAssist = new RetargetTextEditorAction(b, "ContentAssistProposal."); //$NON-NLS-1$
+    fContentAssist.setActionDefinitionId(
+      PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+
+    fGotoMatchingBracket = new RetargetTextEditorAction(b, "GotoMatchingBracket."); //$NON-NLS-1$
+    fGotoMatchingBracket.setActionDefinitionId(
+      PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
+
+    // fContentAssist.setImageDescriptor(JavaPluginImages.DESC_CLCL_CODE_ASSIST);
+    // fContentAssist.setDisabledImageDescriptor(JavaPluginImages.DESC_DLCL_CODE_ASSIST);
+
     // fContentAssist = new RetargetTextEditorAction(PHPEditorMessages.getResourceBundle(), "ContentAssistProposal."); //$NON-NLS-1$
     //  fContentAssistTip = new RetargetTextEditorAction(PHPEditorMessages.getResourceBundle(), "ContentAssistTip."); //$NON-NLS-1$
     //  fTogglePresentation = new PresentationAction();
-    
-       
+
     parserAction = PHPParserAction.getInstance();
   }
 
   /*
    * @see EditorActionBarContributor#contributeToMenu(IMenuManager)
    */
-//  public void contributeToMenu(IMenuManager menu) {
-//             
-//       super.contributeToMenu(menu);
-//             
-//       IMenuManager editMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
-//       if (editMenu != null) {
-//               editMenu.add(new Separator(IContextMenuConstants.GROUP_OPEN));
-//               editMenu.add(new Separator(IContextMenuConstants.GROUP_GENERATE));
-//                     
-//               editMenu.appendToGroup(IContextMenuConstants.GROUP_GENERATE, fRetargetContentAssist);
-//       }             
-//  }
-  
+  //  public void contributeToMenu(IMenuManager menu) {                
+  //    super.contributeToMenu(menu);
+  //    IMenuManager editMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
+  //    if (editMenu != null) {
+  //      MenuManager structureSelection= new MenuManager(JavaEditorMessages.getString("ExpandSelectionMenu.label")); //$NON-NLS-1$
+  //      structureSelection.add(fStructureSelectEnclosingAction);
+  //      structureSelection.add(fStructureSelectNextAction);
+  //      structureSelection.add(fStructureSelectPreviousAction);
+  //      structureSelection.add(fStructureSelectHistoryAction);
+  //      editMenu.appendToGroup(IContextMenuConstants.GROUP_OPEN, structureSelection);
+  //      editMenu.appendToGroup(IContextMenuConstants.GROUP_OPEN, fGotoPreviousMemberAction);
+  //      editMenu.appendToGroup(IContextMenuConstants.GROUP_OPEN, fGotoNextMemberAction);
+  //      editMenu.appendToGroup(IContextMenuConstants.GROUP_OPEN, fGotoMatchingBracket);
+
+  //      editMenu.appendToGroup(IContextMenuConstants.GROUP_GENERATE, fShowOutline);
+  //    }
+  //  }
+  /*
+   * @see EditorActionBarContributor#contributeToMenu(IMenuManager)
+   */
+  //  public void contributeToMenu(IMenuManager menu) {
+  //           
+  //     super.contributeToMenu(menu);
+  //           
+  //     IMenuManager editMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
+  //     if (editMenu != null) {
+  //             editMenu.add(new Separator(IContextMenuConstants.GROUP_OPEN));
+  //             editMenu.add(new Separator(IContextMenuConstants.GROUP_GENERATE));
+  //                   
+  //             editMenu.appendToGroup(IContextMenuConstants.GROUP_GENERATE, fRetargetContentAssist);
+  //     }             
+  //  }
+
+  /*
+   * @see EditorActionBarContributor#contributeToToolBar(IToolBarManager)
+   */
+  public void contributeToToolBar(IToolBarManager tbm) {
+    tbm.add(new Separator());
+    Iterator e = fRetargetToolbarActions.iterator();
+    while (e.hasNext())
+      tbm.add((IAction) e.next());
+  }
+
   /*
    * @see IEditorActionBarContributor#init(IActionBars)
    */
@@ -85,14 +132,19 @@ public class PHPActionContributor extends BasicTextEditorActionContributor   {
     super.init(bars);
 
     IMenuManager menuManager = bars.getMenuManager();
-    IMenuManager editMenu = menuManager.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
+    IMenuManager editMenu =
+      menuManager.findMenuUsingPath(IWorkbenchActionConstants.M_EDIT);
     if (editMenu != null) {
       editMenu.add(new Separator());
       editMenu.add(fContentAssist);
+      editMenu.add(fGotoMatchingBracket);
+      
       //   editMenu.add(fContentAssistTip);
     }
 
-       bars.setGlobalActionHandler(PHPdtActionConstants.CONTENT_ASSIST, fContentAssist);
+    bars.setGlobalActionHandler(
+      PHPdtActionConstants.CONTENT_ASSIST,
+      fContentAssist);
     //    IToolBarManager toolBarManager = bars.getToolBarManager();
     //    if (toolBarManager != null) {
     //      toolBarManager.add(new Separator());
@@ -109,15 +161,23 @@ public class PHPActionContributor extends BasicTextEditorActionContributor   {
 
     fContentAssist.setAction(getAction(textEditor, "ContentAssistProposal")); //$NON-NLS-1$
     //  fContentAssistTip.setAction(getAction(editor, "ContentAssistTip")); //$NON-NLS-1$
-    
+    fGotoMatchingBracket.setAction(
+      getAction(textEditor, GotoMatchingBracketAction.GOTO_MATCHING_BRACKET));
+
     IActionBars bars = getActionBars();
-    bars.setGlobalActionHandler(PHPdtActionConstants.COMMENT, getAction(textEditor, "Comment"));
-    bars.setGlobalActionHandler(PHPdtActionConstants.UNCOMMENT, getAction(textEditor, "Uncomment"));
-    bars.setGlobalActionHandler(PHPdtActionConstants.FORMAT, getAction(textEditor, "Format"));
-    
+    bars.setGlobalActionHandler(
+      PHPdtActionConstants.COMMENT,
+      getAction(textEditor, "Comment"));
+    bars.setGlobalActionHandler(
+      PHPdtActionConstants.UNCOMMENT,
+      getAction(textEditor, "Uncomment"));
+    bars.setGlobalActionHandler(
+      PHPdtActionConstants.FORMAT,
+      getAction(textEditor, "Format"));
+
     if (part instanceof PHPEditor) {
-      PHPEditor cuEditor= (PHPEditor)part;
-      ActionGroup group= cuEditor.getActionGroup();
+      PHPEditor cuEditor = (PHPEditor) part;
+      ActionGroup group = cuEditor.getActionGroup();
       if (group != null)
         group.fillActionBars(bars);
     }
@@ -132,7 +192,7 @@ public class PHPActionContributor extends BasicTextEditorActionContributor   {
    * @see IEditorActionBarContributor#setActiveEditor(IEditorPart)
    */
   public void setActiveEditor(IEditorPart part) {
-    doSetActiveEditor(part);   
+    doSetActiveEditor(part);
   }
 
   /*
index 479f880..ed60680 100644 (file)
@@ -12,7 +12,9 @@ Contributors:
     Klaus Hartlage - www.eclipseproject.de
 **********************************************************************/
 import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup;
+import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
 import net.sourceforge.phpdt.ui.actions.GenerateActionGroup;
+import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction;
 import net.sourceforge.phpeclipse.IPreferenceConstants;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner;
@@ -25,8 +27,13 @@ import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension3;
+import org.eclipse.jface.text.Region;
 import org.eclipse.jface.text.source.AnnotationRulerColumn;
 import org.eclipse.jface.text.source.CompositeRuler;
 import org.eclipse.jface.text.source.ISourceViewer;
@@ -35,6 +42,8 @@ import org.eclipse.jface.text.source.IVerticalRulerColumn;
 import org.eclipse.jface.text.source.LineNumberRulerColumn;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.RGB;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.actions.ActionContext;
@@ -42,6 +51,7 @@ import org.eclipse.ui.actions.ActionGroup;
 import org.eclipse.ui.editors.text.TextEditor;
 import org.eclipse.ui.texteditor.ContentAssistAction;
 import org.eclipse.ui.texteditor.DefaultRangeIndicator;
+import org.eclipse.ui.texteditor.IEditorStatusLine;
 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
 import org.eclipse.ui.texteditor.TextOperationAction;
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
@@ -49,12 +59,15 @@ import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
  * PHP specific text editor.
  */
 public class PHPEditor extends TextEditor {
+// extends StatusTextEditor implements IViewPartInputProvider  { // extends TextEditor {
 
   // protected PHPActionGroup fActionGroups;
   /** The outline page */
   private PHPContentOutlinePage fOutlinePage;
   private IPreferenceStore phpPrefStore;
 
+  /** The editor's bracket matcher */
+  private PHPPairMatcher fBracketMatcher;
   /** The line number ruler column */
   private LineNumberRulerColumn fLineNumberRulerColumn;
 
@@ -67,6 +80,7 @@ public class PHPEditor extends TextEditor {
    */
   public PHPEditor() {
     super();
+    setEditorContextMenuId("#PHPEditorContext"); //$NON-NLS-1$
     setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$
   }
   //
@@ -127,9 +141,6 @@ public class PHPEditor extends TextEditor {
       PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
     setAction("ContentAssistProposal", action); //$NON-NLS-1$
 
-    // System.out.println(action.getId());
-    // System.out.println(action.getActionDefinitionId());
-
     setAction(
       "ContentAssistTip",
       new TextOperationAction(
@@ -147,9 +158,6 @@ public class PHPEditor extends TextEditor {
     action.setActionDefinitionId(PHPEditorActionDefinitionIds.COMMENT);
     setAction("Comment", action);
 
-    // System.out.println(action.getId());
-    // System.out.println(action.getActionDefinitionId());
-
     action =
       new TextOperationAction(
         PHPEditorMessages.getResourceBundle(),
@@ -159,20 +167,20 @@ public class PHPEditor extends TextEditor {
     action.setActionDefinitionId(PHPEditorActionDefinitionIds.UNCOMMENT);
     setAction("Uncomment", action);
 
-    action = new TextOperationAction(
-        PHPEditorMessages.getResourceBundle(), "Format.", this, ISourceViewer.FORMAT); //$NON-NLS-1$
+    action = new TextOperationAction(PHPEditorMessages.getResourceBundle(), "Format.", this, ISourceViewer.FORMAT); //$NON-NLS-1$
     action.setActionDefinitionId(PHPEditorActionDefinitionIds.FORMAT);
     setAction("Format", action); //$NON-NLS-1$
-    
-    // System.out.println(action.getId());
-    // System.out.println(action.getActionDefinitionId());
-
-    //  fActionGroups = new PHPActionGroup(this, ITextEditorActionConstants.GROUP_EDIT);
 
+    markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$
     markAsStateDependentAction("Comment", true); //$NON-NLS-1$
     markAsStateDependentAction("Uncomment", true); //$NON-NLS-1$
     markAsStateDependentAction("Format", true); //$NON-NLS-1$
-    
+
+    action = new GotoMatchingBracketAction(this);
+    action.setActionDefinitionId(
+      PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
+    setAction(GotoMatchingBracketAction.GOTO_MATCHING_BRACKET, action);
+
     fGenerateActionGroup =
       new GenerateActionGroup(this, ITextEditorActionConstants.GROUP_EDIT);
 
@@ -248,18 +256,22 @@ public class PHPEditor extends TextEditor {
       fOutlinePage.setInput(input);
   }
 
+  /*
+   * @see org.phpeclipse.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput()
+   */
+//  public Object getViewPartInput() {
+//    return getEditorInput().getAdapter(IFile.class);
+//  }
+  
   /** The <code>PHPEditor</code> implementation of this 
    * <code>AbstractTextEditor</code> method adds any 
    * PHPEditor specific entries.
    */
   public void editorContextMenuAboutToShow(MenuManager menu) {
     super.editorContextMenuAboutToShow(menu);
-    //  addAction(menu, "ContentAssistProposal"); //$NON-NLS-1$
-    //  addAction(menu, "ContentAssistTip"); //$NON-NLS-1$
-    addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "Format"); //$NON-NLS-1$ 
-    
-    // fActionGroups.fillContextMenu(menu);
-    
+
+    addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "Format"); //$NON-NLS-1$
+
     ActionContext context =
       new ActionContext(getSelectionProvider().getSelection());
     fContextMenuGroup.setContext(context);
@@ -471,7 +483,7 @@ public class PHPEditor extends TextEditor {
   }
 
   /* (non-Javadoc)
-   * Method declared on AbstractTextEditor
+   * Method declared on TextEditor
    */
   protected void initializeEditor() {
     PHPEditorEnvironment.connect(this);
@@ -504,4 +516,126 @@ public class PHPEditor extends TextEditor {
       }
     });
   }
+  
+  private static IRegion getSignedSelection(ITextViewer viewer) {
+
+    StyledText text = viewer.getTextWidget();
+    int caretOffset = text.getCaretOffset();
+    Point selection = text.getSelection();
+
+    // caret left
+    int offset, length;
+    if (caretOffset == selection.x) {
+      offset = selection.y;
+      length = selection.x - selection.y;
+
+      // caret right
+    } else {
+      offset = selection.x;
+      length = selection.y - selection.x;
+    }
+
+    return new Region(offset, length);
+  }
+
+  private final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' };
+
+  private static boolean isBracket(char character) {
+    for (int i = 0; i != BRACKETS.length; ++i)
+      if (character == BRACKETS[i])
+        return true;
+    return false;
+  }
+
+  private static boolean isSurroundedByBrackets(
+    IDocument document,
+    int offset) {
+    if (offset == 0 || offset == document.getLength())
+      return false;
+
+    try {
+      return isBracket(document.getChar(offset - 1))
+        && isBracket(document.getChar(offset));
+
+    } catch (BadLocationException e) {
+      return false;
+    }
+  }
+  /**
+    * Jumps to the matching bracket.
+    */
+  public void gotoMatchingBracket() {
+
+    if (fBracketMatcher == null)
+      fBracketMatcher = new PHPPairMatcher(BRACKETS);
+
+    ISourceViewer sourceViewer = getSourceViewer();
+    IDocument document = sourceViewer.getDocument();
+    if (document == null)
+      return;
+
+    IRegion selection = getSignedSelection(sourceViewer);
+
+    int selectionLength = Math.abs(selection.getLength());
+    if (selectionLength > 1) {
+      setStatusLineErrorMessage(PHPEditorMessages.getString("GotoMatchingBracket.error.invalidSelection")); //$NON-NLS-1$              
+      sourceViewer.getTextWidget().getDisplay().beep();
+      return;
+    }
+
+    // #26314
+    int sourceCaretOffset = selection.getOffset() + selection.getLength();
+    if (isSurroundedByBrackets(document, sourceCaretOffset))
+      sourceCaretOffset -= selection.getLength();
+
+    IRegion region = fBracketMatcher.match(document, sourceCaretOffset);
+    if (region == null) {
+      setStatusLineErrorMessage(PHPEditorMessages.getString("GotoMatchingBracket.error.noMatchingBracket")); //$NON-NLS-1$             
+      sourceViewer.getTextWidget().getDisplay().beep();
+      return;
+    }
+
+    int offset = region.getOffset();
+    int length = region.getLength();
+
+    if (length < 1)
+      return;
+
+    int anchor = fBracketMatcher.getAnchor();
+    int targetOffset =
+      (PHPPairMatcher.RIGHT == anchor) ? offset : offset + length - 1;
+
+    boolean visible = false;
+    if (sourceViewer instanceof ITextViewerExtension3) {
+      ITextViewerExtension3 extension = (ITextViewerExtension3) sourceViewer;
+      visible = (extension.modelOffset2WidgetOffset(targetOffset) > -1);
+    } else {
+      IRegion visibleRegion = sourceViewer.getVisibleRegion();
+      visible =
+        (targetOffset >= visibleRegion.getOffset()
+          && targetOffset < visibleRegion.getOffset() + visibleRegion.getLength());
+    }
+
+    if (!visible) {
+      setStatusLineErrorMessage(PHPEditorMessages.getString("GotoMatchingBracket.error.bracketOutsideSelectedElement")); //$NON-NLS-1$         
+      sourceViewer.getTextWidget().getDisplay().beep();
+      return;
+    }
+
+    if (selection.getLength() < 0)
+      targetOffset -= selection.getLength();
+
+    sourceViewer.setSelectedRange(targetOffset, selection.getLength());
+    sourceViewer.revealRange(targetOffset, selection.getLength());
+  }
+  /**
+     * Ses the given message as error message to this editor's status line.
+     * @param msg message to be set
+     */
+  protected void setStatusLineErrorMessage(String msg) {
+    IEditorStatusLine statusLine =
+      (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
+    if (statusLine != null)
+      statusLine.setMessage(true, msg, null);
+  }
 }
index 2a236ab..fb97a56 100644 (file)
@@ -1,6 +1,14 @@
 package net.sourceforge.phpeclipse.phpeditor;
 
 public interface PHPEditorActionDefinitionIds {
+  /**
+   * Action definition ID of the edit -> go to matching bracket action
+   * (value <code>"org.phpeclipse.phpdt.ui.edit.text.php.goto.matching.bracket"</code>).
+   *
+   * @since 2.1
+   */
+  public static final String GOTO_MATCHING_BRACKET= "net.sourceforge.phpeclipse.ui.edit.text.php.goto.matching.bracket"; //$NON-NLS-1$
+
        /**
         * Value: net.sourceforge.phpeclipse.phpeditor.comment
         */
index 87fb2bb..d79bc16 100644 (file)
@@ -42,3 +42,11 @@ ParserAction.label=Parse the PHP file
 ParserAction.tooltip=Parse the current PHP file
 ParserAction.image=java.gif
 ParserAction.description=Parse the current PHP file
+
+
+GotoMatchingBracket.label=Go to Matching &Bracket
+GotoMatchingBracket.tooltip=Go to Matching Bracket
+GotoMatchingBracket.description=Go to Matching Bracket
+GotoMatchingBracket.error.invalidSelection=No bracket selected
+GotoMatchingBracket.error.noMatchingBracket=No matching bracket found
+GotoMatchingBracket.error.bracketOutsideSelectedElement=Matching bracket is outside of selected element
index 3bfd969..6f5c592 100644 (file)
@@ -367,13 +367,13 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
 
     //    try {
     //
-    //      JavaCodeReader reader= new JavaCodeReader();
+    //      PHPCodeReader reader= new PHPCodeReader();
     //      reader.configureBackwardReader(document, offset, true, true);
     //  
     //      int nestingLevel= 0;
     //
     //      int curr= reader.read();    
-    //      while (curr != JavaCodeReader.EOF) {
+    //      while (curr != PHPCodeReader.EOF) {
     //
     //        if (')' == (char) curr)
     //          ++ nestingLevel;