new PartitionScanner version
authorjsurfer <jsurfer>
Thu, 2 Sep 2004 18:32:47 +0000 (18:32 +0000)
committerjsurfer <jsurfer>
Thu, 2 Sep 2004 18:32:47 +0000 (18:32 +0000)
43 files changed:
net.sourceforge.phpeclipse/plugin.xml
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/Compiler.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/PHPDocCharArrayCommentReader.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/PHPDocUtil.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/phpdoc/SingleCharReader.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/CodeFormatter.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/impl/SplitLine.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/EditTemplateDialog.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/PHPEditorPreferencePage.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/TemplatePreferencePage.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/BufferedDocumentScanner.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/FastJavaPartitionScanner.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/IPHPPartitions.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/SmartSemicolonAutoEditStrategy.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/folding/DefaultJavaFoldingPreferenceBlock.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaStringAutoIndentStrategy.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaInformationProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/SourceViewerInformationControl.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/phpdoc/PHPDocCodeScanner.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationEngine.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/DeclarationProposal.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/JavaTextTools.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/PHPSourceViewerConfiguration.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaDocumentSetupParticipant.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaSourceViewer.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/JavaStorageDocumentProvider.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSourceViewerConfiguration.java [deleted file]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPTextHover.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormatter.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/html/HTMLFormattingStrategy.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/DefaultPHPPartitioner_delete_it.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLPartitionScanner.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDocumentPartitioner.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/views/browser/BrowserView.java

index dc3e02e..9b3a053 100644 (file)
@@ -34,6 +34,9 @@
       <import plugin="org.eclipse.update.ui"/>
       <import plugin="net.sourceforge.phpeclipse.quantum.sql"/> 
       <import plugin="net.sourceforge.phpeclipse.webbrowser"/>
+      <import plugin="net.sourceforge.phpeclipse.core"/>
+      <import plugin="net.sourceforge.phpeclipse.ui"/>
+      <import plugin="net.sourceforge.phpeclipse.xml.ui"/>
    </requires>
 
    <extension
             type="text"
             extension="phtml">
       </fileTypes>
-      <fileTypes
+  <!--    <fileTypes
             type="text"
             extension="html">
       </fileTypes>
       <fileTypes
             type="text"
             extension="xml">
-      </fileTypes>
+      </fileTypes> 
       <fileTypes
             type="text"
             extension="tpl">
-      </fileTypes>
+      </fileTypes> -->
    </extension>
    
    <extension
             symbolicFontName="net.sourceforge.phpdt.ui.editors.textfont"
             id="net.sourceforge.phpeclipse.PHPUnitEditor">
       </editor>
-      <editor
+ <!--     <editor
             name="%phpEditorName"
             default="true"
             icon="icons/obj16/htmledit.gif"
             class="net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor"
             symbolicFontName="net.sourceforge.phpdt.ui.editors.textfont"
             id="net.sourceforge.phpeclipse.PHPUnitEditor">
-      </editor>
+      </editor> -->
    </extension>
       <extension
          point="org.eclipse.ui.fontDefinitions">
             extensions="php,php3,php4,php5,module,inc,phtml"
             class="net.sourceforge.phpeclipse.phpeditor.JavaDocumentSetupParticipant">
       </participant>
-      <participant
+   <!--   <participant
             extensions="html,xml"
             class="net.sourceforge.phpeclipse.phpeditor.HTMLDocumentSetupParticipant">
       </participant>
       <participant
             extensions="tpl"
             class="net.sourceforge.phpeclipse.phpeditor.SmartyDocumentSetupParticipant">
-      </participant>
+      </participant> -->
    </extension>
    <extension
          id="net.sourceforge.phpeclipse.JavaDocumentFactory"
          point="org.eclipse.ui.preferencePages">
       <page
             name="PHP"
+            category="net.sourceforge.phpeclipse.ui.preferencePage"
             class="net.sourceforge.phpeclipse.PHPEclipseBasePreferencePage"
             id="net.sourceforge.phpeclipse.preference.PHPEclipsePreferencePage">
       </page>
             id="net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider">
       </provider>
    </extension>
-   <extension
+<!--  <extension
          point="org.eclipse.ui.editors.documentProviders">
       <provider
             extensions="%htmlFileExtension"
             class="net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider"
             id="net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider">
       </provider>
-   </extension>
+   </extension> -->
    <extension
          point="org.eclipse.ui.views">
       <category
index ea02cbb..07d33a0 100644 (file)
@@ -165,7 +165,7 @@ public class Compiler implements ITypeRequestor, ProblemSeverities {
    * @param parseLiteralExpressionsAsConstants
    *            <code>boolean</code> This parameter is used to optimize the
    *            literals or leave them as they are in the source. If you put
-   *            true, "Hello" + " world" will be converted to "Hello world".
+   *            true, "Hello" . " world" will be converted to "Hello world".
    */
   public Compiler(INameEnvironment environment, IErrorHandlingPolicy policy,
       Map settings, final ICompilerRequestor requestor,
index f30009d..939f999 100644 (file)
@@ -2467,13 +2467,15 @@ public class Parser //extends PHPParserSuperclass
     //| static_member '(' function_call_parameter_list ')'
     //| variable_without_objects '(' function_call_parameter_list ')'
     char[] defineName = null;
+    char[] ident = null;
     int startPos=0;
     int endPos=0;
     if (Scanner.TRACE) {
       System.out.println("TRACE: function_call()");
     }
     if (token == TokenNameIdentifier) {
-      defineName = scanner.getCurrentIdentifierSource();
+      ident = scanner.getCurrentIdentifierSource();
+      defineName = ident;
       startPos = scanner.getCurrentTokenStartPosition();
       endPos = scanner.getCurrentTokenEndPosition();
       getNextToken();
@@ -2545,7 +2547,13 @@ public class Parser //extends PHPParserSuperclass
     }
     non_empty_function_call_parameter_list();
     if (token != TokenNameRPAREN) {
-      throwSyntaxError("')' expected in function call.");
+      String functionName;
+      if (ident==null) {
+        functionName = new String(" ");
+      } else {
+        functionName = new String(ident);
+      }
+      throwSyntaxError("')' expected in function call ("+functionName+").");
     }
     getNextToken();
   }
index 4816997..5a06b54 100644 (file)
@@ -46,7 +46,7 @@ public class PHPDocCharArrayCommentReader extends SingleCharReader {
       if (fWasNewLine) {
         do {
           ch = fCharArray[fCurrPos++];
-        } while (fCurrPos < fEndPos && Character.isWhitespace(ch));
+        } while (fCurrPos < fEndPos &&Character.isWhitespace(ch));
         if (ch == '*') {
           if (fCurrPos < fEndPos) {
             do {
index 900d535..1ef819f 100644 (file)
@@ -33,7 +33,7 @@ public class PHPDocUtil {
         phpFileReader.read(phpDocDeclarationCharArray, 0, location.getPHPDocLength());
         PHPDocCharArrayCommentReader phpdocConverter = new PHPDocCharArrayCommentReader(phpDocDeclarationCharArray);
         hoverInfoBuffer.append(phpdocConverter.getString());
-        hoverInfoBuffer.append("<br><br>");
+//        hoverInfoBuffer.append("<br><br>");
         phpFileReader.close();
       }
 
index 87340b4..6bd996e 100644 (file)
@@ -54,7 +54,11 @@ public abstract class SingleCharReader extends Reader {
                StringBuffer buf= new StringBuffer();
                int ch;
                while ((ch= read()) != -1) {
-                       buf.append((char)ch);
+                   if (ch=='\n'||ch=='\r') {
+                     buf.append("<br>");
+                   } else {
+                         buf.append((char)ch);
+                   }
                }
                return buf.toString();
        }
index e4ec3cf..420ed30 100644 (file)
@@ -9,6 +9,7 @@
  *     IBM Corporation - initial API and implementation
  ******************************************************************************/
 package net.sourceforge.phpdt.internal.formatter;
+
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.StringReader;
@@ -31,85 +32,107 @@ import net.sourceforge.phpdt.internal.ui.preferences.CodeFormatterPreferencePage
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.formatter.IContentFormatterExtension;
 import org.eclipse.jface.text.formatter.IFormattingContext;
+
 /**
  * <h2>How to format a piece of code ?</h2>
  * <ul>
  * <li>Create an instance of <code>CodeFormatter</code>
- * <li>Use the method <code>void format(aString)</code> on this instance to
- * format <code>aString</code>. It will return the formatted string.
+ * <li>Use the method <code>void format(aString)</code> on this instance to format <code>aString</code>. It will return the
+ * formatted string.
  * </ul>
  */
 public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
- // IContentFormatterExtension {
+  // IContentFormatterExtension {
   public FormatterOptions options;
+
   /**
    * Represents a block in the <code>constructions</code> stack.
    */
   public static final int BLOCK = ITerminalSymbols.TokenNameLBRACE;
+
   /**
-   * Represents a block following a control statement in the <code>constructions</code>
-   * stack.
+   * 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.
+   * 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).
+   * Level of indentation of the current token (number of tab char put in front of it).
    */
   private int indentationLevel;
+
   /**
    * Regular level of indentation of all the lines
    */
   private int initialIndentationLevel;
+
   /**
    * Used to split a line.
    */
   Scanner splitScanner;
+
   /**
-   * To remember the offset between the beginning of the line and the beginning
-   * of the comment.
+   * To remember the offset between the beginning of the line and the beginning of the comment.
    */
   int currentCommentOffset;
+
   int currentLineIndentationLevel;
+
   int maxLineSize = 30;
+
   private boolean containsOpenCloseBraces;
+
   private int indentationLevelForOpenCloseBraces;
+
   /**
    * 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.
    * 
@@ -118,15 +141,16 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   public CodeFormatter(ConfigurableOption[] settings) {
     this(convertConfigurableOptions(settings));
   }
+
   /**
-   * Creates a new instance of Code Formatter using the FormattingOptions
-   * object given as argument
+   * Creates a new instance of Code Formatter using the FormattingOptions object given as argument
    * 
    * @deprecated Use CodeFormatter(ConfigurableOption[]) instead
    */
   public CodeFormatter() {
     this((Map) null);
   }
+
   /**
    * Creates a new instance of Code Formatter using the given settings.
    */
@@ -156,20 +180,21 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     currentLineBuffer = new StringBuffer();
     this.options = new FormatterOptions(settings);
   }
+
   /**
-   * Returns true if a lineSeparator has to be inserted before <code>operator</code>
-   * false otherwise.
+   * Returns true if a lineSeparator has to be inserted before <code>operator</code> false otherwise.
    */
   private static boolean breakLineBeforeOperator(int operator) {
     switch (operator) {
-      case TokenNameCOMMA :
-      case TokenNameSEMICOLON :
-      case TokenNameEQUAL :
-        return false;
-      default :
-        return true;
+    case TokenNameCOMMA:
+    case TokenNameSEMICOLON:
+    case TokenNameEQUAL:
+      return false;
+    default:
+      return true;
     }
   }
+
   /**
    * @deprecated backport 1.0 internal functionality
    */
@@ -180,40 +205,30 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         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$
+          options.put("net.sourceforge.phpdt.core.formatter.newline.openingBrace", valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         } else if (optionName.equals("newline.controlStatement")) { //$NON-NLS-1$
-          options.put(
-              "net.sourceforge.phpdt.core.formatter.newline.controlStatement",
-              valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+          options
+              .put("net.sourceforge.phpdt.core.formatter.newline.controlStatement", valueIndex == 0 ? "insert" : "do not insert"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         } else if (optionName.equals("newline.clearAll")) { //$NON-NLS-1$
-          options.put("net.sourceforge.phpdt.core.formatter.newline.clearAll",
-              valueIndex == 0 ? "clear all" : "preserve one"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+          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$
+          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$
+          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$
+          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$
+          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$
+          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$
+          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.
    */
@@ -227,9 +242,9 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     }
     return (bufr.toString());
   }
+
   /**
-   * Inserts <code>tabCount</code> tab character or their equivalent number
-   * of spaces.
+   * Inserts <code>tabCount</code> tab character or their equivalent number of spaces.
    */
   private void dumpTab(int tabCount) {
     if (options.indentWithTab) {
@@ -244,6 +259,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       }
     }
   }
+
   /**
    * Dumps <code>currentLineBuffer</code> into the formatted string.
    */
@@ -253,17 +269,14 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     beginningOfLineIndex = formattedSource.length();
     if (containsOpenCloseBraces) {
       containsOpenCloseBraces = false;
-      outputLine(currentString, false, indentationLevelForOpenCloseBraces, 0,
-          -1, null, 0);
+      outputLine(currentString, false, indentationLevelForOpenCloseBraces, 0, -1, null, 0);
       indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
     } else {
-      outputLine(currentString, false, currentLineIndentationLevel, 0, -1,
-          null, 0);
+      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') {
+      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') {
@@ -276,6 +289,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     }
     updateMappedPositions(scanner.startPosition);
   }
+
   /**
    * Formats the input string.
    */
@@ -332,22 +346,21 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           if (Scanner.DEBUG) {
             int currentEndPosition = scanner.getCurrentTokenEndPosition();
             int currentStartPosition = scanner.getCurrentTokenStartPosition();
-            System.out.print(currentStartPosition + "," + currentEndPosition
-                + ": ");
+            System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
             System.out.println(scanner.toStringAction(token));
           }
           // Patch for line comment
           // See PR http://dev.eclipse.org/bugs/show_bug.cgi?id=23096
           if (token == ITerminalSymbols.TokenNameCOMMENT_LINE) {
             int length = scanner.currentPosition;
-            loop : for (int index = length - 1; index >= 0; index--) {
+            loop: for (int index = length - 1; index >= 0; index--) {
               switch (scanner.source[index]) {
-                case '\r' :
-                case '\n' :
-                  scanner.currentPosition--;
-                  break;
-                default :
-                  break loop;
+              case '\r':
+              case '\n':
+                scanner.currentPosition--;
+                break;
+              default:
+                break loop;
               }
             }
           }
@@ -360,8 +373,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         if (token == Scanner.TokenNameEOF)
           break;
         /*
-         * ## MODIFYING the indentation level before generating new lines and
-         * indentation in the output string
+         * ## 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
@@ -369,27 +381,26 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         // switch/case
         if (clearNonBlockIndents && (token != Scanner.TokenNameWHITESPACE)) {
           switch (token) {
-            case TokenNameelse :
-              if (constructionsCount > 0
-                  && constructions[constructionsCount - 1] == TokenNameelse) {
-                pendingNewLines = 1;
-                specialElse = true;
-              }
-              indentationLevel += popInclusiveUntil(TokenNameif);
+          case TokenNameelse:
+            if (constructionsCount > 0 && constructions[constructionsCount - 1] == TokenNameelse) {
+              pendingNewLines = 1;
+              specialElse = true;
+            }
+            indentationLevel += popInclusiveUntil(TokenNameif);
+            break;
+          //                                           case TokenNamecatch :
+          //                                                   indentationLevel += popInclusiveUntil(TokenNamecatch);
+          //                                                   break;
+          //                                           case TokenNamefinally :
+          //                                                   indentationLevel += popInclusiveUntil(TokenNamecatch);
+          //                                                   break;
+          case TokenNamewhile:
+            if (nlicsToken == TokenNamedo) {
+              indentationLevel += pop(TokenNamedo);
               break;
-            //                                         case TokenNamecatch :
-            //                                                 indentationLevel += popInclusiveUntil(TokenNamecatch);
-            //                                                 break;
-            //                                         case TokenNamefinally :
-            //                                                 indentationLevel += popInclusiveUntil(TokenNamecatch);
-            //                                                 break;
-            case TokenNamewhile :
-              if (nlicsToken == TokenNamedo) {
-                indentationLevel += pop(TokenNamedo);
-                break;
-              }
-            default :
-              indentationLevel += popExclusiveUntilBlockOrCase();
+            }
+          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.
@@ -404,8 +415,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         //                             if (token == Scanner.TokenNamethrows) {
         //                                     inThrowsClause = true;
         //                             }
-        if ((token == Scanner.TokenNameclass || token == Scanner.TokenNameinterface)
-            && previousToken != Scanner.TokenNameDOT) {
+        if ((token == Scanner.TokenNameclass || token == Scanner.TokenNameinterface) && previousToken != Scanner.TokenNameDOT) {
           inClassOrInterfaceHeader = true;
         }
         /*
@@ -438,21 +448,17 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           // previous token is a close paren.
           // add a new line if a parenthesis belonging to a for() statement
           // has been closed and the current token is not an opening brace
-          if (token != TokenNameLBRACE
-              && !isComment(token)
-              // to avoid adding new line between else and a comment
-              && token != TokenNameDOT
-              && !(previousCompilableToken == TokenNameRPAREN && token == TokenNameSEMICOLON)) {
+          if (token != TokenNameLBRACE && !isComment(token)
+          // to avoid adding new line between else and a comment
+              && token != TokenNameDOT && !(previousCompilableToken == TokenNameRPAREN && token == TokenNameSEMICOLON)) {
             newLine(1);
             currentLineIndentationLevel = indentationLevel;
             pendingNewLines = 0;
             pendingSpace = false;
           } else {
-            if (token == TokenNameLBRACE
-                && options.newLineBeforeOpeningBraceMode) {
+            if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode) {
               newLine(1);
-              if (constructionsCount > 0
-                  && constructions[constructionsCount - 1] != BLOCK
+              if (constructionsCount > 0 && constructions[constructionsCount - 1] != BLOCK
                   && constructions[constructionsCount - 1] != NONINDENT_BLOCK) {
                 currentLineIndentationLevel = indentationLevel - 1;
               } else {
@@ -463,8 +469,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
             }
           }
         }
-        if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode
-            && constructionsCount > 0
+        if (token == TokenNameLBRACE && options.newLineBeforeOpeningBraceMode && constructionsCount > 0
             && constructions[constructionsCount - 1] == TokenNamedo) {
           newLine(1);
           currentLineIndentationLevel = indentationLevel - 1;
@@ -502,53 +507,42 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
             && 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;
+          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);
+              && (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;
+          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;
+          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;
+          boolean commaAndCloseBrace = previousToken == TokenNameRBRACE && token == TokenNameCOMMA;
           // Add a newline and indent, if appropriate.
           if (specialElse
-              || (!commentAndOpenBrace && !closeBraceAndCloseParen
-                  && !nlicsOption && !semiColonAndCloseBrace && !commaAndCloseBrace)) {
+              || (!commentAndOpenBrace && !closeBraceAndCloseParen && !nlicsOption && !semiColonAndCloseBrace && !commaAndCloseBrace)) {
             // if clearAllBlankLinesMode=false, leaves the blank lines
             // inserted by the user
             // if clearAllBlankLinesMode=true, removes all of then
             // and insert only blank lines required by the formatting.
             if (!options.clearAllBlankLinesMode) {
               //  (isComment(token))
-              pendingNewLines = (pendingNewLines < newLinesInWhitespace)
-                  ? newLinesInWhitespace
-                  : pendingNewLines;
+              pendingNewLines = (pendingNewLines < newLinesInWhitespace) ? newLinesInWhitespace : pendingNewLines;
               pendingNewLines = (pendingNewLines > 2) ? 2 : pendingNewLines;
             }
-            if (previousCompilableToken == TokenNameLBRACE
-                && token == TokenNameRBRACE) {
+            if (previousCompilableToken == TokenNameLBRACE && token == TokenNameRBRACE) {
               containsOpenCloseBraces = true;
               indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
               if (isComment(previousToken)) {
                 newLine(pendingNewLines);
               } else {
                 /*
-                 * if (!(constructionsCount > 1 &&
-                 * constructions[constructionsCount-1] == NONINDENT_BLOCK &&
+                 * if (!(constructionsCount > 1 && constructions[constructionsCount-1] == NONINDENT_BLOCK &&
                  * (constructions[constructionsCount-2] == TokenNamefor
                  */
                 if (options.newLineInEmptyBlockMode) {
@@ -567,8 +561,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
                 newLine(pendingNewLines);
               }
             }
-            if (((previousCompilableToken == TokenNameSEMICOLON)
-                || (previousCompilableToken == TokenNameLBRACE)
+            if (((previousCompilableToken == TokenNameSEMICOLON) || (previousCompilableToken == TokenNameLBRACE)
                 || (previousCompilableToken == TokenNameRBRACE) || (isComment(previousToken)))
                 && (token == TokenNameRBRACE)) {
               indentationOffset = -1;
@@ -578,8 +571,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
               // PR 1FI5IPO
               currentLineIndentationLevel++;
             } else {
-              currentLineIndentationLevel = indentationLevel
-                  + indentationOffset;
+              currentLineIndentationLevel = indentationLevel + indentationOffset;
             }
             pendingSpace = false;
             indentationOffset = 0;
@@ -591,120 +583,108 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
             nlicsToken = 0;
           }
         }
-        boolean phpTagAndWhitespace = 
-           previousToken == TokenNameINLINE_HTML && token == TokenNameWHITESPACE;
+        boolean phpTagAndWhitespace = previousToken == TokenNameINLINE_HTML && token == TokenNameWHITESPACE;
         switch (token) {
-          //          case TokenNameDOLLAR :
-          //            dollarBraceCount++;
-          //            break;
-          case TokenNameelse :
-            //                         case TokenNamefinally :
-            expectingOpenBrace = true;
-            pendingNewlineAfterParen = true;
-            indentationLevel += pushControlStatement(token);
-            break;
-          case TokenNamecase :
-          case TokenNamedefault :
-            if (tokenBeforeColonCount == tokenBeforeColon.length) {
-              System.arraycopy(tokenBeforeColon, 0,
-                  (tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 0,
-                  tokenBeforeColonCount);
-            }
-            tokenBeforeColon[tokenBeforeColonCount++] = TokenNamecase;
-            indentationLevel += pushControlStatement(TokenNamecase);
-            break;
-          case TokenNameQUESTION :
-            if (tokenBeforeColonCount == tokenBeforeColon.length) {
-              System.arraycopy(tokenBeforeColon, 0,
-                  (tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 0,
-                  tokenBeforeColonCount);
-            }
-            tokenBeforeColon[tokenBeforeColonCount++] = token;
-            break;
-          case TokenNameswitch :
-          case TokenNamefor :
-          case TokenNameif :
-          case TokenNamewhile :
-            if (openParenthesisCount == openParenthesis.length) {
-              System.arraycopy(openParenthesis, 0,
-                  (openParenthesis = new int[openParenthesisCount * 2]), 0,
-                  openParenthesisCount);
-            }
-            openParenthesis[openParenthesisCount++] = 0;
-            expectingOpenBrace = true;
-            indentationLevel += pushControlStatement(token);
-            break;
-          case TokenNametry :
-            pendingNewlineAfterParen = true;
-          case TokenNamecatch :
-            // several CATCH statements can be contiguous.
-            // a CATCH is encountered pop until first CATCH (if a CATCH
-            // follows a TRY it works the same way,
-            // as CATCH and TRY are the same token in the stack).
-            expectingOpenBrace = true;
-            indentationLevel += pushControlStatement(TokenNamecatch);
-            break;
-          case TokenNamedo :
-            expectingOpenBrace = true;
-            indentationLevel += pushControlStatement(token);
-            nlicsToken = token;
-            break;
-          case TokenNamenew :
-            break;
-          case TokenNameLPAREN :
-            //                                         if (previousToken == TokenNamesynchronized) {
-            //                                                 indentationLevel += pushControlStatement(previousToken);
-            //                                         } else {
-            // Put a space between the previous and current token if the
-            // previous token was not a keyword, open paren, logical
-            // compliment (eg: !), semi-colon, open brace, close brace,
-            // super, or this.
-            if (previousCompilableToken != TokenNameLBRACKET
-                && previousToken != TokenNameIdentifier && previousToken != 0
-                && previousToken != TokenNameNOT
-                && previousToken != TokenNameLPAREN
-                && previousToken != TokenNameTWIDDLE
-                && previousToken != TokenNameSEMICOLON
-                && previousToken != TokenNameLBRACE
-                && previousToken != TokenNameRBRACE
-                && previousToken != TokenNamesuper) {
-              //       && previousToken != TokenNamethis) {
-              space();
-            }
-            // If in a for/if/while statement, increase the parenthesis count
-            // for the current openParenthesisCount
-            // else increase the count for stand alone parenthesis.
-            if (openParenthesisCount > 0)
-              openParenthesis[openParenthesisCount - 1]++;
-            else
-              openParenthesis[0]++;
-            pendingSpace = false;
-            //S }
-            break;
-          case TokenNameRPAREN :
-            // Decrease the parenthesis count
-            // if there is no more unclosed parenthesis,
-            // a new line and indent may be append (depending on the next
-            // token).
-            if ((openParenthesisCount > 1)
-                && (openParenthesis[openParenthesisCount - 1] > 0)) {
-              openParenthesis[openParenthesisCount - 1]--;
-              if (openParenthesis[openParenthesisCount - 1] <= 0) {
-                pendingNewlineAfterParen = true;
-                inAssignment = false;
-                openParenthesisCount--;
-              }
-            } else {
-              openParenthesis[0]--;
+        //          case TokenNameDOLLAR :
+        //            dollarBraceCount++;
+        //            break;
+        case TokenNameelse:
+          //                           case TokenNamefinally :
+          expectingOpenBrace = true;
+          pendingNewlineAfterParen = true;
+          indentationLevel += pushControlStatement(token);
+          break;
+        case TokenNamecase:
+        case TokenNamedefault:
+          if (tokenBeforeColonCount == tokenBeforeColon.length) {
+            System
+                .arraycopy(tokenBeforeColon, 0, (tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 0, tokenBeforeColonCount);
+          }
+          tokenBeforeColon[tokenBeforeColonCount++] = TokenNamecase;
+          indentationLevel += pushControlStatement(TokenNamecase);
+          break;
+        case TokenNameQUESTION:
+          if (tokenBeforeColonCount == tokenBeforeColon.length) {
+            System
+                .arraycopy(tokenBeforeColon, 0, (tokenBeforeColon = new int[tokenBeforeColonCount * 2]), 0, tokenBeforeColonCount);
+          }
+          tokenBeforeColon[tokenBeforeColonCount++] = token;
+          break;
+        case TokenNameswitch:
+        case TokenNamefor:
+        case TokenNameif:
+        case TokenNamewhile:
+          if (openParenthesisCount == openParenthesis.length) {
+            System.arraycopy(openParenthesis, 0, (openParenthesis = new int[openParenthesisCount * 2]), 0, openParenthesisCount);
+          }
+          openParenthesis[openParenthesisCount++] = 0;
+          expectingOpenBrace = true;
+          indentationLevel += pushControlStatement(token);
+          break;
+        case TokenNametry:
+          pendingNewlineAfterParen = true;
+        case TokenNamecatch:
+          // several CATCH statements can be contiguous.
+          // a CATCH is encountered pop until first CATCH (if a CATCH
+          // follows a TRY it works the same way,
+          // as CATCH and TRY are the same token in the stack).
+          expectingOpenBrace = true;
+          indentationLevel += pushControlStatement(TokenNamecatch);
+          break;
+        case TokenNamedo:
+          expectingOpenBrace = true;
+          indentationLevel += pushControlStatement(token);
+          nlicsToken = token;
+          break;
+        case TokenNamenew:
+          break;
+        case TokenNameLPAREN:
+          //                                           if (previousToken == TokenNamesynchronized) {
+          //                                                   indentationLevel += pushControlStatement(previousToken);
+          //                                           } else {
+          // Put a space between the previous and current token if the
+          // previous token was not a keyword, open paren, logical
+          // compliment (eg: !), semi-colon, open brace, close brace,
+          // super, or this.
+          if (previousCompilableToken != TokenNameLBRACKET && previousToken != TokenNameIdentifier && previousToken != 0
+              && previousToken != TokenNameNOT && previousToken != TokenNameLPAREN && previousToken != TokenNameTWIDDLE
+              && previousToken != TokenNameSEMICOLON && previousToken != TokenNameLBRACE && previousToken != TokenNameRBRACE
+              && previousToken != TokenNamesuper) {
+            //         && previousToken != TokenNamethis) {
+            space();
+          }
+          // If in a for/if/while statement, increase the parenthesis count
+          // for the current openParenthesisCount
+          // else increase the count for stand alone parenthesis.
+          if (openParenthesisCount > 0)
+            openParenthesis[openParenthesisCount - 1]++;
+          else
+            openParenthesis[0]++;
+          pendingSpace = false;
+          //S }
+          break;
+        case TokenNameRPAREN:
+          // Decrease the parenthesis count
+          // if there is no more unclosed parenthesis,
+          // a new line and indent may be append (depending on the next
+          // token).
+          if ((openParenthesisCount > 1) && (openParenthesis[openParenthesisCount - 1] > 0)) {
+            openParenthesis[openParenthesisCount - 1]--;
+            if (openParenthesis[openParenthesisCount - 1] <= 0) {
+              pendingNewlineAfterParen = true;
+              inAssignment = false;
+              openParenthesisCount--;
             }
-            pendingSpace = false;
-            break;
-          case TokenNameLBRACE :
-            if (previousCompilableToken == TokenNameDOLLAR) {
-              dollarBraceCount++;
-            } else {
-            if ((previousCompilableToken == TokenNameRBRACKET)
-                || (previousCompilableToken == TokenNameEQUAL)) {
+          } else {
+            openParenthesis[0]--;
+          }
+          pendingSpace = false;
+          break;
+        case TokenNameLBRACE:
+          if (previousCompilableToken == TokenNameDOLLAR) {
+            dollarBraceCount++;
+          } else {
+            if ((previousCompilableToken == TokenNameRBRACKET) || (previousCompilableToken == TokenNameEQUAL)) {
               //                  if (previousCompilableToken == TokenNameRBRACKET) {
               inArrayAssignment = true;
               inAssignment = false;
@@ -713,211 +693,198 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
               indentationLevel += pushBlock();
             } else {
               // Add new line and increase indentation level after open brace.
-                pendingNewLines = 1;
-                indentationLevel += pushBlock();
-              }
-            }
-            break;
-          case TokenNameRBRACE :
-            if (dollarBraceCount > 0) {
-              dollarBraceCount--;
-              break;
-            }
-            if (previousCompilableToken == TokenNameRPAREN) {
-              pendingSpace = false;
-            }
-            if (inArrayAssignment) {
-              inArrayAssignment = false;
-              pendingNewLines = 1;
-              indentationLevel += popInclusiveUntilBlock();
-            } else {
               pendingNewLines = 1;
-              indentationLevel += popInclusiveUntilBlock();
-              if (previousCompilableToken == TokenNameRPAREN) {
-                // fix for 1FGDDV6: LFCOM:WIN98 - Weird splitting on message
-                // expression
-                currentLineBuffer.append(options.lineSeparatorSequence);
-                increaseLineDelta(options.lineSeparatorSequence.length);
-              }
-              if (constructionsCount > 0) {
-                switch (constructions[constructionsCount - 1]) {
-                  case TokenNamefor :
-                  //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;
-                }
-              }
+              indentationLevel += pushBlock();
             }
+          }
+          break;
+        case TokenNameRBRACE:
+          if (dollarBraceCount > 0) {
+            dollarBraceCount--;
             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;
+          }
+          if (previousCompilableToken == TokenNameRPAREN) {
             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;
+          }
+          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);
             }
-            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;
+            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;
               }
-              tokenBeforeColonCount--;
             }
-            break;
-          case TokenNameEQUAL :
-            inAssignment = true;
-            break;
-          case Scanner.TokenNameCOMMENT_LINE :
+          }
+          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 (inAssignment) {
-              currentLineIndentationLevel++;
+            if (expectingOpenBrace) {
+              clearNonBlockIndents = true;
+              expectingOpenBrace = false;
             }
-            break; // a line is always inserted after a one-line comment
-          case Scanner.TokenNameCOMMENT_PHPDOC :
-          case Scanner.TokenNameCOMMENT_BLOCK :
-            currentCommentOffset = getCurrentCommentOffset();
-            pendingNewLines = 1;
-            break;
-          case Scanner.TokenNameWHITESPACE :
-            if (!phpTagAndWhitespace) {
-              // Count the number of line terminators in the whitespace so
-              // line spacing can be preserved near comments.
-              char[] source = scanner.source;
-              newLinesInWhitespace = 0;
-              for (int i = scanner.startPosition, max = scanner.currentPosition; i < max; i++) {
-                if (source[i] == '\r') {
-                  if (i < max - 1) {
-                    if (source[++i] == '\n') {
-                      newLinesInWhitespace++;
-                    } else {
-                      newLinesInWhitespace++;
-                    }
+          }
+          inAssignment = false;
+          pendingSpace = false;
+          break;
+        case TokenNamePLUS_PLUS:
+        case TokenNameMINUS_MINUS:
+          // Do not put a space between a post-increment/decrement
+          // and the identifier being modified.
+          if (previousToken == TokenNameIdentifier || previousToken == TokenNameRBRACKET) {
+            pendingSpace = false;
+          }
+          break;
+        case TokenNamePLUS:
+        // previously ADDITION
+        case TokenNameMINUS:
+          // Handle the unary operators plus and minus via a flag
+          if (!isLiteralToken(previousToken) && previousToken != TokenNameIdentifier && previousToken != TokenNameRPAREN
+              && previousToken != TokenNameRBRACKET) {
+            unarySignModifier = 1;
+          }
+          break;
+        case TokenNameCOLON:
+          // In a switch/case statement, add a newline & indent
+          // when a colon is encountered.
+          if (tokenBeforeColonCount > 0) {
+            if (tokenBeforeColon[tokenBeforeColonCount - 1] == TokenNamecase) {
+              pendingNewLines = 1;
+            }
+            tokenBeforeColonCount--;
+          }
+          break;
+        case TokenNameEQUAL:
+          inAssignment = true;
+          break;
+        case Scanner.TokenNameCOMMENT_LINE:
+          pendingNewLines = 1;
+          if (inAssignment) {
+            currentLineIndentationLevel++;
+          }
+          break; // a line is always inserted after a one-line comment
+        case Scanner.TokenNameCOMMENT_PHPDOC:
+        case Scanner.TokenNameCOMMENT_BLOCK:
+          currentCommentOffset = getCurrentCommentOffset();
+          pendingNewLines = 1;
+          break;
+        case Scanner.TokenNameWHITESPACE:
+          if (!phpTagAndWhitespace) {
+            // Count the number of line terminators in the whitespace so
+            // line spacing can be preserved near comments.
+            char[] source = scanner.source;
+            newLinesInWhitespace = 0;
+            for (int i = scanner.startPosition, max = scanner.currentPosition; i < max; i++) {
+              if (source[i] == '\r') {
+                if (i < max - 1) {
+                  if (source[++i] == '\n') {
+                    newLinesInWhitespace++;
                   } else {
                     newLinesInWhitespace++;
                   }
-                } else if (source[i] == '\n') {
+                } else {
                   newLinesInWhitespace++;
                 }
+              } else if (source[i] == '\n') {
+                newLinesInWhitespace++;
               }
-              increaseLineDelta(scanner.startPosition - scanner.currentPosition);
-              break;
-            }
-          //          case TokenNameHTML :
-          //            // Add the next token to the formatted source string.
-          //            // outputCurrentToken(token);
-          //            int startPosition = scanner.startPosition;
-          //            flushBuffer();
-          //            for (int i = startPosition, max = scanner.currentPosition; i <
-          // max; i++) {
-          //              char currentCharacter = scanner.source[i];
-          //              updateMappedPositions(i);
-          //              currentLineBuffer.append(currentCharacter);
-          //            }
-          //            break;
-          default :
-            if ((token == TokenNameIdentifier) || isLiteralToken(token)
-                || token == TokenNamesuper) {
-              //                                                       || token == TokenNamethis) {
-              // Do not put a space between a unary operator
-              // (eg: ++, --, +, -) and the identifier being modified.
-              if (previousToken == TokenNamePLUS_PLUS
-                  || previousToken == TokenNameMINUS_MINUS
-                  || (previousToken == TokenNameMINUS_GREATER && options.compactDereferencingMode) // ->
-                  || (previousToken == TokenNamePLUS && unarySignModifier > 0)
-                  || (previousToken == TokenNameMINUS && unarySignModifier > 0)) {
-                pendingSpace = false;
-              }
-              unarySignModifier = 0;
             }
+            increaseLineDelta(scanner.startPosition - scanner.currentPosition);
             break;
+          }
+        //          case TokenNameHTML :
+        //            // Add the next token to the formatted source string.
+        //            // outputCurrentToken(token);
+        //            int startPosition = scanner.startPosition;
+        //            flushBuffer();
+        //            for (int i = startPosition, max = scanner.currentPosition; i <
+        // max; i++) {
+        //              char currentCharacter = scanner.source[i];
+        //              updateMappedPositions(i);
+        //              currentLineBuffer.append(currentCharacter);
+        //            }
+        //            break;
+        default:
+          if ((token == TokenNameIdentifier) || isLiteralToken(token) || token == TokenNamesuper) {
+            //                                                 || token == TokenNamethis) {
+            // Do not put a space between a unary operator
+            // (eg: ++, --, +, -) and the identifier being modified.
+            if (previousToken == TokenNamePLUS_PLUS || previousToken == TokenNameMINUS_MINUS
+                || (previousToken == TokenNameMINUS_GREATER && options.compactDereferencingMode) // ->
+                || (previousToken == TokenNamePLUS && unarySignModifier > 0)
+                || (previousToken == TokenNameMINUS && unarySignModifier > 0)) {
+              pendingSpace = false;
+            }
+            unarySignModifier = 0;
+          }
+          break;
         }
         // Do not output whitespace tokens.
         if (token != Scanner.TokenNameWHITESPACE || phpTagAndWhitespace) {
           /*
-           * Add pending space to the formatted source string. Do not output a
-           * space under the following circumstances: 1) this is the first pass 2)
-           * previous token is an open paren 3) previous token is a period 4)
-           * previous token is the logical compliment (eg: !) 5) previous token
-           * is the bitwise compliment (eg: ~) 6) previous token is the open
-           * bracket (eg: [) 7) in an assignment statement, if the previous
-           * token is an open brace or the current token is a close brace 8)
-           * previous token is a single line comment 9) current token is a '->'
+           * Add pending space to the formatted source string. Do not output a space under the following circumstances: 1) this is
+           * the first pass 2) previous token is an open paren 3) previous token is a period 4) previous token is the logical
+           * compliment (eg: !) 5) previous token is the bitwise compliment (eg: ~) 6) previous token is the open bracket (eg: [) 7)
+           * in an assignment statement, if the previous token is an open brace or the current token is a close brace 8) previous
+           * token is a single line comment 9) current token is a '->'
            */
-          if (token == TokenNameMINUS_GREATER
-              && options.compactDereferencingMode)
+          if (token == TokenNameMINUS_GREATER && options.compactDereferencingMode)
             pendingSpace = false;
-          
-          boolean openAndCloseBrace = previousCompilableToken == TokenNameLBRACE
-              && token == TokenNameRBRACE;
-          if (pendingSpace
-              && insertSpaceAfter(previousToken)
+
+          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)
+            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) {
+          if (token == Scanner.TokenNameCOMMENT_LINE && openParenthesisCount > 1) {
             pendingNewLines = 0;
             currentLineBuffer.append(options.lineSeparatorSequence);
             increaseLineDelta(options.lineSeparatorSequence.length);
@@ -927,8 +894,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         // Whitespace tokens do not need to be remembered.
         if (token != Scanner.TokenNameWHITESPACE || phpTagAndWhitespace) {
           previousToken = token;
-          if (token != Scanner.TokenNameCOMMENT_BLOCK
-              && token != Scanner.TokenNameCOMMENT_LINE
+          if (token != Scanner.TokenNameCOMMENT_BLOCK && token != Scanner.TokenNameCOMMENT_LINE
               && token != Scanner.TokenNameCOMMENT_PHPDOC) {
             previousCompilableToken = token;
           }
@@ -943,9 +909,9 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       // 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.
+   * Formats the char array <code>sourceString</code>, and returns a string containing the formatted version.
    * 
    * @return the formatted ouput.
    */
@@ -956,37 +922,37 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     format();
     return formattedSource.toString();
   }
+
   /**
-   * Formats the char array <code>sourceString</code>, and returns a string
-   * containing the formatted version.
+   * Formats the char array <code>sourceString</code>, and returns a string containing the formatted version.
    * 
    * @param string
-   *            the string to format
+   *          the string to format
    * @param indentationLevel
-   *            the initial indentation level
+   *          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.
+   * 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
+   *          the string to format
    * @param indentationLevel
-   *            the initial indentation level
+   *          the initial indentation level
    * @param positions
-   *            the array of positions to map
+   *          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) {
+
+  public String format(String string, int indentationLevel, int[] positions, String lineSeparator) {
     if (lineSeparator != null) {
       this.options.setLineSeparator(lineSeparator);
     }
@@ -1002,32 +968,32 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       return this.formatSourceString(string);
     }
   }
+
   /**
-   * Formats the char array <code>sourceString</code>, and returns a string
-   * containing the formatted version. The initial indentation level is 0.
+   * 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
+   *          the string to format
    * @return the formatted ouput.
    */
   public String format(String string) {
     return this.format(string, 0, (int[]) null);
   }
+
   /**
-   * Formats a given source string, starting indenting it at a particular depth
-   * and using the given options
+   * Formats a given source string, starting indenting it at a particular depth and using the given options
    * 
    * @deprecated backport 1.0 internal functionality
    */
-  public static String format(String sourceString, int initialIndentationLevel,
-      ConfigurableOption[] options) {
+  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.
+   * 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;
@@ -1050,61 +1016,54 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     for (int i = currentStartPosition - 1; i >= beginningOfLine; i--) {
       char currentCharacter = source[i];
       switch (currentCharacter) {
-        case '\t' :
-          offset += options.tabSize;
-          break;
-        case ' ' :
-          offset++;
-          break;
-        case '\r' :
-        case '\n' :
-          break;
-        default :
-          return offset;
+      case '\t':
+        offset += options.tabSize;
+        break;
+      case ' ':
+        offset++;
+        break;
+      case '\r':
+      case '\n':
+        break;
+      default:
+        return offset;
       }
     }
     return offset;
   }
+
   /**
-   * Returns an array of descriptions for the configurable options. The
-   * descriptions may be changed and passed back to a different compiler.
+   * 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),
+    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),
+        new ConfigurableOption(componentName, "newline.controlStatement", locale, options.newlineInControlStatementMode ? 0 : 1),
         //$NON-NLS-1$
-        new ConfigurableOption(componentName, "newline.clearAll", locale,
-            options.clearAllBlankLinesMode ? 0 : 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),
+        new ConfigurableOption(componentName, "newline.emptyBlock", locale, options.newLineInEmptyBlockMode ? 0 : 1),
         //$NON-NLS-1$
-        new ConfigurableOption(componentName, "line.split", locale,
-            options.maxLineLength),
+        new ConfigurableOption(componentName, "line.split", locale, options.maxLineLength),
         //$NON-NLS-1$
-        new ConfigurableOption(componentName, "style.compactAssignment",
-            locale, options.compactAssignmentMode ? 0 : 1),
+        new ConfigurableOption(componentName, "style.compactAssignment", locale, options.compactAssignmentMode ? 0 : 1),
         //$NON-NLS-1$
-        new ConfigurableOption(componentName, "tabulation.char", locale,
-            options.indentWithTab ? 0 : 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$
+        new ConfigurableOption(componentName, "tabulation.size", locale, options.tabSize) //$NON-NLS-1$
     };
   }
+
   /**
-   * Returns the array of mapped positions. Returns null is no positions have
-   * been set.
+   * Returns the array of mapped positions. Returns null is no positions have been set.
    * 
    * @return int[]
    * @deprecated There is no need to retrieve the mapped positions anymore.
@@ -1112,174 +1071,180 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
   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
+   *          the token of which the priority is requested
    */
   private static int getTokenPriority(int token) {
     switch (token) {
-      case TokenNameextends :
-        //                     case TokenNameimplements :
-        //                     case TokenNamethrows :
-        return 10;
-      case TokenNameSEMICOLON :
-        // ;
-        return 20;
-      case TokenNameCOMMA :
-        // ,
-        return 25;
-      case TokenNameEQUAL :
-        // =
-        return 30;
-      case TokenNameAND_AND :
-      // &&
-      case TokenNameOR_OR :
-        // ||
-        return 40;
-      case TokenNameQUESTION :
-      // ?
-      case TokenNameCOLON :
-        // :
-        return 50; // it's better cutting on ?: than on ;
-      case TokenNameEQUAL_EQUAL :
-      // ==
-      case TokenNameEQUAL_EQUAL_EQUAL :
-      // ===
-      case TokenNameNOT_EQUAL :
+    case TokenNameextends:
+      //                       case TokenNameimplements :
+      //                       case TokenNamethrows :
+      return 10;
+    case TokenNameSEMICOLON:
+      // ;
+      return 20;
+    case TokenNameCOMMA:
+      // ,
+      return 25;
+    case TokenNameEQUAL:
+      // =
+      return 30;
+    case TokenNameAND_AND:
+    // &&
+    case TokenNameOR_OR:
+      // ||
+      return 40;
+    case TokenNameQUESTION:
+    // ?
+    case TokenNameCOLON:
+      // :
+      return 50; // it's better cutting on ?: than on ;
+    case TokenNameEQUAL_EQUAL:
+    // ==
+    case TokenNameEQUAL_EQUAL_EQUAL:
+    // ===
+    case TokenNameNOT_EQUAL:
+    // !=
+    case TokenNameNOT_EQUAL_EQUAL:
       // !=
-      case TokenNameNOT_EQUAL_EQUAL :
-        // !=
-        return 60;
-      case TokenNameLESS :
-      // <
-      case TokenNameLESS_EQUAL :
-      // <=
-      case TokenNameGREATER :
-      // >
-      case TokenNameGREATER_EQUAL :
-        // >=
-        //                     case TokenNameinstanceof : // instanceof
-        return 70;
-      case TokenNamePLUS :
-      // +
-      case TokenNameMINUS :
-        // -
-        return 80;
-      case TokenNameMULTIPLY :
-      // *
-      case TokenNameDIVIDE :
-      // /
-      case TokenNameREMAINDER :
-        // %
-        return 90;
-      case TokenNameLEFT_SHIFT :
-      // <<
-      case TokenNameRIGHT_SHIFT :
-        // >>
-        //                     case TokenNameUNSIGNED_RIGHT_SHIFT : // >>>
-        return 100;
-      case TokenNameAND :
-      // &
-      case TokenNameOR :
-      // |
-      case TokenNameXOR :
-        // ^
-        return 110;
-      case TokenNameMULTIPLY_EQUAL :
-      // *=
-      case TokenNameDIVIDE_EQUAL :
-      // /=
-      case TokenNameREMAINDER_EQUAL :
-      // %=
-      case TokenNamePLUS_EQUAL :
-      // +=
-      case TokenNameMINUS_EQUAL :
-      // -=
-      case TokenNameLEFT_SHIFT_EQUAL :
-      // <<=
-      case TokenNameRIGHT_SHIFT_EQUAL :
-      // >>=
-      //                       case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>=
-      case TokenNameAND_EQUAL :
-      // &=
-      case TokenNameXOR_EQUAL :
-      // ^=
-      case TokenNameOR_EQUAL :
-        // |=
-        return 120;
-      case TokenNameDOT :
-        // .
-        return 130;
-      default :
-        return Integer.MAX_VALUE;
+      return 60;
+    case TokenNameLESS:
+    // <
+    case TokenNameLESS_EQUAL:
+    // <=
+    case TokenNameGREATER:
+    // >
+    case TokenNameGREATER_EQUAL:
+      // >=
+      //                       case TokenNameinstanceof : // instanceof
+      return 70;
+    case TokenNamePLUS:
+    // +
+    case TokenNameMINUS:
+      // -
+      return 80;
+    case TokenNameMULTIPLY:
+    // *
+    case TokenNameDIVIDE:
+    // /
+    case TokenNameREMAINDER:
+      // %
+      return 90;
+    case TokenNameLEFT_SHIFT:
+    // <<
+    case TokenNameRIGHT_SHIFT:
+      // >>
+      //                       case TokenNameUNSIGNED_RIGHT_SHIFT : // >>>
+      return 100;
+    case TokenNameAND:
+    // &
+    case TokenNameOR:
+    // |
+    case TokenNameXOR:
+      // ^
+      return 110;
+    case TokenNameMULTIPLY_EQUAL:
+    // *=
+    case TokenNameDIVIDE_EQUAL:
+    // /=
+    case TokenNameREMAINDER_EQUAL:
+    // %=
+    case TokenNamePLUS_EQUAL:
+    // +=
+    case TokenNameMINUS_EQUAL:
+    // -=
+    case TokenNameLEFT_SHIFT_EQUAL:
+    // <<=
+    case TokenNameRIGHT_SHIFT_EQUAL:
+    // >>=
+    //                 case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>=
+    case TokenNameAND_EQUAL:
+    // &=
+    case TokenNameXOR_EQUAL:
+    // ^=
+    case TokenNameOR_EQUAL:
+    // .=
+    case TokenNameDOT_EQUAL:
+      // |=
+      return 120;
+    case TokenNameDOT:
+      // .
+      return 130;
+    default:
+      return Integer.MAX_VALUE;
     }
   }
+
   /**
-   * Handles the exception raised when an invalid token is encountered. Returns
-   * true if the exception has been handled, false otherwise.
+   * Handles the exception raised when an invalid token is encountered. Returns true if the exception has been handled, false
+   * otherwise.
    */
   private boolean handleInvalidToken(Exception e) {
-    if (e.getMessage().equals(Scanner.INVALID_CHARACTER_CONSTANT)
-        || e.getMessage().equals(Scanner.INVALID_CHAR_IN_STRING)
+    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.
+   * Returns true if a space has to be inserted after <code>operator</code> false otherwise.
    */
   private boolean insertSpaceAfter(int token) {
     switch (token) {
-      case TokenNameLPAREN :
-      case TokenNameNOT :
-      case TokenNameTWIDDLE :
-      case TokenNameDOT :
-      case 0 :
-      // no token
-      case TokenNameWHITESPACE :
-      case TokenNameLBRACKET :
-      case TokenNameDOLLAR :
-      case Scanner.TokenNameCOMMENT_LINE :
-        return false;
-      default :
-        return true;
+    case TokenNameLPAREN:
+    case TokenNameNOT:
+    case TokenNameTWIDDLE:
+    case TokenNameDOT:
+    case 0:
+    // no token
+    case TokenNameWHITESPACE:
+    case TokenNameLBRACKET:
+    case TokenNameDOLLAR:
+    case Scanner.TokenNameCOMMENT_LINE:
+      return false;
+    default:
+      return true;
     }
   }
+
   /**
-   * Returns true if a space has to be inserted before <code>operator</code>
-   * false otherwise. <br>
-   * Cannot be static as it uses the code formatter options (to know if the
-   * compact assignment mode is on).
+   * Returns true if a space has to be inserted before <code>operator</code> false otherwise. <br>
+   * Cannot be static as it uses the code formatter options (to know if the compact assignment mode is on).
    */
   private boolean insertSpaceBefore(int token) {
     switch (token) {
-      case TokenNameEQUAL :
-        return (!options.compactAssignmentMode);
-      default :
-        return false;
+    case TokenNameEQUAL:
+      return (!options.compactAssignmentMode);
+    default:
+      return false;
     }
   }
+
   private static boolean isComment(int token) {
-    boolean result = token == Scanner.TokenNameCOMMENT_BLOCK
-        || token == Scanner.TokenNameCOMMENT_LINE
+    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
@@ -1289,12 +1254,13 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         || token == TokenNameStringDoubleQuote;
     return result;
   }
+
   /**
-   * If the length of <code>oneLineBuffer</code> exceeds <code>maxLineLength</code>,
-   * it is split and the result is dumped in <code>formattedSource</code>
+   * 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
+   *          the number of new lines to append
    */
   private void newLine(int newLineCount) {
     // format current line
@@ -1303,12 +1269,10 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     String currentLine = currentLineBuffer.toString();
     if (containsOpenCloseBraces) {
       containsOpenCloseBraces = false;
-      outputLine(currentLine, false, indentationLevelForOpenCloseBraces, 0, -1,
-          null, 0);
+      outputLine(currentLine, false, indentationLevelForOpenCloseBraces, 0, -1, null, 0);
       indentationLevelForOpenCloseBraces = currentLineIndentationLevel;
     } else {
-      outputLine(currentLine, false, currentLineIndentationLevel, 0, -1, null,
-          0);
+      outputLine(currentLine, false, currentLineIndentationLevel, 0, -1, null, 0);
     }
     // dump line break(s)
     for (int i = 0; i < newLineCount; i++) {
@@ -1317,150 +1281,153 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     }
     // reset formatter for next line
     int currentLength = currentLine.length();
-    currentLineBuffer = new StringBuffer(currentLength > maxLineSize
-        ? maxLineSize = currentLength
-        : maxLineSize);
+    currentLineBuffer = new StringBuffer(currentLength > maxLineSize ? maxLineSize = currentLength : maxLineSize);
     increaseGlobalDelta(splitDelta);
     increaseGlobalDelta(lineDelta);
     lineDelta = 0;
     currentLineIndentationLevel = initialIndentationLevel;
   }
+
   private String operatorString(int operator) {
     switch (operator) {
-      case TokenNameextends :
-        return "extends"; //$NON-NLS-1$
-      //                       case TokenNameimplements :
-      //                               return "implements"; //$NON-NLS-1$
-      //
-      //                       case TokenNamethrows :
-      //                               return "throws"; //$NON-NLS-1$
-      case TokenNameSEMICOLON :
-        // ;
-        return ";"; //$NON-NLS-1$
-      case TokenNameCOMMA :
-        // ,
-        return ","; //$NON-NLS-1$
-      case TokenNameEQUAL :
-        // =
-        return "="; //$NON-NLS-1$
-      case TokenNameAND_AND :
-        // && (15.22)
-        return "&&"; //$NON-NLS-1$
-      case TokenNameOR_OR :
-        // || (15.23)
-        return "||"; //$NON-NLS-1$
-      case TokenNameQUESTION :
-        // ? (15.24)
-        return "?"; //$NON-NLS-1$
-      case TokenNameCOLON :
-        // : (15.24)
-        return ":"; //$NON-NLS-1$
-      case TokenNamePAAMAYIM_NEKUDOTAYIM :
-        // : (15.24)
-        return "::"; //$NON-NLS-1$
-      case TokenNameEQUAL_EQUAL :
-        // == (15.20, 15.20.1, 15.20.2, 15.20.3)
-        return "=="; //$NON-NLS-1$
-      case TokenNameEQUAL_EQUAL_EQUAL :
-        // == (15.20, 15.20.1, 15.20.2, 15.20.3)
-        return "==="; //$NON-NLS-1$
-      case TokenNameEQUAL_GREATER :
-        // -= (15.25.2)
-        return "=>"; //$NON-NLS-1$                             
-      case TokenNameNOT_EQUAL :
-        // != (15.20, 15.20.1, 15.20.2, 15.20.3)
-        return "!="; //$NON-NLS-1$
-      case TokenNameNOT_EQUAL_EQUAL :
-        // != (15.20, 15.20.1, 15.20.2, 15.20.3)
-        return "!=="; //$NON-NLS-1$
-      case TokenNameLESS :
-        // < (15.19.1)
-        return "<"; //$NON-NLS-1$
-      case TokenNameLESS_EQUAL :
-        // <= (15.19.1)
-        return "<="; //$NON-NLS-1$
-      case TokenNameGREATER :
-        // > (15.19.1)
-        return ">"; //$NON-NLS-1$
-      case TokenNameGREATER_EQUAL :
-        // >= (15.19.1)
-        return ">="; //$NON-NLS-1$
-      //                       case TokenNameinstanceof : // instanceof
-      //                               return "instanceof"; //$NON-NLS-1$
-      case TokenNamePLUS :
-        // + (15.17, 15.17.2)
-        return "+"; //$NON-NLS-1$
-      case TokenNameMINUS :
-        // - (15.17.2)
-        return "-"; //$NON-NLS-1$
-      case TokenNameMULTIPLY :
-        // * (15.16.1)
-        return "*"; //$NON-NLS-1$
-      case TokenNameDIVIDE :
-        // / (15.16.2)
-        return "/"; //$NON-NLS-1$
-      case TokenNameREMAINDER :
-        // % (15.16.3)
-        return "%"; //$NON-NLS-1$
-      case TokenNameLEFT_SHIFT :
-        // << (15.18)
-        return "<<"; //$NON-NLS-1$
-      case TokenNameRIGHT_SHIFT :
-        // >> (15.18)
-        return ">>"; //$NON-NLS-1$
-      //                       case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
-      //                               return ">>>"; //$NON-NLS-1$
-      case TokenNameAND :
-        // & (15.21, 15.21.1, 15.21.2)
-        return "&"; //$NON-NLS-1$
-      case TokenNameOR :
-        // | (15.21, 15.21.1, 15.21.2)
-        return "|"; //$NON-NLS-1$
-      case TokenNameXOR :
-        // ^ (15.21, 15.21.1, 15.21.2)
-        return "^"; //$NON-NLS-1$
-      case TokenNameMULTIPLY_EQUAL :
-        // *= (15.25.2)
-        return "*="; //$NON-NLS-1$
-      case TokenNameDIVIDE_EQUAL :
-        // /= (15.25.2)
-        return "/="; //$NON-NLS-1$
-      case TokenNameREMAINDER_EQUAL :
-        // %= (15.25.2)
-        return "%="; //$NON-NLS-1$
-      case TokenNamePLUS_EQUAL :
-        // += (15.25.2)
-        return "+="; //$NON-NLS-1$
-      case TokenNameMINUS_EQUAL :
-        // -= (15.25.2)
-        return "-="; //$NON-NLS-1$
-      case TokenNameMINUS_GREATER :
-        // -= (15.25.2)
-        return "->"; //$NON-NLS-1$
-      case TokenNameLEFT_SHIFT_EQUAL :
-        // <<= (15.25.2)
-        return "<<="; //$NON-NLS-1$
-      case TokenNameRIGHT_SHIFT_EQUAL :
-        // >>= (15.25.2)
-        return ">>="; //$NON-NLS-1$
-      //                       case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
-      //                               return ">>>="; //$NON-NLS-1$
-      case TokenNameAND_EQUAL :
-        // &= (15.25.2)
-        return "&="; //$NON-NLS-1$
-      case TokenNameXOR_EQUAL :
-        // ^= (15.25.2)
-        return "^="; //$NON-NLS-1$
-      case TokenNameOR_EQUAL :
-        // |= (15.25.2)
-        return "|="; //$NON-NLS-1$
-      case TokenNameDOT :
-        // .
-        return "."; //$NON-NLS-1$
-      default :
-        return ""; //$NON-NLS-1$
+    case TokenNameextends:
+      return "extends"; //$NON-NLS-1$
+    //                 case TokenNameimplements :
+    //                         return "implements"; //$NON-NLS-1$
+    //
+    //                 case TokenNamethrows :
+    //                         return "throws"; //$NON-NLS-1$
+    case TokenNameSEMICOLON:
+      // ;
+      return ";"; //$NON-NLS-1$
+    case TokenNameCOMMA:
+      // ,
+      return ","; //$NON-NLS-1$
+    case TokenNameEQUAL:
+      // =
+      return "="; //$NON-NLS-1$
+    case TokenNameAND_AND:
+      // && (15.22)
+      return "&&"; //$NON-NLS-1$
+    case TokenNameOR_OR:
+      // || (15.23)
+      return "||"; //$NON-NLS-1$
+    case TokenNameQUESTION:
+      // ? (15.24)
+      return "?"; //$NON-NLS-1$
+    case TokenNameCOLON:
+      // : (15.24)
+      return ":"; //$NON-NLS-1$
+    case TokenNamePAAMAYIM_NEKUDOTAYIM:
+      // : (15.24)
+      return "::"; //$NON-NLS-1$
+    case TokenNameEQUAL_EQUAL:
+      // == (15.20, 15.20.1, 15.20.2, 15.20.3)
+      return "=="; //$NON-NLS-1$
+    case TokenNameEQUAL_EQUAL_EQUAL:
+      // == (15.20, 15.20.1, 15.20.2, 15.20.3)
+      return "==="; //$NON-NLS-1$
+    case TokenNameEQUAL_GREATER:
+      // -= (15.25.2)
+      return "=>"; //$NON-NLS-1$                               
+    case TokenNameNOT_EQUAL:
+      // != (15.20, 15.20.1, 15.20.2, 15.20.3)
+      return "!="; //$NON-NLS-1$
+    case TokenNameNOT_EQUAL_EQUAL:
+      // != (15.20, 15.20.1, 15.20.2, 15.20.3)
+      return "!=="; //$NON-NLS-1$
+    case TokenNameLESS:
+      // < (15.19.1)
+      return "<"; //$NON-NLS-1$
+    case TokenNameLESS_EQUAL:
+      // <= (15.19.1)
+      return "<="; //$NON-NLS-1$
+    case TokenNameGREATER:
+      // > (15.19.1)
+      return ">"; //$NON-NLS-1$
+    case TokenNameGREATER_EQUAL:
+      // >= (15.19.1)
+      return ">="; //$NON-NLS-1$
+    //                 case TokenNameinstanceof : // instanceof
+    //                         return "instanceof"; //$NON-NLS-1$
+    case TokenNamePLUS:
+      // + (15.17, 15.17.2)
+      return "+"; //$NON-NLS-1$
+    case TokenNameMINUS:
+      // - (15.17.2)
+      return "-"; //$NON-NLS-1$
+    case TokenNameMULTIPLY:
+      // * (15.16.1)
+      return "*"; //$NON-NLS-1$
+    case TokenNameDIVIDE:
+      // / (15.16.2)
+      return "/"; //$NON-NLS-1$
+    case TokenNameREMAINDER:
+      // % (15.16.3)
+      return "%"; //$NON-NLS-1$
+    case TokenNameLEFT_SHIFT:
+      // << (15.18)
+      return "<<"; //$NON-NLS-1$
+    case TokenNameRIGHT_SHIFT:
+      // >> (15.18)
+      return ">>"; //$NON-NLS-1$
+    //                 case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
+    //                         return ">>>"; //$NON-NLS-1$
+    case TokenNameAND:
+      // & (15.21, 15.21.1, 15.21.2)
+      return "&"; //$NON-NLS-1$
+    case TokenNameOR:
+      // | (15.21, 15.21.1, 15.21.2)
+      return "|"; //$NON-NLS-1$
+    case TokenNameXOR:
+      // ^ (15.21, 15.21.1, 15.21.2)
+      return "^"; //$NON-NLS-1$
+    case TokenNameMULTIPLY_EQUAL:
+      // *= (15.25.2)
+      return "*="; //$NON-NLS-1$
+    case TokenNameDIVIDE_EQUAL:
+      // /= (15.25.2)
+      return "/="; //$NON-NLS-1$
+    case TokenNameREMAINDER_EQUAL:
+      // %= (15.25.2)
+      return "%="; //$NON-NLS-1$
+    case TokenNamePLUS_EQUAL:
+      // += (15.25.2)
+      return "+="; //$NON-NLS-1$
+    case TokenNameMINUS_EQUAL:
+      // -= (15.25.2)
+      return "-="; //$NON-NLS-1$
+    case TokenNameMINUS_GREATER:
+      // -= (15.25.2)
+      return "->"; //$NON-NLS-1$
+    case TokenNameLEFT_SHIFT_EQUAL:
+      // <<= (15.25.2)
+      return "<<="; //$NON-NLS-1$
+    case TokenNameRIGHT_SHIFT_EQUAL:
+      // >>= (15.25.2)
+      return ">>="; //$NON-NLS-1$
+    //                 case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
+    //                         return ">>>="; //$NON-NLS-1$
+    case TokenNameAND_EQUAL:
+      // &= (15.25.2)
+      return "&="; //$NON-NLS-1$
+    case TokenNameXOR_EQUAL:
+      // ^= (15.25.2)
+      return "^="; //$NON-NLS-1$
+    case TokenNameOR_EQUAL:
+      // |= (15.25.2)
+      return "|="; //$NON-NLS-1$
+    case TokenNameDOT_EQUAL:
+      // .= 
+      return ".="; //$NON-NLS-1$
+    case TokenNameDOT:
+      // .
+      return "."; //$NON-NLS-1$
+    default:
+      return ""; //$NON-NLS-1$
     }
   }
+
   /**
    * Appends <code>stringToOutput</code> to the formatted output. <br>
    * If it contains \n, append a LINE_SEPARATOR and indent after it.
@@ -1474,111 +1441,112 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       }
     }
   }
+
   /**
    * Appends <code>token</code> to the formatted output. <br>
-   * If it contains <code>\n</code>, append a LINE_SEPARATOR and indent
-   * after it.
+   * If it contains <code>\n</code>, append a LINE_SEPARATOR and indent after it.
    */
   private void outputCurrentToken(int token) {
     char[] source = scanner.source;
     int startPosition = scanner.startPosition;
     switch (token) {
-      case Scanner.TokenNameCOMMENT_PHPDOC :
-      case Scanner.TokenNameCOMMENT_BLOCK :
-      case Scanner.TokenNameCOMMENT_LINE :
-        boolean endOfLine = false;
-        int currentCommentOffset = getCurrentCommentOffset();
-        int beginningOfLineSpaces = 0;
-        endOfLine = false;
-        currentCommentOffset = getCurrentCommentOffset();
-        beginningOfLineSpaces = 0;
-        boolean pendingCarriageReturn = false;
-        for (int i = startPosition, max = scanner.currentPosition; i < max; i++) {
-          char currentCharacter = source[i];
-          updateMappedPositions(i);
-          switch (currentCharacter) {
-            case '\r' :
-              pendingCarriageReturn = true;
-              endOfLine = true;
-              break;
-            case '\n' :
-              if (pendingCarriageReturn) {
-                increaseGlobalDelta(options.lineSeparatorSequence.length - 2);
-              } else {
-                increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
-              }
-              pendingCarriageReturn = false;
-              currentLineBuffer.append(options.lineSeparatorSequence);
-              beginningOfLineSpaces = 0;
-              endOfLine = true;
-              break;
-            case '\t' :
-              if (pendingCarriageReturn) {
-                pendingCarriageReturn = false;
-                increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
-                currentLineBuffer.append(options.lineSeparatorSequence);
-                beginningOfLineSpaces = 0;
-                endOfLine = true;
-              }
-              if (endOfLine) {
-                // we remove a maximum of currentCommentOffset characters (tabs
-                // are converted to space numbers).
-                beginningOfLineSpaces += options.tabSize;
-                if (beginningOfLineSpaces > currentCommentOffset) {
-                  currentLineBuffer.append(currentCharacter);
-                } else {
-                  increaseGlobalDelta(-1);
-                }
-              } else {
-                currentLineBuffer.append(currentCharacter);
-              }
-              break;
-            case ' ' :
-              if (pendingCarriageReturn) {
-                pendingCarriageReturn = false;
-                increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
-                currentLineBuffer.append(options.lineSeparatorSequence);
-                beginningOfLineSpaces = 0;
-                endOfLine = true;
-              }
-              if (endOfLine) {
-                // we remove a maximum of currentCommentOffset characters (tabs
-                // are converted to space numbers).
-                beginningOfLineSpaces++;
-                if (beginningOfLineSpaces > currentCommentOffset) {
-                  currentLineBuffer.append(currentCharacter);
-                } else {
-                  increaseGlobalDelta(-1);
-                }
-              } else {
-                currentLineBuffer.append(currentCharacter);
-              }
-              break;
-            default :
-              if (pendingCarriageReturn) {
-                pendingCarriageReturn = false;
-                increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
-                currentLineBuffer.append(options.lineSeparatorSequence);
-                beginningOfLineSpaces = 0;
-                endOfLine = true;
-              } else {
-                beginningOfLineSpaces = 0;
-                currentLineBuffer.append(currentCharacter);
-                endOfLine = false;
-              }
+    case Scanner.TokenNameCOMMENT_PHPDOC:
+    case Scanner.TokenNameCOMMENT_BLOCK:
+    case Scanner.TokenNameCOMMENT_LINE:
+      boolean endOfLine = false;
+      int currentCommentOffset = getCurrentCommentOffset();
+      int beginningOfLineSpaces = 0;
+      endOfLine = false;
+      currentCommentOffset = getCurrentCommentOffset();
+      beginningOfLineSpaces = 0;
+      boolean pendingCarriageReturn = false;
+      for (int i = startPosition, max = scanner.currentPosition; i < max; i++) {
+        char currentCharacter = source[i];
+        updateMappedPositions(i);
+        switch (currentCharacter) {
+        case '\r':
+          pendingCarriageReturn = true;
+          endOfLine = true;
+          break;
+        case '\n':
+          if (pendingCarriageReturn) {
+            increaseGlobalDelta(options.lineSeparatorSequence.length - 2);
+          } else {
+            increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
+          }
+          pendingCarriageReturn = false;
+          currentLineBuffer.append(options.lineSeparatorSequence);
+          beginningOfLineSpaces = 0;
+          endOfLine = true;
+          break;
+        case '\t':
+          if (pendingCarriageReturn) {
+            pendingCarriageReturn = false;
+            increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
+            currentLineBuffer.append(options.lineSeparatorSequence);
+            beginningOfLineSpaces = 0;
+            endOfLine = true;
+          }
+          if (endOfLine) {
+            // we remove a maximum of currentCommentOffset characters (tabs
+            // are converted to space numbers).
+            beginningOfLineSpaces += options.tabSize;
+            if (beginningOfLineSpaces > currentCommentOffset) {
+              currentLineBuffer.append(currentCharacter);
+            } else {
+              increaseGlobalDelta(-1);
+            }
+          } else {
+            currentLineBuffer.append(currentCharacter);
+          }
+          break;
+        case ' ':
+          if (pendingCarriageReturn) {
+            pendingCarriageReturn = false;
+            increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
+            currentLineBuffer.append(options.lineSeparatorSequence);
+            beginningOfLineSpaces = 0;
+            endOfLine = true;
+          }
+          if (endOfLine) {
+            // we remove a maximum of currentCommentOffset characters (tabs
+            // are converted to space numbers).
+            beginningOfLineSpaces++;
+            if (beginningOfLineSpaces > currentCommentOffset) {
+              currentLineBuffer.append(currentCharacter);
+            } else {
+              increaseGlobalDelta(-1);
+            }
+          } else {
+            currentLineBuffer.append(currentCharacter);
+          }
+          break;
+        default:
+          if (pendingCarriageReturn) {
+            pendingCarriageReturn = false;
+            increaseGlobalDelta(options.lineSeparatorSequence.length - 1);
+            currentLineBuffer.append(options.lineSeparatorSequence);
+            beginningOfLineSpaces = 0;
+            endOfLine = true;
+          } else {
+            beginningOfLineSpaces = 0;
+            currentLineBuffer.append(currentCharacter);
+            endOfLine = false;
           }
         }
-        updateMappedPositions(scanner.currentPosition - 1);
-        multipleLineCommentCounter++;
-        break;
-      default :
-        for (int i = startPosition, max = scanner.currentPosition; i < max; i++) {
-          char currentCharacter = source[i];
-          updateMappedPositions(i);
-          currentLineBuffer.append(currentCharacter);
-        }
+      }
+      updateMappedPositions(scanner.currentPosition - 1);
+      multipleLineCommentCounter++;
+      break;
+    default:
+      for (int i = startPosition, max = scanner.currentPosition; i < max; i++) {
+        char currentCharacter = source[i];
+        updateMappedPositions(i);
+        currentLineBuffer.append(currentCharacter);
+      }
     }
   }
+
   /**
    * Outputs <code>currentString</code>:<br>
    * <ul>
@@ -1587,17 +1555,16 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
    * </ul>
    * 
    * @param currentString
-   *            string to output
+   *          string to output
    * @param preIndented
-   *            whether the string to output was pre-indented
+   *          whether the string to output was pre-indented
    * @param depth
-   *            number of indentation to put in front of <code>currentString</code>
+   *          number of indentation to put in front of <code>currentString</code>
    * @param operator
-   *            value of the operator belonging to <code>currentString</code>.
+   *          value of the operator belonging to <code>currentString</code>.
    */
-  private void outputLine(String currentString, boolean preIndented, int depth,
-      int operator, int substringIndex, int[] startSubstringIndexes,
-      int offsetInGlobalLine) {
+  private void outputLine(String currentString, boolean preIndented, int depth, int operator, int substringIndex,
+      int[] startSubstringIndexes, int offsetInGlobalLine) {
     boolean emptyFirstSubString = false;
     String operatorString = operatorString(operator);
     boolean placeOperatorBehind = !breakLineBeforeOperator(operator);
@@ -1615,9 +1582,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         }
         formattedSource.append(operatorString);
         increaseSplitDelta(operatorString.length());
-        if (insertSpaceAfter(operator)
-            && operator != TokenNameimplements
-            && operator != TokenNameextends) {
+        if (insertSpaceAfter(operator) && operator != TokenNameimplements && operator != TokenNameextends) {
           //                   && operator != TokenNamethrows) {
           formattedSource.append(' ');
           increaseSplitDelta(1);
@@ -1625,15 +1590,13 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       }
     }
     SplitLine splitLine = null;
-    if (options.maxLineLength == 0
-        || getLength(currentString, depth) < options.maxLineLength
+    if (options.maxLineLength == 0 || getLength(currentString, depth) < options.maxLineLength
         || (splitLine = split(currentString, offsetInGlobalLine)) == null) {
       // depending on the type of operator, outputs new line before of after
       // dumping it
       // indent before postfix operator
       // indent also when the line cannot be split
-      if (operator == TokenNameextends
-          || operator == TokenNameimplements ) {
+      if (operator == TokenNameextends || operator == TokenNameimplements) {
         //                             || operator == TokenNamethrows) {
         formattedSource.append(' ');
         increaseSplitDelta(1);
@@ -1646,13 +1609,11 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       int max = currentString.length();
       if (multipleLineCommentCounter != 0) {
         try {
-          BufferedReader reader = new BufferedReader(new StringReader(
-              currentString));
+          BufferedReader reader = new BufferedReader(new StringReader(currentString));
           String line = reader.readLine();
           while (line != null) {
-            updateMappedPositionsWhileSplitting(beginningOfLineIndex,
-                beginningOfLineIndex + line.length()
-                    + options.lineSeparatorSequence.length);
+            updateMappedPositionsWhileSplitting(beginningOfLineIndex, beginningOfLineIndex + line.length()
+                + options.lineSeparatorSequence.length);
             formattedSource.append(line);
             beginningOfLineIndex = beginningOfLineIndex + line.length();
             if ((line = reader.readLine()) != null) {
@@ -1666,42 +1627,38 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           e.printStackTrace();
         }
       } else {
-        updateMappedPositionsWhileSplitting(beginningOfLineIndex,
-            beginningOfLineIndex + max);
+        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);
+          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);
+          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]);
+          increaseSplitDelta(startSubstringIndexes[substringIndex] + max - startSubstringIndexes[substringIndex + 1]);
         }
       }
       // dump postfix operator?
@@ -1721,8 +1678,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     }
     // 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)) {
+    if (options.maxLineLength != 0 && splitLine != null && (operator == TokenNameextends)) {
       //                               || operator == TokenNameimplements
       //                               || operator == TokenNamethrows)) {
       formattedSource.append(options.lineSeparatorSequence);
@@ -1759,10 +1715,8 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
         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
+        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);
@@ -1784,8 +1738,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
           }
           formattedSource.append(lastOperatorString);
           increaseSplitDelta(lastOperatorString.length());
-          if (insertSpaceAfter(lastOperator) && lastOperator != TokenNameimplements
-              && lastOperator != TokenNameextends) {
+          if (insertSpaceAfter(lastOperator) && lastOperator != TokenNameimplements && lastOperator != TokenNameextends) {
             //                                 && lastOperator != TokenNamethrows) {
             formattedSource.append(' ');
             increaseSplitDelta(1);
@@ -1802,21 +1755,21 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       //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)) {
+    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>.
+   * 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;
@@ -1828,13 +1781,13 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     }
     return delta;
   }
+
   /**
-   * Pops elements until the stack is empty or the top element is <code>token</code>.
-   * <br>
+   * 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
+   *          the token to be left as the top of the stack
    */
   private int popExclusiveUntil(int token) {
     int delta = 0;
@@ -1846,44 +1799,43 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     }
     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>
+   * 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--) {
+    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>
+   * 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
+    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>
+   * 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
+   *          the token to remove from the stack
    */
   private int popInclusiveUntil(int token) {
     int startCount = constructionsCount;
@@ -1900,16 +1852,15 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     }
     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>
+   * 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--) {
+    for (int i = startCount - 1; i >= 0 && (constructions[i] != BLOCK && constructions[i] != NONINDENT_BLOCK); i--) {
       delta--;
       constructionsCount--;
     }
@@ -1920,22 +1871,18 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     }
     return delta;
   }
+
   /**
    * Pushes a block in the stack. <br>
-   * Pushes a <code>BLOCK</code> if the stack is empty or if the top element
-   * is a <code>BLOCK</code>, pushes <code>NONINDENT_BLOCK</code>
-   * otherwise. Creates a new bigger array if the current one is full.
+   * Pushes a <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)) {
+      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 {
@@ -1943,33 +1890,31 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     }
     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);
+      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;
+    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.
+   * 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.
+   *          int[]
+   * @deprecated Set the positions to map using the format(String, int, int[]) method.
    * 
    * @see #getMappedPositions()
    */
@@ -1979,6 +1924,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     globalDelta = 0;
     mappedPositions = new int[positions.length];
   }
+
   /**
    * Appends a space character to the current line buffer.
    */
@@ -1986,29 +1932,26 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     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.
+   * 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
+   * @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.
+   * 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
+   * @return an object containing the operator and all the substrings or null if the string cannot be split
    */
   public SplitLine split(String stringToSplit, int offsetInGlobalLine) {
     /*
-     * See http://dev.eclipse.org/bugs/show_bug.cgi?id=12540 and
-     * http://dev.eclipse.org/bugs/show_bug.cgi?id=14387
+     * See http://dev.eclipse.org/bugs/show_bug.cgi?id=12540 and http://dev.eclipse.org/bugs/show_bug.cgi?id=14387
      */
     if (stringToSplit.indexOf("//$NON-NLS") != -1) { //$NON-NLS-1$
       return null;
@@ -2016,475 +1959,477 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     // split doesn't work correct for PHP
     return null;
     // local variables
-//    int currentToken = 0;
-//    int splitTokenType = 0;
-//    int splitTokenDepth = Integer.MAX_VALUE;
-//    int splitTokenPriority = Integer.MAX_VALUE;
-//    int[] substringsStartPositions = new int[10];
-//    // contains the start position of substrings
-//    int[] substringsEndPositions = new int[10];
-//    // contains the start position of substrings
-//    int substringsCount = 1; // index in the substringsStartPosition array
-//    int[] splitOperators = new int[10];
-//    // contains the start position of substrings
-//    int splitOperatorsCount = 0; // index in the substringsStartPosition array
-//    int[] openParenthesisPosition = new int[10];
-//    int openParenthesisPositionCount = 0;
-//    int position = 0;
-//    int lastOpenParenthesisPosition = -1;
-//    // used to remember the position of the 1st open parenthesis
-//    // needed for a pattern like: A.B(C); we want formatted like A.B( split C);
-//    // setup the scanner with a new source
-//    int lastCommentStartPosition = -1;
-//    // to remember the start position of the last comment
-//    int firstTokenOnLine = -1;
-//    // to remember the first token of the line
-//    int previousToken = -1;
-//    // to remember the previous token.
-//    splitScanner.setSource(stringToSplit.toCharArray());
-//    try {
-//      // start the loop
-//      while (true) {
-//        // takes the next token
-//        try {
-//          if (currentToken != Scanner.TokenNameWHITESPACE)
-//            previousToken = currentToken;
-//          currentToken = splitScanner.getNextToken();
-//          if (Scanner.DEBUG) {
-//            int currentEndPosition = splitScanner.getCurrentTokenEndPosition();
-//            int currentStartPosition = splitScanner
-//                .getCurrentTokenStartPosition();
-//            System.out.print(currentStartPosition + "," + currentEndPosition
-//                + ": ");
-//            System.out.println(scanner.toStringAction(currentToken));
-//          }
-//        } catch (InvalidInputException e) {
-//          if (!handleInvalidToken(e))
-//            throw e;
-//          currentToken = 0;
-//          // this value is not modify when an exception is raised.
-//        }
-//        if (currentToken == TokenNameEOF)
-//          break;
-//        if (firstTokenOnLine == -1) {
-//          firstTokenOnLine = currentToken;
-//        }
-//        switch (currentToken) {
-//          case TokenNameRBRACE :
-//          case TokenNameRPAREN :
-//            if (openParenthesisPositionCount > 0) {
-//              if (openParenthesisPositionCount == 1
-//                  && lastOpenParenthesisPosition < openParenthesisPosition[0]) {
-//                lastOpenParenthesisPosition = openParenthesisPosition[0];
-//              } else if ((splitTokenDepth == Integer.MAX_VALUE)
-//                  || (splitTokenDepth > openParenthesisPositionCount && openParenthesisPositionCount == 1)) {
-//                splitTokenType = 0;
-//                splitTokenDepth = openParenthesisPositionCount;
-//                splitTokenPriority = Integer.MAX_VALUE;
-//                substringsStartPositions[0] = 0;
-//                // better token means the whole line until now is the first
-//                // substring
-//                substringsCount = 1; // resets the count of substrings
-//                substringsEndPositions[0] = openParenthesisPosition[0];
-//                // substring ends on operator start
-//                position = openParenthesisPosition[0];
-//                // the string mustn't be cut before the closing parenthesis but
-//                // after the opening one.
-//                splitOperatorsCount = 1; // resets the count of split operators
-//                splitOperators[0] = 0;
-//              }
-//              openParenthesisPositionCount--;
-//            }
-//            break;
-//          case TokenNameLBRACE :
-//          case TokenNameLPAREN :
-//            if (openParenthesisPositionCount == openParenthesisPosition.length) {
-//              System
-//                  .arraycopy(
-//                      openParenthesisPosition,
-//                      0,
-//                      (openParenthesisPosition = new int[openParenthesisPositionCount * 2]),
-//                      0, openParenthesisPositionCount);
-//            }
-//            openParenthesisPosition[openParenthesisPositionCount++] = splitScanner.currentPosition;
-//            if (currentToken == TokenNameLPAREN
-//                && previousToken == TokenNameRPAREN) {
-//              openParenthesisPosition[openParenthesisPositionCount - 1] = splitScanner.startPosition;
-//            }
-//            break;
-//          case TokenNameSEMICOLON :
-//          // ;
-//          case TokenNameCOMMA :
-//          // ,
-//          case TokenNameEQUAL :
-//            // =
-//            if (openParenthesisPositionCount < splitTokenDepth
-//                || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority > getTokenPriority(currentToken))) {
-//              // the current token is better than the one we currently have
-//              // (in level or in priority if same level)
-//              // reset the substringsCount
-//              splitTokenDepth = openParenthesisPositionCount;
-//              splitTokenType = currentToken;
-//              splitTokenPriority = getTokenPriority(currentToken);
-//              substringsStartPositions[0] = 0;
-//              // better token means the whole line until now is the first
-//              // substring
-//              if (separateFirstArgumentOn(firstTokenOnLine)
-//                  && openParenthesisPositionCount > 0) {
-//                substringsCount = 2; // resets the count of substrings
-//                substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1];
-//                substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1];
-//                substringsEndPositions[1] = splitScanner.startPosition;
-//                splitOperatorsCount = 2; // resets the count of split operators
-//                splitOperators[0] = 0;
-//                splitOperators[1] = currentToken;
-//                position = splitScanner.currentPosition;
-//                // next substring will start from operator end
-//              } else {
-//                substringsCount = 1; // resets the count of substrings
-//                substringsEndPositions[0] = splitScanner.startPosition;
-//                // substring ends on operator start
-//                position = splitScanner.currentPosition;
-//                // next substring will start from operator end
-//                splitOperatorsCount = 1; // resets the count of split operators
-//                splitOperators[0] = currentToken;
-//              }
-//            } else {
-//              if ((openParenthesisPositionCount == splitTokenDepth && splitTokenPriority == getTokenPriority(currentToken))
-//                  && splitTokenType != TokenNameEQUAL
-//                  && currentToken != TokenNameEQUAL) {
-//                // fix for 1FG0BCN: LFCOM:WIN98 - Missing one indentation after
-//                // split
-//                // take only the 1st = into account.
-//                // if another token with the same priority is found,
-//                // push the start position of the substring and
-//                // push the token into the stack.
-//                // create a new array object if the current one is full.
-//                if (substringsCount == substringsStartPositions.length) {
-//                  System
-//                      .arraycopy(
-//                          substringsStartPositions,
-//                          0,
-//                          (substringsStartPositions = new int[substringsCount * 2]),
-//                          0, substringsCount);
-//                  System.arraycopy(substringsEndPositions, 0,
-//                      (substringsEndPositions = new int[substringsCount * 2]),
-//                      0, substringsCount);
-//                }
-//                if (splitOperatorsCount == splitOperators.length) {
-//                  System.arraycopy(splitOperators, 0,
-//                      (splitOperators = new int[splitOperatorsCount * 2]), 0,
-//                      splitOperatorsCount);
-//                }
-//                substringsStartPositions[substringsCount] = position;
-//                substringsEndPositions[substringsCount++] = splitScanner.startPosition;
-//                // substring ends on operator start
-//                position = splitScanner.currentPosition;
-//                // next substring will start from operator end
-//                splitOperators[splitOperatorsCount++] = currentToken;
-//              }
-//            }
-//            break;
-//          case TokenNameCOLON :
-//            // : (15.24)
-//            // see 1FK7C5R, we only split on a colon, when it is associated
-//            // with a question-mark.
-//            // indeed it might appear also behind a case statement, and we do
-//            // not to break at this point.
-//            if ((splitOperatorsCount == 0)
-//                || splitOperators[splitOperatorsCount - 1] != TokenNameQUESTION) {
-//              break;
-//            }
-//          case TokenNameextends :
-//          case TokenNameimplements :
-//          //case TokenNamethrows :
-//          case TokenNameDOT :
-//          // .
-//          case TokenNameMULTIPLY :
-//          // * (15.16.1)
-//          case TokenNameDIVIDE :
-//          // / (15.16.2)
-//          case TokenNameREMAINDER :
-//          // % (15.16.3)
-//          case TokenNamePLUS :
-//          // + (15.17, 15.17.2)
-//          case TokenNameMINUS :
-//          // - (15.17.2)
-//          case TokenNameLEFT_SHIFT :
-//          // << (15.18)
-//          case TokenNameRIGHT_SHIFT :
-//          // >> (15.18)
-//          //                         case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
-//          case TokenNameLESS :
-//          // < (15.19.1)
-//          case TokenNameLESS_EQUAL :
-//          // <= (15.19.1)
-//          case TokenNameGREATER :
-//          // > (15.19.1)
-//          case TokenNameGREATER_EQUAL :
-//          // >= (15.19.1)
-//          //                         case TokenNameinstanceof : // instanceof
-//          case TokenNameEQUAL_EQUAL :
-//          // == (15.20, 15.20.1, 15.20.2, 15.20.3)
-//          case TokenNameEQUAL_EQUAL_EQUAL :
-//          // == (15.20, 15.20.1, 15.20.2, 15.20.3)
-//          case TokenNameNOT_EQUAL :
-//          // != (15.20, 15.20.1, 15.20.2, 15.20.3)
-//          case TokenNameNOT_EQUAL_EQUAL :
-//          // != (15.20, 15.20.1, 15.20.2, 15.20.3)
-//          case TokenNameAND :
-//          // & (15.21, 15.21.1, 15.21.2)
-//          case TokenNameOR :
-//          // | (15.21, 15.21.1, 15.21.2)
-//          case TokenNameXOR :
-//          // ^ (15.21, 15.21.1, 15.21.2)
-//          case TokenNameAND_AND :
-//          // && (15.22)
-//          case TokenNameOR_OR :
-//          // || (15.23)
-//          case TokenNameQUESTION :
-//          // ? (15.24)
-//          case TokenNameMULTIPLY_EQUAL :
-//          // *= (15.25.2)
-//          case TokenNameDIVIDE_EQUAL :
-//          // /= (15.25.2)
-//          case TokenNameREMAINDER_EQUAL :
-//          // %= (15.25.2)
-//          case TokenNamePLUS_EQUAL :
-//          // += (15.25.2)
-//          case TokenNameMINUS_EQUAL :
-//          // -= (15.25.2)
-//          case TokenNameLEFT_SHIFT_EQUAL :
-//          // <<= (15.25.2)
-//          case TokenNameRIGHT_SHIFT_EQUAL :
-//          // >>= (15.25.2)
-//          //                                 case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
-//          case TokenNameAND_EQUAL :
-//          // &= (15.25.2)
-//          case TokenNameXOR_EQUAL :
-//          // ^= (15.25.2)
-//          case TokenNameOR_EQUAL :
-//            // |= (15.25.2)
-//            if ((openParenthesisPositionCount < splitTokenDepth || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority > getTokenPriority(currentToken)))
-//                && !((currentToken == TokenNamePLUS || currentToken == TokenNameMINUS) && (previousToken == TokenNameLBRACE
-//                    || previousToken == TokenNameLBRACKET || splitScanner.startPosition == 0))) {
-//              // the current token is better than the one we currently have
-//              // (in level or in priority if same level)
-//              // reset the substringsCount
-//              splitTokenDepth = openParenthesisPositionCount;
-//              splitTokenType = currentToken;
-//              splitTokenPriority = getTokenPriority(currentToken);
-//              substringsStartPositions[0] = 0;
-//              // better token means the whole line until now is the first
-//              // substring
-//              if (separateFirstArgumentOn(firstTokenOnLine)
-//                  && openParenthesisPositionCount > 0) {
-//                substringsCount = 2; // resets the count of substrings
-//                substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1];
-//                substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1];
-//                substringsEndPositions[1] = splitScanner.startPosition;
-//                splitOperatorsCount = 3; // resets the count of split operators
-//                splitOperators[0] = 0;
-//                splitOperators[1] = 0;
-//                splitOperators[2] = currentToken;
-//                position = splitScanner.currentPosition;
-//                // next substring will start from operator end
-//              } else {
-//                substringsCount = 1; // resets the count of substrings
-//                substringsEndPositions[0] = splitScanner.startPosition;
-//                // substring ends on operator start
-//                position = splitScanner.currentPosition;
-//                // next substring will start from operator end
-//                splitOperatorsCount = 2; // resets the count of split operators
-//                splitOperators[0] = 0;
-//                // nothing for first operand since operator will be inserted in
-//                // front of the second operand
-//                splitOperators[1] = currentToken;
-//              }
-//            } else {
-//              if (openParenthesisPositionCount == splitTokenDepth
-//                  && splitTokenPriority == getTokenPriority(currentToken)) {
-//                // if another token with the same priority is found,
-//                // push the start position of the substring and
-//                // push the token into the stack.
-//                // create a new array object if the current one is full.
-//                if (substringsCount == substringsStartPositions.length) {
-//                  System
-//                      .arraycopy(
-//                          substringsStartPositions,
-//                          0,
-//                          (substringsStartPositions = new int[substringsCount * 2]),
-//                          0, substringsCount);
-//                  System.arraycopy(substringsEndPositions, 0,
-//                      (substringsEndPositions = new int[substringsCount * 2]),
-//                      0, substringsCount);
-//                }
-//                if (splitOperatorsCount == splitOperators.length) {
-//                  System.arraycopy(splitOperators, 0,
-//                      (splitOperators = new int[splitOperatorsCount * 2]), 0,
-//                      splitOperatorsCount);
-//                }
-//                substringsStartPositions[substringsCount] = position;
-//                substringsEndPositions[substringsCount++] = splitScanner.startPosition;
-//                // substring ends on operator start
-//                position = splitScanner.currentPosition;
-//                // next substring will start from operator end
-//                splitOperators[splitOperatorsCount++] = currentToken;
-//              }
-//            }
-//          default :
-//            break;
-//        }
-//        if (isComment(currentToken)) {
-//          lastCommentStartPosition = splitScanner.startPosition;
-//        } else {
-//          lastCommentStartPosition = -1;
-//        }
-//      }
-//    } catch (InvalidInputException e) {
-//      return null;
-//    }
-//    // if the string cannot be split, return null.
-//    if (splitOperatorsCount == 0)
-//      return null;
-//    // ## SPECIAL CASES BEGIN
-//    if (((splitOperatorsCount == 2 && splitOperators[1] == TokenNameDOT
-//        && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1)
-//        || (splitOperatorsCount > 2 && splitOperators[1] == TokenNameDOT
-//            && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1 && lastOpenParenthesisPosition <= options.maxLineLength) || (separateFirstArgumentOn(firstTokenOnLine)
-//        && splitTokenDepth > 0 && lastOpenParenthesisPosition > -1))
-//        && (lastOpenParenthesisPosition < splitScanner.source.length && splitScanner.source[lastOpenParenthesisPosition] != ')')) {
-//      // fix for 1FH4J2H: LFCOM:WINNT - Formatter - Empty parenthesis should
-//      // not be broken on two lines
-//      // only one split on a top level .
-//      // or more than one split on . and substring before open parenthesis fits
-//      // one line.
-//      // or split inside parenthesis and first token is not a for/while/if
-//      SplitLine sl = split(
-//          stringToSplit.substring(lastOpenParenthesisPosition),
-//          lastOpenParenthesisPosition);
-//      if (sl == null || sl.operators[0] != TokenNameCOMMA) {
-//        // trim() is used to remove the extra blanks at the end of the
-//        // substring. See PR 1FGYPI1
-//        return new SplitLine(new int[]{0, 0}, new String[]{
-//            stringToSplit.substring(0, lastOpenParenthesisPosition).trim(),
-//            stringToSplit.substring(lastOpenParenthesisPosition)}, new int[]{
-//            offsetInGlobalLine,
-//            lastOpenParenthesisPosition + offsetInGlobalLine});
-//      } else {
-//        // right substring can be split and is split on comma
-//        // copy substrings and operators
-//        // except if the 1st string is empty.
-//        int startIndex = (sl.substrings[0].length() == 0) ? 1 : 0;
-//        int subStringsLength = sl.substrings.length + 1 - startIndex;
-//        String[] result = new String[subStringsLength];
-//        int[] startIndexes = new int[subStringsLength];
-//        int operatorsLength = sl.operators.length + 1 - startIndex;
-//        int[] operators = new int[operatorsLength];
-//        result[0] = stringToSplit.substring(0, lastOpenParenthesisPosition);
-//        operators[0] = 0;
-//        System.arraycopy(sl.startSubstringsIndexes, startIndex, startIndexes,
-//            1, subStringsLength - 1);
-//        for (int i = subStringsLength - 1; i >= 0; i--) {
-//          startIndexes[i] += offsetInGlobalLine;
-//        }
-//        System.arraycopy(sl.substrings, startIndex, result, 1,
-//            subStringsLength - 1);
-//        System.arraycopy(sl.operators, startIndex, operators, 1,
-//            operatorsLength - 1);
-//        return new SplitLine(operators, result, startIndexes);
-//      }
-//    }
-//    // if the last token is a comment and the substring before the comment fits
-//    // on a line,
-//    // split before the comment and return the result.
-//    if (lastCommentStartPosition > -1
-//        && lastCommentStartPosition < options.maxLineLength
-//        && splitTokenPriority > 50) {
-//      int end = lastCommentStartPosition;
-//      int start = lastCommentStartPosition;
-//      if (stringToSplit.charAt(end - 1) == ' ') {
-//        end--;
-//      }
-//      if (start != end && stringToSplit.charAt(start) == ' ') {
-//        start++;
-//      }
-//      return new SplitLine(new int[]{0, 0}, new String[]{
-//          stringToSplit.substring(0, end), stringToSplit.substring(start)},
-//          new int[]{0, start});
-//    }
-//    if (position != stringToSplit.length()) {
-//      if (substringsCount == substringsStartPositions.length) {
-//        System.arraycopy(substringsStartPositions, 0,
-//            (substringsStartPositions = new int[substringsCount * 2]), 0,
-//            substringsCount);
-//        System.arraycopy(substringsEndPositions, 0,
-//            (substringsEndPositions = new int[substringsCount * 2]), 0,
-//            substringsCount);
-//      }
-//      // avoid empty extra substring, e.g. line terminated with a semi-colon
-//      substringsStartPositions[substringsCount] = position;
-//      substringsEndPositions[substringsCount++] = stringToSplit.length();
-//    }
-//    if (splitOperatorsCount == splitOperators.length) {
-//      System.arraycopy(splitOperators, 0,
-//          (splitOperators = new int[splitOperatorsCount * 2]), 0,
-//          splitOperatorsCount);
-//    }
-//    splitOperators[splitOperatorsCount] = 0;
-//    // the last element of the stack is the position of the end of
-//    // StringToSPlit
-//    // +1 because the substring method excludes the last character
-//    String[] result = new String[substringsCount];
-//    for (int i = 0; i < substringsCount; i++) {
-//      int start = substringsStartPositions[i];
-//      int end = substringsEndPositions[i];
-//      if (stringToSplit.charAt(start) == ' ') {
-//        start++;
-//        substringsStartPositions[i]++;
-//      }
-//      if (end != start && stringToSplit.charAt(end - 1) == ' ') {
-//        end--;
-//      }
-//      result[i] = stringToSplit.substring(start, end);
-//      substringsStartPositions[i] += offsetInGlobalLine;
-//    }
-//    if (splitOperatorsCount > substringsCount) {
-//      System.arraycopy(substringsStartPositions, 0,
-//          (substringsStartPositions = new int[splitOperatorsCount]), 0,
-//          substringsCount);
-//      System.arraycopy(substringsEndPositions, 0,
-//          (substringsEndPositions = new int[splitOperatorsCount]), 0,
-//          substringsCount);
-//      for (int i = substringsCount; i < splitOperatorsCount; i++) {
-//        substringsStartPositions[i] = position;
-//        substringsEndPositions[i] = position;
-//      }
-//      System.arraycopy(splitOperators, 0,
-//          (splitOperators = new int[splitOperatorsCount]), 0,
-//          splitOperatorsCount);
-//    } else {
-//      System.arraycopy(substringsStartPositions, 0,
-//          (substringsStartPositions = new int[substringsCount]), 0,
-//          substringsCount);
-//      System.arraycopy(substringsEndPositions, 0,
-//          (substringsEndPositions = new int[substringsCount]), 0,
-//          substringsCount);
-//      System.arraycopy(splitOperators, 0,
-//          (splitOperators = new int[substringsCount]), 0, substringsCount);
-//    }
-//    SplitLine splitLine = new SplitLine(splitOperators, result,
-//        substringsStartPositions);
-//    return splitLine;
+    //    int currentToken = 0;
+    //    int splitTokenType = 0;
+    //    int splitTokenDepth = Integer.MAX_VALUE;
+    //    int splitTokenPriority = Integer.MAX_VALUE;
+    //    int[] substringsStartPositions = new int[10];
+    //    // contains the start position of substrings
+    //    int[] substringsEndPositions = new int[10];
+    //    // contains the start position of substrings
+    //    int substringsCount = 1; // index in the substringsStartPosition array
+    //    int[] splitOperators = new int[10];
+    //    // contains the start position of substrings
+    //    int splitOperatorsCount = 0; // index in the substringsStartPosition array
+    //    int[] openParenthesisPosition = new int[10];
+    //    int openParenthesisPositionCount = 0;
+    //    int position = 0;
+    //    int lastOpenParenthesisPosition = -1;
+    //    // used to remember the position of the 1st open parenthesis
+    //    // needed for a pattern like: A.B(C); we want formatted like A.B( split C);
+    //    // setup the scanner with a new source
+    //    int lastCommentStartPosition = -1;
+    //    // to remember the start position of the last comment
+    //    int firstTokenOnLine = -1;
+    //    // to remember the first token of the line
+    //    int previousToken = -1;
+    //    // to remember the previous token.
+    //    splitScanner.setSource(stringToSplit.toCharArray());
+    //    try {
+    //      // start the loop
+    //      while (true) {
+    //        // takes the next token
+    //        try {
+    //          if (currentToken != Scanner.TokenNameWHITESPACE)
+    //            previousToken = currentToken;
+    //          currentToken = splitScanner.getNextToken();
+    //          if (Scanner.DEBUG) {
+    //            int currentEndPosition = splitScanner.getCurrentTokenEndPosition();
+    //            int currentStartPosition = splitScanner
+    //                .getCurrentTokenStartPosition();
+    //            System.out.print(currentStartPosition + "," + currentEndPosition
+    //                + ": ");
+    //            System.out.println(scanner.toStringAction(currentToken));
+    //          }
+    //        } catch (InvalidInputException e) {
+    //          if (!handleInvalidToken(e))
+    //            throw e;
+    //          currentToken = 0;
+    //          // this value is not modify when an exception is raised.
+    //        }
+    //        if (currentToken == TokenNameEOF)
+    //          break;
+    //        if (firstTokenOnLine == -1) {
+    //          firstTokenOnLine = currentToken;
+    //        }
+    //        switch (currentToken) {
+    //          case TokenNameRBRACE :
+    //          case TokenNameRPAREN :
+    //            if (openParenthesisPositionCount > 0) {
+    //              if (openParenthesisPositionCount == 1
+    //                  && lastOpenParenthesisPosition < openParenthesisPosition[0]) {
+    //                lastOpenParenthesisPosition = openParenthesisPosition[0];
+    //              } else if ((splitTokenDepth == Integer.MAX_VALUE)
+    //                  || (splitTokenDepth > openParenthesisPositionCount && openParenthesisPositionCount == 1)) {
+    //                splitTokenType = 0;
+    //                splitTokenDepth = openParenthesisPositionCount;
+    //                splitTokenPriority = Integer.MAX_VALUE;
+    //                substringsStartPositions[0] = 0;
+    //                // better token means the whole line until now is the first
+    //                // substring
+    //                substringsCount = 1; // resets the count of substrings
+    //                substringsEndPositions[0] = openParenthesisPosition[0];
+    //                // substring ends on operator start
+    //                position = openParenthesisPosition[0];
+    //                // the string mustn't be cut before the closing parenthesis but
+    //                // after the opening one.
+    //                splitOperatorsCount = 1; // resets the count of split operators
+    //                splitOperators[0] = 0;
+    //              }
+    //              openParenthesisPositionCount--;
+    //            }
+    //            break;
+    //          case TokenNameLBRACE :
+    //          case TokenNameLPAREN :
+    //            if (openParenthesisPositionCount == openParenthesisPosition.length) {
+    //              System
+    //                  .arraycopy(
+    //                      openParenthesisPosition,
+    //                      0,
+    //                      (openParenthesisPosition = new int[openParenthesisPositionCount * 2]),
+    //                      0, openParenthesisPositionCount);
+    //            }
+    //            openParenthesisPosition[openParenthesisPositionCount++] = splitScanner.currentPosition;
+    //            if (currentToken == TokenNameLPAREN
+    //                && previousToken == TokenNameRPAREN) {
+    //              openParenthesisPosition[openParenthesisPositionCount - 1] = splitScanner.startPosition;
+    //            }
+    //            break;
+    //          case TokenNameSEMICOLON :
+    //          // ;
+    //          case TokenNameCOMMA :
+    //          // ,
+    //          case TokenNameEQUAL :
+    //            // =
+    //            if (openParenthesisPositionCount < splitTokenDepth
+    //                || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority > getTokenPriority(currentToken))) {
+    //              // the current token is better than the one we currently have
+    //              // (in level or in priority if same level)
+    //              // reset the substringsCount
+    //              splitTokenDepth = openParenthesisPositionCount;
+    //              splitTokenType = currentToken;
+    //              splitTokenPriority = getTokenPriority(currentToken);
+    //              substringsStartPositions[0] = 0;
+    //              // better token means the whole line until now is the first
+    //              // substring
+    //              if (separateFirstArgumentOn(firstTokenOnLine)
+    //                  && openParenthesisPositionCount > 0) {
+    //                substringsCount = 2; // resets the count of substrings
+    //                substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1];
+    //                substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1];
+    //                substringsEndPositions[1] = splitScanner.startPosition;
+    //                splitOperatorsCount = 2; // resets the count of split operators
+    //                splitOperators[0] = 0;
+    //                splitOperators[1] = currentToken;
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //              } else {
+    //                substringsCount = 1; // resets the count of substrings
+    //                substringsEndPositions[0] = splitScanner.startPosition;
+    //                // substring ends on operator start
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //                splitOperatorsCount = 1; // resets the count of split operators
+    //                splitOperators[0] = currentToken;
+    //              }
+    //            } else {
+    //              if ((openParenthesisPositionCount == splitTokenDepth && splitTokenPriority == getTokenPriority(currentToken))
+    //                  && splitTokenType != TokenNameEQUAL
+    //                  && currentToken != TokenNameEQUAL) {
+    //                // fix for 1FG0BCN: LFCOM:WIN98 - Missing one indentation after
+    //                // split
+    //                // take only the 1st = into account.
+    //                // if another token with the same priority is found,
+    //                // push the start position of the substring and
+    //                // push the token into the stack.
+    //                // create a new array object if the current one is full.
+    //                if (substringsCount == substringsStartPositions.length) {
+    //                  System
+    //                      .arraycopy(
+    //                          substringsStartPositions,
+    //                          0,
+    //                          (substringsStartPositions = new int[substringsCount * 2]),
+    //                          0, substringsCount);
+    //                  System.arraycopy(substringsEndPositions, 0,
+    //                      (substringsEndPositions = new int[substringsCount * 2]),
+    //                      0, substringsCount);
+    //                }
+    //                if (splitOperatorsCount == splitOperators.length) {
+    //                  System.arraycopy(splitOperators, 0,
+    //                      (splitOperators = new int[splitOperatorsCount * 2]), 0,
+    //                      splitOperatorsCount);
+    //                }
+    //                substringsStartPositions[substringsCount] = position;
+    //                substringsEndPositions[substringsCount++] = splitScanner.startPosition;
+    //                // substring ends on operator start
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //                splitOperators[splitOperatorsCount++] = currentToken;
+    //              }
+    //            }
+    //            break;
+    //          case TokenNameCOLON :
+    //            // : (15.24)
+    //            // see 1FK7C5R, we only split on a colon, when it is associated
+    //            // with a question-mark.
+    //            // indeed it might appear also behind a case statement, and we do
+    //            // not to break at this point.
+    //            if ((splitOperatorsCount == 0)
+    //                || splitOperators[splitOperatorsCount - 1] != TokenNameQUESTION) {
+    //              break;
+    //            }
+    //          case TokenNameextends :
+    //          case TokenNameimplements :
+    //          //case TokenNamethrows :
+    //          case TokenNameDOT :
+    //          // .
+    //          case TokenNameMULTIPLY :
+    //          // * (15.16.1)
+    //          case TokenNameDIVIDE :
+    //          // / (15.16.2)
+    //          case TokenNameREMAINDER :
+    //          // % (15.16.3)
+    //          case TokenNamePLUS :
+    //          // + (15.17, 15.17.2)
+    //          case TokenNameMINUS :
+    //          // - (15.17.2)
+    //          case TokenNameLEFT_SHIFT :
+    //          // << (15.18)
+    //          case TokenNameRIGHT_SHIFT :
+    //          // >> (15.18)
+    //          // case TokenNameUNSIGNED_RIGHT_SHIFT : // >>> (15.18)
+    //          case TokenNameLESS :
+    //          // < (15.19.1)
+    //          case TokenNameLESS_EQUAL :
+    //          // <= (15.19.1)
+    //          case TokenNameGREATER :
+    //          // > (15.19.1)
+    //          case TokenNameGREATER_EQUAL :
+    //          // >= (15.19.1)
+    //          // case TokenNameinstanceof : // instanceof
+    //          case TokenNameEQUAL_EQUAL :
+    //          // == (15.20, 15.20.1, 15.20.2, 15.20.3)
+    //          case TokenNameEQUAL_EQUAL_EQUAL :
+    //          // == (15.20, 15.20.1, 15.20.2, 15.20.3)
+    //          case TokenNameNOT_EQUAL :
+    //          // != (15.20, 15.20.1, 15.20.2, 15.20.3)
+    //          case TokenNameNOT_EQUAL_EQUAL :
+    //          // != (15.20, 15.20.1, 15.20.2, 15.20.3)
+    //          case TokenNameAND :
+    //          // & (15.21, 15.21.1, 15.21.2)
+    //          case TokenNameOR :
+    //          // | (15.21, 15.21.1, 15.21.2)
+    //          case TokenNameXOR :
+    //          // ^ (15.21, 15.21.1, 15.21.2)
+    //          case TokenNameAND_AND :
+    //          // && (15.22)
+    //          case TokenNameOR_OR :
+    //          // || (15.23)
+    //          case TokenNameQUESTION :
+    //          // ? (15.24)
+    //          case TokenNameMULTIPLY_EQUAL :
+    //          // *= (15.25.2)
+    //          case TokenNameDIVIDE_EQUAL :
+    //          // /= (15.25.2)
+    //          case TokenNameREMAINDER_EQUAL :
+    //          // %= (15.25.2)
+    //          case TokenNamePLUS_EQUAL :
+    //          // += (15.25.2)
+    //          case TokenNameMINUS_EQUAL :
+    //          // -= (15.25.2)
+    //          case TokenNameLEFT_SHIFT_EQUAL :
+    //          // <<= (15.25.2)
+    //          case TokenNameRIGHT_SHIFT_EQUAL :
+    //          // >>= (15.25.2)
+    //          // case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL : // >>>= (15.25.2)
+    //          case TokenNameAND_EQUAL :
+    //          // &= (15.25.2)
+    //          case TokenNameXOR_EQUAL :
+    //          // ^= (15.25.2)
+    //          case TokenNameOR_EQUAL :
+    //            // |= (15.25.2)
+    //            if ((openParenthesisPositionCount < splitTokenDepth || (openParenthesisPositionCount == splitTokenDepth && splitTokenPriority
+    // > getTokenPriority(currentToken)))
+    //                && !((currentToken == TokenNamePLUS || currentToken == TokenNameMINUS) && (previousToken == TokenNameLBRACE
+    //                    || previousToken == TokenNameLBRACKET || splitScanner.startPosition == 0))) {
+    //              // the current token is better than the one we currently have
+    //              // (in level or in priority if same level)
+    //              // reset the substringsCount
+    //              splitTokenDepth = openParenthesisPositionCount;
+    //              splitTokenType = currentToken;
+    //              splitTokenPriority = getTokenPriority(currentToken);
+    //              substringsStartPositions[0] = 0;
+    //              // better token means the whole line until now is the first
+    //              // substring
+    //              if (separateFirstArgumentOn(firstTokenOnLine)
+    //                  && openParenthesisPositionCount > 0) {
+    //                substringsCount = 2; // resets the count of substrings
+    //                substringsEndPositions[0] = openParenthesisPosition[splitTokenDepth - 1];
+    //                substringsStartPositions[1] = openParenthesisPosition[splitTokenDepth - 1];
+    //                substringsEndPositions[1] = splitScanner.startPosition;
+    //                splitOperatorsCount = 3; // resets the count of split operators
+    //                splitOperators[0] = 0;
+    //                splitOperators[1] = 0;
+    //                splitOperators[2] = currentToken;
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //              } else {
+    //                substringsCount = 1; // resets the count of substrings
+    //                substringsEndPositions[0] = splitScanner.startPosition;
+    //                // substring ends on operator start
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //                splitOperatorsCount = 2; // resets the count of split operators
+    //                splitOperators[0] = 0;
+    //                // nothing for first operand since operator will be inserted in
+    //                // front of the second operand
+    //                splitOperators[1] = currentToken;
+    //              }
+    //            } else {
+    //              if (openParenthesisPositionCount == splitTokenDepth
+    //                  && splitTokenPriority == getTokenPriority(currentToken)) {
+    //                // if another token with the same priority is found,
+    //                // push the start position of the substring and
+    //                // push the token into the stack.
+    //                // create a new array object if the current one is full.
+    //                if (substringsCount == substringsStartPositions.length) {
+    //                  System
+    //                      .arraycopy(
+    //                          substringsStartPositions,
+    //                          0,
+    //                          (substringsStartPositions = new int[substringsCount * 2]),
+    //                          0, substringsCount);
+    //                  System.arraycopy(substringsEndPositions, 0,
+    //                      (substringsEndPositions = new int[substringsCount * 2]),
+    //                      0, substringsCount);
+    //                }
+    //                if (splitOperatorsCount == splitOperators.length) {
+    //                  System.arraycopy(splitOperators, 0,
+    //                      (splitOperators = new int[splitOperatorsCount * 2]), 0,
+    //                      splitOperatorsCount);
+    //                }
+    //                substringsStartPositions[substringsCount] = position;
+    //                substringsEndPositions[substringsCount++] = splitScanner.startPosition;
+    //                // substring ends on operator start
+    //                position = splitScanner.currentPosition;
+    //                // next substring will start from operator end
+    //                splitOperators[splitOperatorsCount++] = currentToken;
+    //              }
+    //            }
+    //          default :
+    //            break;
+    //        }
+    //        if (isComment(currentToken)) {
+    //          lastCommentStartPosition = splitScanner.startPosition;
+    //        } else {
+    //          lastCommentStartPosition = -1;
+    //        }
+    //      }
+    //    } catch (InvalidInputException e) {
+    //      return null;
+    //    }
+    //    // if the string cannot be split, return null.
+    //    if (splitOperatorsCount == 0)
+    //      return null;
+    //    // ## SPECIAL CASES BEGIN
+    //    if (((splitOperatorsCount == 2 && splitOperators[1] == TokenNameDOT
+    //        && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1)
+    //        || (splitOperatorsCount > 2 && splitOperators[1] == TokenNameDOT
+    //            && splitTokenDepth == 0 && lastOpenParenthesisPosition > -1 && lastOpenParenthesisPosition <= options.maxLineLength) ||
+    // (separateFirstArgumentOn(firstTokenOnLine)
+    //        && splitTokenDepth > 0 && lastOpenParenthesisPosition > -1))
+    //        && (lastOpenParenthesisPosition < splitScanner.source.length && splitScanner.source[lastOpenParenthesisPosition] != ')')) {
+    //      // fix for 1FH4J2H: LFCOM:WINNT - Formatter - Empty parenthesis should
+    //      // not be broken on two lines
+    //      // only one split on a top level .
+    //      // or more than one split on . and substring before open parenthesis fits
+    //      // one line.
+    //      // or split inside parenthesis and first token is not a for/while/if
+    //      SplitLine sl = split(
+    //          stringToSplit.substring(lastOpenParenthesisPosition),
+    //          lastOpenParenthesisPosition);
+    //      if (sl == null || sl.operators[0] != TokenNameCOMMA) {
+    //        // trim() is used to remove the extra blanks at the end of the
+    //        // substring. See PR 1FGYPI1
+    //        return new SplitLine(new int[]{0, 0}, new String[]{
+    //            stringToSplit.substring(0, lastOpenParenthesisPosition).trim(),
+    //            stringToSplit.substring(lastOpenParenthesisPosition)}, new int[]{
+    //            offsetInGlobalLine,
+    //            lastOpenParenthesisPosition + offsetInGlobalLine});
+    //      } else {
+    //        // right substring can be split and is split on comma
+    //        // copy substrings and operators
+    //        // except if the 1st string is empty.
+    //        int startIndex = (sl.substrings[0].length() == 0) ? 1 : 0;
+    //        int subStringsLength = sl.substrings.length + 1 - startIndex;
+    //        String[] result = new String[subStringsLength];
+    //        int[] startIndexes = new int[subStringsLength];
+    //        int operatorsLength = sl.operators.length + 1 - startIndex;
+    //        int[] operators = new int[operatorsLength];
+    //        result[0] = stringToSplit.substring(0, lastOpenParenthesisPosition);
+    //        operators[0] = 0;
+    //        System.arraycopy(sl.startSubstringsIndexes, startIndex, startIndexes,
+    //            1, subStringsLength - 1);
+    //        for (int i = subStringsLength - 1; i >= 0; i--) {
+    //          startIndexes[i] += offsetInGlobalLine;
+    //        }
+    //        System.arraycopy(sl.substrings, startIndex, result, 1,
+    //            subStringsLength - 1);
+    //        System.arraycopy(sl.operators, startIndex, operators, 1,
+    //            operatorsLength - 1);
+    //        return new SplitLine(operators, result, startIndexes);
+    //      }
+    //    }
+    //    // if the last token is a comment and the substring before the comment fits
+    //    // on a line,
+    //    // split before the comment and return the result.
+    //    if (lastCommentStartPosition > -1
+    //        && lastCommentStartPosition < options.maxLineLength
+    //        && splitTokenPriority > 50) {
+    //      int end = lastCommentStartPosition;
+    //      int start = lastCommentStartPosition;
+    //      if (stringToSplit.charAt(end - 1) == ' ') {
+    //        end--;
+    //      }
+    //      if (start != end && stringToSplit.charAt(start) == ' ') {
+    //        start++;
+    //      }
+    //      return new SplitLine(new int[]{0, 0}, new String[]{
+    //          stringToSplit.substring(0, end), stringToSplit.substring(start)},
+    //          new int[]{0, start});
+    //    }
+    //    if (position != stringToSplit.length()) {
+    //      if (substringsCount == substringsStartPositions.length) {
+    //        System.arraycopy(substringsStartPositions, 0,
+    //            (substringsStartPositions = new int[substringsCount * 2]), 0,
+    //            substringsCount);
+    //        System.arraycopy(substringsEndPositions, 0,
+    //            (substringsEndPositions = new int[substringsCount * 2]), 0,
+    //            substringsCount);
+    //      }
+    //      // avoid empty extra substring, e.g. line terminated with a semi-colon
+    //      substringsStartPositions[substringsCount] = position;
+    //      substringsEndPositions[substringsCount++] = stringToSplit.length();
+    //    }
+    //    if (splitOperatorsCount == splitOperators.length) {
+    //      System.arraycopy(splitOperators, 0,
+    //          (splitOperators = new int[splitOperatorsCount * 2]), 0,
+    //          splitOperatorsCount);
+    //    }
+    //    splitOperators[splitOperatorsCount] = 0;
+    //    // the last element of the stack is the position of the end of
+    //    // StringToSPlit
+    //    // +1 because the substring method excludes the last character
+    //    String[] result = new String[substringsCount];
+    //    for (int i = 0; i < substringsCount; i++) {
+    //      int start = substringsStartPositions[i];
+    //      int end = substringsEndPositions[i];
+    //      if (stringToSplit.charAt(start) == ' ') {
+    //        start++;
+    //        substringsStartPositions[i]++;
+    //      }
+    //      if (end != start && stringToSplit.charAt(end - 1) == ' ') {
+    //        end--;
+    //      }
+    //      result[i] = stringToSplit.substring(start, end);
+    //      substringsStartPositions[i] += offsetInGlobalLine;
+    //    }
+    //    if (splitOperatorsCount > substringsCount) {
+    //      System.arraycopy(substringsStartPositions, 0,
+    //          (substringsStartPositions = new int[splitOperatorsCount]), 0,
+    //          substringsCount);
+    //      System.arraycopy(substringsEndPositions, 0,
+    //          (substringsEndPositions = new int[splitOperatorsCount]), 0,
+    //          substringsCount);
+    //      for (int i = substringsCount; i < splitOperatorsCount; i++) {
+    //        substringsStartPositions[i] = position;
+    //        substringsEndPositions[i] = position;
+    //      }
+    //      System.arraycopy(splitOperators, 0,
+    //          (splitOperators = new int[splitOperatorsCount]), 0,
+    //          splitOperatorsCount);
+    //    } else {
+    //      System.arraycopy(substringsStartPositions, 0,
+    //          (substringsStartPositions = new int[substringsCount]), 0,
+    //          substringsCount);
+    //      System.arraycopy(substringsEndPositions, 0,
+    //          (substringsEndPositions = new int[substringsCount]), 0,
+    //          substringsCount);
+    //      System.arraycopy(splitOperators, 0,
+    //          (splitOperators = new int[substringsCount]), 0, substringsCount);
+    //    }
+    //    SplitLine splitLine = new SplitLine(splitOperators, result,
+    //        substringsStartPositions);
+    //    return splitLine;
   }
+
   private void updateMappedPositions(int startPosition) {
     if (positionsToMap == null) {
       return;
     }
     char[] source = scanner.source;
     int sourceLength = source.length;
-    while (indexToMap < positionsToMap.length
-        && positionsToMap[indexToMap] <= startPosition) {
+    while (indexToMap < positionsToMap.length && positionsToMap[indexToMap] <= startPosition) {
       int posToMap = positionsToMap[indexToMap];
       if (posToMap < 0 || posToMap >= sourceLength) {
         // protection against out of bounds position
@@ -2506,17 +2451,17 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
       indexToMap++;
     }
   }
-  private void updateMappedPositionsWhileSplitting(int startPosition,
-      int endPosition) {
+
+  private void updateMappedPositionsWhileSplitting(int startPosition, int endPosition) {
     if (mappedPositions == null || mappedPositions.length == indexInMap)
       return;
-    while (indexInMap < mappedPositions.length
-        && startPosition <= mappedPositions[indexInMap]
+    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++) {
@@ -2525,25 +2470,26 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter {
     for (int i = 0, max = s.length(); i < max; i++) {
       char currentChar = s.charAt(i);
       switch (currentChar) {
-        case '\t' :
-          length += options.tabSize;
-          break;
-        default :
-          length++;
+      case '\t':
+        length += options.tabSize;
+        break;
+      default:
+        length++;
       }
     }
     return length;
   }
+
   /**
    * Sets the initial indentation level
    * 
    * @param indentationLevel
-   *            new indentation level
+   *          new indentation level
    * 
    * @deprecated
    */
   public void setInitialIndentationLevel(int newIndentationLevel) {
     this.initialIndentationLevel = currentLineIndentationLevel = indentationLevel = newIndentationLevel;
   }
-  
+
 }
\ No newline at end of file
index 049c220..745aaa3 100644 (file)
@@ -192,6 +192,9 @@ public class SplitLine implements ITerminalSymbols {
         case TokenNameOR_EQUAL : // |= (15.25.2)
           operatorString = "|="; //$NON-NLS-1$
           break;
+        case TokenNameDOT_EQUAL : // .=
+          operatorString = ".="; //$NON-NLS-1$
+          break;
         case TokenNameDOT : // .
           operatorString = "."; //$NON-NLS-1$
           break;
index 4c20296..7a33214 100644 (file)
@@ -17,12 +17,13 @@ import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
 import net.sourceforge.phpdt.internal.corext.template.TemplateTranslator;
 import net.sourceforge.phpdt.internal.ui.dialogs.StatusDialog;
 import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
 import net.sourceforge.phpdt.internal.ui.text.template.TemplateVariableProcessor;
 import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
 import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
 import net.sourceforge.phpeclipse.IPreferenceConstants;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jface.action.Action;
@@ -88,7 +89,7 @@ public class EditTemplateDialog extends StatusDialog {
 
        //      SimpleJavaSourceViewerConfiguration(JavaTextTools tools, ITextEditor editor, IContentAssistProcessor processor) {
                SimpleJavaSourceViewerConfiguration(JavaTextTools tools, IContentAssistProcessor processor) {   
-      super(tools, null);
+      super(tools, null, IPHPPartitions.PHP_PARTITIONING);
                        fProcessor= processor;
                }
                
index c7e7b17..30cbe67 100644 (file)
@@ -27,20 +27,19 @@ import net.sourceforge.phpdt.core.JavaCore;
 import net.sourceforge.phpdt.internal.ui.IJavaHelpContextIds;
 import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
 import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
 import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter;
 import net.sourceforge.phpdt.internal.ui.util.TabFolderLayout;
 import net.sourceforge.phpdt.ui.PreferenceConstants;
 import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 import net.sourceforge.phpeclipse.phpeditor.EditorUtility;
 import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
-import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
 import net.sourceforge.phpeclipse.preferences.ColorEditor;
 
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Preferences;
-import net.sourceforge.phpdt.internal.ui.preferences.FoldingConfigurationBlock;
-import net.sourceforge.phpdt.internal.ui.preferences.PreferencesMessages;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.PreferenceConverter;
@@ -52,7 +51,6 @@ import org.eclipse.jface.text.source.SourceViewer;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.events.SelectionListener;
 import org.eclipse.swt.graphics.Color;
@@ -309,7 +307,7 @@ public class JavaEditorPreferencePage extends PreferencePage implements
 
 //  private Button fAddJavaDocTagsButton;
 
-//  private Button fEscapeStringsButton;
+  private Button fEscapeStringsButton;
 
   //   private Button fGuessMethodArgumentsButton;
   private SourceViewer fPreviewViewer;
@@ -609,13 +607,13 @@ public class JavaEditorPreferencePage extends PreferencePage implements
     overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
         OverlayPreferenceStore.BOOLEAN,
         PreferenceConstants.EDITOR_CLOSE_BRACKETS_PHP));
-    overlayKeys
-        .add(new OverlayPreferenceStore.OverlayKey(
-            OverlayPreferenceStore.BOOLEAN,
-            PreferenceConstants.EDITOR_CLOSE_BRACES));
-    overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
-        OverlayPreferenceStore.BOOLEAN,
-        PreferenceConstants.EDITOR_CLOSE_JAVADOCS));
+//    overlayKeys
+//        .add(new OverlayPreferenceStore.OverlayKey(
+//            OverlayPreferenceStore.BOOLEAN,
+//            PreferenceConstants.EDITOR_CLOSE_BRACES));
+//    overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
+//        OverlayPreferenceStore.BOOLEAN,
+//        PreferenceConstants.EDITOR_CLOSE_JAVADOCS));
     overlayKeys
         .add(new OverlayPreferenceStore.OverlayKey(
             OverlayPreferenceStore.BOOLEAN,
@@ -901,7 +899,7 @@ public class JavaEditorPreferencePage extends PreferencePage implements
         SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER, store);
 
     fPreviewViewer.configure(new PHPSourceViewerConfiguration(fJavaTextTools,
-        null));
+        null, IPHPPartitions.PHP_PARTITIONING));
     //         Font font= JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT);
     //         fPreviewViewer.getTextWidget().setFont(font);
     fPreviewViewer.getTextWidget().setFont(
@@ -910,7 +908,8 @@ public class JavaEditorPreferencePage extends PreferencePage implements
     fPreviewViewer.setEditable(false);
     String content = loadPreviewContentFromFile("ColorSettingPreviewCode.txt"); //$NON-NLS-1$
     IDocument document = new Document(content);
-    fJavaTextTools.setupJavaDocumentPartitioner(document, ".php", null); //IJavaPartitions.JAVA_PARTITIONING);
+//    fJavaTextTools.setupJavaDocumentPartitioner(document, ".php", null); //IJavaPartitions.JAVA_PARTITIONING);
+    fJavaTextTools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING);
     fPreviewViewer.setDocument(document);
     return fPreviewViewer.getControl();
   }
@@ -1287,23 +1286,23 @@ public class JavaEditorPreferencePage extends PreferencePage implements
     group.setText(PreferencesMessages
         .getString("JavaEditorPreferencePage.typing.description")); //$NON-NLS-1$
 
-//    label = PreferencesMessages
-//        .getString("JavaEditorPreferencePage.wrapStrings");
-//    //$NON-NLS-1$
-//    Button button = addCheckBox(group, label,
-//        PreferenceConstants.EDITOR_WRAP_STRINGS, 1);
-//
-//    label = PreferencesMessages
-//        .getString("JavaEditorPreferencePage.escapeStrings");
-//    //$NON-NLS-1$
-//    fEscapeStringsButton = addCheckBox(group, label,
-//        PreferenceConstants.EDITOR_ESCAPE_STRINGS, 1);
-//    createDependency(button, fEscapeStringsButton);
+    label = PreferencesMessages
+        .getString("JavaEditorPreferencePage.wrapStrings");
+    //$NON-NLS-1$
+    Button button = addCheckBox(group, label,
+        PreferenceConstants.EDITOR_WRAP_STRINGS, 1);
 
-//    label = PreferencesMessages
-//        .getString("JavaEditorPreferencePage.smartPaste");
-//    //$NON-NLS-1$
-//    addCheckBox(group, label, PreferenceConstants.EDITOR_SMART_PASTE, 1);
+    label = PreferencesMessages
+        .getString("JavaEditorPreferencePage.escapeStrings");
+    //$NON-NLS-1$
+    fEscapeStringsButton = addCheckBox(group, label,
+        PreferenceConstants.EDITOR_ESCAPE_STRINGS, 1);
+    createDependency(button, fEscapeStringsButton);
+
+    label = PreferencesMessages
+        .getString("JavaEditorPreferencePage.smartPaste");
+    //$NON-NLS-1$
+    addCheckBox(group, label, PreferenceConstants.EDITOR_SMART_PASTE, 1);
 
     label = PreferencesMessages
         .getString("JavaEditorPreferencePage.insertSpaceForTabs");
@@ -1324,7 +1323,7 @@ public class JavaEditorPreferencePage extends PreferencePage implements
 //        .getString("JavaEditorPreferencePage.closeBraces");
 //    //$NON-NLS-1$
 //    addCheckBox(group, label, PreferenceConstants.EDITOR_CLOSE_BRACES, 1);
-//
+
 //    label = PreferencesMessages
 //        .getString("JavaEditorPreferencePage.closeJavaDocs");
 //    //$NON-NLS-1$
@@ -1677,8 +1676,8 @@ public class JavaEditorPreferencePage extends PreferencePage implements
 //    boolean closeJavaDocs = fOverlayStore
 //        .getBoolean(PreferenceConstants.EDITOR_CLOSE_JAVADOCS);
 //    fAddJavaDocTagsButton.setEnabled(closeJavaDocs);
-//    fEscapeStringsButton.setEnabled(fOverlayStore
-//        .getBoolean(PreferenceConstants.EDITOR_WRAP_STRINGS));
+    fEscapeStringsButton.setEnabled(fOverlayStore
+        .getBoolean(PreferenceConstants.EDITOR_WRAP_STRINGS));
     //         boolean fillMethodArguments=
     // fOverlayStore.getBoolean(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES);
     //         fGuessMethodArgumentsButton.setEnabled(fillMethodArguments);
index 6500ee1..72ab748 100644 (file)
@@ -25,12 +25,13 @@ import net.sourceforge.phpdt.core.JavaCore;
 import net.sourceforge.phpdt.internal.ui.PHPUIMessages;
 import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
 import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
 import net.sourceforge.phpdt.internal.ui.util.TabFolderLayout;
 import net.sourceforge.phpdt.ui.PreferenceConstants;
 import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
 import net.sourceforge.phpeclipse.IPreferenceConstants;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
 import net.sourceforge.phpeclipse.preferences.ColorEditor;
 
 import org.eclipse.core.runtime.IStatus;
@@ -760,12 +761,12 @@ public class PHPEditorPreferencePage extends PreferencePage
         .add(new OverlayPreferenceStore.OverlayKey(
             OverlayPreferenceStore.BOOLEAN,
             PreferenceConstants.EDITOR_SMART_PASTE));
-    // overlayKeys.add(new
-    // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
-    // PreferenceConstants.EDITOR_CLOSE_STRINGS));
-    // overlayKeys.add(new
-    // OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
-    // PreferenceConstants.EDITOR_CLOSE_BRACKETS));
+//     overlayKeys.add(new
+//     OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+//     PreferenceConstants.EDITOR_CLOSE_STRINGS));
+//     overlayKeys.add(new
+//     OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
+//     PreferenceConstants.EDITOR_CLOSE_BRACKETS));
     overlayKeys
         .add(new OverlayPreferenceStore.OverlayKey(
             OverlayPreferenceStore.BOOLEAN,
@@ -1060,7 +1061,7 @@ public class PHPEditorPreferencePage extends PreferencePage
     fPreviewViewer = new SourceViewer(parent, null, SWT.V_SCROLL | SWT.H_SCROLL
         | SWT.BORDER);
     fPreviewViewer.configure(new PHPSourceViewerConfiguration(fJavaTextTools,
-        null));
+        null, IPHPPartitions.PHP_PARTITIONING));
     fPreviewViewer.getTextWidget().setFont(
         JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT));
     fPreviewViewer.setEditable(false);
index d719efe..f375353 100644 (file)
@@ -11,12 +11,13 @@ import net.sourceforge.phpdt.internal.corext.template.Template;
 import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
 import net.sourceforge.phpdt.internal.corext.template.TemplateSet;
 import net.sourceforge.phpdt.internal.corext.template.Templates;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
 import net.sourceforge.phpdt.internal.ui.text.template.TemplateContentProvider;
 import net.sourceforge.phpdt.internal.ui.text.template.TemplateLabelProvider;
 import net.sourceforge.phpdt.internal.ui.util.SWTUtil;
 import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jface.dialogs.ErrorDialog;
@@ -359,7 +360,7 @@ public class TemplatePreferencePage
     document.setDocumentPartitioner(partitioner);
     partitioner.connect(document);
 
-    viewer.configure(new PHPSourceViewerConfiguration(tools, null));
+    viewer.configure(new PHPSourceViewerConfiguration(tools, null, IPHPPartitions.PHP_PARTITIONING));
     // (tools, null));
     viewer.setEditable(false);
     viewer.setDocument(document);
index 26116e0..cb1a56d 100644 (file)
@@ -1,14 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package net.sourceforge.phpdt.internal.ui.text;
 
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
 
+import org.eclipse.jface.text.Assert;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.rules.ICharacterScanner;
-import org.eclipse.jface.util.Assert;
 
 
 
@@ -105,8 +111,13 @@ public final class BufferedDocumentScanner implements ICharacterScanner {
                                fOffset= 0;
                        }
                }
-
+        try {
                return fBuffer[fOffset++];
+        } catch (ArrayIndexOutOfBoundsException e) {
+          System.out.println("Offset:"+fOffset);
+          System.out.println("Buffer:"+fBuffer);
+          throw e;
+        }
        }
 
        /*
@@ -148,4 +159,4 @@ public final class BufferedDocumentScanner implements ICharacterScanner {
        public final char[][] getLegalLineDelimiters() {
                return fDelimiters;
        }
-}
\ No newline at end of file
+}
index 70f5461..ed3302f 100644 (file)
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package net.sourceforge.phpdt.internal.ui.text;
 
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
+import net.sourceforge.phpeclipse.ui.text.rules.AbstractPartitioner;
 
+import org.eclipse.jface.text.Assert;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.rules.ICharacterScanner;
 import org.eclipse.jface.text.rules.IPartitionTokenScanner;
 import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
 import org.eclipse.jface.text.rules.Token;
 
-
 /**
- * This scanner recognizes the JavaDoc comments, Java multi line comments, Java single line comments,
- * Java strings and Java characters.
+ * This scanner recognizes the JavaDoc comments, Java multi line comments, Java single line comments, Java strings.
  */
-public class FastJavaPartitionScanner implements IPartitionTokenScanner {
-
-//     private final static String SKIP= "__skip"; //$NON-NLS-1$       
-//     public final static String JAVA_STRING= "__php_string"; //$NON-NLS-1$
-//     public final static String JAVA_SINGLE_LINE_COMMENT= "__php_singleline_comment"; //$NON-NLS-1$
-//     public final static String JAVA_MULTI_LINE_COMMENT= "__php_multiline_comment"; //$NON-NLS-1$
-//     public final static String JAVA_DOC= "__php_phpdoc"; //$NON-NLS-1$
-
-       // states
-       private static final int HTML= 0;       
-       private static final int SINGLE_LINE_COMMENT= 1; 
-       private static final int MULTI_LINE_COMMENT= 2;
-       private static final int PHPDOC= 3;
-//     private static final int CHARACTER= 4;
-       private static final int STRING_SQ= 4;  // single quote string
-       private static final int STRING_DQ= 5;  // double quote string
-       private static final int PHP= 6;  // double quote string
-       
-       // beginning of prefixes and postfixes
-       private static final int NONE= 0;
-       private static final int BACKSLASH= 1; // postfix for STRING and CHARACTER
-       private static final int SLASH= 2; // prefix for SINGLE_LINE or MULTI_LINE or JAVADOC
-       private static final int SLASH_STAR= 3; // prefix for MULTI_LINE_COMMENT or JAVADOC
-       private static final int SLASH_STAR_STAR= 4; // prefix for MULTI_LINE_COMMENT or JAVADOC
-       private static final int STAR= 5; // postfix for MULTI_LINE_COMMENT or JAVADOC
-       private static final int CARRIAGE_RETURN=6; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT
-       
-       /** The scanner. */
-//     private final BufferedRuleBasedScanner fScanner= new BufferedRuleBasedScanner(1000);
-       private final BufferedDocumentScanner fScanner= new BufferedDocumentScanner(1000);      // faster implementation
-       
-       /** The offset of the last returned token. */
-       private int fTokenOffset;
-       /** The length of the last returned token. */
-       private int fTokenLength;
-       
-       /** The state of the scanner. */        
-       private int fState;
-       /** The last significant characters read. */
-       private int fLast;
-       /** The amount of characters already read on first call to nextToken(). */
-       private int fPrefixLength;
-       
-       // emulate JavaPartitionScanner 
-//     private static final boolean fgEmulate= false;
-       private int fJavaOffset;
-       private int fJavaLength;
-       
-       private final IToken[] fTokens= new IToken[] {
-               new Token(null),
-               new Token(IPHPPartitions.PHP_SINGLELINE_COMMENT),
-               new Token(IPHPPartitions.PHP_MULTILINE_COMMENT),
-               new Token(IPHPPartitions.PHP_PHPDOC_COMMENT),
-               new Token(IPHPPartitions.PHP_STRING_SQ),
-               new Token(IPHPPartitions.PHP_STRING_DQ),
-               new Token(IPHPPartitions.PHP_PARTITIONING),
-       };
-
-       /*
-        * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
-        */
-       public IToken nextToken() {
-
-               fTokenOffset += fTokenLength;
-               fTokenLength= fPrefixLength;
-
-               while (true) {
-                       final int ch= fScanner.read();
-                       
-                       // characters
-                       switch (ch) {
-                       case ICharacterScanner.EOF:
-                               if (fTokenLength > 0) {
-                                       fLast= NONE; // ignore last
-                                       return preFix(fState, HTML, NONE, 0);
-
-                               } else {
-                                       fLast= NONE;
-                                       fPrefixLength= 0;
-                                       return Token.EOF;
-                               }
-
-                       case '\r':
-                               if ( fLast != CARRIAGE_RETURN) {
-                                               fLast= CARRIAGE_RETURN;
-                                               fTokenLength++;
-                                               continue;
-
-                               } else {
-                                       
-                                       switch (fState) {
-                                       case SINGLE_LINE_COMMENT:
-//                                     case CHARACTER:
-                                       case STRING_SQ:  
-                                       case STRING_DQ:
-                                               if (fTokenLength > 0) {
-                                                       IToken token= fTokens[fState];
-                                                       
-                                                       // emulate JavaPartitionScanner
-//                                                     if (fgEmulate) {
-//                                                             fTokenLength++;
-//                                                             fLast= NONE;
-//                                                             fPrefixLength= 0;
-//                                                     } else {                                                                
-                                                               fLast= CARRIAGE_RETURN; 
-                                                               fPrefixLength= 1;
-//                                                     }
-                                                       
-                                                       fState= HTML;
-                                                       return token;
-
-                                               } else {
-                                                       consume();
-                                                       continue;       
-                                               }
-
-                                       default:
-                                               consume();
-                                               continue;
-                                       }                                       
-                               }
-       
-                       case '\n':                              
-                               switch (fState) {
-                               case SINGLE_LINE_COMMENT:
-//                             case CHARACTER:
-                               case STRING_SQ:
-                               case STRING_DQ:                         
-                                       // assert(fTokenLength > 0);
-                                       return postFix(fState);
-
-                               default:
-                                       consume();
-                                       continue;
-                               }
-
-                       default:
-                               if ( fLast == CARRIAGE_RETURN) {                        
-                                       switch (fState) {
-                                       case SINGLE_LINE_COMMENT:
-//                                     case CHARACTER:
-                                       case STRING_SQ:
-                                       case STRING_DQ:
-
-                                               int last;
-                                               int newState;
-                                               switch (ch) {
-                                               case '/':
-                                                       last= SLASH;
-                                                       newState= HTML;
-                                                       break;
-
-                                               case '*':
-                                                       last= STAR;
-                                                       newState= HTML;
-                                                       break;
-                                               
-                                               case '\'':
-                                                       last= NONE;
-       //                                              newState= CHARACTER;
-                                                       newState= STRING_SQ;
-                                                       break;
-
-                                               case '"':
-                                                       last= NONE;
-                                                       newState= STRING_DQ;
-                                                       break;
-
-                                               case '\r':
-                                                       last= CARRIAGE_RETURN;
-                                                       newState= HTML;
-                                                       break;
-
-                                               case '\\':
-                                                       last= BACKSLASH;
-                                                       newState= HTML;
-                                                       break;
-
-                                               default:
-                                                       last= NONE;
-                                                       newState= HTML;
-                                                       break;
-                                               }
-                                               
-                                               fLast= NONE; // ignore fLast
-                                               return preFix(fState, newState, last, 1);
-       
-                                       default:
-                                               break;
-                                       }
-                               }
-                       }
-
-                       // states        
-                       switch (fState) {
-                       case PHP:
-                               switch (ch) {
-                               case '/':
-                                       if (fLast == SLASH) {
-                                               if (fTokenLength - getLastLength(fLast) > 0) {
-                                                       return preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2);
-                                               } else {                                                        
-                                                       preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2);
-                                                       fTokenOffset += fTokenLength;
-                                                       fTokenLength= fPrefixLength;
-                                                       break;
-                                               }
-       
-                                       } else {
-                                               fTokenLength++;
-                                               fLast= SLASH;
-                                               break;
-                                       }
-       
-                               case '*':
-                                       if (fLast == SLASH) {
-                                               if (fTokenLength - getLastLength(fLast) > 0)
-                                                       return preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2);
-                                               else {
-                                                       preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2);
-                                                       fTokenOffset += fTokenLength;
-                                                       fTokenLength= fPrefixLength;
-                                                       break;
-                                               }
-
-                                       } else {
-                                               consume();
-                                               break;
-                                       }
-                                       
-                               case '\'':
-                                       fLast= NONE; // ignore fLast
-                                       if (fTokenLength > 0)
-                                               return preFix(PHP, STRING_SQ, NONE, 1);
-                                       else {                                          
-                                               preFix(PHP, STRING_SQ, NONE, 1);
-                                               fTokenOffset += fTokenLength;
-                                               fTokenLength= fPrefixLength;
-                                               break;
-                                       }
-
-                               case '"':
-                                       fLast= NONE; // ignore fLast                            
-                                       if (fTokenLength > 0)
-                                               return preFix(PHP, STRING_DQ, NONE, 1);
-                                       else {
-                                               preFix(PHP, STRING_DQ, NONE, 1);
-                                               fTokenOffset += fTokenLength;
-                                               fTokenLength= fPrefixLength;
-                                               break;
-                                       }
-       
-                               default:
-                                       consume();
-                                       break;
-                               }
-                               break;
-       
-                       case SINGLE_LINE_COMMENT:
-                               consume();
-                               break;
-                               
-                       case PHPDOC:
-                               switch (ch) {
-                               case '/':
-                                       switch (fLast) {
-                                       case SLASH_STAR_STAR:
-                                               return postFix(MULTI_LINE_COMMENT);
-       
-                                       case STAR:
-                                               return postFix(PHPDOC);
-
-                                       default:
-                                               consume();
-                                               break;
-                                       }
-                                       break;
-
-                               case '*':
-                                       fTokenLength++;
-                                       fLast= STAR;
-                                       break;
-
-                               default:
-                                       consume();
-                                       break;
-                               }
-                               break;
-       
-                       case MULTI_LINE_COMMENT:
-                               switch (ch) {
-                               case '*':
-                                       if (fLast == SLASH_STAR) {
-                                               fLast= SLASH_STAR_STAR;
-                                               fTokenLength++;
-                                               fState= PHPDOC;
-                                       } else {
-                                               fTokenLength++;
-                                               fLast= STAR;
-                                       }
-                                       break;
-       
-                               case '/':
-                                       if (fLast == STAR) {
-                                               return postFix(MULTI_LINE_COMMENT);
-                                       } else {
-                                               consume();
-                                               break;
-                                       }
-       
-                               default:
-                                       consume();
-                                       break;                  
-                               }
-                               break;
-                               
-                       case STRING_DQ:
-                               switch (ch) {
-                               case '\\':
-                                       fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
-                                       fTokenLength++;
-                                       break;
-                                       
-                               case '\"':                                                      
-                                       if (fLast != BACKSLASH) {
-                                               return postFix(STRING_DQ);
-
-                                       } else {
-                                               consume();
-                                               break;                                  
-                                       }
-                               
-                               default:
-                                       consume();
-                                       break;
-                               }
-                               break;
-       
-                       case STRING_SQ:
-                               switch (ch) {
-                               case '\\':
-                                       fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
-                                       fTokenLength++;
-                                       break;
-       
-                               case '\'':
-                                       if (fLast != BACKSLASH) {
-                                               return postFix(STRING_SQ);
-       
-                                       } else {
-                                               consume();
-                                               break;
-                                       }
-       
-                               default:
-                                       consume();
-                                       break;
-                               }
-                               break;
-                       }
-               } 
-       }               
-
-       private static final int getLastLength(int last) {
-               switch (last) {
-               default:
-                       return -1;
-
-               case NONE:
-                       return 0;
-                       
-               case CARRIAGE_RETURN:
-               case BACKSLASH:
-               case SLASH:
-               case STAR:
-                       return 1;
-
-               case SLASH_STAR:
-                       return 2;
-
-               case SLASH_STAR_STAR:
-                       return 3;
-               }       
-       }
-
-       private final void consume() {
-               fTokenLength++;
-               fLast= NONE;    
-       }
-       
-       private final IToken postFix(int state) {
-               fTokenLength++;
-               fLast= NONE;
-               fState= HTML;
-               fPrefixLength= 0;               
-               return fTokens[state];
-       }
-
-       private final IToken preFix(int state, int newState, int last, int prefixLength) {
-               // emulate JavaPartitionScanner
-//             if (fgEmulate && state == JAVA && (fTokenLength - getLastLength(fLast) > 0)) {
-//                     fTokenLength -= getLastLength(fLast);
-//                     fJavaOffset= fTokenOffset;
-//                     fJavaLength= fTokenLength;
-//                     fTokenLength= 1;
-//                     fState= newState;
-//                     fPrefixLength= prefixLength;
-//                     fLast= last;
-//                     return fTokens[state];
-//
-//             } else {
-                       fTokenLength -= getLastLength(fLast);
-                       fLast= last;
-                       fPrefixLength= prefixLength;
-                       IToken token= fTokens[state];           
-                       fState= newState;
-                       return token;
-//             }
-       }
-
-       private static int getState(String contentType) {
-
-               if (contentType == null)
-                       return HTML;
-               
-               else if (contentType.equals(IPHPPartitions.PHP_PARTITIONING))
-                       return PHP;
-               
-               else if (contentType.equals(IPHPPartitions.PHP_SINGLELINE_COMMENT))
-                       return SINGLE_LINE_COMMENT;
-
-               else if (contentType.equals(IPHPPartitions.PHP_MULTILINE_COMMENT))
-                       return MULTI_LINE_COMMENT;
-
-               else if (contentType.equals(IPHPPartitions.PHP_PHPDOC_COMMENT))
-                       return PHPDOC;
-
-               else if (contentType.equals(IPHPPartitions.PHP_STRING_DQ))
-                       return STRING_DQ;
-               
-               else if (contentType.equals(IPHPPartitions.PHP_STRING_SQ))
-                       return STRING_SQ;
-               
-//             else if (contentType.equals(SKIP))
-//                     return CHARACTER;
-                       
-               else
-                       return HTML;
-       }
-
-       /*
-        * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int)
-        */
-       public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
-
-               fScanner.setRange(document, offset, length);
-               fTokenOffset= partitionOffset;
-               fTokenLength= 0;
-               fPrefixLength= offset - partitionOffset;
-               fLast= NONE;
-               
-               if (offset == partitionOffset) {
-                       // restart at beginning of partition
-                       fState= HTML;
-               } else {
-                       fState= getState(contentType);                  
-               }
-
-               // emulate JavaPartitionScanner
-//             if (fgEmulate) {
-//                     fJavaOffset= -1;
-//                     fJavaLength= 0;
-//             }
-       }
-
-       /*
-        * @see ITokenScanner#setRange(IDocument, int, int)
-        */
-       public void setRange(IDocument document, int offset, int length) {
-
-               fScanner.setRange(document, offset, length);
-               fTokenOffset= offset;
-               fTokenLength= 0;                
-               fPrefixLength= 0;
-               fLast= NONE;
-               fState= HTML;
-
-               // emulate JavaPartitionScanner
-//             if (fgEmulate) {
-//                     fJavaOffset= -1;
-//                     fJavaLength= 0;
-//             }
-       }
-
-       /*
-        * @see ITokenScanner#getTokenLength()
-        */
-       public int getTokenLength() {
-               return fTokenLength;
-       }
-
-       /*
-        * @see ITokenScanner#getTokenOffset()
-        */
-       public int getTokenOffset() {
-               return fTokenOffset;
-       }
-
-}
+public class FastJavaPartitionScanner implements IPartitionTokenScanner, IPHPPartitions {
+
+  // states
+  private static final int PHP = 0;
+
+  private static final int SINGLE_LINE_COMMENT = 1;
+
+  private static final int MULTI_LINE_COMMENT = 2;
+
+  private static final int PHPDOC = 3;
+
+  private static final int STRING_DQ = 4;
+
+  private static final int STRING_SQ = 5;
+
+  //   private static final int CHARACTER= 4;
+
+  // beginning of prefixes and postfixes
+  private static final int NONE = 0;
+
+  private static final int BACKSLASH = 1; // postfix for STRING and CHARACTER
+
+  private static final int SLASH = 2; // prefix for SINGLE_LINE or MULTI_LINE or JAVADOC
+
+  private static final int SLASH_STAR = 3; // prefix for MULTI_LINE_COMMENT or JAVADOC
+
+  private static final int SLASH_STAR_STAR = 4; // prefix for MULTI_LINE_COMMENT or JAVADOC
+
+  private static final int STAR = 5; // postfix for MULTI_LINE_COMMENT or JAVADOC
+
+  private static final int CARRIAGE_RETURN = 6; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT
+
+  /** The scanner. */
+  private final BufferedDocumentScanner fScanner = new BufferedDocumentScanner(1000); // faster implementation
+
+  /** The offset of the last returned token. */
+  private int fTokenOffset;
+
+  /** The length of the last returned token. */
+  private int fTokenLength;
+
+  /** The state of the scanner. */
+  private int fState;
+
+  /** The last significant characters read. */
+  private int fLast;
+
+  /** The amount of characters already read on first call to nextToken(). */
+  private int fPrefixLength;
+
+  // emulate JavaPartitionScanner
+  private boolean fEmulate = false;
+
+  private int fJavaOffset;
+
+  private int fJavaLength;
+
+  private final IToken[] fTokens = new IToken[] { new Token(null), new Token(PHP_SINGLELINE_COMMENT),
+      new Token(PHP_MULTILINE_COMMENT), new Token(PHP_PHPDOC_COMMENT), new Token(PHP_STRING_DQ), new Token(PHP_STRING_SQ) };
+
+  public FastJavaPartitionScanner(boolean emulate) {
+    fEmulate = emulate;
+  }
+
+  public FastJavaPartitionScanner() {
+    this(false);
+  }
+
+  /*
+   * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+   */
+  public IToken nextToken() {
+
+    // emulate JavaPartitionScanner
+    if (fEmulate) {
+      if (fJavaOffset != -1 && fTokenOffset + fTokenLength != fJavaOffset + fJavaLength) {
+        fTokenOffset += fTokenLength;
+        return fTokens[PHP];
+      } else {
+        fJavaOffset = -1;
+        fJavaLength = 0;
+      }
+    }
+
+    fTokenOffset += fTokenLength;
+    fTokenLength = fPrefixLength;
+
+    while (true) {
+      final int ch = fScanner.read();
+
+      // characters
+      switch (ch) {
+      case ICharacterScanner.EOF:
+        if (fTokenLength > 0) {
+          fLast = NONE; // ignore last
+          return preFix(fState, PHP, NONE, 0);
+
+        } else {
+          fLast = NONE;
+          fPrefixLength = 0;
+          return Token.EOF;
+        }
+
+      case '\r':
+        // emulate JavaPartitionScanner
+        if (!fEmulate && fLast != CARRIAGE_RETURN) {
+          fLast = CARRIAGE_RETURN;
+          fTokenLength++;
+          continue;
+
+        } else {
+
+          switch (fState) {
+          case SINGLE_LINE_COMMENT:
+            //                                 case CHARACTER:
+            //                                 case STRING_DQ:
+            //                                 case STRING_SQ:
+            if (fTokenLength > 0) {
+              IToken token = fTokens[fState];
+
+              // emulate JavaPartitionScanner
+              if (fEmulate) {
+                fTokenLength++;
+                fLast = NONE;
+                fPrefixLength = 0;
+              } else {
+                fLast = CARRIAGE_RETURN;
+                fPrefixLength = 1;
+              }
+
+              fState = PHP;
+              return token;
+
+            } else {
+              consume();
+              continue;
+            }
+
+          default:
+            consume();
+            continue;
+          }
+        }
+
+      case '\n':
+        switch (fState) {
+        case SINGLE_LINE_COMMENT:
+          //                           case CHARACTER:
+          //                           case STRING_DQ:
+          //                           case STRING_SQ:
+          // assert(fTokenLength > 0);
+          return postFix(fState);
+
+        default:
+          consume();
+          continue;
+        }
+
+      default:
+        if (!fEmulate && fLast == CARRIAGE_RETURN) {
+          switch (fState) {
+          case SINGLE_LINE_COMMENT:
+            //                                 case CHARACTER:
+            //                                 case STRING_DQ:
+            //                                 case STRING_SQ:
+            int last;
+            int newState;
+            switch (ch) {
+            case '/':
+              last = SLASH;
+              newState = PHP;
+              break;
+
+            case '*':
+              last = STAR;
+              newState = PHP;
+              break;
+
+            case '\'':
+              last = NONE;
+              newState = STRING_SQ;
+              break;
+
+            case '"':
+              last = NONE;
+              newState = STRING_DQ;
+              break;
+
+            case '\r':
+              last = CARRIAGE_RETURN;
+              newState = PHP;
+              break;
+
+            case '\\':
+              last = BACKSLASH;
+              newState = PHP;
+              break;
+
+            default:
+              last = NONE;
+              newState = PHP;
+              break;
+            }
+
+            fLast = NONE; // ignore fLast
+            return preFix(fState, newState, last, 1);
+
+          default:
+            break;
+          }
+        }
+      }
+
+      // states
+      switch (fState) {
+      case PHP:
+        switch (ch) {
+        case '#':
+          if (fTokenLength > 0) {
+            return preFix(PHP, SINGLE_LINE_COMMENT, NONE, 1);
+          } else {
+            preFix(PHP, SINGLE_LINE_COMMENT, NONE, 1);
+            fTokenOffset += fTokenLength;
+            fTokenLength = fPrefixLength;
+            break;
+          }
+        case '/':
+          if (fLast == SLASH) {
+            if (fTokenLength - getLastLength(fLast) > 0) {
+              return preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2);
+            } else {
+              preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2);
+              fTokenOffset += fTokenLength;
+              fTokenLength = fPrefixLength;
+              break;
+            }
+
+          } else {
+            fTokenLength++;
+            fLast = SLASH;
+            break;
+          }
+
+        case '*':
+          if (fLast == SLASH) {
+            if (fTokenLength - getLastLength(fLast) > 0)
+              return preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+            else {
+              preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+              fTokenOffset += fTokenLength;
+              fTokenLength = fPrefixLength;
+              break;
+            }
+
+          } else {
+            consume();
+            break;
+          }
+
+        case '\'':
+          fLast = NONE; // ignore fLast
+          if (fTokenLength > 0)
+            return preFix(PHP, STRING_SQ, NONE, 1);
+          else {
+            preFix(PHP, STRING_SQ, NONE, 1);
+            fTokenOffset += fTokenLength;
+            fTokenLength = fPrefixLength;
+            break;
+          }
+
+        case '"':
+          fLast = NONE; // ignore fLast
+          if (fTokenLength > 0)
+            return preFix(PHP, STRING_DQ, NONE, 1);
+          else {
+            preFix(PHP, STRING_DQ, NONE, 1);
+            fTokenOffset += fTokenLength;
+            fTokenLength = fPrefixLength;
+            break;
+          }
+
+        default:
+          consume();
+          break;
+        }
+        break;
+
+      case SINGLE_LINE_COMMENT:
+        consume();
+        break;
+
+      case PHPDOC:
+        switch (ch) {
+        case '/':
+          switch (fLast) {
+          case SLASH_STAR_STAR:
+            return postFix(MULTI_LINE_COMMENT);
+
+          case STAR:
+            return postFix(PHPDOC);
+
+          default:
+            consume();
+            break;
+          }
+          break;
+
+        case '*':
+          fTokenLength++;
+          fLast = STAR;
+          break;
+
+        default:
+          consume();
+          break;
+        }
+        break;
+
+      case MULTI_LINE_COMMENT:
+        switch (ch) {
+        case '*':
+          if (fLast == SLASH_STAR) {
+            fLast = SLASH_STAR_STAR;
+            fTokenLength++;
+            fState = PHPDOC;
+          } else {
+            fTokenLength++;
+            fLast = STAR;
+          }
+          break;
+
+        case '/':
+          if (fLast == STAR) {
+            return postFix(MULTI_LINE_COMMENT);
+          } else {
+            consume();
+            break;
+          }
+
+        default:
+          consume();
+          break;
+        }
+        break;
+
+      case STRING_DQ:
+        switch (ch) {
+        case '\\':
+          fLast = (fLast == BACKSLASH) ? NONE : BACKSLASH;
+          fTokenLength++;
+          break;
+
+        case '\"':
+          if (fLast != BACKSLASH) {
+            return postFix(STRING_DQ);
+
+          } else {
+            consume();
+            break;
+          }
+
+        default:
+          consume();
+          break;
+        }
+        break;
+      case STRING_SQ:
+        switch (ch) {
+        case '\\':
+          fLast = (fLast == BACKSLASH) ? NONE : BACKSLASH;
+          fTokenLength++;
+          break;
+
+        case '\'':
+          if (fLast != BACKSLASH) {
+            return postFix(STRING_SQ);
+
+          } else {
+            consume();
+            break;
+          }
+
+        default:
+          consume();
+          break;
+        }
+        break;
+      //                       case CHARACTER:
+      //                               switch (ch) {
+      //                               case '\\':
+      //                                       fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+      //                                       fTokenLength++;
+      //                                       break;
+      //       
+      //                               case '\'':
+      //                                       if (fLast != BACKSLASH) {
+      //                                               return postFix(CHARACTER);
+      //       
+      //                                       } else {
+      //                                               consume();
+      //                                               break;
+      //                                       }
+      //       
+      //                               default:
+      //                                       consume();
+      //                                       break;
+      //                               }
+      //                               break;
+      }
+    }
+  }
+
+  private static final int getLastLength(int last) {
+    switch (last) {
+    default:
+      return -1;
+
+    case NONE:
+      return 0;
+
+    case CARRIAGE_RETURN:
+    case BACKSLASH:
+    case SLASH:
+    case STAR:
+      return 1;
+
+    case SLASH_STAR:
+      return 2;
+
+    case SLASH_STAR_STAR:
+      return 3;
+    }
+  }
+
+  private final void consume() {
+    fTokenLength++;
+    fLast = NONE;
+  }
+
+  private final IToken postFix(int state) {
+    fTokenLength++;
+    fLast = NONE;
+    fState = PHP;
+    fPrefixLength = 0;
+    return fTokens[state];
+  }
+
+  private final IToken preFix(int state, int newState, int last, int prefixLength) {
+    // emulate JavaPartitionScanner
+    if (fEmulate && state == PHP && (fTokenLength - getLastLength(fLast) > 0)) {
+      fTokenLength -= getLastLength(fLast);
+      fJavaOffset = fTokenOffset;
+      fJavaLength = fTokenLength;
+      fTokenLength = 1;
+      fState = newState;
+      fPrefixLength = prefixLength;
+      fLast = last;
+      return fTokens[state];
+
+    } else {
+      fTokenLength -= getLastLength(fLast);
+      fLast = last;
+      fPrefixLength = prefixLength;
+      IToken token = fTokens[state];
+      fState = newState;
+      return token;
+    }
+  }
+
+  private static int getState(String contentType) {
+
+    if (contentType == null)
+      return PHP;
+
+    else if (contentType.equals(PHP_SINGLELINE_COMMENT))
+      return SINGLE_LINE_COMMENT;
+
+    else if (contentType.equals(PHP_MULTILINE_COMMENT))
+      return MULTI_LINE_COMMENT;
+
+    else if (contentType.equals(PHP_PHPDOC_COMMENT))
+      return PHPDOC;
+
+    else if (contentType.equals(PHP_STRING_DQ))
+      return STRING_DQ;
+    else if (contentType.equals(PHP_STRING_SQ))
+      return STRING_SQ;
+    //         else if (contentType.equals(JAVA_CHARACTER))
+    //                 return CHARACTER;
+
+    else
+      return PHP;
+  }
+
+  /*
+   * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int)
+   */
+  public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
+    fScanner.setRange(document, offset, length);
+    setRange(document, offset, length);
+    fTokenOffset = partitionOffset;
+    fTokenLength = 0;
+    fPrefixLength = offset - partitionOffset;
+    fLast = NONE;
+
+    if (offset == partitionOffset) {
+      // restart at beginning of partition
+      fState = PHP;
+    } else {
+      fState = getState(contentType);
+    }
+
+    // emulate JavaPartitionScanner
+    if (fEmulate) {
+      fJavaOffset = -1;
+      fJavaLength = 0;
+    }
+  }
+
+  /*
+   * @see ITokenScanner#setRange(IDocument, int, int)
+   */
+  public void setRange(IDocument document, int offset, int length) {
+    fScanner.setRange(document, offset, length);
+    fTokenOffset = offset;
+    fTokenLength = 0;
+    fPrefixLength = 0;
+    fLast = NONE;
+    fState = PHP;
+
+    // emulate JavaPartitionScanner
+    if (fEmulate) {
+      fJavaOffset = -1;
+      fJavaLength = 0;
+    }
+  }
+
+  /*
+   * @see ITokenScanner#getTokenLength()
+   */
+  public int getTokenLength() {
+    return fTokenLength;
+  }
+
+  /*
+   * @see ITokenScanner#getTokenOffset()
+   */
+  public int getTokenOffset() {
+    if (AbstractPartitioner.DEBUG) {
+      Assert.isTrue(fTokenOffset >= 0, Integer.toString(fTokenOffset));
+    }
+    return fTokenOffset;
+  }
+
+}
\ No newline at end of file
index 8d6b040..8ba709a 100644 (file)
@@ -10,7 +10,8 @@ package net.sourceforge.phpdt.internal.ui.text;
  */
 public interface IPHPPartitions
 {
-       public final static String PHP_PARTITIONING = "__php"; //$NON-NLS-1$
+       public final static String PHP_PARTITIONING = "___php_partitioning"; //$NON-NLS-1$
+       
        public final static String PHP_PHPDOC_COMMENT = "__php_phpdoc_comment"; //$NON-NLS-1$
        public final static String PHP_SINGLELINE_COMMENT = "__php_singleline_comment"; //$NON-NLS-1$
        public final static String PHP_MULTILINE_COMMENT = "__php_multiline_comment"; //$NON-NLS-1$
@@ -22,6 +23,7 @@ public interface IPHPPartitions
        public final static String CSS_MULTILINE_COMMENT = "__css_multiline_comment"; //$NON-NLS-1$
        public final static String HTML = "__html"; //$NON-NLS-1$
        public final static String HTML_MULTILINE_COMMENT = "__html_multiline_comment"; //$NON-NLS-1$
+       
        public final static String SMARTY = "__smarty"; //$NON-NLS-1$
        public final static String SMARTY_MULTILINE_COMMENT = "__smarty_multiline_comment"; //$NON-NLS-1$
        
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/SmartSemicolonAutoEditStrategy.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/SmartSemicolonAutoEditStrategy.java
new file mode 100644 (file)
index 0000000..edd3013
--- /dev/null
@@ -0,0 +1,1005 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text;
+
+import java.util.Arrays;
+
+import net.sourceforge.phpdt.internal.core.Assert;
+import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager.UndoSpec;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.PHPUnitEditor;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IAutoEditStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.texteditor.ITextEditorExtension2;
+import org.eclipse.ui.texteditor.ITextEditorExtension3;
+
+/**
+ * Modifies <code>DocumentCommand</code>s inserting semicolons and opening braces to place them
+ * smartly, i.e. moving them to the end of a line if that is what the user expects.
+ * 
+ * <p>In practice,  semicolons and braces (and the caret) are moved to the end of the line if they are typed
+ * anywhere except for semicolons in a <code>for</code> statements definition. If the line contains a semicolon
+ * or brace after the current caret position, the cursor is moved after it.</p>
+ * 
+ * @see org.eclipse.jface.text.DocumentCommand
+ * @since 3.0
+ */
+public class SmartSemicolonAutoEditStrategy implements IAutoEditStrategy {
+
+       /** String representation of a semicolon. */
+       private static final String SEMICOLON= ";"; //$NON-NLS-1$
+       /** Char representation of a semicolon. */
+       private static final char SEMICHAR= ';';
+       /** String represenattion of a opening brace. */
+       private static final String BRACE= "{"; //$NON-NLS-1$
+       /** Char representation of a opening brace */
+       private static final char BRACECHAR= '{';
+
+       private char fCharacter;
+       private String fPartitioning;
+
+       /**
+        * Creates a new SmartSemicolonAutoEditStrategy.
+        * 
+        * @param partitioning the document partitioning
+        */
+       public SmartSemicolonAutoEditStrategy(String partitioning) {
+               fPartitioning= partitioning;
+       }
+
+       /*
+        * @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.DocumentCommand)
+        */
+       public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
+               // 0: early pruning
+               // also customize if <code>doit</code> is false (so it works in code completion situations)
+               //              if (!command.doit)
+               //                      return;
+
+               if (command.text == null)
+                       return;
+
+               if (command.text.equals(SEMICOLON))
+                       fCharacter= SEMICHAR;
+               else if (command.text.equals(BRACE))
+                       fCharacter= BRACECHAR;
+               else
+                       return;
+
+               IPreferenceStore store= PHPeclipsePlugin.getDefault().getPreferenceStore();
+               if (fCharacter == SEMICHAR && !store.getBoolean(PreferenceConstants.EDITOR_SMART_SEMICOLON))
+                       return;
+               if (fCharacter == BRACECHAR && !store.getBoolean(PreferenceConstants.EDITOR_SMART_OPENING_BRACE))
+                       return;
+               
+               IWorkbenchPage page= PHPeclipsePlugin.getActivePage();
+               if (page == null)
+                       return;
+               IEditorPart part= page.getActiveEditor();
+               if (!(part instanceof PHPUnitEditor))
+                       return;
+               PHPUnitEditor editor= (PHPUnitEditor)part;
+               if (editor.getInsertMode() != ITextEditorExtension3.SMART_INSERT || !editor.isEditable())
+                       return;
+               ITextEditorExtension2 extension= (ITextEditorExtension2)editor.getAdapter(ITextEditorExtension2.class);
+               if (extension != null && !extension.validateEditorInputState())
+                       return;
+               if (isMultilineSelection(document, command))
+                       return;
+
+               // 1: find concerned line / position in java code, location in statement
+               int pos= command.offset;
+               ITextSelection line;
+               try {
+                       IRegion l= document.getLineInformationOfOffset(pos);
+                       line= new TextSelection(document, l.getOffset(), l.getLength());
+               } catch (BadLocationException e) {
+                       return;
+               }
+
+               // 2: choose action based on findings (is for-Statement?)
+               // for now: compute the best position to insert the new character
+               int positionInLine= computeCharacterPosition(document, line, pos - line.getOffset(), fCharacter, fPartitioning);
+               int position= positionInLine + line.getOffset();
+
+               // never position before the current position!
+               if (position < pos)
+                       return;
+
+               // never double already existing content 
+               if (alreadyPresent(document, fCharacter, position))
+                       return;
+               
+               // don't do special processing if what we do is actually the normal behaviour
+               String insertion= adjustSpacing(document, position, fCharacter);
+               if (command.offset == position && insertion.equals(command.text))
+                       return;
+
+               try {
+                       
+                       final SmartBackspaceManager manager= (SmartBackspaceManager) editor.getAdapter(SmartBackspaceManager.class);
+                       if (manager != null && PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SMART_BACKSPACE)) {
+                               TextEdit e1= new ReplaceEdit(command.offset, command.text.length(), document.get(command.offset, command.length));
+                               UndoSpec s1= new UndoSpec(command.offset + command.text.length(),
+                                               new Region(command.offset, 0),
+                                               new TextEdit[] {e1},
+                                               0,
+                                               null);
+
+                               DeleteEdit smart= new DeleteEdit(position, insertion.length());
+                               ReplaceEdit raw= new ReplaceEdit(command.offset, command.length, command.text);
+                               UndoSpec s2= new UndoSpec(position + insertion.length(),
+                                               new Region(command.offset + command.text.length(), 0),
+                                               new TextEdit[] {smart, raw},
+                                               2,
+                                               s1);
+                               manager.register(s2);
+                       }
+                       
+                       // 3: modify command
+                       command.offset= position;
+                       command.length= 0;
+                       command.caretOffset= position;
+                       command.text= insertion;
+                       command.doit= true;
+                       command.owner= null;
+               } catch (MalformedTreeException e) {
+                       PHPeclipsePlugin.log(e);
+               } catch (BadLocationException e) {
+                 PHPeclipsePlugin.log(e);
+               }
+
+               
+       }
+
+       /**
+        * Returns <code>true</code> if the document command is applied on a multi
+        * line selection, <code>false</code> otherwise.
+        * 
+        * @param document the document
+        * @param command the command
+        * @return <code>true</code> if <code>command</code> is a multiline command
+        */
+       private boolean isMultilineSelection(IDocument document, DocumentCommand command) {
+               try {
+                       return document.getNumberOfLines(command.offset, command.length) > 1;
+               } catch (BadLocationException e) {
+                       // ignore
+                       return false;
+               }
+       }
+
+       /**
+        * Adds a space before a brace if it is inserted after a parenthesis, equal sign, or one
+        * of the keywords <code>try, else, do</code>. 
+        * 
+        * @param document the document we are working on
+        * @param position the insert position of <code>character</code>
+        * @param character the character to be inserted
+        * @return a <code>String</code> consisting of <code>character</code> plus any additional spacing
+        */
+       private String adjustSpacing(IDocument doc, int position, char character) {
+               if (character == BRACECHAR) {
+                       if (position > 0 && position <= doc.getLength()) {
+                               int pos= position - 1;
+                               if (looksLike(doc, pos, ")") //$NON-NLS-1$
+                               || looksLike(doc, pos, "=") //$NON-NLS-1$
+                               || looksLike(doc, pos, "]") //$NON-NLS-1$
+                               || looksLike(doc, pos, "try") //$NON-NLS-1$
+                               || looksLike(doc, pos, "else") //$NON-NLS-1$
+                               || looksLike(doc, pos, "synchronized") //$NON-NLS-1$
+                               || looksLike(doc, pos, "static") //$NON-NLS-1$
+                               || looksLike(doc, pos, "finally") //$NON-NLS-1$
+                               || looksLike(doc, pos, "do")) //$NON-NLS-1$
+                                       return new String(new char[] { ' ', character });
+                       }
+               }
+
+               return new String(new char[] { character });
+       }
+
+       /**
+        * Checks whether a character to be inserted is already present at the insert location (perhaps
+        * separated by some whitespace from <code>position</code>.
+        * 
+        * @param document the document we are working on
+        * @param position the insert position of <code>ch</code>
+        * @param character the character to be inserted
+        * @return <code>true</code> if <code>ch</code> is already present at <code>location</code>, <code>false</code> otherwise
+        */
+       private boolean alreadyPresent(IDocument document, char ch, int position) {
+               int pos= firstNonWhitespaceForward(document, position, fPartitioning, document.getLength());
+               try {
+                       if (pos != -1 && document.getChar(pos) == ch)
+                               return true;
+               } catch (BadLocationException e) {
+               }
+
+               return false;
+       }
+
+       /**
+        * Computes the next insert position of the given character in the current line.
+        * 
+        * @param document the document we are working on
+        * @param line the line where the change is being made
+        * @param offset the position of the caret in the line when <code>character</code> was typed
+        * @param character the character to look for
+        * @param partitioning the document partitioning
+        * @return the position where <code>character</code> should be inserted / replaced
+        */
+       protected static int computeCharacterPosition(IDocument document, ITextSelection line, int offset, char character, String partitioning) {
+               String text= line.getText();
+               if (text == null)
+                       return 0;
+
+               int insertPos;
+               if (character == BRACECHAR) {
+
+                       insertPos= computeArrayInitializationPos(document, line, offset, partitioning);
+
+                       if (insertPos == -1) {
+                               insertPos= computeAfterTryDoElse(document, line, offset);
+                       }
+
+                       if (insertPos == -1) {
+                               insertPos= computeAfterParenthesis(document, line, offset, partitioning);
+                       }
+
+               } else if (character == SEMICHAR) {
+
+                       if (isForStatement(text, offset)) {
+                               insertPos= -1; // don't do anything in for statements, as semis are vital part of these
+                       } else {
+                               int nextPartitionPos= nextPartitionOrLineEnd(document, line, offset, partitioning);
+                               insertPos= startOfWhitespaceBeforeOffset(text, nextPartitionPos);
+                               // if there is a semi present, return its location as alreadyPresent() will take it out this way.
+                               if (insertPos > 0 && text.charAt(insertPos - 1) == character)
+                                       insertPos= insertPos - 1;
+                       }
+                       
+               } else {
+                       Assert.isTrue(false);
+                       return -1;
+               }
+
+               return insertPos;
+       }
+
+       /**
+        * Computes an insert position for an opening brace if <code>offset</code> maps to a position in
+        * <code>document</code> that looks like being the RHS of an assignment or like an array definition.
+        * 
+        * @param document the document being modified
+        * @param line the current line under investigation
+        * @param offset the offset of the caret position, relative to the line start.
+        * @param partitioning the document partitioning
+        * @return an insert position  relative to the line start if <code>line</code> looks like being an array initialization at <code>offset</code>, -1 otherwise
+        */
+       private static int computeArrayInitializationPos(IDocument document, ITextSelection line, int offset, String partitioning) {
+               // search backward while WS, find = (not != <= >= ==) in default partition
+               int pos= offset + line.getOffset();
+
+               if (pos == 0)
+                       return -1;
+                       
+               int p= firstNonWhitespaceBackward(document, pos - 1, partitioning, -1);
+               
+               if (p == -1)
+                       return -1;
+                       
+               try {
+                               
+                       char ch= document.getChar(p);
+                       if (ch != '=' && ch != ']')
+                               return -1;
+                       
+                       if (p == 0)
+                               return offset;
+                               
+                       p= firstNonWhitespaceBackward(document, p - 1, partitioning, -1);
+                       if (p == -1)
+                               return -1;
+                       
+                       ch= document.getChar(p);
+                       if (Character.isJavaIdentifierPart(ch) || ch == ']' || ch == '[')
+                               return offset;
+       
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Computes an insert position for an opening brace if <code>offset</code> maps to a position in
+        * <code>document</code> involving a keyword taking a block after it. These are: <code>try</code>, 
+        * <code>do</code>, <code>synchronized</code>, <code>static</code>, <code>finally</code>, or <code>else</code>.
+        * 
+        * @param document the document being modified
+        * @param line the current line under investigation
+        * @param offset the offset of the caret position, relative to the line start.
+        * @return an insert position  relative to the line start if <code>line</code> contains one of the above keywords at or before <code>offset</code>, -1 otherwise
+        */
+       private static int computeAfterTryDoElse(IDocument doc, ITextSelection line, int offset) {
+               // search backward while WS, find 'try', 'do', 'else' in default partition
+               int p= offset + line.getOffset();
+               p= firstWhitespaceToRight(doc, p);
+               if (p == -1)
+                       return -1;
+               p--;
+
+               if (looksLike(doc, p, "try") //$NON-NLS-1$
+                               || looksLike(doc, p, "do")  //$NON-NLS-1$
+                               || looksLike(doc, p, "synchronized")  //$NON-NLS-1$
+                               || looksLike(doc, p, "static")  //$NON-NLS-1$
+                               || looksLike(doc, p, "finally")  //$NON-NLS-1$
+                               || looksLike(doc, p, "else"))  //$NON-NLS-1$
+                       return p + 1 - line.getOffset();
+
+               return -1;
+       }
+
+       /**
+        * Computes an insert position for an opening brace if <code>offset</code> maps to a position in
+        * <code>document</code> with a expression in parenthesis that will take a block after the closing parenthesis.
+        * 
+        * @param document the document being modified
+        * @param line the current line under investigation
+        * @param offset the offset of the caret position, relative to the line start.
+        * @param partitioning the document partitioning
+        * @return an insert position relative to the line start if <code>line</code> contains a parenthesized expression that can be followed by a block, -1 otherwise
+        */
+       private static int computeAfterParenthesis(IDocument document, ITextSelection line, int offset, String partitioning) {
+               // find the opening parenthesis for every closing parenthesis on the current line after offset
+               // return the position behind the closing parenthesis if it looks like a method declaration
+               // or an expression for an if, while, for, catch statement
+               int pos= offset + line.getOffset();
+               int length= line.getOffset() + line.getLength();
+               int scanTo= scanForward(document, pos, partitioning, length, '}');
+               if (scanTo == -1)
+                       scanTo= length;
+                       
+               int closingParen= findClosingParenToLeft(document, pos, partitioning) - 1;
+
+               while (true) {
+                       int startScan= closingParen + 1;
+                       closingParen= scanForward(document, startScan, partitioning, scanTo, ')');
+                       if (closingParen == -1)
+                               break;
+
+                       int openingParen= findOpeningParenMatch(document, closingParen, partitioning);
+
+                       // no way an expression at the beginning of the document can mean anything
+                       if (openingParen < 1)
+                               break;
+
+                       // only select insert positions for parenthesis currently embracing the caret
+                       if (openingParen > pos)
+                               continue;
+
+                       if (looksLikeAnonymousClassDef(document, openingParen - 1, partitioning))
+                               return closingParen + 1 - line.getOffset();
+
+                       if (looksLikeIfWhileForCatch(document, openingParen - 1, partitioning))
+                               return closingParen + 1 - line.getOffset();
+
+                       if (looksLikeMethodDecl(document, openingParen - 1, partitioning))
+                               return closingParen + 1 - line.getOffset();
+
+               }
+
+               return -1;
+       }
+
+       /**
+        * Finds a closing parenthesis to the left of <code>position</code> in document, where that parenthesis is only
+        * separated by whitespace from <code>position</code>. If no such parenthesis can be found, <code>position</code> is returned.
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param partitioning the document partitioning
+        * @return the position of a closing parenthesis left to <code>position</code> separated only by whitespace, or <code>position</code> if no parenthesis can be found
+        */
+       private static int findClosingParenToLeft(IDocument document, int position, String partitioning) {
+               final char CLOSING_PAREN= ')';
+               try {
+                       if (position < 1)
+                               return position;
+
+                       int nonWS= firstNonWhitespaceBackward(document, position - 1, partitioning, -1);
+                       if (nonWS != -1 && document.getChar(nonWS) == CLOSING_PAREN)
+                               return nonWS;
+               } catch (BadLocationException e1) {
+               }
+               return position;
+       }
+
+       /**
+        * Finds the first whitespace character position to the right of (and including) <code>position</code>.
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @return the position of a whitespace character greater or equal than <code>position</code> separated only by whitespace, or -1 if none found
+        */
+       private static int firstWhitespaceToRight(IDocument document, int position) {
+               int length= document.getLength();
+               Assert.isTrue(position >= 0);
+               Assert.isTrue(position <= length);
+
+               try {
+                       while (position < length) {
+                               char ch= document.getChar(position);
+                               if (Character.isWhitespace(ch))
+                                       return position;
+                               position++;
+                       }
+                       return position;
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Finds the highest position in <code>document</code> such that the position is &lt;= <code>position</code>
+        * and &gt; <code>bound</code> and <code>Character.isWhitespace(document.getChar(pos))</code> evaluates to <code>false</code>
+        * and the position is in the default partition.   
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param partitioning the document partitioning
+        * @param bound the first position in <code>document</code> to not consider any more, with <code>bound</code> &gt; <code>position</code>
+        * @return the highest position of one element in <code>chars</code> in [<code>position</code>, <code>scanTo</code>) that resides in a Java partition, or <code>-1</code> if none can be found
+        */
+       private static int firstNonWhitespaceBackward(IDocument document, int position, String partitioning, int bound) {
+               Assert.isTrue(position < document.getLength());
+               Assert.isTrue(bound >= -1);
+
+               try {
+                       while (position > bound) {
+                               char ch= document.getChar(position);
+                               if (!Character.isWhitespace(ch) && isDefaultPartition(document, position, partitioning))
+                                       return position;
+                               position--;
+                       }
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Finds the smallest position in <code>document</code> such that the position is &gt;= <code>position</code>
+        * and &lt; <code>bound</code> and <code>Character.isWhitespace(document.getChar(pos))</code> evaluates to <code>false</code>
+        * and the position is in the default partition.   
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param partitioning the document partitioning
+        * @param bound the first position in <code>document</code> to not consider any more, with <code>bound</code> &gt; <code>position</code>
+        * @return the smallest position of one element in <code>chars</code> in [<code>position</code>, <code>scanTo</code>) that resides in a Java partition, or <code>-1</code> if none can be found
+        */
+       private static int firstNonWhitespaceForward(IDocument document, int position, String partitioning, int bound) {
+               Assert.isTrue(position >= 0);
+               Assert.isTrue(bound <= document.getLength());
+
+               try {
+                       while (position < bound) {
+                               char ch= document.getChar(position);
+                               if (!Character.isWhitespace(ch) && isDefaultPartition(document, position, partitioning))
+                                       return position;
+                               position++;
+                       }
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Finds the highest position in <code>document</code> such that the position is &lt;= <code>position</code>
+        * and &gt; <code>bound</code> and <code>document.getChar(position) == ch</code> evaluates to <code>true</code> for at least one
+        * ch in <code>chars</code> and the position is in the default partition.   
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param partitioning the document partitioning
+        * @param bound the first position in <code>document</code> to not consider any more, with <code>scanTo</code> &gt; <code>position</code>
+        * @param chars an array of <code>char</code> to search for
+        * @return the highest position of one element in <code>chars</code> in (<code>bound</code>, <code>position</code>] that resides in a Java partition, or <code>-1</code> if none can be found
+        */
+       private static int scanBackward(IDocument document, int position, String partitioning, int bound, char[] chars) {
+               Assert.isTrue(bound >= -1);
+               Assert.isTrue(position < document.getLength() );
+               
+               Arrays.sort(chars);
+               
+               try {
+                       while (position > bound) {
+
+                               if (Arrays.binarySearch(chars, document.getChar(position)) >= 0 && isDefaultPartition(document, position, partitioning))
+                                       return position;
+
+                               position--;
+                       }
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+//     /**
+//      * Finds the highest position in <code>document</code> such that the position is &lt;= <code>position</code>
+//      * and &gt; <code>bound</code> and <code>document.getChar(position) == ch</code> evaluates to <code>true</code>
+//      * and the position is in the default partition.   
+//      * 
+//      * @param document the document being modified
+//      * @param position the first character position in <code>document</code> to be considered
+//      * @param bound the first position in <code>document</code> to not consider any more, with <code>scanTo</code> &gt; <code>position</code>
+//      * @param chars an array of <code>char</code> to search for
+//      * @return the highest position of one element in <code>chars</code> in [<code>position</code>, <code>scanTo</code>) that resides in a Java partition, or <code>-1</code> if none can be found
+//      */
+//     private static int scanBackward(IDocument document, int position, int bound, char ch) {
+//             return scanBackward(document, position, bound, new char[] {ch});
+//     }
+//
+       /**
+        * Finds the lowest position in <code>document</code> such that the position is &gt;= <code>position</code>
+        * and &lt; <code>bound</code> and <code>document.getChar(position) == ch</code> evaluates to <code>true</code> for at least one
+        * ch in <code>chars</code> and the position is in the default partition.   
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param partitioning the document partitioning
+        * @param bound the first position in <code>document</code> to not consider any more, with <code>scanTo</code> &gt; <code>position</code>
+        * @param chars an array of <code>char</code> to search for
+        * @return the lowest position of one element in <code>chars</code> in [<code>position</code>, <code>bound</code>) that resides in a Java partition, or <code>-1</code> if none can be found
+        */
+       private static int scanForward(IDocument document, int position, String partitioning, int bound, char[] chars) {
+               Assert.isTrue(position >= 0);
+               Assert.isTrue(bound <= document.getLength());
+               
+               Arrays.sort(chars);
+               
+               try {
+                       while (position < bound) {
+
+                               if (Arrays.binarySearch(chars, document.getChar(position)) >= 0 && isDefaultPartition(document, position, partitioning))
+                                       return position;
+
+                               position++;
+                       }
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Finds the lowest position in <code>document</code> such that the position is &gt;= <code>position</code>
+        * and &lt; <code>bound</code> and <code>document.getChar(position) == ch</code> evaluates to <code>true</code>
+        * and the position is in the default partition.   
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param partitioning the document partitioning
+        * @param bound the first position in <code>document</code> to not consider any more, with <code>scanTo</code> &gt; <code>position</code>
+        * @param chars an array of <code>char</code> to search for
+        * @return the lowest position of one element in <code>chars</code> in [<code>position</code>, <code>bound</code>) that resides in a Java partition, or <code>-1</code> if none can be found
+        */
+       private static int scanForward(IDocument document, int position, String partitioning, int bound, char ch) {
+               return scanForward(document, position, partitioning, bound, new char[] {ch});
+       }
+
+       /**
+        * Checks whether the content of <code>document</code> in the range (<code>offset</code>, <code>length</code>)
+        * contains the <code>new</code> keyword.
+        * 
+        * @param document the document being modified
+        * @param offset the first character position in <code>document</code> to be considered
+        * @param length the length of the character range to be considered
+        * @param partitioning the document partitioning
+        * @return <code>true</code> if the specified character range contains a <code>new</code> keyword, <code>false</code> otherwise.
+        */
+       private static boolean isNewMatch(IDocument document, int offset, int length, String partitioning) {
+               Assert.isTrue(length >= 0);
+               Assert.isTrue(offset >= 0);
+               Assert.isTrue(offset + length < document.getLength() + 1);
+
+               try {
+                       String text= document.get(offset, length);
+                       int pos= text.indexOf("new"); //$NON-NLS-1$
+                       
+                       while (pos != -1 && !isDefaultPartition(document, pos + offset, partitioning))
+                               pos= text.indexOf("new", pos + 2); //$NON-NLS-1$
+
+                       if (pos < 0)
+                               return false;
+
+                       if (pos != 0 && Character.isJavaIdentifierPart(text.charAt(pos - 1)))
+                               return false;
+
+                       if (pos + 3 < length && Character.isJavaIdentifierPart(text.charAt(pos + 3)))
+                               return false;
+                       
+                       return true;
+
+               } catch (BadLocationException e) {
+               }
+               return false;
+       }
+
+       /**
+        * Checks whether the content of <code>document</code> at <code>position</code> looks like an
+        * anonymous class definition. <code>position</code> must be to the left of the opening
+        * parenthesis of the definition's parameter list.
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param partitioning the document partitioning
+        * @return <code>true</code> if the content of <code>document</code> looks like an anonymous class definition, <code>false</code> otherwise
+        */
+       private static boolean looksLikeAnonymousClassDef(IDocument document, int position, String partitioning) {
+               int previousCommaOrParen= scanBackward(document, position - 1, partitioning, -1, new char[] {',', '('});
+               if (previousCommaOrParen == -1 || position < previousCommaOrParen + 5) // 2 for borders, 3 for "new"
+                       return false;
+
+               if (isNewMatch(document, previousCommaOrParen + 1, position - previousCommaOrParen - 2, partitioning))
+                       return true;
+
+               return false;
+       }
+
+       /**
+        * Checks whether <code>position</code> resides in a default (Java) partition of <code>document</code>.
+        * 
+        * @param document the document being modified
+        * @param position the position to be checked
+        * @param partitioning the document partitioning
+        * @return <code>true</code> if <code>position</code> is in the default partition of <code>document</code>, <code>false</code> otherwise
+        */
+       private static boolean isDefaultPartition(IDocument document, int position, String partitioning) {
+               Assert.isTrue(position >= 0);
+               Assert.isTrue(position <= document.getLength());
+               
+               try {
+                       // don't use getPartition2 since we're interested in the scanned character's partition
+                       ITypedRegion region= TextUtilities.getPartition(document, partitioning, position, false);
+                       return region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE);
+                       
+               } catch (BadLocationException e) {
+               }
+               
+               return false;
+       }
+
+       /**
+        * Finds the position of the parenthesis matching the closing parenthesis at <code>position</code>.
+        * 
+        * @param document the document being modified
+        * @param position the position in <code>document</code> of a closing parenthesis
+        * @param partitioning the document partitioning
+        * @return the position in <code>document</code> of the matching parenthesis, or -1 if none can be found
+        */
+       private static int findOpeningParenMatch(IDocument document, int position, String partitioning) {
+               final char CLOSING_PAREN= ')';
+               final char OPENING_PAREN= '(';
+
+               Assert.isTrue(position < document.getLength());
+               Assert.isTrue(position >= 0);
+               Assert.isTrue(isDefaultPartition(document, position, partitioning));
+
+               try {
+
+                       Assert.isTrue(document.getChar(position) == CLOSING_PAREN);
+                       
+                       int depth= 1;
+                       while (true) {
+                               position= scanBackward(document, position - 1, partitioning, -1, new char[] {CLOSING_PAREN, OPENING_PAREN});
+                               if (position == -1)
+                                       return -1;
+                                       
+                               if (document.getChar(position) == CLOSING_PAREN)
+                                       depth++;
+                               else
+                                       depth--;
+                               
+                               if (depth == 0)
+                                       return position;
+                       }
+
+               } catch (BadLocationException e) {
+                       return -1;
+               }
+       }
+
+       /**
+        * Checks whether, to the left of <code>position</code> and separated only by whitespace, 
+        * <code>document</code> contains a keyword taking a parameter list and a block after it.
+        * These are: <code>if</code>, <code>while</code>, <code>catch</code>, <code>for</code>, <code>synchronized</code>, <code>switch</code>. 
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param partitioning the document partitioning
+        * @return <code>true</code> if <code>document</code> contains any of the above keywords to the left of <code>position</code>, <code>false</code> otherwise
+        */
+       private static boolean looksLikeIfWhileForCatch(IDocument document, int position, String partitioning) {
+               position= firstNonWhitespaceBackward(document, position, partitioning, -1);
+               if (position == -1)
+                       return false;
+
+               return looksLike(document, position, "if") //$NON-NLS-1$
+                               || looksLike(document, position, "while") //$NON-NLS-1$
+                               || looksLike(document, position, "catch") //$NON-NLS-1$
+                               || looksLike(document, position, "synchronized") //$NON-NLS-1$
+                               || looksLike(document, position, "switch") //$NON-NLS-1$
+                               || looksLike(document, position, "for"); //$NON-NLS-1$
+       }
+
+       /**
+        * Checks whether code>document</code> contains the <code>String</code> <code>like</code> such 
+        * that its last character is at <code>position</code>. If <code>like</code> starts with a
+        * identifier part (as determined by {@link Character#isJavaIdentifier(char)}), it is also made
+        * sure that <code>like</code> is preceded by some non-identifier character or stands at the
+        * document start.
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param like the <code>String</code> to look for.
+        * @return <code>true</code> if  <code>document</code> contains <code>like</code> such that it ends at <code>position</code>, <code>false</code> otherwise
+        */
+       private static boolean looksLike(IDocument document, int position, String like) {
+               int length= like.length();
+               if (position < length - 1)
+                       return false;
+
+               try {
+                       if (!like.equals(document.get(position - length + 1, length)))
+                               return false;
+
+                       if (position >= length && Character.isJavaIdentifierPart(like.charAt(0)) && Character.isJavaIdentifierPart(document.getChar(position - length)))
+                               return false;
+
+               } catch (BadLocationException e) {
+                       return false;
+               }
+
+               return true;
+       }
+
+       /**
+        * Checks whether the content of <code>document</code> at <code>position</code> looks like a
+        * method declaration header (i.e. only the return type and method name). <code>position</code>
+        * must be just left of the opening parenthesis of the parameter list.
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param partitioning the document partitioning
+        * @return <code>true</code> if the content of <code>document</code> looks like a method definition, <code>false</code> otherwise
+        */
+       private static boolean looksLikeMethodDecl(IDocument document, int position, String partitioning) {
+               
+               // method name
+               position= eatIdentToLeft(document, position, partitioning);
+               if (position < 1)
+                       return false;
+                       
+               position= eatBrackets(document, position - 1, partitioning);
+               if (position < 1)
+                       return false;
+               
+               position= eatIdentToLeft(document, position - 1, partitioning);
+
+               return position != -1;
+       }
+
+       /**
+        * From <code>position</code> to the left, eats any whitespace and then a pair of brackets
+        * as used to declare an array return type like <pre>String [ ]</pre>.
+        * The return value is either the position of the opening bracket or <code>position</code> if no 
+        * pair of brackets can be parsed. 
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param partitioning the document partitioning
+        * @return the smallest character position of bracket pair or <code>position</code>
+        */
+       private static int eatBrackets(IDocument document, int position, String partitioning) {
+               // accept array return type
+               int pos= firstNonWhitespaceBackward(document, position, partitioning, -1);
+               try {
+                       if (pos > 1 && document.getChar(pos) == ']') {
+                               pos= firstNonWhitespaceBackward(document, pos - 1, partitioning, -1);
+                               if (pos > 0 && document.getChar(pos) == '[')
+                                       return pos;
+                       }
+               } catch (BadLocationException e) {
+                       // won't happen
+               }
+               return position;
+       }
+
+       /**
+        * From <code>position</code> to the left, eats any whitespace and the first identifier, returning 
+        * the position of the first identifier character (in normal read order).
+        * <p>When called on a document with content <code>" some string  "</code> and positionition 13, the
+        * return value will be 6 (the first letter in <code>string</code>).
+        * </p>
+        * 
+        * @param document the document being modified
+        * @param position the first character position in <code>document</code> to be considered
+        * @param partitioning the document partitioning
+        * @return the smallest character position of an identifier or -1 if none can be found; always &lt;= <code>position</code>
+        */
+       private static int eatIdentToLeft(IDocument document, int position, String partitioning) {
+               if (position < 0)
+                       return -1;
+               Assert.isTrue(position < document.getLength());
+               
+               int p= firstNonWhitespaceBackward(document, position, partitioning, -1);
+               if (p == -1)
+                       return -1;
+
+               try {
+                       while (p >= 0) {
+
+                               char ch= document.getChar(p);
+                               if (Character.isJavaIdentifierPart(ch)) {
+                                       p--;
+                                       continue;
+                               }
+
+                               // length must be > 0
+                               if (Character.isWhitespace(ch) && p != position)
+                                       return p + 1;
+                               else
+                                       return -1;
+
+                       }
+
+                       // start of document reached
+                       return 0;
+
+               } catch (BadLocationException e) {
+               }
+               return -1;
+       }
+
+       /**
+        * Returns a position in the first java partition after the last non-empty and non-comment partition.
+        * There is no non-whitespace from the returned position to the end of the partition it is contained in.
+        * 
+        * @param document the document being modified
+        * @param line the line under investigation
+        * @param offset the caret offset into <code>line</code>
+        * @param partitioning the document partitioning
+        * @return the position of the next Java partition, or the end of <code>line</code>
+        */
+       private static int nextPartitionOrLineEnd(IDocument document, ITextSelection line, int offset, String partitioning) {
+               // run relative to document
+               final int docOffset= offset + line.getOffset();
+               final int eol= line.getOffset() + line.getLength();
+               int nextPartitionPos= eol; // init with line end
+               int validPosition= docOffset;
+
+               try {
+                       ITypedRegion partition= TextUtilities.getPartition(document, partitioning, nextPartitionPos, true);
+                       validPosition= getValidPositionForPartition(document, partition, eol);
+                       while (validPosition == -1) {
+                               nextPartitionPos= partition.getOffset() - 1;
+                               if (nextPartitionPos < docOffset) {
+                                       validPosition= docOffset;
+                                       break;
+                               }
+                               partition= TextUtilities.getPartition(document, partitioning, nextPartitionPos, false);
+                               validPosition= getValidPositionForPartition(document, partition, eol);
+                       }
+               } catch (BadLocationException e) {
+               }
+
+               validPosition= Math.max(validPosition, docOffset);
+               // make relative to line
+               validPosition -= line.getOffset();
+               return validPosition;
+       }
+
+       /**
+        * Returns a valid insert location (except for whitespace) in <code>partition</code> or -1 if
+        * there is no valid insert location. 
+        * An valid insert location is right after any java string or character partition, or at the end
+        * of a java default partition, but never behind <code>maxOffset</code>. Comment partitions or 
+        * empty java partitions do never yield valid insert positions.
+        * 
+        * @param doc the document being modified
+        * @param partition the current partition
+        * @param maxOffset the maximum offset to consider
+        * @return a valid insert location in <code>partition</code>, or -1 if there is no valid insert location
+        */
+       private static int getValidPositionForPartition(IDocument doc, ITypedRegion partition, int maxOffset) {
+               final int INVALID= -1;
+
+               if (IPHPPartitions.PHP_PHPDOC_COMMENT.equals(partition.getType()))
+                       return INVALID;
+               if (IPHPPartitions.PHP_MULTILINE_COMMENT.equals(partition.getType()))
+                       return INVALID;
+               if (IPHPPartitions.PHP_SINGLELINE_COMMENT.equals(partition.getType()))
+                       return INVALID;
+
+               int endOffset= Math.min(maxOffset, partition.getOffset() + partition.getLength());
+
+//             if (IPHPPartitions.JAVA_CHARACTER.equals(partition.getType()))
+//                     return endOffset;
+               if (IPHPPartitions.PHP_STRING_DQ.equals(partition.getType()))
+                       return endOffset;
+               if (IPHPPartitions.PHP_STRING_SQ.equals(partition.getType()))
+                       return endOffset;
+               if (IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())) {
+                       try {
+                               if (doc.get(partition.getOffset(), endOffset - partition.getOffset()).trim().length() == 0)
+                                       return INVALID;
+                               else
+                                       return endOffset;
+                       } catch (BadLocationException e) {
+                               return INVALID;
+                       }
+               }
+               // default: we don't know anything about the partition - assume valid 
+               return endOffset;
+       }
+
+       /**
+        * Determines whether the current line contains a for statement.
+        * Algorithm: any "for" word in the line is a positive, "for" contained in a string literal will
+        * produce a false positive.
+        * 
+        * @param line the line where the change is being made
+        * @param offset the position of the caret
+        * @return <code>true</code> if <code>line</code> contains <code>for</code>, <code>false</code> otherwise
+        */
+       private static boolean isForStatement(String line, int offset) {
+               /* searching for (^|\s)for(\s|$) */
+               int forPos= line.indexOf("for"); //$NON-NLS-1$
+               if (forPos != -1) {
+                       if ((forPos == 0 || !Character.isJavaIdentifierPart(line.charAt(forPos - 1))) && (line.length() == forPos + 3 || !Character.isJavaIdentifierPart(line.charAt(forPos + 3))))
+                               return true;
+               }
+               return false;
+       }
+
+       /**
+        * Returns the position in <code>text</code> after which there comes only whitespace, up to 
+        * <code>offset</code>.
+        *  
+        * @param text the text being searched
+        * @param offset the maximum offset to search for
+        * @return the smallest value <code>v</code> such that <code>text.substring(v, offset).trim() == 0</code>
+        */
+       private static int startOfWhitespaceBeforeOffset(String text, int offset) {
+               int i= Math.min(offset, text.length());
+               for (; i >= 1; i--) {
+                       if (!Character.isWhitespace(text.charAt(i - 1)))
+                               break;
+               }
+               return i;
+       }
+}
index 411b38b..b873cc6 100644 (file)
@@ -63,7 +63,7 @@ public class DefaultJavaFoldingPreferenceBlock implements IJavaFoldingPreference
        private OverlayKey[] createKeys() {
                ArrayList overlayKeys= new ArrayList();
 
-//             overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_JAVADOC));
+               overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_JAVADOC));
 //             overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_INNERTYPES));
                overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_METHODS));
 //             overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_IMPORTS));
index 56d3d75..ea00344 100644 (file)
@@ -53,12 +53,12 @@ public class JavaStringAutoIndentStrategy extends DefaultAutoIndentStrategy {
                                        token = tokenizer.nextToken();
                                        if (token.equals("\n")) { //$NON-NLS-1$
                                                buffer.append("\\n"); //$NON-NLS-1$
-                                               buffer.append("\" + " + delimiter); //$NON-NLS-1$
+                                               buffer.append("\" . " + delimiter); //$NON-NLS-1$
                                                buffer.append(indentation);
                                                buffer.append("\""); //$NON-NLS-1$
                                                continue;
                                        } else {
-                                               buffer.append("\" + " + delimiter); //$NON-NLS-1$
+                                               buffer.append("\" . " + delimiter); //$NON-NLS-1$
                                                buffer.append(indentation);
                                                buffer.append("\""); //$NON-NLS-1$
                                        }
@@ -67,7 +67,7 @@ public class JavaStringAutoIndentStrategy extends DefaultAutoIndentStrategy {
                                }
                        } else if (token.equals("\n")) { //$NON-NLS-1$
                                buffer.append("\\n"); //$NON-NLS-1$
-                               buffer.append("\" + " + delimiter); //$NON-NLS-1$
+                               buffer.append("\" . " + delimiter); //$NON-NLS-1$
                                buffer.append(indentation);
                                buffer.append("\""); //$NON-NLS-1$
                                continue;
@@ -170,7 +170,7 @@ public class JavaStringAutoIndentStrategy extends DefaultAutoIndentStrategy {
                
                IPreferenceStore preferenceStore= PHPeclipsePlugin.getDefault().getPreferenceStore();
                if (isLineDelimiter(document, command.text))
-                       command.text= "\" +" + command.text + indentation + "\"";  //$NON-NLS-1$//$NON-NLS-2$
+                       command.text= "\" ." + command.text + indentation + "\"";  //$NON-NLS-1$//$NON-NLS-2$
                else if (command.text.length() > 1 && preferenceStore.getBoolean(PreferenceConstants.EDITOR_ESCAPE_STRINGS))
                        command.text= getModifiedText(command.text, indentation, delimiter);            
        }
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaInformationProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaInformationProvider.java
new file mode 100644 (file)
index 0000000..098883a
--- /dev/null
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.text.java.hover;
+
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.information.IInformationProvider;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IPerspectiveDescriptor;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+
+import net.sourceforge.phpdt.ui.text.java.hover.IJavaEditorTextHover;
+
+import net.sourceforge.phpdt.internal.ui.text.JavaWordFinder;
+
+
+public class JavaInformationProvider implements IInformationProvider {
+
+       class EditorWatcher implements IPartListener {
+               
+               /**
+                * @see IPartListener#partOpened(IWorkbenchPart)
+                */
+               public void partOpened(IWorkbenchPart part) {
+               }
+               
+               /**
+                * @see IPartListener#partDeactivated(IWorkbenchPart)
+                */
+               public void partDeactivated(IWorkbenchPart part) {
+               }
+               
+               /**
+                * @see IPartListener#partClosed(IWorkbenchPart)
+                */
+               public void partClosed(IWorkbenchPart part) {
+                       if (part == fEditor) {
+                               fEditor.getSite().getWorkbenchWindow().getPartService().removePartListener(fPartListener);
+                               fPartListener= null;
+                       }
+               }
+               
+               /**
+                * @see IPartListener#partActivated(IWorkbenchPart)
+                */
+               public void partActivated(IWorkbenchPart part) {
+                       update();
+               }
+               
+               public void partBroughtToTop(IWorkbenchPart part) {
+                       update();
+               }       
+       }
+       
+       protected IEditorPart fEditor;
+       protected IPartListener fPartListener;
+       
+       protected String fCurrentPerspective;
+       protected IJavaEditorTextHover fImplementation;
+       
+       
+       public JavaInformationProvider(IEditorPart editor) {
+               
+               fEditor= editor;
+               
+               if (fEditor != null) {
+                       
+                       fPartListener= new EditorWatcher();
+                       IWorkbenchWindow window= fEditor.getSite().getWorkbenchWindow();
+                       window.getPartService().addPartListener(fPartListener);
+                       
+                       update();
+               }
+       }
+       
+       protected void update() {
+               
+               IWorkbenchWindow window= fEditor.getSite().getWorkbenchWindow();
+               IWorkbenchPage page= window.getActivePage();
+               if (page != null) {
+                       
+                       IPerspectiveDescriptor perspective= page.getPerspective();
+                       if (perspective != null)  {
+                               String perspectiveId= perspective.getId();
+                               
+                               if (fCurrentPerspective == null || fCurrentPerspective != perspectiveId) {
+                                       fCurrentPerspective= perspectiveId;
+               
+                                       fImplementation= new JavaTypeHover();
+                                       fImplementation.setEditor(fEditor);
+                               }
+                       }
+               }
+       }
+       
+       /*
+        * @see IInformationProvider#getSubject(ITextViewer, int)
+        */
+       public IRegion getSubject(ITextViewer textViewer, int offset) {
+               
+               if (textViewer != null)
+                       return JavaWordFinder.findWord(textViewer.getDocument(), offset);
+               
+               return null;    
+       }
+
+       /*
+        * @see IInformationProvider#getInformation(ITextViewer, IRegion)
+        */
+       public String getInformation(ITextViewer textViewer, IRegion subject) {
+               if (fImplementation != null) {
+                       String s= fImplementation.getHoverInfo(textViewer, subject);
+                       if (s != null && s.trim().length() > 0)
+                               return s;
+               }
+               
+               return null;
+       }
+}
index 2936e54..d48678b 100644 (file)
@@ -10,9 +10,9 @@
  *******************************************************************************/
 package net.sourceforge.phpdt.internal.ui.text.java.hover;
 
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
-import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
 
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.text.Document;
index 1d17285..24aa1f8 100644 (file)
@@ -1,16 +1,15 @@
 /**********************************************************************
-Copyright (c) 2000, 2002 IBM Corp. and others.
-All rights reserved. This program and the accompanying materials
-are made available under the terms of the Common Public License v1.0
-which accompanies this distribution, and is available at
-http://www.eclipse.org/legal/cpl-v10.html
-
-Contributors:
-    IBM Corporation - Initial implementation
-**********************************************************************/
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ **********************************************************************/
 package net.sourceforge.phpdt.internal.ui.text.phpdoc;
 
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -30,15 +29,11 @@ import org.eclipse.jface.text.rules.Token;
 import org.eclipse.jface.text.rules.WhitespaceRule;
 import org.eclipse.jface.text.rules.WordRule;
 
-
-
-
 /**
  * A rule based PHPDoc scanner.
  */
 public final class PHPDocCodeScanner extends AbstractJavaScanner {
-               
-               
+
   /**
    * A key word detector.
    */
@@ -58,8 +53,7 @@ public final class PHPDocCodeScanner extends AbstractJavaScanner {
       return Character.isLetter(c);
     }
   };
-       
-       
+
   /**
    * Detector for HTML comment delimiters.
    */
@@ -79,68 +73,77 @@ public final class PHPDocCodeScanner extends AbstractJavaScanner {
       return (c == '-' || c == '!' || c == '>');
     }
   };
-       
+
   class TagRule extends SingleLineRule {
-               
+
     /*
      * @see SingleLineRule
      */
     public TagRule(IToken token) {
       super("<", ">", token, (char) 0); //$NON-NLS-2$ //$NON-NLS-1$
     }
-               
+
     /*
-     * @see SingleLineRule 
+     * @see SingleLineRule
      */
     public TagRule(IToken token, char escapeCharacter) {
       super("<", ">", token, escapeCharacter); //$NON-NLS-2$ //$NON-NLS-1$
     }
-               
+
     private IToken checkForWhitespace(ICharacterScanner scanner) {
-                       
+
       try {
-                               
-        char c= getDocument().getChar(getTokenOffset() + 1);
-        if (!Character.isWhitespace(c)) 
+
+        char c = getDocument().getChar(getTokenOffset() + 1);
+        if (!Character.isWhitespace(c))
           return fToken;
-                                       
+
       } catch (BadLocationException x) {
       }
-                       
+
       return Token.UNDEFINED;
     }
-                               
+
     /*
      * @see PatternRule#evaluate(ICharacterScanner)
      */
     public IToken evaluate(ICharacterScanner scanner) {
-      IToken result= super.evaluate(scanner);
+      IToken result = super.evaluate(scanner);
       if (result == fToken)
         return checkForWhitespace(scanner);
       return result;
     }
   };
-       
-       
-  private static String[] fgKeywords= {"@author", "@deprecated", "@exception", "@param", "@return", "@see", "@serial", "@serialData", "@serialField", "@since", "@throws", "@version"}; //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-7$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
-       
-  private static String[] fgTokenProperties= {
-               IPreferenceConstants.PHPDOC_KEYWORD,
-               IPreferenceConstants.PHPDOC_TAG,
-               IPreferenceConstants.PHPDOC_LINK,
-               IPreferenceConstants.PHPDOC_DEFAULT
-  };                   
-       
-       
+
+  private static String[] fgKeywords = {
+      "@author",
+      "@copyright", 
+      "@deprecated", 
+      "@exception",
+      "@link",
+      "@package", 
+      "@param", 
+      "@return", 
+      "@see", 
+      "@serial", 
+      "@serialData", 
+      "@serialField", 
+      "@since", 
+      "@throws", 
+      "@version" }; //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-7$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+  private static String[] fgTokenProperties = { IPreferenceConstants.PHPDOC_KEYWORD, IPreferenceConstants.PHPDOC_TAG,
+      IPreferenceConstants.PHPDOC_LINK, IPreferenceConstants.PHPDOC_DEFAULT };
+
   public PHPDocCodeScanner(IColorManager manager, IPreferenceStore store) {
     super(manager, store);
     initialize();
   }
-       
+
   public IDocument getDocument() {
     return fDocument;
   }
-       
+
   /*
    * @see AbstractJavaScanner#getTokenProperties()
    */
@@ -152,42 +155,37 @@ public final class PHPDocCodeScanner extends AbstractJavaScanner {
    * @see AbstractJavaScanner#createRules()
    */
   protected List createRules() {
-               
-    List list= new ArrayList();
-               
+
+    List list = new ArrayList();
+
     // Add rule for tags.
-    Token token= getToken(IPreferenceConstants.PHPDOC_TAG);
+    Token token = getToken(IPreferenceConstants.PHPDOC_TAG);
     list.add(new TagRule(token));
-               
-               
+
     // Add rule for HTML comments
-    WordRule wordRule= new WordRule(new HTMLCommentDetector(), token);
+    WordRule wordRule = new WordRule(new HTMLCommentDetector(), token);
     wordRule.addWord("<!--", token); //$NON-NLS-1$
     wordRule.addWord("--!>", token); //$NON-NLS-1$
     list.add(wordRule);
-               
-               
+
     // Add rule for links.
-    token= getToken(IPreferenceConstants.PHPDOC_LINK);
+    token = getToken(IPreferenceConstants.PHPDOC_LINK);
     list.add(new SingleLineRule("{@link", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
-               
-               
+
     // Add generic whitespace rule.
     list.add(new WhitespaceRule(new PHPWhitespaceDetector()));
-               
-               
+
     // Add word rule for keywords.
-    token= getToken(IPreferenceConstants.PHPDOC_DEFAULT);
-    wordRule= new WordRule(new JavaDocKeywordDetector(), token);
-               
-    token= getToken(IPreferenceConstants.PHPDOC_KEYWORD);
-    for (int i= 0; i < fgKeywords.length; i++)
+    token = getToken(IPreferenceConstants.PHPDOC_DEFAULT);
+    wordRule = new WordRule(new JavaDocKeywordDetector(), token);
+
+    token = getToken(IPreferenceConstants.PHPDOC_KEYWORD);
+    for (int i = 0; i < fgKeywords.length; i++)
       wordRule.addWord(fgKeywords[i], token);
     list.add(wordRule);
-               
+
     setDefaultReturnToken(getToken(IPreferenceConstants.PHPDOC_DEFAULT));
     return list;
   }
 }
 
-
index e7c66c1..9ff8886 100644 (file)
@@ -17,6 +17,7 @@ import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
 
 import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
@@ -34,6 +35,7 @@ public class DeclarationEngine {
   /** Token determines last which declarations are allowed for proposal */
   private int fLastSignificantToken;
 
+  private IProject fProject;
   private IFile fFile;
 //  private String fFileName;
 
@@ -41,8 +43,9 @@ public class DeclarationEngine {
    * Creates the template engine for a particular context type.
    * See <code>TemplateContext</code> for supported context types.
    */
-  public DeclarationEngine(ContextType contextType, int lastSignificantToken, IFile file) {
+  public DeclarationEngine(IProject project, ContextType contextType, int lastSignificantToken, IFile file) {
     // Assert.isNotNull(contextType);
+    fProject = project;
     fContextType = contextType;
 
     fLastSignificantToken = lastSignificantToken;
@@ -151,7 +154,7 @@ public class DeclarationEngine {
           if (maxProposals-- < 0) {
             return;
           }
-          fProposals.add(new DeclarationProposal(identifier, location, context, region, viewer));
+          fProposals.add( new DeclarationProposal(fProject, identifier, location, context, region, viewer));
         }
       }
     }
index 539a49b..76da3b3 100644 (file)
@@ -14,6 +14,7 @@ import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation;
 
+import org.eclipse.core.resources.IProject;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
@@ -28,6 +29,7 @@ import org.eclipse.swt.graphics.Image;
  * A PHP identifier proposal.
  */
 public class DeclarationProposal extends AbstractProposal { //implements IPHPCompletionProposal {
+  private IProject fProject;
   private final TemplateContext fContext;
   private final PHPIdentifierLocation fLocation;
 
@@ -48,6 +50,7 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom
    * @param image     the icon of the proposal.
    */
   public DeclarationProposal(
+      IProject project,
     String identifierName,
     PHPIdentifierLocation location,
     TemplateContext context,
@@ -56,6 +59,7 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom
     super(viewer);
     //    Image image_fun,
     //    Image image_var) {
+    fProject = project;
     fIdentifierName = identifierName;
     fLocation = location;
     fContext = context;
@@ -138,10 +142,18 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom
    */
   public String getAdditionalProposalInfo() {
     StringBuffer hoverInfoBuffer = new StringBuffer();
-    String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
+//    String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
+    String workspaceLocation;
+    if (fProject!=null) {
+      workspaceLocation = fProject.getLocation().toString()+'/';
+    } else {
+      // should never happen?
+      workspaceLocation = PHPeclipsePlugin.getWorkspace()
+      .getRoot().getLocation().toString();
+    }
     String filename = workspaceLocation + fLocation.getFilename();
     PHPDocUtil.appendPHPDoc(hoverInfoBuffer, filename, fLocation);
-    return textToHTML(hoverInfoBuffer.toString());
+    return hoverInfoBuffer.toString();
   }
 
   /*
@@ -155,7 +167,15 @@ public class DeclarationProposal extends AbstractProposal { //implements IPHPCom
    * @see ICompletionProposal#getDisplayString()
    */
   public String getDisplayString() {
-    String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
+//    String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString();
+    String workspaceLocation;
+    if (fProject!=null) {
+      workspaceLocation = fProject.getLocation().toString()+'/';
+    } else {
+      // should never happen?
+      workspaceLocation = PHPeclipsePlugin.getWorkspace()
+      .getRoot().getLocation().toString();
+    }
     String filename = workspaceLocation + fLocation.getFilename();
     return fIdentifierName + TemplateMessages.getString("TemplateProposal.delimiter") + PHPDocUtil.getUsage(filename, fLocation) + TemplateMessages.getString("TemplateProposal.delimiter") + filename; // $NON-NLS-1$ //$NON-NLS-1$
   }
index ab65d86..2ac2f8b 100644 (file)
@@ -1570,6 +1570,14 @@ public final static String EDITOR_TEXT_FONT= "net.sourceforge.phpdt.ui.editors.t
         * @since 3.0
         */     
        public static final String EDITOR_SMART_SEMICOLON= "smart_semicolon"; //$NON-NLS-1$
+       /**
+        * A named preference that controls the smart backspace behavior.
+        * <p>
+        * Value is of type <code>Boolean</code>.
+        * 
+        * @since 3.0
+        */
+       public static final String EDITOR_SMART_BACKSPACE= "smart_backspace"; //$NON-NLS-1$
        
        /**
         * A named preference that controls the "smart opening brace" smart typing handler
@@ -2421,11 +2429,13 @@ public final static String EDITOR_TEXT_FONT= "net.sourceforge.phpdt.ui.editors.t
        // folding
        store.setDefault(PreferenceConstants.EDITOR_FOLDING_ENABLED, true);
        store.setDefault(PreferenceConstants.EDITOR_FOLDING_PROVIDER,  "net.sourceforge.phpdt.ui.text.defaultFoldingProvider"); //$NON-NLS-1$
-       store.setDefault(PreferenceConstants.EDITOR_FOLDING_JAVADOC, false);
+       store.setDefault(PreferenceConstants.EDITOR_FOLDING_JAVADOC, true);
        store.setDefault(PreferenceConstants.EDITOR_FOLDING_INNERTYPES, true);
        store.setDefault(PreferenceConstants.EDITOR_FOLDING_METHODS, false);
        store.setDefault(PreferenceConstants.EDITOR_FOLDING_IMPORTS, false);
 
+       store.setDefault(PreferenceConstants.EDITOR_SMART_BACKSPACE, true);
+       
     // do more complicated stuff
     // NewJavaProjectPreferencePage.initDefaults(store);       
   }
index 0d592a8..33a5411 100644 (file)
@@ -5,17 +5,23 @@ package net.sourceforge.phpdt.ui.text;
  * All Rights Reserved.
  */
 
+import net.sourceforge.phpdt.internal.ui.text.FastJavaPartitionScanner;
 import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
 import net.sourceforge.phpdt.internal.ui.text.JavaColorManager;
 import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCodeScanner;
 import net.sourceforge.phpeclipse.IPreferenceConstants;
-import net.sourceforge.phpeclipse.phpeditor.php.HTMLCodeScanner;
-import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.php.HTMLPartitionScanner;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPDocumentPartitioner;
 import net.sourceforge.phpeclipse.phpeditor.php.PHPPartitionScanner;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner;
 import net.sourceforge.phpeclipse.phpeditor.php.SmartyCodeScanner;
 import net.sourceforge.phpeclipse.phpeditor.php.SmartyDocCodeScanner;
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.SingleTokenScanner;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLPartitionScanner;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
 
-import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.Preferences;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.text.IDocument;
@@ -24,9 +30,10 @@ import org.eclipse.jface.text.IDocumentPartitioner;
 import org.eclipse.jface.text.rules.DefaultPartitioner;
 import org.eclipse.jface.text.rules.IPartitionTokenScanner;
 import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.Token;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.ui.part.FileEditorInput;
+
 //
 //import org.phpeclipse.phpdt.internal.ui.text.FastJavaPartitionScanner;
 //import org.phpeclipse.phpdt.internal.ui.text.JavaColorManager;
@@ -36,136 +43,155 @@ import org.eclipse.ui.part.FileEditorInput;
 //import org.phpeclipse.phpdt.internal.ui.text.phpdoc.JavaDocScanner;
 
 /**
- * Tools required to configure a Java text viewer. 
- * The color manager and all scanner exist only one time, i.e.
- * the same instances are returned to all clients. Thus, clients
- * share those tools.
+ * Tools required to configure a Java text viewer. The color manager and all scanner exist only one time, i.e. the same instances
+ * are returned to all clients. Thus, clients share those tools.
  * <p>
  * This class may be instantiated; it is not intended to be subclassed.
  * </p>
  */
-public class JavaTextTools {
-
-  private static PHPPartitionScanner HTML_PARTITION_SCANNER = null;
-  private static PHPPartitionScanner PHP_PARTITION_SCANNER = null;
-  private static PHPPartitionScanner SMARTY_PARTITION_SCANNER = null;
-
-  // private final static String[] TYPES= new String[] { PHPPartitionScanner.PHP, PHPPartitionScanner.JAVA_DOC, PHPPartitionScanner.JAVA_MULTILINE_COMMENT };
-  private final static String[] TYPES =
-    new String[] {
-      IPHPPartitions.PHP_PARTITIONING,
-      IPHPPartitions.PHP_PHPDOC_COMMENT,
-      IPHPPartitions.HTML,
-      IPHPPartitions.HTML_MULTILINE_COMMENT,
-      IPHPPartitions.JAVASCRIPT,
-      IPHPPartitions.CSS,
-      IPHPPartitions.SMARTY,
-      IPHPPartitions.SMARTY_MULTILINE_COMMENT };
-  private static PHPPartitionScanner XML_PARTITION_SCANNER = null;
-
-  /**
-   * This tools' preference listener. 
+public class JavaTextTools implements IPHPPartitions {
+//  private static final String[] TOKENS = { 
+//  JSPScriptScanner.JSP_DEFAULT, 
+//  JSPScriptScanner.JSP_BRACKET };
+  private final static String[] LEGAL_CONTENT_TYPES = new String[] { 
+         PHP_PHPDOC_COMMENT, 
+         PHP_MULTILINE_COMMENT,
+      PHP_SINGLELINE_COMMENT, 
+      PHP_STRING_DQ, 
+      PHP_STRING_SQ };
+  
+  private static XMLPartitionScanner HTML_PARTITION_SCANNER = null;
+
+  private static FastJavaPartitionScanner PHP_PARTITION_SCANNER = null;
+
+  private static HTMLPartitionScanner SMARTY_PARTITION_SCANNER = null;
+
+  private static XMLPartitionScanner XML_PARTITION_SCANNER = null;
+
+  // private final static String[] TYPES= new String[] { PHPPartitionScanner.PHP, PHPPartitionScanner.JAVA_DOC,
+  // PHPPartitionScanner.JAVA_MULTILINE_COMMENT };
+//  private final static String[] TYPES = new String[] { 
+//      IPHPPartitions.PHP_PARTITIONING, 
+//      IPHPPartitions.PHP_PHPDOC_COMMENT,
+//  //      IPHPPartitions.HTML,
+//      //      IPHPPartitions.HTML_MULTILINE_COMMENT,
+//      IPHPPartitions.JAVASCRIPT, 
+//      IPHPPartitions.CSS, 
+//      IPHPPartitions.SMARTY, 
+//      IPHPPartitions.SMARTY_MULTILINE_COMMENT };
+
+  /**
+   * This tools' preference listener.
    */
   private class PreferenceListener implements IPropertyChangeListener, Preferences.IPropertyChangeListener {
     public void propertyChange(PropertyChangeEvent event) {
       adaptToPreferenceChange(event);
     }
+
     public void propertyChange(Preferences.PropertyChangeEvent event) {
-      adaptToPreferenceChange(
-        new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue()));
+      adaptToPreferenceChange(new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event
+          .getNewValue()));
     }
   };
 
-  /** The color manager */
-  private JavaColorManager fColorManager;
+  //  /** The color manager */
+  private JavaColorManager colorManager;
+
   /** The PHP source code scanner */
   private PHPCodeScanner fCodeScanner;
+
   /** The PHP multiline comment scanner */
   private SingleTokenPHPScanner fMultilineCommentScanner;
+
   /** The Java singleline comment scanner */
   private SingleTokenPHPScanner fSinglelineCommentScanner;
+
   /** The Java string scanner */
   private SingleTokenPHPScanner fStringScanner;
+
   /** The PHPDoc scanner */
   private PHPDocCodeScanner fPHPDocScanner;
+
   /** The HTML scanner */
-  private HTMLCodeScanner fHTMLScanner;
+  //  private HTMLCodeScanner fHTMLScanner;
   /** The Smarty scanner */
   private SmartyCodeScanner fSmartyScanner;
+
   /** The SmartyDoc scanner */
   private SmartyDocCodeScanner fSmartyDocScanner;
-  /** The Java partitions scanner */
-  private PHPPartitionScanner fPartitionScanner;
-
+  
+  /** The Java partitions scanner. */
+  private FastJavaPartitionScanner fPartitionScanner;  
+  
   /** The preference store */
   private IPreferenceStore fPreferenceStore;
+  
+  /** The XML Language text tools */
+  private XMLTextTools xmlTextTools;
   /**
    * The core preference store.
+   * 
    * @since 2.1
    */
   private Preferences fCorePreferenceStore;
+
   /** The preference change listener */
   private PreferenceListener fPreferenceListener = new PreferenceListener();
 
+  /** The JSP partitions scanner */
+  private PHPPartitionScanner jspPartitionScanner = null;
+
+  /** The JSP script subpartitions scanner */
+//  private JSPScriptScanner jspScriptScanner;
+
+  /** The PHP plain text scanner */
+//  private RuleBasedScanner jspTextScanner;
+
+  /** The PHP brackets scanner */
+//  private RuleBasedScanner jspBracketScanner;
+
   /**
    * Creates a new Java text tools collection.
    * 
-   * @param store the preference store to initialize the text tools. The text tool
-   * instance installs a listener on the passed preference store to adapt itself to 
-   * changes in the preference store. In general <code>PreferenceConstants.
-   * getPreferenceStore()</code> shoould be used to initialize the text tools.
-   * 
-   * @see org.phpeclipse.phpdt.ui.PreferenceConstants#getPreferenceStore()
-   * @since 2.0
+   * @param store
+   *          the preference store to initialize the text tools. The text tool instance installs a listener on the passed preference
+   *          store to adapt itself to changes in the preference store. In general <code>PreferenceConstants.
+   *                   getPreferenceStore()</code>
+   *          should be used to initialize the text tools.
+   * @param coreStore
+   *          optional preference store to initialize the text tools. The text tool instance installs a listener on the passed
+   *          preference store to adapt itself to changes in the preference store.
+   * @see org.eclipse.jdt.ui.PreferenceConstants#getPreferenceStore()
+   * @since 2.1
    */
-//  public JavaTextTools(IPreferenceStore store) {
-//    fPreferenceStore = store;
-//    fPreferenceStore.addPropertyChangeListener(fPreferenceListener);
-//
-//    fColorManager = new JavaColorManager();
-//    fCodeScanner = new PHPCodeScanner(fColorManager, store);
-//    fMultilineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_MULTILINE_COMMENT);
-//    fSinglelineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_SINGLELINE_COMMENT);
-//    fStringScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_STRING);
-//    fPHPDocScanner = new PHPDocCodeScanner(fColorManager, store);
-//    fHTMLScanner = new HTMLCodeScanner(fColorManager, store);
-//    fSmartyScanner = new SmartyCodeScanner(fColorManager, store);
-//    fSmartyDocScanner = new SmartyDocCodeScanner(fColorManager, store);
-////    fPartitionScanner = new FastJavaPartitionScanner();
-//    fPartitionScanner = new PHPPartitionScanner();
-//  }
-  /**
-        * Creates a new Java text tools collection.
-        * @param store the preference store to initialize the text tools. The text tool
-        *                      instance installs a listener on the passed preference store to adapt itself to 
-        *                      changes in the preference store. In general <code>PreferenceConstants.
-        *                      getPreferenceStore()</code> should be used to initialize the text tools.
-        * @param coreStore optional preference store to initialize the text tools. The text tool
-        *                      instance installs a listener on the passed preference store to adapt itself to 
-        *                      changes in the preference store.
-        * @see org.eclipse.jdt.ui.PreferenceConstants#getPreferenceStore()
-        * @since 2.1
-        */
-       public JavaTextTools(IPreferenceStore store, Preferences coreStore) {
-               this(store, coreStore, true);
-       }
+  public JavaTextTools(IPreferenceStore store, Preferences coreStore) {
+    this(store, coreStore, true);
+  }
+
   /**
    * Creates a new Java text tools collection.
    * 
-   * @param store the preference store to initialize the text tools. The text tool
-   *                   instance installs a listener on the passed preference store to adapt itself to 
-   *                   changes in the preference store. In general <code>PreferenceConstants.
-   *                   getPreferenceStore()</code> shoould be used to initialize the text tools.
-   * @param coreStore optional preference store to initialize the text tools. The text tool
-   *                   instance installs a listener on the passed preference store to adapt itself to 
-   *                   changes in the preference store.
-   * @param autoDisposeOnDisplayDispose        if <code>true</code>  the color manager
-   *                   automatically disposes all managed colors when the current display gets disposed
-   *                   and all calls to {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()} are ignored.
+   * @param store
+   *          the preference store to initialize the text tools. The text tool instance installs a listener on the passed preference
+   *          store to adapt itself to changes in the preference store. In general <code>PreferenceConstants.
+   *                   getPreferenceStore()</code>
+   *          shoould be used to initialize the text tools.
+   * @param coreStore
+   *          optional preference store to initialize the text tools. The text tool instance installs a listener on the passed
+   *          preference store to adapt itself to changes in the preference store.
+   * @param autoDisposeOnDisplayDispose
+   *          if <code>true</code> the color manager automatically disposes all managed colors when the current display gets
+   *          disposed and all calls to {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()}are ignored.
    * @see org.eclipse.jdt.ui.PreferenceConstants#getPreferenceStore()
    * @since 2.1
    */
   public JavaTextTools(IPreferenceStore store, Preferences coreStore, boolean autoDisposeOnDisplayDispose) {
+    //    super(store, TOKENS, );
+//  REVISIT: preference store
+       xmlTextTools = new XMLTextTools(
+               XMLPlugin.getDefault().getPreferenceStore());
+       
+    colorManager = new JavaColorManager(autoDisposeOnDisplayDispose);
     fPreferenceStore = store;
     fPreferenceStore.addPropertyChangeListener(fPreferenceListener);
 
@@ -173,21 +199,36 @@ public class JavaTextTools {
     if (fCorePreferenceStore != null)
       fCorePreferenceStore.addPropertyChangeListener(fPreferenceListener);
 
-    fColorManager = new JavaColorManager(autoDisposeOnDisplayDispose);
-    
-    fCodeScanner = new PHPCodeScanner(fColorManager, store);
-    fMultilineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_MULTILINE_COMMENT);
-    fSinglelineCommentScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_SINGLELINE_COMMENT);
-    fStringScanner = new SingleTokenPHPScanner(fColorManager, store, IPreferenceConstants.PHP_STRING);
-    fPHPDocScanner = new PHPDocCodeScanner(fColorManager, store);
-    fHTMLScanner = new HTMLCodeScanner(fColorManager, store);
-    fSmartyScanner = new SmartyCodeScanner(fColorManager, store);
-    fSmartyDocScanner = new SmartyDocCodeScanner(fColorManager, store);
-  //  fPartitionScanner = new FastJavaPartitionScanner();
-    fPartitionScanner = new PHPPartitionScanner();
+    fCodeScanner = new PHPCodeScanner((JavaColorManager) colorManager, store);
+    fMultilineCommentScanner = new SingleTokenPHPScanner((JavaColorManager) colorManager, store,
+        IPreferenceConstants.PHP_MULTILINE_COMMENT);
+    fSinglelineCommentScanner = new SingleTokenPHPScanner((JavaColorManager) colorManager, store,
+        IPreferenceConstants.PHP_SINGLELINE_COMMENT);
+    fStringScanner = new SingleTokenPHPScanner((JavaColorManager) colorManager, store, IPreferenceConstants.PHP_STRING);
+    fPHPDocScanner = new PHPDocCodeScanner((JavaColorManager) colorManager, store);
+    //    fHTMLScanner = new HTMLCodeScanner((JavaColorManager)fColorManager, store);
+    fSmartyScanner = new SmartyCodeScanner((JavaColorManager) colorManager, store);
+    fSmartyDocScanner = new SmartyDocCodeScanner((JavaColorManager) colorManager, store);
+
+    fPartitionScanner= new FastJavaPartitionScanner();
+
+//    jspScriptScanner = new JSPScriptScanner();
+    //  fPartitionScanner = new FastJavaPartitionScanner();
+    //    fPartitionScanner = new PHPPartitionScanner();
+
+//    jspBracketScanner = new RuleBasedScanner();
+//    jspBracketScanner.setDefaultReturnToken(new Token(JSPScriptScanner.JSP_BRACKET));
+//    jspTextScanner = new RuleBasedScanner();
+//    jspTextScanner.setDefaultReturnToken(new Token(JSPScriptScanner.JSP_DEFAULT));
   }
 
   /**
+        * 
+        */
+       public XMLTextTools getXMLTextTools() {
+               return xmlTextTools;
+       }
+  /**
    * Disposes all the individual tools of this tools collection.
    */
   public void dispose() {
@@ -197,11 +238,11 @@ public class JavaTextTools {
     fSinglelineCommentScanner = null;
     fStringScanner = null;
     fPHPDocScanner = null;
-    fPartitionScanner = null;
+    //    fPartitionScanner = null;
 
-    if (fColorManager != null) {
-      fColorManager.dispose();
-      fColorManager = null;
+    if (colorManager != null) {
+      colorManager.dispose();
+      colorManager = null;
     }
 
     if (fPreferenceStore != null) {
@@ -218,18 +259,17 @@ public class JavaTextTools {
   }
 
   /**
-   * Returns the color manager which is used to manage
-   * any Java-specific colors needed for such things like syntax highlighting.
-   *
+   * Returns the color manager which is used to manage any Java-specific colors needed for such things like syntax highlighting.
+   * 
    * @return the color manager to be used for Java text viewers
    */
-  public IColorManager getColorManager() {
-    return fColorManager;
+  public JavaColorManager getColorManager() {
+    return (JavaColorManager) colorManager;
   }
 
   /**
    * Returns a scanner which is configured to scan Java source code.
-   *
+   * 
    * @return a Java source code scanner
    */
   public RuleBasedScanner getCodeScanner() {
@@ -238,7 +278,7 @@ public class JavaTextTools {
 
   /**
    * Returns a scanner which is configured to scan Java multiline comments.
-   *
+   * 
    * @return a Java multiline comment scanner
    * 
    * @since 2.0
@@ -249,18 +289,17 @@ public class JavaTextTools {
 
   /**
    * Returns a scanner which is configured to scan HTML code.
-   *
+   * 
    * @return a HTML scanner
    * 
    * @since 2.0
    */
-  public RuleBasedScanner getHTMLScanner() {
-    return fHTMLScanner;
-  }
-
+  //  public RuleBasedScanner getHTMLScanner() {
+  //    return fHTMLScanner;
+  //  }
   /**
    * Returns a scanner which is configured to scan Smarty code.
-   *
+   * 
    * @return a Smarty scanner
    * 
    * @since 2.0
@@ -270,18 +309,19 @@ public class JavaTextTools {
   }
 
   /**
-        * Returns a scanner which is configured to scan Smarty code.
-        *
-        * @return a Smarty scanner
-        * 
-        * @since 2.0
-        */
+   * Returns a scanner which is configured to scan Smarty code.
+   * 
+   * @return a Smarty scanner
+   * 
+   * @since 2.0
+   */
   public RuleBasedScanner getSmartyDocScanner() {
     return fSmartyDocScanner;
   }
+
   /**
    * Returns a scanner which is configured to scan Java singleline comments.
-   *
+   * 
    * @return a Java singleline comment scanner
    * 
    * @since 2.0
@@ -292,7 +332,7 @@ public class JavaTextTools {
 
   /**
    * Returns a scanner which is configured to scan Java strings.
-   *
+   * 
    * @return a Java string scanner
    * 
    * @since 2.0
@@ -302,10 +342,9 @@ public class JavaTextTools {
   }
 
   /**
-   * Returns a scanner which is configured to scan JavaDoc compliant comments.
-   * Notes that the start sequence "/**" and the corresponding end sequence
-   * are part of the JavaDoc comment.
-   *
+   * Returns a scanner which is configured to scan JavaDoc compliant comments. Notes that the start sequence "/**" and the
+   * corresponding end sequence are part of the JavaDoc comment.
+   * 
    * @return a JavaDoc scanner
    */
   public RuleBasedScanner getJavaDocScanner() {
@@ -313,21 +352,18 @@ public class JavaTextTools {
   }
 
   /**
-   * Returns a scanner which is configured to scan 
-   * Java-specific partitions, which are multi-line comments,
-   * JavaDoc comments, and regular Java source code.
-   *
+   * Returns a scanner which is configured to scan Java-specific partitions, which are multi-line comments, JavaDoc comments, and
+   * regular Java source code.
+   * 
    * @return a Java partition scanner
    */
-  public IPartitionTokenScanner getPartitionScanner() {
-    return fPartitionScanner;
-  }
-
+  //  public IPartitionTokenScanner getPartitionScanner() {
+  //    return fPartitionScanner;
+  //  }
   /**
-   * Factory method for creating a PHP-specific document partitioner
-   * using this object's partitions scanner. This method is a 
+   * Factory method for creating a PHP-specific document partitioner using this object's partitions scanner. This method is a
    * convenience method.
-   *
+   * 
    * @return a newly created Java document partitioner
    */
   public IDocumentPartitioner createDocumentPartitioner() {
@@ -335,10 +371,9 @@ public class JavaTextTools {
   }
 
   /**
-   * Factory method for creating a PHP-specific document partitioner
-   * using this object's partitions scanner. This method is a 
+   * Factory method for creating a PHP-specific document partitioner using this object's partitions scanner. This method is a
    * convenience method.
-   *
+   * 
    * @return a newly created Java document partitioner
    */
   public IDocumentPartitioner createDocumentPartitioner(String extension) {
@@ -356,114 +391,110 @@ public class JavaTextTools {
     if (extension.equalsIgnoreCase(".html") || extension.equalsIgnoreCase(".htm")) {
       // html
       partitioner = createHTMLPartitioner();
+      partitioner = createJSPPartitioner();
     } else if (extension.equalsIgnoreCase(".xml")) {
       // xml
       partitioner = createXMLPartitioner();
-    } else if (extension.equalsIgnoreCase(".js")) {
-      // javascript
-      partitioner = createJavaScriptPartitioner();
-    } else if (extension.equalsIgnoreCase(".css")) {
-      // cascading style sheets
-      partitioner = createCSSPartitioner();
+//    } else if (extension.equalsIgnoreCase(".js")) {
+//      // javascript
+//      partitioner = createJavaScriptPartitioner();
+//    } else if (extension.equalsIgnoreCase(".css")) {
+//      // cascading style sheets
+//      partitioner = createCSSPartitioner();
     } else if (extension.equalsIgnoreCase(".tpl")) {
       // smarty ?
       partitioner = createSmartyPartitioner();
-    } else if (extension.equalsIgnoreCase(".inc")) {
-      // php include files ?
-      partitioner = createIncludePartitioner();
+//    } else if (extension.equalsIgnoreCase(".inc")) {
+//      // php include files ?
+//      partitioner = createIncludePartitioner();
     }
-
+  
     if (partitioner == null) {
-      partitioner = createPHPPartitioner();
+      partitioner = createJSPPartitioner();
     }
 
     return partitioner;
   }
-       /**
-        * Sets up the Java document partitioner for the given document for the default partitioning.
-        * 
-        * @param document the document to be set up
-        * @since 3.0
-        */
-       public void setupJavaDocumentPartitioner(IDocument document) {
-               setupJavaDocumentPartitioner(document, IDocumentExtension3.DEFAULT_PARTITIONING,null);
-       }
-       /**
-        * Sets up the Java document partitioner for the given document for the given partitioning.
-        * @param document the document to be set up
-        * @param partitioning the document partitioning
-        * @param element TODO
-        * 
-        * @since 3.0
-        */
-       public void setupJavaDocumentPartitioner(IDocument document, String partitioning, Object element) {
-               IDocumentPartitioner partitioner = createDocumentPartitioner(".php");
-                        
-//             if (document instanceof IDocumentExtension3) {
-//                     IDocumentExtension3 extension3= (IDocumentExtension3) document;
-//                     extension3.setDocumentPartitioner(partitioning, partitioner);
-//             } else {
-                       document.setDocumentPartitioner(partitioner);
-//             }
-               partitioner.connect(document);
-       }
-       public void setupHTMLDocumentPartitioner(IDocument document, String partitioning, Object element) {
-               IDocumentPartitioner partitioner = createDocumentPartitioner(".html");
-                        
-//             if (document instanceof IDocumentExtension3) {
-//                     IDocumentExtension3 extension3= (IDocumentExtension3) document;
-//                     extension3.setDocumentPartitioner(partitioning, partitioner);
-//             } else {
-                       document.setDocumentPartitioner(partitioner);
-//             }
-               partitioner.connect(document);
-       }
-       public void setupSmartyDocumentPartitioner(IDocument document, String partitioning, Object element) {
-               IDocumentPartitioner partitioner = createDocumentPartitioner(".tpl");
-                        
-//             if (document instanceof IDocumentExtension3) {
-//                     IDocumentExtension3 extension3= (IDocumentExtension3) document;
-//                     extension3.setDocumentPartitioner(partitioning, partitioner);
-//             } else {
-                       document.setDocumentPartitioner(partitioner);
-//             }
-               partitioner.connect(document);
-       }
+
+  
+  /**
+   * Sets up the Java document partitioner for the given document for the given partitioning.
+   * 
+   * @param document
+   *          the document to be set up
+   * @param partitioning
+   *          the document partitioning
+   * @param element
+   *          TODO
+   * 
+   * @since 3.0
+   */
+//  public void setupJavaDocumentPartitioner(IDocument document, String partitioning, Object element) {
+//    IDocumentPartitioner partitioner = createDocumentPartitioner(".php");
+//
+//    //               if (document instanceof IDocumentExtension3) {
+//    //                       IDocumentExtension3 extension3= (IDocumentExtension3) document;
+//    //                       extension3.setDocumentPartitioner(partitioning, partitioner);
+//    //               } else {
+//    document.setDocumentPartitioner(partitioner);
+//    //               }
+//    partitioner.connect(document);
+//  }
+
+  public void setupHTMLDocumentPartitioner(IDocument document, String partitioning, Object element) {
+    IDocumentPartitioner partitioner = createDocumentPartitioner(".html");
+
+    //         if (document instanceof IDocumentExtension3) {
+    //                 IDocumentExtension3 extension3= (IDocumentExtension3) document;
+    //                 extension3.setDocumentPartitioner(partitioning, partitioner);
+    //         } else {
+    document.setDocumentPartitioner(partitioner);
+    //         }
+    partitioner.connect(document);
+  }
+
+  public void setupSmartyDocumentPartitioner(IDocument document, String partitioning, Object element) {
+    IDocumentPartitioner partitioner = createDocumentPartitioner(".tpl");
+
+    //         if (document instanceof IDocumentExtension3) {
+    //                 IDocumentExtension3 extension3= (IDocumentExtension3) document;
+    //                 extension3.setDocumentPartitioner(partitioning, partitioner);
+    //         } else {
+    document.setDocumentPartitioner(partitioner);
+    //         }
+    partitioner.connect(document);
+  }
+
   /**
-   * Returns the names of the document position categories used by the document
-   * partitioners created by this object to manage their partition information.
-   * If the partitioners don't use document position categories, the returned
-   * result is <code>null</code>.
-   *
-   * @return the partition managing position categories or <code>null</code> 
-   *                   if there is none
+   * Returns the names of the document position categories used by the document partitioners created by this object to manage their
+   * partition information. If the partitioners don't use document position categories, the returned result is <code>null</code>.
+   * 
+   * @return the partition managing position categories or <code>null</code> if there is none
    */
   public String[] getPartitionManagingPositionCategories() {
     return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY };
   }
 
   /**
-   * Determines whether the preference change encoded by the given event
-   * changes the behavior of one its contained components.
+   * Determines whether the preference change encoded by the given event changes the behavior of one its contained components.
    * 
-   * @param event the event to be investigated
+   * @param event
+   *          the event to be investigated
    * @return <code>true</code> if event causes a behavioral change
    * 
    * @since 2.0
    */
   public boolean affectsBehavior(PropertyChangeEvent event) {
-    return fCodeScanner.affectsBehavior(event)
-      || fMultilineCommentScanner.affectsBehavior(event)
-      || fSinglelineCommentScanner.affectsBehavior(event)
-      || fStringScanner.affectsBehavior(event)
-      || fPHPDocScanner.affectsBehavior(event);
+    return fCodeScanner.affectsBehavior(event) || fMultilineCommentScanner.affectsBehavior(event)
+        || fSinglelineCommentScanner.affectsBehavior(event) || fStringScanner.affectsBehavior(event)
+        || fPHPDocScanner.affectsBehavior(event);
   }
 
   /**
-   * Adapts the behavior of the contained components to the change
-   * encoded in the given event.
+   * Adapts the behavior of the contained components to the change encoded in the given event.
    * 
-   * @param event the event to which to adapt
+   * @param event
+   *          the event to which to adapt
    * @since 2.0
    */
   protected void adaptToPreferenceChange(PropertyChangeEvent event) {
@@ -477,80 +508,179 @@ public class JavaTextTools {
       fStringScanner.adaptToPreferenceChange(event);
     if (fPHPDocScanner.affectsBehavior(event))
       fPHPDocScanner.adaptToPreferenceChange(event);
-    if (fHTMLScanner.affectsBehavior(event))
-      fHTMLScanner.adaptToPreferenceChange(event);
+    //    if (fHTMLScanner.affectsBehavior(event))
+    //      fHTMLScanner.adaptToPreferenceChange(event);
     if (fSmartyScanner.affectsBehavior(event))
       fSmartyScanner.adaptToPreferenceChange(event);
     if (fSmartyDocScanner.affectsBehavior(event))
       fSmartyDocScanner.adaptToPreferenceChange(event);
+    XMLPlugin.getDefault().getXMLTextTools().affectsBehavior(event);
   }
 
   /**
-        * Return a partitioner for .html files.
-        */
-  private static IDocumentPartitioner createHTMLPartitioner() {
-    return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
+   * Return a partitioner for .html files.
+   */
+  public IDocumentPartitioner createHTMLPartitioner() {
+//    return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
+    return xmlTextTools.createXMLPartitioner();
   }
 
-  private static IDocumentPartitioner createIncludePartitioner() {
-    return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
-  }
+//  private static IDocumentPartitioner createIncludePartitioner() {
+//    //    return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+//    return new DefaultPartitioner(getPHPPartitionScanner(), FastJavaPartitionScanner.PHP_PARTITION_TYPES);
+//
+//  }
 
-  private static IDocumentPartitioner createJavaScriptPartitioner() {
-    return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
-  }
+//  private static IDocumentPartitioner createJavaScriptPartitioner() {
+//    return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
+//  }
 
   /**
-       * Return a partitioner for .php files.
-       */
-  private static IDocumentPartitioner createPHPPartitioner() {
-    return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+   * Return a partitioner for .php files.  
+   */
+  public IDocumentPartitioner createPHPPartitioner() {
+    //    return new DefaultPartitioner(getPHPPartitionScanner(), TYPES);
+    return new DefaultPartitioner(getPHPPartitionScanner(), LEGAL_CONTENT_TYPES);
+  } 
+
+  private IDocumentPartitioner createJSPPartitioner() {
+        return new PHPDocumentPartitioner(
+            getJSPPartitionScanner(), getPHPPartitionScanner());
+//    return new JSPDocumentPartitioner(getJSPPartitionScanner(), jspScriptScanner);
   }
+  /**
+   *  
+   */
+//  public IPartitionTokenScanner getJSPScriptScanner() {
+//    return jspScriptScanner;
+//  }
 
-  private static IDocumentPartitioner createSmartyPartitioner() {
-    return new DefaultPartitioner(getSmartyPartitionScanner(), TYPES);
+  private IDocumentPartitioner createSmartyPartitioner() {
+    return new DefaultPartitioner(getSmartyPartitionScanner(), XMLTextTools.TYPES);
   }
 
-  private static IDocumentPartitioner createXMLPartitioner() {
-    return new DefaultPartitioner(getXMLPartitionScanner(), TYPES);
+  private IDocumentPartitioner createXMLPartitioner() {
+//    return new DefaultPartitioner(getXMLPartitionScanner(), XMLTextTools.TYPES);
+    return xmlTextTools.createXMLPartitioner();
   }
 
-  private static IDocumentPartitioner createCSSPartitioner() {
-    return new DefaultPartitioner(getHTMLPartitionScanner(), TYPES);
-  }
+//  private IDocumentPartitioner createCSSPartitioner() {
+//    return new DefaultPartitioner(getHTMLPartitionScanner(), XMLTextTools.TYPES);
+//  }
+
   /**
-       * Return a scanner for creating html partitions.
-       */
-  private static PHPPartitionScanner getHTMLPartitionScanner() {
-    if (HTML_PARTITION_SCANNER == null)
-      HTML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.HTML_FILE);
-    return HTML_PARTITION_SCANNER;
-  }
+   * Return a scanner for creating html partitions.
+   */
+//  private static XMLPartitionScanner getHTMLPartitionScanner() {
+//    //    if (HTML_PARTITION_SCANNER == null)
+//    //      HTML_PARTITION_SCANNER = new HTMLPartitionScanner(IPHPPartitions.HTML_FILE);
+//    //    return HTML_PARTITION_SCANNER;^
+//    if (HTML_PARTITION_SCANNER == null)
+//      HTML_PARTITION_SCANNER = new XMLPartitionScanner(false);
+//    return HTML_PARTITION_SCANNER;
+//  }
+
   /**
-       * Return a scanner for creating php partitions.
-       */
-  private static PHPPartitionScanner getPHPPartitionScanner() {
-    if (PHP_PARTITION_SCANNER == null)
-      PHP_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.PHP_FILE);
-    return PHP_PARTITION_SCANNER;
+   * Return a scanner for creating php partitions.
+   */ 
+  private FastJavaPartitionScanner getPHPPartitionScanner() {
+//    if (PHP_PARTITION_SCANNER == null)
+//      PHP_PARTITION_SCANNER = new FastJavaPartitionScanner(); //new PHPPartitionScanner(IPHPPartitions.PHP_FILE);
+//    return PHP_PARTITION_SCANNER;
+    return fPartitionScanner;
   }
 
   /**
-       * Return a scanner for creating smarty partitions.
-       */
-  private static PHPPartitionScanner getSmartyPartitionScanner() {
+   * Returns a scanner which is configured to scan plain text in JSP.
+   * 
+   * @return a JSP text scanner
+   */
+//  public RuleBasedScanner getJSPTextScanner() {
+//    return jspTextScanner;
+//  }
+
+  /**
+   * Returns a scanner which is configured to scan plain text in JSP.
+   * 
+   * @return a JSP text scanner
+   */
+//  public RuleBasedScanner getJSPBracketScanner() {
+//    return jspBracketScanner;
+//  }
+
+  /**
+   * Return a scanner for creating smarty partitions.
+   */
+  private static HTMLPartitionScanner getSmartyPartitionScanner() {
     if (SMARTY_PARTITION_SCANNER == null)
-      SMARTY_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.SMARTY_FILE);
+      SMARTY_PARTITION_SCANNER = new HTMLPartitionScanner(IPHPPartitions.SMARTY_FILE);
     return SMARTY_PARTITION_SCANNER;
   }
 
   /**
-       * Return a scanner for creating xml partitions.
-       */
-  private static PHPPartitionScanner getXMLPartitionScanner() {
+   * Return a scanner for creating xml partitions.
+   */
+  private static XMLPartitionScanner getXMLPartitionScanner() {
+    //    if (XML_PARTITION_SCANNER == null)
+    //      XML_PARTITION_SCANNER = new HTMLPartitionScanner(IPHPPartitions.XML_FILE);
+    //    return XML_PARTITION_SCANNER;
     if (XML_PARTITION_SCANNER == null)
-      XML_PARTITION_SCANNER = new PHPPartitionScanner(IPHPPartitions.XML_FILE);
+      XML_PARTITION_SCANNER = new XMLPartitionScanner(false);
     return XML_PARTITION_SCANNER;
   }
+  
+  private PHPPartitionScanner getJSPPartitionScanner() {
+    if (jspPartitionScanner == null)
+      jspPartitionScanner = new PHPPartitionScanner();
+    return jspPartitionScanner;
+  }
+
+  /**
+        * Sets up the Java document partitioner for the given document for the default partitioning.
+        * 
+        * @param document the document to be set up
+        * @since 3.0
+        */
+       public void setupJavaDocumentPartitioner(IDocument document) {
+               setupJavaDocumentPartitioner(document, IDocumentExtension3.DEFAULT_PARTITIONING);
+       }
+
+       /**
+        * Sets up the Java document partitioner for the given document for the given partitioning.
+        * 
+        * @param document the document to be set up
+        * @param partitioning the document partitioning
+        * @since 3.0
+        */
+       public void setupJavaDocumentPartitioner(IDocument document, String partitioning) {
+               IDocumentPartitioner partitioner= createDocumentPartitioner();
+               if (document instanceof IDocumentExtension3) {
+                       IDocumentExtension3 extension3= (IDocumentExtension3) document;
+                       extension3.setDocumentPartitioner(partitioning, partitioner);
+               } else {
+                       document.setDocumentPartitioner(partitioner);
+               }
+               partitioner.connect(document);
+       }
+
+       /**
+        * Returns this text tool's preference store.
+        * 
+        * @return the preference store
+        * @since 3.0
+        */
+       protected IPreferenceStore getPreferenceStore() {
+               return fPreferenceStore;
+       }
 
+       /**
+        * Returns this text tool's core preference store.
+        * 
+        * @return the core preference store
+        * @since 3.0
+        */
+       protected Preferences getCorePreferenceStore() {
+               return fCorePreferenceStore;
+       }
 }
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/PHPSourceViewerConfiguration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/text/PHPSourceViewerConfiguration.java
new file mode 100644 (file)
index 0000000..0dcaeed
--- /dev/null
@@ -0,0 +1,930 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ Klaus Hartlage - www.eclipseproject.de
+ **********************************************************************/
+package net.sourceforge.phpdt.ui.text;
+
+import java.util.Vector;
+
+import net.sourceforge.phpdt.core.JavaCore;
+import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference;
+import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.JavaAnnotationHover;
+import net.sourceforge.phpdt.internal.ui.text.JavaCompositeReconcilingStrategy;
+import net.sourceforge.phpdt.internal.ui.text.JavaElementProvider;
+import net.sourceforge.phpdt.internal.ui.text.JavaOutlineInformationControl;
+import net.sourceforge.phpdt.internal.ui.text.JavaPresentationReconciler;
+import net.sourceforge.phpdt.internal.ui.text.JavaReconciler;
+import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter;
+import net.sourceforge.phpdt.internal.ui.text.java.JavaFormattingStrategy;
+import net.sourceforge.phpdt.internal.ui.text.java.JavaStringAutoIndentStrategy;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy;
+import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaInformationProvider;
+import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCompletionProcessor;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.PHPEditor;
+import net.sourceforge.phpeclipse.phpeditor.html.HTMLFormattingStrategy;
+import net.sourceforge.phpeclipse.phpeditor.php.HTMLCompletionProcessor;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPAutoIndentStrategy;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPCompletionProcessor;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPDocumentPartitioner;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPDoubleClickSelector;
+import net.sourceforge.phpeclipse.phpeditor.php.PHPPartitionScanner;
+import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider;
+import net.sourceforge.phpeclipse.xml.ui.XMLPlugin;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLConfiguration;
+import net.sourceforge.phpeclipse.xml.ui.internal.text.XMLPartitionScanner;
+import net.sourceforge.phpeclipse.xml.ui.text.XMLTextTools;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.DefaultAutoIndentStrategy;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IAutoIndentStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewerExtension2;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.formatter.ContentFormatter;
+import org.eclipse.jface.text.formatter.IContentFormatter;
+import org.eclipse.jface.text.formatter.IFormattingStrategy;
+import org.eclipse.jface.text.information.IInformationPresenter;
+import org.eclipse.jface.text.information.IInformationProvider;
+import org.eclipse.jface.text.information.InformationPresenter;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.reconciler.IReconciler;
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.DefaultPartitioner;
+import org.eclipse.jface.text.rules.RuleBasedScanner;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.texteditor.ChainedPreferenceStore;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Configuration for an <code>SourceViewer</code> which shows PHP code.
+ */
+public class PHPSourceViewerConfiguration extends SourceViewerConfiguration {
+  /**
+   * Preference key used to look up display tab width.
+   * 
+   * @since 2.0
+   */
+  public final static String PREFERENCE_TAB_WIDTH = PreferenceConstants.EDITOR_TAB_WIDTH;
+
+  /**
+   * Preference key for inserting spaces rather than tabs.
+   * 
+   * @since 2.0
+   */
+  public final static String SPACES_FOR_TABS = PreferenceConstants.EDITOR_SPACES_FOR_TABS;
+
+  //  public static final String HTML_DEFAULT =
+  // IPHPPartitionScannerConstants.HTML;
+  //IDocument.DEFAULT_CONTENT_TYPE;
+  private JavaTextTools fJavaTextTools;
+
+  private ITextEditor fTextEditor;
+  /**
+        * The document partitioning.
+        * @since 3.0
+        */
+  private String fDocumentPartitioning;
+       
+  private ContentFormatter fFormatter;
+
+  private HTMLFormattingStrategy fFormattingStrategy;
+
+  /**
+   * Single token scanner.
+   */
+  static class SingleTokenScanner extends BufferedRuleBasedScanner {
+    public SingleTokenScanner(TextAttribute attribute) {
+      setDefaultReturnToken(new Token(attribute));
+    }
+  };
+
+  /**
+   * The document partitioning.
+   * 
+   * @since 3.0
+   */
+//  private String fDocumentPartitioning;
+
+//  /**
+//   * The Java source code scanner
+//   * 
+//   * @since 3.0
+//   */
+//  private AbstractJavaScanner fCodeScanner;
+//
+//  /**
+//   * The Java multi-line comment scanner
+//   * 
+//   * @since 3.0
+//   */
+//  private AbstractJavaScanner fMultilineCommentScanner;
+//
+//  /**
+//   * The Java single-line comment scanner
+//   * 
+//   * @since 3.0
+//   */
+//  private AbstractJavaScanner fSinglelineCommentScanner;
+//
+//  /**
+//   * The Java string scanner
+//   * 
+//   * @since 3.0
+//   */
+//  private AbstractJavaScanner fStringScanner;
+//
+//  /**
+//   * The Javadoc scanner
+//   * 
+//   * @since 3.0
+//   */
+//  private AbstractJavaScanner fJavaDocScanner;
+
+  /**
+   * The preference store, can be read-only
+   * 
+   * @since 3.0
+   */
+  private IPreferenceStore fPreferenceStore;
+
+  /**
+   * The color manager
+   * 
+   * @since 3.0
+   */
+  private IColorManager fColorManager;
+
+  private XMLTextTools fXMLTextTools;
+  private XMLConfiguration xmlConfiguration;
+  /**
+   * Creates a new Java source viewer configuration for viewers in the given editor using the given preference store, the color
+   * manager and the specified document partitioning.
+   * <p>
+   * Creates a Java source viewer configuration in the new setup without text tools. Clients are allowed to call
+   * {@link JavaSourceViewerConfiguration#handlePropertyChangeEvent(PropertyChangeEvent)}and disallowed to call
+   * {@link JavaSourceViewerConfiguration#getPreferenceStore()}on the resulting Java source viewer configuration.
+   * </p>
+   * 
+   * @param colorManager
+   *          the color manager
+   * @param preferenceStore
+   *          the preference store, can be read-only
+   * @param editor
+   *          the editor in which the configured viewer(s) will reside
+   * @param partitioning
+   *          the document partitioning for this configuration
+   * @since 3.0
+   */
+  public PHPSourceViewerConfiguration(IColorManager colorManager, IPreferenceStore preferenceStore, ITextEditor editor,
+      String partitioning) {
+    fColorManager = colorManager;
+    fPreferenceStore = preferenceStore;
+    fTextEditor = editor;
+    fDocumentPartitioning = partitioning;
+    fJavaTextTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
+    fXMLTextTools = XMLPlugin.getDefault().getXMLTextTools();
+    xmlConfiguration = new XMLConfiguration(fXMLTextTools);
+
+    //         initializeScanners(); 
+  }
+
+  /**
+   * Default constructor.
+   */
+  public PHPSourceViewerConfiguration(JavaTextTools tools, PHPEditor editor, String partitioning) {   
+       fJavaTextTools= tools;
+       fColorManager= tools.getColorManager();
+       fPreferenceStore= createPreferenceStore();
+       fDocumentPartitioning = partitioning;
+//     fCodeScanner= (AbstractJavaScanner) fJavaTextTools.getCodeScanner();
+//     fMultilineCommentScanner= (AbstractJavaScanner) fJavaTextTools.getMultilineCommentScanner();
+//     fSinglelineCommentScanner= (AbstractJavaScanner) fJavaTextTools.getSinglelineCommentScanner();
+//     fStringScanner= (AbstractJavaScanner) fJavaTextTools.getStringScanner();
+//     fJavaDocScanner= (AbstractJavaScanner) fJavaTextTools.getJavaDocScanner();
+       fTextEditor= editor;
+    fXMLTextTools = XMLPlugin.getDefault().getXMLTextTools();
+    xmlConfiguration = new XMLConfiguration(fXMLTextTools);
+  }
+
+  /*
+   * @see SourceViewerConfiguration#getContentFormatter(ISourceViewer)
+   */
+  public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
+    //    if (fFormatter == null) {
+    //      fFormatter = new ContentFormatter();
+    //      fFormattingStrategy = new HTMLFormattingStrategy(this,
+    // sourceViewer);
+    //      fFormatter.setFormattingStrategy(fFormattingStrategy, HTML_DEFAULT);
+    //      fFormatter.enablePartitionAwareFormatting(false);
+    //      fFormatter.setPartitionManagingPositionCategories(getConfiguredContentTypes(null));
+    //    }
+    //    return fFormatter;
+    if (fFormatter == null) {
+      //ContentFormatter
+      fFormatter = new ContentFormatter();
+      IFormattingStrategy strategy = new JavaFormattingStrategy(sourceViewer);
+      fFormatter.setFormattingStrategy(strategy, IDocument.DEFAULT_CONTENT_TYPE);
+      fFormatter.enablePartitionAwareFormatting(false);
+      fFormatter.setPartitionManagingPositionCategories(getPartitionManagingPositionCategories());
+    }
+    return fFormatter;
+  }
+
+  /**
+   * Returns the names of the document position categories used by the document partitioners created by this object to manage their
+   * partition information. If the partitioners don't use document position categories, the returned result is <code>null</code>.
+   * 
+   * @return the partition managing position categories or <code>null</code> if there is none
+   */
+  public String[] getPartitionManagingPositionCategories() {
+    return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY };
+  }
+
+  //  /**
+  //   * Returns the names of the document position categories used by the
+  // document
+  //   * partitioners created by this object to manage their partition
+  // information.
+  //   * If the partitioners don't use document position categories, the
+  // returned
+  //   * result is <code>null</code>.
+  //   *
+  //   * @return the partition managing position categories or
+  // <code>null</code>
+  //   * if there is none
+  //   */
+  //  private String[] getPartitionManagingPositionCategories() {
+  //    return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY };
+  //  }
+  public ITextEditor getEditor() {
+    return fTextEditor;
+  }
+
+  /**
+   * Returns the preference store used by this configuration to initialize the individual bits and pieces.
+   * 
+   * @return the preference store used to initialize this configuration
+   * 
+   * @since 2.0
+   */
+  protected IPreferenceStore getPreferenceStore() {
+    return PHPeclipsePlugin.getDefault().getPreferenceStore();
+  }
+
+  //  /* (non-Javadoc)
+  //   * Method declared on SourceViewerConfiguration
+  //   */
+  //  public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+  //    return new PHPAnnotationHover();
+  //  }
+  /*
+   * @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer)
+   */
+  public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+    return new JavaAnnotationHover(JavaAnnotationHover.VERTICAL_RULER_HOVER);
+  }
+
+  /*
+   * @see SourceViewerConfiguration#getOverviewRulerAnnotationHover(ISourceViewer)
+   * @since 3.0
+   */
+  public IAnnotationHover getOverviewRulerAnnotationHover(ISourceViewer sourceViewer) {
+    return new JavaAnnotationHover(JavaAnnotationHover.OVERVIEW_RULER_HOVER);
+  }
+
+  /*
+   * (non-Javadoc) Method declared on SourceViewerConfiguration
+   */
+  public IAutoIndentStrategy getAutoIndentStrategy(ISourceViewer sourceViewer, String contentType) {
+    if (IPHPPartitions.PHP_STRING_DQ.equals(contentType))
+      return new JavaStringAutoIndentStrategy(getConfiguredDocumentPartitioning(sourceViewer));
+
+    return (IPHPPartitions.PHP_PARTITIONING.equals(contentType) ? new PHPAutoIndentStrategy() : new DefaultAutoIndentStrategy());
+  }
+
+  /**
+   * Returns the PHP source code scanner for this configuration.
+   * 
+   * @return the PHP source code scanner
+   */
+  protected RuleBasedScanner getCodeScanner() {
+    return fJavaTextTools.getCodeScanner();
+  }
+
+  /**
+   * Returns the HTML source code scanner for this configuration.
+   * 
+   * @return the HTML source code scanner
+   */
+//  protected RuleBasedScanner getHTMLScanner() {
+//    return fJavaTextTools.getHTMLScanner();
+//  }
+
+  /**
+   * Returns the Smarty source code scanner for this configuration.
+   * 
+   * @return the Smarty source code scanner
+   */
+  protected RuleBasedScanner getSmartyScanner() {
+    return fJavaTextTools.getSmartyScanner();
+  }
+
+  /*
+   * @see SourceViewerConfiguration#getReconciler(ISourceViewer)
+   */
+  /*
+   * @see SourceViewerConfiguration#getReconciler(ISourceViewer)
+   */
+  public IReconciler getReconciler(ISourceViewer sourceViewer) {
+
+    final ITextEditor editor = getEditor();
+    if (editor != null && editor.isEditable()) {
+
+      JavaCompositeReconcilingStrategy strategy = new JavaCompositeReconcilingStrategy(editor,
+          getConfiguredDocumentPartitioning(sourceViewer));
+      JavaReconciler reconciler = new JavaReconciler(editor, strategy, false);
+      reconciler.setIsIncrementalReconciler(false);
+      reconciler.setProgressMonitor(new NullProgressMonitor());
+      reconciler.setDelay(500);
+
+      return reconciler;
+    }
+    return null;
+  }
+
+  //   public IReconciler getReconciler(ISourceViewer sourceViewer) {
+  //           if (getEditor() != null && getEditor().isEditable()) {
+  //                   JavaReconciler reconciler = new JavaReconciler(getEditor(),
+  //                                   new JavaReconcilingStrategy(getEditor()), false);
+  //                   reconciler.setProgressMonitor(new NullProgressMonitor());
+  //                   reconciler.setDelay(500);
+  //                   return reconciler;
+  //           }
+  //           return null;
+  //   }
+  /*
+   * @see SourceViewerConfiguration#getConfiguredTextHoverStateMasks(ISourceViewer, String)
+   * @since 2.1
+   */
+  public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer, String contentType) {
+    JavaEditorTextHoverDescriptor[] hoverDescs = PHPeclipsePlugin.getDefault().getJavaEditorTextHoverDescriptors();
+    int stateMasks[] = new int[hoverDescs.length];
+    int stateMasksLength = 0;
+    for (int i = 0; i < hoverDescs.length; i++) {
+      if (hoverDescs[i].isEnabled()) {
+        int j = 0;
+        int stateMask = hoverDescs[i].getStateMask();
+        while (j < stateMasksLength) {
+          if (stateMasks[j] == stateMask)
+            break;
+          j++;
+        }
+        if (j == stateMasksLength)
+          stateMasks[stateMasksLength++] = stateMask;
+      }
+    }
+    if (stateMasksLength == hoverDescs.length)
+      return stateMasks;
+    int[] shortenedStateMasks = new int[stateMasksLength];
+    System.arraycopy(stateMasks, 0, shortenedStateMasks, 0, stateMasksLength);
+    return shortenedStateMasks;
+  }
+
+  /*
+   * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String, int)
+   * @since 2.1
+   */
+  public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType, int stateMask) {
+    JavaEditorTextHoverDescriptor[] hoverDescs = PHPeclipsePlugin.getDefault().getJavaEditorTextHoverDescriptors();
+    int i = 0;
+    while (i < hoverDescs.length) {
+      if (hoverDescs[i].isEnabled() && hoverDescs[i].getStateMask() == stateMask)
+        return new JavaEditorTextHoverProxy(hoverDescs[i], getEditor());
+      i++;
+    }
+    return null;
+    //         if (fEditor != null) {
+    //                 IEditorInput editorInput = fEditor.getEditorInput();
+    //                 if (editorInput instanceof IFileEditorInput) {
+    //                         try {
+    //                                 IFile f = ((IFileEditorInput) editorInput).getFile();
+    //                                 return new PHPTextHover(f.getProject());
+    //                         } catch (NullPointerException e) {
+    //                                 // this exception occurs, if getTextHover is called by
+    //                                 // preference pages !
+    //                         }
+    //                 }
+    //         }
+    //         return new PHPTextHover(null);
+  }
+
+  /*
+   * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String)
+   */
+  public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
+    return getTextHover(sourceViewer, contentType, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
+  }
+
+  /**
+   * Returns the SmartyDoc source code scanner for this configuration.
+   * 
+   * @return the SmartyDoc source code scanner
+   */
+  protected RuleBasedScanner getSmartyDocScanner() {
+    return fJavaTextTools.getSmartyDocScanner();
+  }
+
+  /**
+   * Returns the PHPDoc source code scanner for this configuration.
+   * 
+   * @return the PHPDoc source code scanner
+   */
+  protected RuleBasedScanner getPHPDocScanner() {
+    return fJavaTextTools.getJavaDocScanner();
+  }
+
+  /*
+   * (non-Javadoc) Method declared on SourceViewerConfiguration
+   */
+  public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+    return new String[] { 
+        IDocument.DEFAULT_CONTENT_TYPE, 
+        PHPPartitionScanner.PHP_SCRIPTING_AREA,
+        
+        IPHPPartitions.HTML, 
+        IPHPPartitions.HTML_MULTILINE_COMMENT,
+        IPHPPartitions.PHP_PARTITIONING, 
+        IPHPPartitions.PHP_SINGLELINE_COMMENT,
+        IPHPPartitions.PHP_MULTILINE_COMMENT,
+        IPHPPartitions.PHP_PHPDOC_COMMENT, 
+        IPHPPartitions.PHP_STRING_DQ,
+        IPHPPartitions.PHP_STRING_SQ,
+        IPHPPartitions.CSS,
+        IPHPPartitions.CSS_MULTILINE_COMMENT, 
+        IPHPPartitions.JAVASCRIPT, 
+        IPHPPartitions.JS_MULTILINE_COMMENT,
+        IPHPPartitions.SMARTY, 
+        IPHPPartitions.SMARTY_MULTILINE_COMMENT,
+        
+        XMLPartitionScanner.XML_PI,
+               XMLPartitionScanner.XML_COMMENT,
+               XMLPartitionScanner.XML_DECL,
+               XMLPartitionScanner.XML_TAG,
+               XMLPartitionScanner.XML_ATTRIBUTE,
+               XMLPartitionScanner.XML_CDATA,
+               
+               XMLPartitionScanner.DTD_INTERNAL,
+               XMLPartitionScanner.DTD_INTERNAL_PI,
+               XMLPartitionScanner.DTD_INTERNAL_COMMENT,
+               XMLPartitionScanner.DTD_INTERNAL_DECL,
+               
+               PHPDocumentPartitioner.PHP_TEMPLATE_DATA,
+               PHPDocumentPartitioner.PHP_SCRIPT_CODE
+               };
+  }
+
+  public String[] getConfiguredHTMLContentTypes() {
+    return new String[] {  
+        XMLPartitionScanner.XML_PI,
+               XMLPartitionScanner.XML_COMMENT,
+               XMLPartitionScanner.XML_DECL,
+               XMLPartitionScanner.XML_TAG,
+               XMLPartitionScanner.XML_ATTRIBUTE,
+               XMLPartitionScanner.XML_CDATA,
+               
+               XMLPartitionScanner.DTD_INTERNAL,
+               XMLPartitionScanner.DTD_INTERNAL_PI,
+               XMLPartitionScanner.DTD_INTERNAL_COMMENT,
+               XMLPartitionScanner.DTD_INTERNAL_DECL,
+        };
+  }
+  public String[] getConfiguredPHPContentTypes() {
+    return new String[] { 
+        IDocument.DEFAULT_CONTENT_TYPE, 
+        IPHPPartitions.PHP_PARTITIONING, 
+        IPHPPartitions.PHP_SINGLELINE_COMMENT,
+        IPHPPartitions.PHP_MULTILINE_COMMENT,
+        IPHPPartitions.PHP_PHPDOC_COMMENT, 
+        IPHPPartitions.PHP_STRING_DQ,
+        IPHPPartitions.PHP_STRING_SQ,
+        IPHPPartitions.CSS,
+        IPHPPartitions.CSS_MULTILINE_COMMENT, 
+        IPHPPartitions.JAVASCRIPT, 
+        IPHPPartitions.JS_MULTILINE_COMMENT,
+        IPHPPartitions.SMARTY, 
+        IPHPPartitions.SMARTY_MULTILINE_COMMENT,
+        };
+  }
+       /*
+        * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getConfiguredDocumentPartitioning(org.eclipse.jface.text.source.ISourceViewer)
+        * @since 3.0
+        */
+       public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
+               if (fDocumentPartitioning != null)
+                       return fDocumentPartitioning;
+               return super.getConfiguredDocumentPartitioning(sourceViewer);
+       }
+  /*
+   * (non-Javadoc) Method declared on SourceViewerConfiguration
+   */
+  public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+    ContentAssistant assistant = new ContentAssistant();
+    IContentAssistProcessor processor = new HTMLCompletionProcessor();
+    assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+    assistant.setContentAssistProcessor(processor, IPHPPartitions.HTML);
+    assistant.setContentAssistProcessor(processor, IPHPPartitions.HTML_MULTILINE_COMMENT);
+    
+    assistant.setContentAssistProcessor(processor, IPHPPartitions.CSS);
+    assistant.setContentAssistProcessor(processor, IPHPPartitions.CSS_MULTILINE_COMMENT);
+    assistant.setContentAssistProcessor(processor, IPHPPartitions.JAVASCRIPT);
+    assistant.setContentAssistProcessor(processor, IPHPPartitions.JS_MULTILINE_COMMENT);
+    // TODO define special smarty partition content assist
+    assistant.setContentAssistProcessor(processor, IPHPPartitions.SMARTY);
+    assistant.setContentAssistProcessor(processor, IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+    
+    assistant.setContentAssistProcessor(processor, PHPDocumentPartitioner.PHP_TEMPLATE_DATA);
+    String[] htmlTypes = getConfiguredHTMLContentTypes();
+    for (int i = 0; i < htmlTypes.length; i++) {
+      assistant.setContentAssistProcessor(processor, htmlTypes[i]); 
+    }
+    processor = new PHPCompletionProcessor(getEditor());
+    
+    assistant.setContentAssistProcessor(processor, PHPDocumentPartitioner.PHP_SCRIPT_CODE);
+    assistant.setContentAssistProcessor(processor, IPHPPartitions.PHP_PARTITIONING);
+    assistant.setContentAssistProcessor(processor, IPHPPartitions.PHP_STRING_DQ);
+    assistant.setContentAssistProcessor(processor, IPHPPartitions.PHP_STRING_SQ);
+    
+    assistant.setContentAssistProcessor(new PHPDocCompletionProcessor(), IPHPPartitions.PHP_PHPDOC_COMMENT);
+    //    assistant.enableAutoActivation(true);
+    //    assistant.setAutoActivationDelay(500);
+    //    assistant.setProposalPopupOrientation(ContentAssistant.PROPOSAL_OVERLAY);
+    //    ContentAssistPreference.configure(assistant, getPreferenceStore());
+    //    assistant.setContextInformationPopupOrientation(
+    //      ContentAssistant.CONTEXT_INFO_ABOVE);
+    //    assistant.setContextInformationPopupBackground(
+    //      PHPEditorEnvironment.getPHPColorProvider().getColor(
+    //        new RGB(150, 150, 0)));
+    ContentAssistPreference.configure(assistant, getPreferenceStore());
+    assistant.setContextInformationPopupOrientation(ContentAssistant.CONTEXT_INFO_ABOVE);
+    assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
+    return assistant;
+  } 
+
+  /*
+   * (non-Javadoc) Method declared on SourceViewerConfiguration
+   */
+  //  public String getDefaultPrefix(ISourceViewer sourceViewer, String
+  // contentType) {
+  //    return (PHPPartitionScanner.PHP.equals(contentType) ? "//" : null);
+  // //$NON-NLS-1$
+  //    // return (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType) ? "//" :
+  // null); //$NON-NLS-1$
+  //  }
+  /*
+   * @see SourceViewerConfiguration#getDefaultPrefix(ISourceViewer, String)
+   * @since 2.0
+   */
+  public String[] getDefaultPrefixes(ISourceViewer sourceViewer, String contentType) {
+    return new String[] { "//", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+  }
+
+  /*
+   * (non-Javadoc) Method declared on SourceViewerConfiguration
+   */
+  public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) {
+    return new PHPDoubleClickSelector();
+  }
+
+  /*
+   * @see SourceViewerConfiguration#getIndentPrefixes(ISourceViewer, String)
+   */
+  public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
+    Vector vector = new Vector();
+    // prefix[0] is either '\t' or ' ' x tabWidth, depending on useSpaces
+    final IPreferenceStore preferences = PHPeclipsePlugin.getDefault().getPreferenceStore();
+    int tabWidth = preferences.getInt(JavaCore.FORMATTER_TAB_SIZE);
+    boolean useSpaces = getPreferenceStore().getBoolean(SPACES_FOR_TABS);
+    for (int i = 0; i <= tabWidth; i++) {
+      StringBuffer prefix = new StringBuffer();
+      if (useSpaces) {
+        for (int j = 0; j + i < tabWidth; j++)
+          prefix.append(' ');
+        if (i != 0)
+          prefix.append('\t');
+      } else {
+        for (int j = 0; j < i; j++)
+          prefix.append(' ');
+        if (i != tabWidth)
+          prefix.append('\t');
+      }
+      vector.add(prefix.toString());
+    }
+    vector.add(""); //$NON-NLS-1$
+    return (String[]) vector.toArray(new String[vector.size()]);
+  }
+  /**
+        * @return <code>true</code> iff the new setup without text tools is in use.
+        * 
+        * @since 3.0
+        */
+       private boolean isNewSetup() {
+               return fJavaTextTools == null;
+       }
+  /**
+        * Creates and returns a preference store which combines the preference
+        * stores from the text tools and which is read-only.
+        *
+        * @return the read-only preference store 
+        * @since 3.0
+        */
+       private IPreferenceStore createPreferenceStore() {
+               Assert.isTrue(!isNewSetup());
+               IPreferenceStore generalTextStore= EditorsUI.getPreferenceStore();
+               if (fJavaTextTools.getCorePreferenceStore() == null)
+                       return new ChainedPreferenceStore(new IPreferenceStore[] { fJavaTextTools.getPreferenceStore(), generalTextStore});
+               
+               return new ChainedPreferenceStore(new IPreferenceStore[] { fJavaTextTools.getPreferenceStore(), new PreferencesAdapter(fJavaTextTools.getCorePreferenceStore()), generalTextStore });
+       }
+  /*
+   * (non-Javadoc) Method declared on SourceViewerConfiguration
+   */
+  public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+    //  PHPColorProvider provider =
+    // PHPEditorEnvironment.getPHPColorProvider();
+    //    JavaColorManager provider =
+    // PHPEditorEnvironment.getPHPColorProvider();
+    PresentationReconciler phpReconciler = new JavaPresentationReconciler();
+    phpReconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+
+//    DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getHTMLScanner());
+//    reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+//    reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+//    dr = new DefaultDamagerRepairer(getHTMLScanner());
+//    reconciler.setDamager(dr, IPHPPartitions.HTML);
+//    reconciler.setRepairer(dr, IPHPPartitions.HTML);
+//    dr = new DefaultDamagerRepairer(getHTMLScanner());
+//    reconciler.setDamager(dr, IPHPPartitions.CSS);
+//    reconciler.setRepairer(dr, IPHPPartitions.CSS);
+//    dr = new DefaultDamagerRepairer(getHTMLScanner());
+//    reconciler.setDamager(dr, IPHPPartitions.CSS_MULTILINE_COMMENT);
+//    reconciler.setRepairer(dr, IPHPPartitions.CSS_MULTILINE_COMMENT);
+//    dr = new DefaultDamagerRepairer(getHTMLScanner());
+//    reconciler.setDamager(dr, IPHPPartitions.JAVASCRIPT);
+//    reconciler.setRepairer(dr, IPHPPartitions.JAVASCRIPT);
+//    dr = new DefaultDamagerRepairer(getHTMLScanner());
+//    reconciler.setDamager(dr, IPHPPartitions.JS_MULTILINE_COMMENT);
+//    reconciler.setRepairer(dr, IPHPPartitions.JS_MULTILINE_COMMENT);
+    DefaultDamagerRepairer phpDR = new DefaultDamagerRepairer(getSmartyScanner());
+    phpReconciler.setDamager(phpDR, IPHPPartitions.SMARTY);
+    phpReconciler.setRepairer(phpDR, IPHPPartitions.SMARTY);
+    phpDR = new DefaultDamagerRepairer(getSmartyDocScanner());
+    phpReconciler.setDamager(phpDR, IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+    phpReconciler.setRepairer(phpDR, IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+//    dr = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor(
+//        PHPColorProvider.MULTI_LINE_COMMENT))));
+//    reconciler.setDamager(dr, IPHPPartitions.HTML_MULTILINE_COMMENT);
+//    reconciler.setRepairer(dr, IPHPPartitions.HTML_MULTILINE_COMMENT);
+
+    phpDR = new DefaultDamagerRepairer(getCodeScanner());
+    phpReconciler.setDamager(phpDR, IDocument.DEFAULT_CONTENT_TYPE);
+    phpReconciler.setRepairer(phpDR, IDocument.DEFAULT_CONTENT_TYPE);
+    
+    phpDR = new DefaultDamagerRepairer(getCodeScanner());
+    phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_PARTITIONING);
+    phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_PARTITIONING);
+
+    phpDR = new DefaultDamagerRepairer(getPHPDocScanner());
+    phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_PHPDOC_COMMENT);
+    phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_PHPDOC_COMMENT);
+
+    phpDR = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor(
+        PHPColorProvider.STRING))));
+    phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_STRING_DQ);
+    phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_STRING_DQ);
+    phpDR = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor(
+        PHPColorProvider.STRING))));
+    phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_STRING_SQ);
+    phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_STRING_SQ);
+    phpDR = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor(
+        PHPColorProvider.SINGLE_LINE_COMMENT))));
+    phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_SINGLELINE_COMMENT);
+    phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_SINGLELINE_COMMENT);
+    phpDR = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor(
+        PHPColorProvider.MULTI_LINE_COMMENT))));
+    phpReconciler.setDamager(phpDR, IPHPPartitions.PHP_MULTILINE_COMMENT);
+    phpReconciler.setRepairer(phpDR, IPHPPartitions.PHP_MULTILINE_COMMENT);
+    
+    PresentationReconciler reconciler = new PresentationReconciler();
+    reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+//
+    JavaTextTools jspTextTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
+    DefaultDamagerRepairer dr = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor(
+        PHPColorProvider.PHPDOC_TAG))));//jspTextTools.getJSPTextScanner());
+       reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+       reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+//     dr = new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(fJavaTextTools.getColorManager().getColor(
+//        PHPColorProvider.PHPDOC_TAG))));//jspTextTools.getJSPBracketScanner());
+//     reconciler.setDamager(dr, JSPScriptScanner.JSP_BRACKET);
+//     reconciler.setRepairer(dr, JSPScriptScanner.JSP_BRACKET);
+       
+    // xml partitions
+       configureEmbeddedPresentationReconciler(reconciler,
+           xmlConfiguration.getPresentationReconciler(sourceViewer),
+               xmlConfiguration.getConfiguredContentTypes(sourceViewer),
+               PHPDocumentPartitioner.PHP_TEMPLATE_DATA);
+
+       // java partitions
+       configureEmbeddedPresentationReconciler(reconciler,
+           phpReconciler,
+               getConfiguredPHPContentTypes(),
+               PHPDocumentPartitioner.PHP_SCRIPT_CODE);
+       
+    return reconciler;
+  }
+  
+  private void configureEmbeddedPresentationReconciler(
+               PresentationReconciler reconciler,
+               IPresentationReconciler embedded,
+               String[] types, 
+               String defaultType
+       ) {
+               for (int i = 0; i < types.length; i++) {
+                       String type = types[i];
+
+                       IPresentationDamager damager = embedded.getDamager(type);
+                       IPresentationRepairer repairer = embedded.getRepairer(type);
+
+                       if (type == IDocument.DEFAULT_CONTENT_TYPE) {
+                               type = defaultType;
+                       }
+
+                       reconciler.setDamager(damager, type);
+                       reconciler.setRepairer(repairer, type);
+               }
+       }
+
+  /*
+   * (non-Javadoc) Method declared on SourceViewerConfiguration
+   */
+  public int getTabWidth(ISourceViewer sourceViewer) {
+    return getPreferenceStore().getInt(PREFERENCE_TAB_WIDTH);
+  }
+
+  /*
+   * (non-Javadoc) Method declared on SourceViewerConfiguration
+   */
+  //  public ITextHover getTextHover(ISourceViewer sourceViewer, String
+  // contentType) {
+  //    if (fEditor != null) {
+  //      IEditorInput editorInput = fEditor.getEditorInput();
+  //      if (editorInput instanceof IFileEditorInput) {
+  //        try {
+  //          IFile f = ((IFileEditorInput) editorInput).getFile();
+  //          return new PHPTextHover(f.getProject());
+  //        } catch (NullPointerException e) {
+  //          // this exception occurs, if getTextHover is called by preference pages
+  // !
+  //        }
+  //      }
+  //    }
+  //    return new PHPTextHover(null);
+  //  }
+  /*
+   * @see SourceViewerConfiguration#getInformationControlCreator(ISourceViewer)
+   * @since 2.0
+   */
+  public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
+    return new IInformationControlCreator() {
+      public IInformationControl createInformationControl(Shell parent) {
+        return new DefaultInformationControl(parent, SWT.NONE, new HTMLTextPresenter(true));
+        // return new HoverBrowserControl(parent);
+      }
+    };
+  }
+
+       /*
+        * @see SourceViewerConfiguration#getInformationPresenter(ISourceViewer)
+        * @since 2.0
+        */
+       public IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) {
+               InformationPresenter presenter= new InformationPresenter(getInformationPresenterControlCreator(sourceViewer));
+               presenter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+               IInformationProvider provider= new JavaInformationProvider(getEditor());
+               presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
+               presenter.setInformationProvider(provider, IPHPPartitions.PHP_PHPDOC_COMMENT);
+//             presenter.setInformationProvider(provider, IPHPPartitions.JAVA_CHARACTER);
+               presenter.setSizeConstraints(60, 10, true, true);
+               return presenter;
+       }
+  /*
+   * @see SourceViewerConfiguration#getInformationPresenter(ISourceViewer)
+   * @since 2.0
+   */
+  //   public IInformationPresenter getInformationPresenter(ISourceViewer
+  // sourceViewer) {
+  //           InformationPresenter presenter= new
+  // InformationPresenter(getInformationPresenterControlCreator(sourceViewer));
+  //           IInformationProvider provider= new JavaInformationProvider(getEditor());
+  //           presenter.setInformationProvider(provider,
+  // IDocument.DEFAULT_CONTENT_TYPE);
+  //           presenter.setInformationProvider(provider, IJavaPartitions.JAVA_DOC);
+  //           presenter.setSizeConstraints(60, 10, true, true);
+  //           return presenter;
+  //   }
+  /**
+   * Returns the information presenter control creator. The creator is a factory creating the presenter controls for the given
+   * source viewer. This implementation always returns a creator for <code>DefaultInformationControl</code> instances.
+   * 
+   * @param sourceViewer
+   *          the source viewer to be configured by this configuration
+   * @return an information control creator
+   * @since 2.1
+   */
+  private IInformationControlCreator getInformationPresenterControlCreator(ISourceViewer sourceViewer) {
+    return new IInformationControlCreator() {
+      public IInformationControl createInformationControl(Shell parent) {
+        int shellStyle = SWT.RESIZE;
+        int style = SWT.V_SCROLL | SWT.H_SCROLL;
+        return new DefaultInformationControl(parent, shellStyle, style, new HTMLTextPresenter(false));
+        // return new HoverBrowserControl(parent);
+      }
+    };
+  }
+
+  /**
+   * Returns the outline presenter control creator. The creator is a factory creating outline presenter controls for the given
+   * source viewer. This implementation always returns a creator for <code>JavaOutlineInformationControl</code> instances.
+   * 
+   * @param sourceViewer
+   *          the source viewer to be configured by this configuration
+   * @return an information control creator
+   * @since 2.1
+   */
+  private IInformationControlCreator getOutlinePresenterControlCreator(ISourceViewer sourceViewer) {
+    return new IInformationControlCreator() {
+      public IInformationControl createInformationControl(Shell parent) {
+        int shellStyle = SWT.RESIZE;
+        int treeStyle = SWT.V_SCROLL | SWT.H_SCROLL;
+        return new JavaOutlineInformationControl(parent, shellStyle, treeStyle);
+      }
+    };
+  }
+
+  /**
+   * Returns the outline presenter which will determine and shown information requested for the current cursor position.
+   * 
+   * @param sourceViewer
+   *          the source viewer to be configured by this configuration
+   * @param doCodeResolve
+   *          a boolean which specifies whether code resolve should be used to compute the Java element
+   * @return an information presenter
+   * @since 2.1
+   */
+  public IInformationPresenter getOutlinePresenter(ISourceViewer sourceViewer, boolean doCodeResolve) {
+    InformationPresenter presenter = new InformationPresenter(getOutlinePresenterControlCreator(sourceViewer));
+    presenter.setAnchor(InformationPresenter.ANCHOR_GLOBAL);
+    IInformationProvider provider = new JavaElementProvider(getEditor(), doCodeResolve);
+    presenter.setInformationProvider(provider, IDocument.DEFAULT_CONTENT_TYPE);
+    presenter.setInformationProvider(provider, IPHPPartitions.PHP_PARTITIONING);
+    presenter.setInformationProvider(provider, IPHPPartitions.PHP_PHPDOC_COMMENT);
+    presenter.setInformationProvider(provider, IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+    presenter.setInformationProvider(provider, IPHPPartitions.HTML);
+    presenter.setInformationProvider(provider, IPHPPartitions.HTML_MULTILINE_COMMENT);
+    presenter.setSizeConstraints(40, 20, true, false);
+    return presenter;
+  }
+}
\ No newline at end of file
index 262d596..fda5d2e 100644 (file)
@@ -72,7 +72,7 @@ public class IdentifierIndexManager {
         line.append(phpdocLength);
       }
     }
-    
+
     private void addClassVariableInformation(char typeOfIdentifier, char[] identifier, StringBuffer line, int phpdocOffset,
         int phpdocLength) {
       line.append('\t');
@@ -80,7 +80,7 @@ public class IdentifierIndexManager {
       line.append(identifier);
       line.append("\to"); // Offset
       // we don't store the '$' in the index for class variables:
-      line.append(fScanner.getCurrentTokenStartPosition()+1);
+      line.append(fScanner.getCurrentTokenStartPosition() + 1);
       if (phpdocOffset >= 0) {
         line.append("\tp"); // phpdoc offset
         line.append(phpdocOffset);
@@ -113,33 +113,27 @@ public class IdentifierIndexManager {
       char[] ident;
       char[] classVariable;
       int counter = 0;
+      boolean hasModifiers = false;
       int phpdocOffset = -1;
       int phpdocLength = -1;
       try {
         while (fToken != TokenNameEOF && fToken != TokenNameERROR) {
           phpdocOffset = -1;
+          hasModifiers = false;
           if (fToken == TokenNameCOMMENT_PHPDOC) {
             phpdocOffset = fScanner.getCurrentTokenStartPosition();
             phpdocLength = fScanner.getCurrentTokenEndPosition() - fScanner.getCurrentTokenStartPosition() + 1;
             getNextToken();
+            while (fToken == TokenNamestatic || fToken == TokenNamefinal || fToken == TokenNamepublic
+                || fToken == TokenNameprotected || fToken == TokenNameprivate || fToken == TokenNameabstract) {
+              hasModifiers = true;
+              getNextToken();
+            }
             if (fToken == TokenNameEOF || fToken == TokenNameERROR) {
               break;
             }
           }
-          if (fToken == TokenNamevar || fToken == TokenNamestatic || fToken == TokenNamefinal || fToken == TokenNamepublic
-              || fToken == TokenNameprotected || fToken == TokenNameprivate) {
-            while (fToken == TokenNamevar || fToken == TokenNamestatic || fToken == TokenNamefinal || fToken == TokenNamepublic
-                || fToken == TokenNameprotected || fToken == TokenNameprivate) {
-              getNextToken();
-            }  
-            if (fToken == TokenNameVariable) {
-              ident = fScanner.getCurrentIdentifierSource();
-              classVariable = new char[ident.length - 1];
-              System.arraycopy(ident, 1, classVariable, 0, ident.length - 1);
-              addClassVariableInformation('v', classVariable, buf, phpdocOffset, phpdocLength);
-              getNextToken();
-            }
-          } else if (fToken == TokenNamefunction) {
+          if (fToken == TokenNamefunction) {
             getNextToken();
             if (fToken == TokenNameAND) {
               getNextToken();
@@ -174,7 +168,20 @@ public class IdentifierIndexManager {
               }
               parseDeclarations(ident, buf, true);
             }
-          } else if (fToken == TokenNameIdentifier) {
+          } else if (fToken == TokenNamevar || hasModifiers || fToken == TokenNamestatic || fToken == TokenNamefinal
+              || fToken == TokenNamepublic || fToken == TokenNameprotected || fToken == TokenNameprivate) {
+            while (fToken == TokenNamevar || fToken == TokenNamestatic || fToken == TokenNamefinal || fToken == TokenNamepublic
+                || fToken == TokenNameprotected || fToken == TokenNameprivate) {
+              getNextToken();
+            }
+            if (fToken == TokenNameVariable) {
+              ident = fScanner.getCurrentIdentifierSource();
+              classVariable = new char[ident.length - 1];
+              System.arraycopy(ident, 1, classVariable, 0, ident.length - 1);
+              addClassVariableInformation('v', classVariable, buf, phpdocOffset, phpdocLength);
+              getNextToken();
+            }
+          } else if (!hasModifiers && fToken == TokenNameIdentifier) {
             ident = fScanner.getCurrentIdentifierSource();
             getNextToken();
             if (ident.length == 6 && ident[0] == 'd' && ident[1] == 'e' && ident[2] == 'f' && ident[3] == 'i' && ident[4] == 'n'
@@ -221,6 +228,7 @@ public class IdentifierIndexManager {
       char[] ident;
       String identifier;
       int counter = 0;
+      boolean hasModifiers = false;
       int phpdocOffset = -1;
       int phpdocLength = -1;
       fScanner.setSource(charArray);
@@ -230,10 +238,16 @@ public class IdentifierIndexManager {
       try {
         while (fToken != TokenNameEOF) { // && fToken != TokenNameERROR) {
           phpdocOffset = -1;
+          hasModifiers = false;
           if (fToken == TokenNameCOMMENT_PHPDOC) {
             phpdocOffset = fScanner.getCurrentTokenStartPosition();
             phpdocLength = fScanner.getCurrentTokenEndPosition() - fScanner.getCurrentTokenStartPosition() + 1;
             getNextToken();
+            while (fToken == TokenNamestatic || fToken == TokenNamefinal || fToken == TokenNamepublic
+                || fToken == TokenNameprotected || fToken == TokenNameprivate || fToken == TokenNameabstract) {
+              hasModifiers = true;
+              getNextToken();
+            }
             if (fToken == TokenNameEOF || fToken == TokenNameERROR) {
               break;
             }
@@ -267,7 +281,7 @@ public class IdentifierIndexManager {
             ident = fScanner.getCurrentIdentifierSource();
             addIdentifierInformation('g', ident, buf, phpdocOffset, phpdocLength);
             getNextToken();
-          } else if (fToken == TokenNameIdentifier) {
+          } else if (!hasModifiers && fToken == TokenNameIdentifier) {
             ident = fScanner.getCurrentIdentifierSource();
             getNextToken();
             if (ident.length == 6 && ident[0] == 'd' && ident[1] == 'e' && ident[2] == 'f' && ident[3] == 'i' && ident[4] == 'n'
index c570267..d65fe4c 100644 (file)
@@ -30,6 +30,8 @@ public class JavaDocumentSetupParticipant  implements IDocumentSetupParticipant
         */
        public void setup(IDocument document) {
                JavaTextTools tools= PHPeclipsePlugin.getDefault().getJavaTextTools();
-               tools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING, null); //IPHPPartitions.PHP_PARTITIONING, null);
+               tools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING);
+
+//             tools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING, null); //IPHPPartitions.PHP_PARTITIONING, null);
        }
 }
index c5f8376..1b91695 100644 (file)
@@ -15,6 +15,7 @@ import java.util.ArrayList;
 
 import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager;
 import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
 
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.PreferenceConverter;
index a5faee3..e91b68d 100644 (file)
@@ -33,7 +33,9 @@ public class JavaStorageDocumentProvider extends StorageDocumentProvider {
                
                if (document != null) {
                        JavaTextTools tools= PHPeclipsePlugin.getDefault().getJavaTextTools();
-                       tools.setupJavaDocumentPartitioner(document, IPHPPartitions.HTML, element);
+                       tools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING);
+
+//                     tools.setupJavaDocumentPartitioner(document, IDocument.DEFAULT_CONTENT_TYPE, element); //IPHPPartitions.HTML, element);
                }
        }
 }
index d7b5126..040e974 100644 (file)
@@ -42,6 +42,7 @@ import net.sourceforge.phpdt.ui.JavaUI;
 import net.sourceforge.phpdt.ui.PreferenceConstants;
 import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction;
 import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
 import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingStructureProvider;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
@@ -140,7 +141,6 @@ import org.eclipse.ui.editors.text.EditorsUI;
 import org.eclipse.ui.editors.text.IEncodingSupport;
 import org.eclipse.ui.part.IShowInTargetList;
 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
-import org.eclipse.ui.texteditor.AnnotationPreference;
 import org.eclipse.ui.texteditor.ChainedPreferenceStore;
 import org.eclipse.ui.texteditor.DefaultRangeIndicator;
 import org.eclipse.ui.texteditor.IDocumentProvider;
@@ -148,6 +148,7 @@ import org.eclipse.ui.texteditor.IEditorStatusLine;
 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
 import org.eclipse.ui.texteditor.MarkerAnnotation;
 import org.eclipse.ui.texteditor.ResourceAction;
+import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
 import org.eclipse.ui.texteditor.TextEditorAction;
 import org.eclipse.ui.texteditor.TextOperationAction;
 import org.eclipse.ui.views.contentoutline.ContentOutline;
@@ -1741,7 +1742,7 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I
   protected void initializeEditor() {
     //jsurfer old code
     JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
-    setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools, this)); //, IJavaPartitions.JAVA_PARTITIONING));
+    setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools, this, IPHPPartitions.PHP_PARTITIONING)); //, IJavaPartitions.JAVA_PARTITIONING));
     setRangeIndicator(new DefaultRangeIndicator());
     //         IPreferenceStore store=
     // PHPeclipsePlugin.getDefault().getPreferenceStore();
@@ -1893,6 +1894,14 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I
     // getEditorSite().getShell().addShellListener(fActivationListener);
   }
 
+  protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
+       
+       support.setCharacterPairMatcher(fBracketMatcher);
+       support.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR);
+       
+       super.configureSourceViewerDecorationSupport(support);
+  }
+  
   /**
    * Returns this document's complete text.
    * 
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSourceViewerConfiguration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPSourceViewerConfiguration.java
deleted file mode 100644 (file)
index 5ecde70..0000000
+++ /dev/null
@@ -1,731 +0,0 @@
-/**********************************************************************
- Copyright (c) 2000, 2002 IBM Corp. and others.
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Common Public License v1.0
- which accompanies this distribution, and is available at
- http://www.eclipse.org/legal/cpl-v10.html
-
- Contributors:
- IBM Corporation - Initial implementation
- Klaus Hartlage - www.eclipseproject.de
- **********************************************************************/
-package net.sourceforge.phpeclipse.phpeditor;
-import java.util.Vector;
-
-import net.sourceforge.phpdt.core.JavaCore;
-import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
-import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference;
-import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter;
-import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
-import net.sourceforge.phpdt.internal.ui.text.JavaAnnotationHover;
-import net.sourceforge.phpdt.internal.ui.text.JavaCompositeReconcilingStrategy;
-import net.sourceforge.phpdt.internal.ui.text.JavaElementProvider;
-import net.sourceforge.phpdt.internal.ui.text.JavaOutlineInformationControl;
-import net.sourceforge.phpdt.internal.ui.text.JavaPresentationReconciler;
-import net.sourceforge.phpdt.internal.ui.text.JavaReconciler;
-import net.sourceforge.phpdt.internal.ui.text.java.JavaFormattingStrategy;
-import net.sourceforge.phpdt.internal.ui.text.java.JavaReconcilingStrategy;
-import net.sourceforge.phpdt.internal.ui.text.java.JavaStringAutoIndentStrategy;
-import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor;
-import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy;
-import net.sourceforge.phpdt.internal.ui.text.phpdoc.PHPDocCompletionProcessor;
-import net.sourceforge.phpdt.ui.PreferenceConstants;
-import net.sourceforge.phpdt.ui.text.IColorManager;
-import net.sourceforge.phpdt.ui.text.JavaTextTools;
-import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.phpeditor.html.HTMLFormattingStrategy;
-import net.sourceforge.phpeclipse.phpeditor.php.HTMLCompletionProcessor;
-import net.sourceforge.phpeclipse.phpeditor.php.PHPAutoIndentStrategy;
-import net.sourceforge.phpeclipse.phpeditor.php.PHPCompletionProcessor;
-import net.sourceforge.phpeclipse.phpeditor.php.PHPDoubleClickSelector;
-import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider;
-
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.text.DefaultAutoIndentStrategy;
-import org.eclipse.jface.text.DefaultInformationControl;
-import org.eclipse.jface.text.IAutoIndentStrategy;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IInformationControl;
-import org.eclipse.jface.text.IInformationControlCreator;
-import org.eclipse.jface.text.ITextDoubleClickStrategy;
-import org.eclipse.jface.text.ITextHover;
-import org.eclipse.jface.text.ITextViewerExtension2;
-import org.eclipse.jface.text.TextAttribute;
-import org.eclipse.jface.text.contentassist.ContentAssistant;
-import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
-import org.eclipse.jface.text.contentassist.IContentAssistant;
-import org.eclipse.jface.text.formatter.ContentFormatter;
-import org.eclipse.jface.text.formatter.IContentFormatter;
-import org.eclipse.jface.text.formatter.IFormattingStrategy;
-import org.eclipse.jface.text.information.IInformationPresenter;
-import org.eclipse.jface.text.information.IInformationProvider;
-import org.eclipse.jface.text.information.InformationPresenter;
-import org.eclipse.jface.text.presentation.IPresentationReconciler;
-import org.eclipse.jface.text.presentation.PresentationReconciler;
-import org.eclipse.jface.text.reconciler.IReconciler;
-import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
-import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
-import org.eclipse.jface.text.rules.DefaultPartitioner;
-import org.eclipse.jface.text.rules.RuleBasedScanner;
-import org.eclipse.jface.text.rules.Token;
-import org.eclipse.jface.text.source.IAnnotationHover;
-import org.eclipse.jface.text.source.ISourceViewer;
-import org.eclipse.jface.text.source.SourceViewerConfiguration;
-import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.texteditor.ITextEditor;
-/**
- * Configuration for an <code>SourceViewer</code> which shows PHP code.
- */
-public class PHPSourceViewerConfiguration extends SourceViewerConfiguration {
-       /**
-        * Preference key used to look up display tab width.
-        * 
-        * @since 2.0
-        */
-       public final static String PREFERENCE_TAB_WIDTH = PreferenceConstants.EDITOR_TAB_WIDTH;
-       /**
-        * Preference key for inserting spaces rather than tabs.
-        * 
-        * @since 2.0
-        */
-       public final static String SPACES_FOR_TABS = PreferenceConstants.EDITOR_SPACES_FOR_TABS;
-       //  public static final String HTML_DEFAULT =
-       // IPHPPartitionScannerConstants.HTML;
-       //IDocument.DEFAULT_CONTENT_TYPE;
-       private JavaTextTools fJavaTextTools;
-       private ITextEditor fTextEditor;
-       private ContentFormatter fFormatter;
-       private HTMLFormattingStrategy fFormattingStrategy;
-       /**
-        * Single token scanner.
-        */
-       static class SingleTokenScanner extends BufferedRuleBasedScanner {
-               public SingleTokenScanner(TextAttribute attribute) {
-                       setDefaultReturnToken(new Token(attribute));
-               }
-       };
-       /**
-        * The document partitioning.
-        * @since 3.0
-        */
-       private String fDocumentPartitioning;
-       /**
-        * The Java source code scanner
-        * @since 3.0
-        */
-       private AbstractJavaScanner fCodeScanner;
-       /** 
-        * The Java multi-line comment scanner 
-        * @since 3.0
-        */
-       private AbstractJavaScanner fMultilineCommentScanner;
-       /**
-        * The Java single-line comment scanner
-        * @since 3.0
-        */
-       private AbstractJavaScanner fSinglelineCommentScanner;
-       /**
-        * The Java string scanner
-        * @since 3.0
-        */
-       private AbstractJavaScanner fStringScanner;
-       /**
-        * The Javadoc scanner
-        * @since 3.0
-        */
-       private AbstractJavaScanner fJavaDocScanner;
-       /**
-        * The preference store, can be read-only
-        * @since 3.0
-        */
-       private IPreferenceStore fPreferenceStore;
-       /**
-        * The color manager
-        * @since 3.0
-        */
-       private IColorManager fColorManager;
-       
-       /**
-        * Creates a new Java source viewer configuration for viewers in the given editor 
-        * using the given preference store, the color manager and the specified document partitioning.
-        * <p>
-        * Creates a Java source viewer configuration in the new setup without text tools. Clients are
-        * allowed to call {@link JavaSourceViewerConfiguration#handlePropertyChangeEvent(PropertyChangeEvent)}
-        * and disallowed to call {@link JavaSourceViewerConfiguration#getPreferenceStore()} on the resulting
-        * Java source viewer configuration.
-        * </p>
-        *
-        * @param colorManager the color manager
-        * @param preferenceStore the preference store, can be read-only
-        * @param editor the editor in which the configured viewer(s) will reside
-        * @param partitioning the document partitioning for this configuration
-        * @since 3.0
-        */
-       public PHPSourceViewerConfiguration(IColorManager colorManager, IPreferenceStore preferenceStore, ITextEditor editor, String partitioning) {
-               fColorManager= colorManager;
-               fPreferenceStore= preferenceStore;
-               fTextEditor= editor;
-               fDocumentPartitioning= partitioning;
-               fJavaTextTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
-//             initializeScanners();
-       }
-
-       /**
-        * Default constructor.
-        */
-       public PHPSourceViewerConfiguration(JavaTextTools textTools,
-                       PHPEditor editor) {
-               fJavaTextTools = textTools;
-               fTextEditor = editor;
-       }
-       /*
-        * @see SourceViewerConfiguration#getContentFormatter(ISourceViewer)
-        */
-       public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
-               //    if (fFormatter == null) {
-               //      fFormatter = new ContentFormatter();
-               //      fFormattingStrategy = new HTMLFormattingStrategy(this,
-               // sourceViewer);
-               //      fFormatter.setFormattingStrategy(fFormattingStrategy, HTML_DEFAULT);
-               //      fFormatter.enablePartitionAwareFormatting(false);
-               //      fFormatter.setPartitionManagingPositionCategories(getConfiguredContentTypes(null));
-               //    }
-               //    return fFormatter;
-               if (fFormatter == null) {
-                       //ContentFormatter
-                       fFormatter = new ContentFormatter();
-                       IFormattingStrategy strategy = new JavaFormattingStrategy(
-                                       sourceViewer);
-                       fFormatter.setFormattingStrategy(strategy,
-                                       IDocument.DEFAULT_CONTENT_TYPE);
-                       fFormatter.enablePartitionAwareFormatting(false);
-                       fFormatter
-                                       .setPartitionManagingPositionCategories(getPartitionManagingPositionCategories());
-               }
-               return fFormatter;
-       }
-       /**
-        * Returns the names of the document position categories used by the
-        * document partitioners created by this object to manage their partition
-        * information. If the partitioners don't use document position categories,
-        * the returned result is <code>null</code>.
-        * 
-        * @return the partition managing position categories or <code>null</code>
-        *         if there is none
-        */
-       public String[] getPartitionManagingPositionCategories() {
-               return new String[]{DefaultPartitioner.CONTENT_TYPES_CATEGORY};
-       }
-       //  /**
-       //   * Returns the names of the document position categories used by the
-       // document
-       //   * partitioners created by this object to manage their partition
-       // information.
-       //   * If the partitioners don't use document position categories, the
-       // returned
-       //   * result is <code>null</code>.
-       //   *
-       //   * @return the partition managing position categories or
-       // <code>null</code>
-       //   * if there is none
-       //   */
-       //  private String[] getPartitionManagingPositionCategories() {
-       //    return new String[] { DefaultPartitioner.CONTENT_TYPES_CATEGORY };
-       //  }
-       public ITextEditor getEditor() {
-               return fTextEditor;
-       }
-       /**
-        * Returns the preference store used by this configuration to initialize
-        * the individual bits and pieces.
-        * 
-        * @return the preference store used to initialize this configuration
-        * 
-        * @since 2.0
-        */
-       protected IPreferenceStore getPreferenceStore() {
-               return PHPeclipsePlugin.getDefault().getPreferenceStore();
-       }
-       //  /* (non-Javadoc)
-       //   * Method declared on SourceViewerConfiguration
-       //   */
-       //  public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
-       //    return new PHPAnnotationHover();
-       //  }
-       /*
-        * @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer)
-        */
-       public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
-               return new JavaAnnotationHover(JavaAnnotationHover.VERTICAL_RULER_HOVER);
-       }
-       /*
-        * @see SourceViewerConfiguration#getOverviewRulerAnnotationHover(ISourceViewer)
-        * @since 3.0
-        */
-       public IAnnotationHover getOverviewRulerAnnotationHover(
-                       ISourceViewer sourceViewer) {
-               return new JavaAnnotationHover(JavaAnnotationHover.OVERVIEW_RULER_HOVER);
-       }
-       /*
-        * (non-Javadoc) Method declared on SourceViewerConfiguration
-        */
-       public IAutoIndentStrategy getAutoIndentStrategy(
-                       ISourceViewer sourceViewer, String contentType) {
-               if (IPHPPartitions.PHP_STRING_DQ.equals(contentType))
-                       return new JavaStringAutoIndentStrategy(getConfiguredDocumentPartitioning(sourceViewer));
-
-               return (IPHPPartitions.PHP_PARTITIONING.equals(contentType)
-                               ? new PHPAutoIndentStrategy()
-                               : new DefaultAutoIndentStrategy());
-       }
-       /**
-        * Returns the PHP source code scanner for this configuration.
-        * 
-        * @return the PHP source code scanner
-        */
-       protected RuleBasedScanner getCodeScanner() {
-               return fJavaTextTools.getCodeScanner();
-       }
-       /**
-        * Returns the HTML source code scanner for this configuration.
-        * 
-        * @return the HTML source code scanner
-        */
-       protected RuleBasedScanner getHTMLScanner() {
-               return fJavaTextTools.getHTMLScanner();
-       }
-       /**
-        * Returns the Smarty source code scanner for this configuration.
-        * 
-        * @return the Smarty source code scanner
-        */
-       protected RuleBasedScanner getSmartyScanner() {
-               return fJavaTextTools.getSmartyScanner();
-       }
-       /*
-        * @see SourceViewerConfiguration#getReconciler(ISourceViewer)
-        */
-       /*
-        * @see SourceViewerConfiguration#getReconciler(ISourceViewer)
-        */
-       public IReconciler getReconciler(ISourceViewer sourceViewer) {
-
-               final ITextEditor editor= getEditor();
-               if (editor != null && editor.isEditable()) {
-                       
-                       JavaCompositeReconcilingStrategy strategy= new JavaCompositeReconcilingStrategy(editor, getConfiguredDocumentPartitioning(sourceViewer));
-                       JavaReconciler reconciler= new JavaReconciler(editor, strategy, false);
-                       reconciler.setIsIncrementalReconciler(false);
-                       reconciler.setProgressMonitor(new NullProgressMonitor());
-                       reconciler.setDelay(500);
-
-                       return reconciler;
-               }
-               return null;
-       }
-//     public IReconciler getReconciler(ISourceViewer sourceViewer) {
-//             if (getEditor() != null && getEditor().isEditable()) {
-//                     JavaReconciler reconciler = new JavaReconciler(getEditor(),
-//                                     new JavaReconcilingStrategy(getEditor()), false);
-//                     reconciler.setProgressMonitor(new NullProgressMonitor());
-//                     reconciler.setDelay(500);
-//                     return reconciler;
-//             }
-//             return null;
-//     }
-       /*
-        * @see SourceViewerConfiguration#getConfiguredTextHoverStateMasks(ISourceViewer,
-        *      String)
-        * @since 2.1
-        */
-       public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer,
-                       String contentType) {
-               JavaEditorTextHoverDescriptor[] hoverDescs = PHPeclipsePlugin
-                               .getDefault().getJavaEditorTextHoverDescriptors();
-               int stateMasks[] = new int[hoverDescs.length];
-               int stateMasksLength = 0;
-               for (int i = 0; i < hoverDescs.length; i++) {
-                       if (hoverDescs[i].isEnabled()) {
-                               int j = 0;
-                               int stateMask = hoverDescs[i].getStateMask();
-                               while (j < stateMasksLength) {
-                                       if (stateMasks[j] == stateMask)
-                                               break;
-                                       j++;
-                               }
-                               if (j == stateMasksLength)
-                                       stateMasks[stateMasksLength++] = stateMask;
-                       }
-               }
-               if (stateMasksLength == hoverDescs.length)
-                       return stateMasks;
-               int[] shortenedStateMasks = new int[stateMasksLength];
-               System.arraycopy(stateMasks, 0, shortenedStateMasks, 0,
-                               stateMasksLength);
-               return shortenedStateMasks;
-       }
-       /*
-        * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String, int)
-        * @since 2.1
-        */
-       public ITextHover getTextHover(ISourceViewer sourceViewer,
-                       String contentType, int stateMask) {
-               JavaEditorTextHoverDescriptor[] hoverDescs = PHPeclipsePlugin
-                               .getDefault().getJavaEditorTextHoverDescriptors();
-               int i = 0;
-               while (i < hoverDescs.length) {
-                       if (hoverDescs[i].isEnabled()
-                                       && hoverDescs[i].getStateMask() == stateMask)
-                               return new JavaEditorTextHoverProxy(hoverDescs[i], getEditor());
-                       i++;
-               }
-               return null;
-//             if (fEditor != null) {
-//                     IEditorInput editorInput = fEditor.getEditorInput();
-//                     if (editorInput instanceof IFileEditorInput) {
-//                             try {
-//                                     IFile f = ((IFileEditorInput) editorInput).getFile();
-//                                     return new PHPTextHover(f.getProject());
-//                             } catch (NullPointerException e) {
-//                                     // this exception occurs, if getTextHover is called by
-//                                     // preference pages !
-//                             }
-//                     }
-//             }
-//             return new PHPTextHover(null);
-       }
-       /*
-        * @see SourceViewerConfiguration#getTextHover(ISourceViewer, String)
-        */
-       public ITextHover getTextHover(ISourceViewer sourceViewer,
-                       String contentType) {
-               return getTextHover(sourceViewer, contentType,
-                               ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
-       }
-       /**
-        * Returns the SmartyDoc source code scanner for this configuration.
-        * 
-        * @return the SmartyDoc source code scanner
-        */
-       protected RuleBasedScanner getSmartyDocScanner() {
-               return fJavaTextTools.getSmartyDocScanner();
-       }
-       /**
-        * Returns the PHPDoc source code scanner for this configuration.
-        * 
-        * @return the PHPDoc source code scanner
-        */
-       protected RuleBasedScanner getPHPDocScanner() {
-               return fJavaTextTools.getJavaDocScanner();
-       }
-       /*
-        * (non-Javadoc) Method declared on SourceViewerConfiguration
-        */
-       public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
-               return new String[]{IPHPPartitions.HTML,
-                               IPHPPartitions.HTML_MULTILINE_COMMENT,
-                               IPHPPartitions.PHP_PARTITIONING,
-                               IPHPPartitions.PHP_PHPDOC_COMMENT,
-                               IPHPPartitions.CSS,
-                               IPHPPartitions.CSS_MULTILINE_COMMENT,
-                               IPHPPartitions.JAVASCRIPT,
-                               IPHPPartitions.JS_MULTILINE_COMMENT,
-                               IPHPPartitions.SMARTY,
-                               IPHPPartitions.SMARTY_MULTILINE_COMMENT,
-                               IDocument.DEFAULT_CONTENT_TYPE};
-       }
-       /*
-        * (non-Javadoc) Method declared on SourceViewerConfiguration
-        */
-       public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
-               ContentAssistant assistant = new ContentAssistant();
-               IContentAssistProcessor processor = new HTMLCompletionProcessor();
-               assistant.setContentAssistProcessor(processor,
-                               IPHPPartitions.HTML);
-               assistant.setContentAssistProcessor(processor,
-                               IPHPPartitions.HTML_MULTILINE_COMMENT);
-               assistant.setContentAssistProcessor(processor,
-                               IDocument.DEFAULT_CONTENT_TYPE);
-               assistant.setContentAssistProcessor(processor,
-                               IPHPPartitions.CSS);
-               assistant.setContentAssistProcessor(processor,
-                               IPHPPartitions.CSS_MULTILINE_COMMENT);
-               assistant.setContentAssistProcessor(processor,
-                               IPHPPartitions.JAVASCRIPT);
-               assistant.setContentAssistProcessor(processor,
-                               IPHPPartitions.JS_MULTILINE_COMMENT);
-               // TODO define special smarty partition content assist
-               assistant.setContentAssistProcessor(processor,
-                               IPHPPartitions.SMARTY);
-               assistant.setContentAssistProcessor(processor,
-                               IPHPPartitions.SMARTY_MULTILINE_COMMENT);
-               assistant.setContentAssistProcessor(new PHPCompletionProcessor(getEditor()),
-                               IPHPPartitions.PHP_PARTITIONING);
-               assistant.setContentAssistProcessor(new PHPDocCompletionProcessor(),
-                               IPHPPartitions.PHP_PHPDOC_COMMENT);
-               //    assistant.enableAutoActivation(true);
-               //    assistant.setAutoActivationDelay(500);
-               //    assistant.setProposalPopupOrientation(ContentAssistant.PROPOSAL_OVERLAY);
-               //    ContentAssistPreference.configure(assistant, getPreferenceStore());
-               //    assistant.setContextInformationPopupOrientation(
-               //      ContentAssistant.CONTEXT_INFO_ABOVE);
-               //    assistant.setContextInformationPopupBackground(
-               //      PHPEditorEnvironment.getPHPColorProvider().getColor(
-               //        new RGB(150, 150, 0)));
-               ContentAssistPreference.configure(assistant, getPreferenceStore());
-               assistant
-                               .setContextInformationPopupOrientation(ContentAssistant.CONTEXT_INFO_ABOVE);
-               assistant
-                               .setInformationControlCreator(getInformationControlCreator(sourceViewer));
-               return assistant;
-       }
-       /*
-        * (non-Javadoc) Method declared on SourceViewerConfiguration
-        */
-       //  public String getDefaultPrefix(ISourceViewer sourceViewer, String
-       // contentType) {
-       //    return (PHPPartitionScanner.PHP.equals(contentType) ? "//" : null);
-       // //$NON-NLS-1$
-       //    // return (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType) ? "//" :
-       // null); //$NON-NLS-1$
-       //  }
-       /*
-        * @see SourceViewerConfiguration#getDefaultPrefix(ISourceViewer, String)
-        * @since 2.0
-        */
-       public String[] getDefaultPrefixes(ISourceViewer sourceViewer,
-                       String contentType) {
-               return new String[]{"//", ""}; //$NON-NLS-1$ //$NON-NLS-2$
-       }
-       /*
-        * (non-Javadoc) Method declared on SourceViewerConfiguration
-        */
-       public ITextDoubleClickStrategy getDoubleClickStrategy(
-                       ISourceViewer sourceViewer, String contentType) {
-               return new PHPDoubleClickSelector();
-       }
-       /*
-        * @see SourceViewerConfiguration#getIndentPrefixes(ISourceViewer, String)
-        */
-       public String[] getIndentPrefixes(ISourceViewer sourceViewer,
-                       String contentType) {
-               Vector vector = new Vector();
-               // prefix[0] is either '\t' or ' ' x tabWidth, depending on useSpaces
-               final IPreferenceStore preferences = PHPeclipsePlugin.getDefault()
-                               .getPreferenceStore();
-               int tabWidth = preferences.getInt(JavaCore.FORMATTER_TAB_SIZE);
-               boolean useSpaces = getPreferenceStore().getBoolean(SPACES_FOR_TABS);
-               for (int i = 0; i <= tabWidth; i++) {
-                       StringBuffer prefix = new StringBuffer();
-                       if (useSpaces) {
-                               for (int j = 0; j + i < tabWidth; j++)
-                                       prefix.append(' ');
-                               if (i != 0)
-                                       prefix.append('\t');
-                       } else {
-                               for (int j = 0; j < i; j++)
-                                       prefix.append(' ');
-                               if (i != tabWidth)
-                                       prefix.append('\t');
-                       }
-                       vector.add(prefix.toString());
-               }
-               vector.add(""); //$NON-NLS-1$
-               return (String[]) vector.toArray(new String[vector.size()]);
-       }
-       /*
-        * (non-Javadoc) Method declared on SourceViewerConfiguration
-        */
-       public IPresentationReconciler getPresentationReconciler(
-                       ISourceViewer sourceViewer) {
-               //  PHPColorProvider provider =
-               // PHPEditorEnvironment.getPHPColorProvider();
-               //    JavaColorManager provider =
-               // PHPEditorEnvironment.getPHPColorProvider();
-               PresentationReconciler reconciler= new JavaPresentationReconciler();
-               reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
-
-               DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getHTMLScanner());
-               reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
-               reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
-               dr = new DefaultDamagerRepairer(getHTMLScanner());
-               reconciler.setDamager(dr, IPHPPartitions.HTML);
-               reconciler.setRepairer(dr, IPHPPartitions.HTML);
-               dr = new DefaultDamagerRepairer(getHTMLScanner());
-               reconciler.setDamager(dr, IPHPPartitions.CSS);
-               reconciler.setRepairer(dr, IPHPPartitions.CSS);
-               dr = new DefaultDamagerRepairer(getHTMLScanner());
-               reconciler.setDamager(dr,
-                               IPHPPartitions.CSS_MULTILINE_COMMENT);
-               reconciler.setRepairer(dr,
-                               IPHPPartitions.CSS_MULTILINE_COMMENT);
-               dr = new DefaultDamagerRepairer(getHTMLScanner());
-               reconciler.setDamager(dr, IPHPPartitions.JAVASCRIPT);
-               reconciler.setRepairer(dr, IPHPPartitions.JAVASCRIPT);
-               dr = new DefaultDamagerRepairer(getHTMLScanner());
-               reconciler.setDamager(dr,
-                               IPHPPartitions.JS_MULTILINE_COMMENT);
-               reconciler.setRepairer(dr,
-                               IPHPPartitions.JS_MULTILINE_COMMENT);
-               dr = new DefaultDamagerRepairer(getSmartyScanner());
-               reconciler.setDamager(dr, IPHPPartitions.SMARTY);
-               reconciler.setRepairer(dr, IPHPPartitions.SMARTY);
-               dr = new DefaultDamagerRepairer(getSmartyDocScanner());
-               reconciler.setDamager(dr,
-                               IPHPPartitions.SMARTY_MULTILINE_COMMENT);
-               reconciler.setRepairer(dr,
-                               IPHPPartitions.SMARTY_MULTILINE_COMMENT);
-               dr = new DefaultDamagerRepairer(new SingleTokenScanner(
-                               new TextAttribute(fJavaTextTools.getColorManager().getColor(
-                                               PHPColorProvider.MULTI_LINE_COMMENT))));
-               reconciler.setDamager(dr,
-                               IPHPPartitions.HTML_MULTILINE_COMMENT);
-               reconciler.setRepairer(dr,
-                               IPHPPartitions.HTML_MULTILINE_COMMENT);
-               dr = new DefaultDamagerRepairer(getCodeScanner());
-               reconciler.setDamager(dr, IPHPPartitions.PHP_PARTITIONING);
-               reconciler.setRepairer(dr, IPHPPartitions.PHP_PARTITIONING);
-               dr = new DefaultDamagerRepairer(getPHPDocScanner());
-               reconciler.setDamager(dr,
-                               IPHPPartitions.PHP_PHPDOC_COMMENT);
-               reconciler.setRepairer(dr,
-                               IPHPPartitions.PHP_PHPDOC_COMMENT);
-               return reconciler;
-       }
-       /*
-        * (non-Javadoc) Method declared on SourceViewerConfiguration
-        */
-       public int getTabWidth(ISourceViewer sourceViewer) {
-               return getPreferenceStore().getInt(PREFERENCE_TAB_WIDTH);
-       }
-       /*
-        * (non-Javadoc) Method declared on SourceViewerConfiguration
-        */
-       //  public ITextHover getTextHover(ISourceViewer sourceViewer, String
-       // contentType) {
-       //    if (fEditor != null) {
-       //      IEditorInput editorInput = fEditor.getEditorInput();
-       //      if (editorInput instanceof IFileEditorInput) {
-       //        try {
-       //          IFile f = ((IFileEditorInput) editorInput).getFile();
-       //          return new PHPTextHover(f.getProject());
-       //        } catch (NullPointerException e) {
-       //          // this exception occurs, if getTextHover is called by preference pages
-       // !
-       //        }
-       //      }
-       //    }
-       //    return new PHPTextHover(null);
-       //  }
-       /*
-        * @see SourceViewerConfiguration#getInformationControlCreator(ISourceViewer)
-        * @since 2.0
-        */
-       public IInformationControlCreator getInformationControlCreator(
-                       ISourceViewer sourceViewer) {
-               return new IInformationControlCreator() {
-                       public IInformationControl createInformationControl(Shell parent) {
-                               return new DefaultInformationControl(parent, SWT.NONE,
-                                               new HTMLTextPresenter(true));
-                               // return new HoverBrowserControl(parent);
-                       }
-               };
-       }
-       /*
-        * @see SourceViewerConfiguration#getInformationPresenter(ISourceViewer)
-        * @since 2.0
-        */
-       //      public IInformationPresenter getInformationPresenter(ISourceViewer
-       // sourceViewer) {
-       //              InformationPresenter presenter= new
-       // InformationPresenter(getInformationPresenterControlCreator(sourceViewer));
-       //              IInformationProvider provider= new JavaInformationProvider(getEditor());
-       //              presenter.setInformationProvider(provider,
-       // IDocument.DEFAULT_CONTENT_TYPE);
-       //              presenter.setInformationProvider(provider, IJavaPartitions.JAVA_DOC);
-       //              presenter.setSizeConstraints(60, 10, true, true);
-       //              return presenter;
-       //      }
-       /**
-        * Returns the information presenter control creator. The creator is a
-        * factory creating the presenter controls for the given source viewer.
-        * This implementation always returns a creator for <code>DefaultInformationControl</code>
-        * instances.
-        * 
-        * @param sourceViewer
-        *            the source viewer to be configured by this configuration
-        * @return an information control creator
-        * @since 2.1
-        */
-       private IInformationControlCreator getInformationPresenterControlCreator(
-                       ISourceViewer sourceViewer) {
-               return new IInformationControlCreator() {
-                       public IInformationControl createInformationControl(Shell parent) {
-                               int shellStyle = SWT.RESIZE;
-                               int style = SWT.V_SCROLL | SWT.H_SCROLL;
-                               return new DefaultInformationControl(parent, shellStyle, style,
-                                               new HTMLTextPresenter(false));
-                               // return new HoverBrowserControl(parent);
-                       }
-               };
-       }
-       /**
-        * Returns the outline presenter control creator. The creator is a factory
-        * creating outline presenter controls for the given source viewer. This
-        * implementation always returns a creator for <code>JavaOutlineInformationControl</code>
-        * instances.
-        * 
-        * @param sourceViewer
-        *            the source viewer to be configured by this configuration
-        * @return an information control creator
-        * @since 2.1
-        */
-       private IInformationControlCreator getOutlinePresenterControlCreator(
-                       ISourceViewer sourceViewer) {
-               return new IInformationControlCreator() {
-                       public IInformationControl createInformationControl(Shell parent) {
-                               int shellStyle = SWT.RESIZE;
-                               int treeStyle = SWT.V_SCROLL | SWT.H_SCROLL;
-                               return new JavaOutlineInformationControl(parent, shellStyle,
-                                               treeStyle);
-                       }
-               };
-       }
-       /**
-        * Returns the outline presenter which will determine and shown information
-        * requested for the current cursor position.
-        * 
-        * @param sourceViewer
-        *            the source viewer to be configured by this configuration
-        * @param doCodeResolve
-        *            a boolean which specifies whether code resolve should be used
-        *            to compute the Java element
-        * @return an information presenter
-        * @since 2.1
-        */
-       public IInformationPresenter getOutlinePresenter(
-                       ISourceViewer sourceViewer, boolean doCodeResolve) {
-               InformationPresenter presenter = new InformationPresenter(
-                               getOutlinePresenterControlCreator(sourceViewer));
-               presenter.setAnchor(InformationPresenter.ANCHOR_GLOBAL);
-               IInformationProvider provider = new JavaElementProvider(getEditor(),
-                               doCodeResolve);
-               presenter.setInformationProvider(provider,
-                               IDocument.DEFAULT_CONTENT_TYPE);
-               presenter.setInformationProvider(provider,
-                               IPHPPartitions.PHP_PARTITIONING);
-               presenter.setInformationProvider(provider,
-                               IPHPPartitions.PHP_PHPDOC_COMMENT);
-               presenter.setInformationProvider(provider,
-                               IPHPPartitions.SMARTY_MULTILINE_COMMENT);
-               presenter.setInformationProvider(provider,
-                               IPHPPartitions.HTML);
-               presenter.setInformationProvider(provider,
-                               IPHPPartitions.HTML_MULTILINE_COMMENT);
-               presenter.setSizeConstraints(40, 20, true, false);
-               return presenter;
-       }
-}
index 7be2787..7ce2ef1 100644 (file)
@@ -70,7 +70,8 @@ public class PHPTextHover implements ITextHover {
             // elbuffer.getHoverText());
             //            }
           }
-          String hoverInfo = (String) functionDescriptions.get(word);
+          String hoverInfo = 
+            (String) functionDescriptions.get(word);
           if (hoverInfo == null && fProject != null) {
             // get the possible PHPDoc information from the index file
             IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault()
@@ -82,8 +83,14 @@ public class PHPTextHover implements ITextHover {
                 String filename;
                 FileReader phpdocFileReader;
                 StringBuffer hoverInfoBuffer = new StringBuffer();
-                String workspaceLocation = PHPeclipsePlugin.getWorkspace()
-                    .getRoot().getLocation().toString();
+                String workspaceLocation;
+                if (fProject!=null) {
+                  workspaceLocation = fProject.getLocation().toString()+'/';
+                } else {
+                  // should never happen?
+                  workspaceLocation = PHPeclipsePlugin.getWorkspace()
+                  .getRoot().getLocation().toString();
+                }
                 //                boolean foundPHPdoc = false;
                 for (int i = 0; i < list.size(); i++) {
                   location = (PHPIdentifierLocation) list.get(i);
index a7cc596..f37c360 100644 (file)
@@ -19,6 +19,7 @@ import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference;
 import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
 import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
 import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager;
+import net.sourceforge.phpdt.internal.ui.text.SmartSemicolonAutoEditStrategy;
 import net.sourceforge.phpdt.internal.ui.text.java.IJavaReconcilingListener;
 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionManager;
 import net.sourceforge.phpdt.internal.ui.text.link.LinkedPositionUI;
@@ -48,6 +49,7 @@ import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.PreferenceConverter;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IAutoEditStrategy;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.ILineTracker;
 import org.eclipse.jface.text.IRegion;
@@ -498,18 +500,28 @@ public class PHPUnitEditor extends PHPEditor { //implements
       return super.requestWidgetToken(requester);
     }
 
-    /*
-     * @see org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
-     */
+//    /*
+//     * @see org.eclipse.jface.text.source.ISourceViewer#configure(org.eclipse.jface.text.source.SourceViewerConfiguration)
+//     */
+//    public void configure(SourceViewerConfiguration configuration) {
+//      super.configure(configuration);
+//      //                             fCorrectionAssistant= new
+//      // JavaCorrectionAssistant(CompilationUnitEditor.this);
+//      //                             fCorrectionAssistant.install(this);
+//      //TODO install SmartBracesAutoEditStrategy
+//      //                             prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this),
+//      // IDocument.DEFAULT_CONTENT_TYPE);
+//    }
     public void configure(SourceViewerConfiguration configuration) {
-      super.configure(configuration);
-      //                               fCorrectionAssistant= new
-      // JavaCorrectionAssistant(CompilationUnitEditor.this);
-      //                               fCorrectionAssistant.install(this);
-      //TODO install SmartBracesAutoEditStrategy
-      //                               prependAutoEditStrategy(new SmartBracesAutoEditStrategy(this),
-      // IDocument.DEFAULT_CONTENT_TYPE);
-    }
+               super.configure(configuration);
+//             fCorrectionAssistant= new JavaCorrectionAssistant(CompilationUnitEditor.this);
+//             fCorrectionAssistant.install(this);
+               IAutoEditStrategy smartSemi= new SmartSemicolonAutoEditStrategy(IPHPPartitions.PHP_PARTITIONING);
+               prependAutoEditStrategy(smartSemi, IDocument.DEFAULT_CONTENT_TYPE);
+               prependAutoEditStrategy(smartSemi, IPHPPartitions.PHP_STRING_DQ);
+               prependAutoEditStrategy(smartSemi, IPHPPartitions.PHP_STRING_SQ);
+//             prependAutoEditStrategy(smartSemi, IPHPPartitions.JAVA_CHARACTER);
+       }
   };
   /**
         * Remembers data related to the current selection to be able to
index 7e4c33c..e995bef 100644 (file)
@@ -4,8 +4,8 @@ import java.io.StringWriter;
 import java.util.HashSet;
 import java.util.Set;
 
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
-import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
 
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jface.text.source.SourceViewer;
index 2781272..0a52a0e 100644 (file)
@@ -1,6 +1,6 @@
 package net.sourceforge.phpeclipse.phpeditor.html;
 
-import net.sourceforge.phpeclipse.phpeditor.PHPSourceViewerConfiguration;
+import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
 
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/DefaultPHPPartitioner_delete_it.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/DefaultPHPPartitioner_delete_it.java
new file mode 100644 (file)
index 0000000..d746edd
--- /dev/null
@@ -0,0 +1,845 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DefaultPositionUpdater;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.IDocumentPartitionerExtension;
+import org.eclipse.jface.text.IDocumentPartitionerExtension2;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TypedPosition;
+import org.eclipse.jface.text.TypedRegion;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+
+/**
+ * A standard implementation of a document partitioner. It uses a partition token scanner to scan the document and to determine the
+ * document's partitioning. The tokens returned by the scanner are supposed to return the partition type as their data. The
+ * partitioner remembers the document's partitions in the document itself rather than maintaining its own data structure.
+ * 
+ * @see IPartitionTokenScanner
+ * @since 2.0
+ */
+public class DefaultPHPPartitioner_delete_it implements IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2 {
+
+  /**
+   * The position category this partitioner uses to store the document's partitioning information.
+   * 
+   * @deprecated As of 3.0, use <code>getManagingPositionCategories()</code> instead.
+   */
+  public final static String CONTENT_TYPES_CATEGORY = "__content_types_category"; //$NON-NLS-1$
+
+  /** The HTML areas partitioner's scanner */
+  protected IPartitionTokenScanner fHTMLScanner;
+
+  /** The PHP areas partitioner's scanner */
+  protected IPartitionTokenScanner fPHPScanner;
+
+  /** The legal content types of both partitioners */
+  protected String[] fLegalContentTypes;
+
+  /** The legal content types of the HTML partitioner */
+  protected String[] fLegalHTMLContentTypes;
+
+  /** The legal content types of the PHP partitioner */
+  protected String[] fLegalPHPContentTypes;
+
+  /** The partitioner's document */
+  protected IDocument fDocument;
+
+  /** The document length before a document change occurred */
+  protected int fPreviousDocumentLength;
+
+  /** The position updater used to for the default updating of partitions */
+  protected DefaultPositionUpdater fPositionUpdater;
+
+  /** The offset at which the first changed partition starts */
+  protected int fStartOffset;
+
+  /** The offset at which the last changed partition ends */
+  protected int fEndOffset;
+
+  /** The offset at which a partition has been deleted */
+  protected int fDeleteOffset;
+
+  /**
+   * The position category this partitioner uses to store the document's partitioning information.
+   * 
+   * @since 3.0
+   */
+  private String fPositionCategory;
+
+  /**
+   * Creates a new partitioner that uses the given scanner and may return partitions of the given legal content types.
+   * 
+   * @param scanner
+   *          the scanner this partitioner is supposed to use
+   * @param legalContentTypes
+   *          the legal content types of this partitioner
+   */
+  public DefaultPHPPartitioner_delete_it(IPartitionTokenScanner htmlScanner, IPartitionTokenScanner phpScanner, String[] legalContentTypes,
+      String[] legalHTMLContentTypes, String[] legalPHPContentTypes) {
+    fHTMLScanner = htmlScanner;
+    fPHPScanner = phpScanner;
+    fLegalContentTypes = legalContentTypes;
+    fLegalHTMLContentTypes = legalHTMLContentTypes;
+    fLegalPHPContentTypes = legalPHPContentTypes;
+
+    fPositionCategory = CONTENT_TYPES_CATEGORY + hashCode();
+    fPositionUpdater = new DefaultPositionUpdater(fPositionCategory);
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories()
+   * @since 3.0
+   */
+  public String[] getManagingPositionCategories() {
+    return new String[] { fPositionCategory };
+  }
+
+  /*
+   * @see IDocumentPartitioner#connect(IDocument)
+   */
+  public void connect(IDocument document) {
+    Assert.isNotNull(document);
+    Assert.isTrue(!document.containsPositionCategory(fPositionCategory));
+
+    fDocument = document;
+    fDocument.addPositionCategory(fPositionCategory);
+
+    initialize(fDocument.getLength());
+  }
+
+  /**
+   * Performs the initial partitioning of the partitioner's document.
+   */
+  protected void initialize(int initialLength) {
+    char ch;
+    boolean htmlMode = true;
+    int startPosition = 0;
+    int length = 0;
+    int i = 0;
+    try {
+      
+      while (i < initialLength) {
+        ch = fDocument.getChar(i++);
+        if (htmlMode) {
+          if (ch == '<' && fDocument.getChar(i) == '?' && fDocument.getChar(i + 1) == ' ') {
+            length = i - startPosition - 1;
+            if (length != 0) {
+              initializeHTML(startPosition, length);
+              startPosition = i - 1;
+            }
+            htmlMode = false;
+          } else if (ch == '<' && fDocument.getChar(i) == '?'
+              && (fDocument.getChar(i + 1) == 'p' || fDocument.getChar(i + 1) == 'P')
+              && (fDocument.getChar(i + 2) == 'h' || fDocument.getChar(i + 2) == 'H')
+              && (fDocument.getChar(i + 3) == 'p' || fDocument.getChar(i + 3) == 'P')) {
+            length = i - startPosition - 1;
+            if (length != 0) {
+              initializeHTML(startPosition, length);
+              startPosition = i - 1;
+            }
+            htmlMode = false;
+          }
+        } else {
+          switch (ch) {
+          case '"': // double quoted string
+            // read until end of double quoted string
+            while (i < fDocument.getLength()) {
+              if (fDocument.getChar(i++) == '"') {
+                if (fDocument.getChar(i - 2) != '\\') {
+                  break;
+                }
+              }
+            }
+            break;
+          case '\'': // single quoted string
+            // read until end of single quoted string
+            while (i < fDocument.getLength()) {
+              if (fDocument.getChar(i++) == '\'') {
+                if (fDocument.getChar(i - 2) != '\\') {
+                  break;
+                }
+              }
+            }
+            break;
+          case '/': // line comment
+            if (fDocument.getChar(i) == '/') {
+              i++;
+              // read until end of line
+              while (i < fDocument.getLength()) {
+                if (fDocument.getChar(i++) == '\n') {
+                  break;
+                }
+              }
+            } else if (fDocument.getChar(i) == '*') {
+              i++;
+              // read until end of comment
+              while (i < fDocument.getLength()) {
+                if (fDocument.getChar(i++) == '*') {
+                  if (i < fDocument.getLength()) {
+                    if (fDocument.getChar(i) == '/') {
+                      break;
+                    }
+                  }
+                }
+              }
+            }
+            break;
+          case '#': // line comment
+            // read until end of line
+            while (i < fDocument.getLength()) {
+              if (fDocument.getChar(i++) == '\n') {
+                break;
+              }
+            }
+            break;
+          case '?':
+            if (fDocument.getChar(i) == '>') {
+              length = i - startPosition + 1;
+              if (length != 0) {
+                initializePHP(startPosition, length);
+                startPosition = i + 1;
+              }
+              htmlMode = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (BadLocationException x) {
+      // can happen but ignored
+    } finally {
+      if (startPosition<fDocument.getLength()) {
+        length = fDocument.getLength()-startPosition;
+        if (htmlMode) {
+          initializeHTML(startPosition, length);
+        } else {
+          initializePHP(startPosition, length);
+        }
+      }
+    }
+  }
+
+  protected void initializeHTML(int startOffset, int length) {
+
+    fHTMLScanner.setRange(fDocument, startOffset, length);
+
+    try {
+      IToken token = fHTMLScanner.nextToken();
+      while (!token.isEOF()) {
+
+        String contentType = getTokenContentType(token);
+
+        if (isSupportedHTMLContentType(contentType)) {
+          TypedPosition p = new TypedPosition(fHTMLScanner.getTokenOffset(), fHTMLScanner.getTokenLength(), contentType);
+          fDocument.addPosition(fPositionCategory, p);
+        }
+
+        token = fHTMLScanner.nextToken();
+      }
+    } catch (BadLocationException x) {
+      // cannot happen as offsets come from scanner
+    } catch (BadPositionCategoryException x) {
+      // cannot happen if document has been connected before
+    }
+  }
+
+  protected void initializePHP(int startOffset, int length) {
+
+    fPHPScanner.setRange(fDocument, startOffset, length);
+
+    try {
+      IToken token = fPHPScanner.nextToken();
+      while (!token.isEOF()) {
+
+        String contentType = getTokenContentType(token);
+
+        if (isSupportedHTMLContentType(contentType)) {
+          TypedPosition p = new TypedPosition(fPHPScanner.getTokenOffset(), fPHPScanner.getTokenLength(), contentType);
+          fDocument.addPosition(fPositionCategory, p);
+        }
+
+        token = fPHPScanner.nextToken();
+      }
+    } catch (BadLocationException x) {
+      // cannot happen as offsets come from scanner
+    } catch (BadPositionCategoryException x) {
+      // cannot happen if document has been connected before
+    }
+  }
+
+  /*
+   * @see IDocumentPartitioner#disconnect()
+   */
+  public void disconnect() {
+
+    Assert.isTrue(fDocument.containsPositionCategory(fPositionCategory));
+
+    try {
+      fDocument.removePositionCategory(fPositionCategory);
+    } catch (BadPositionCategoryException x) {
+      // can not happen because of Assert
+    }
+  }
+
+  /*
+   * @see IDocumentPartitioner#documentAboutToBeChanged(DocumentEvent)
+   */
+  public void documentAboutToBeChanged(DocumentEvent e) {
+
+    Assert.isTrue(e.getDocument() == fDocument);
+
+    fPreviousDocumentLength = e.getDocument().getLength();
+    fStartOffset = -1;
+    fEndOffset = -1;
+    fDeleteOffset = -1;
+  }
+
+  /*
+   * @see IDocumentPartitioner#documentChanged(DocumentEvent)
+   */
+  public boolean documentChanged(DocumentEvent e) {
+    IRegion region = documentChanged2(e);
+    return (region != null);
+  }
+
+  /**
+   * Helper method for tracking the minimal region containing all partition changes. If <code>offset</code> is smaller than the
+   * remembered offset, <code>offset</code> will from now on be remembered. If <code>offset  + length</code> is greater than the
+   * remembered end offset, it will be remembered from now on.
+   * 
+   * @param offset
+   *          the offset
+   * @param length
+   *          the length
+   */
+  private void rememberRegion(int offset, int length) {
+    // remember start offset
+    if (fStartOffset == -1)
+      fStartOffset = offset;
+    else if (offset < fStartOffset)
+      fStartOffset = offset;
+
+    // remember end offset
+    int endOffset = offset + length;
+    if (fEndOffset == -1)
+      fEndOffset = endOffset;
+    else if (endOffset > fEndOffset)
+      fEndOffset = endOffset;
+  }
+
+  /**
+   * Remembers the given offset as the deletion offset.
+   * 
+   * @param offset
+   *          the offset
+   */
+  private void rememberDeletedOffset(int offset) {
+    fDeleteOffset = offset;
+  }
+
+  /**
+   * Creates the minimal region containing all partition changes using the remembered offset, end offset, and deletion offset.
+   * 
+   * @return the minimal region containing all the partition changes
+   */
+  private IRegion createRegion() {
+    if (fDeleteOffset == -1) {
+      if (fStartOffset == -1 || fEndOffset == -1)
+        return null;
+      return new Region(fStartOffset, fEndOffset - fStartOffset);
+    } else if (fStartOffset == -1 || fEndOffset == -1) {
+      return new Region(fDeleteOffset, 0);
+    } else {
+      int offset = Math.min(fDeleteOffset, fStartOffset);
+      int endOffset = Math.max(fDeleteOffset, fEndOffset);
+      return new Region(offset, endOffset - offset);
+    }
+  }
+
+  /*
+   * @see IDocumentPartitionerExtension#documentChanged2(DocumentEvent)
+   * @since 2.0
+   */
+  public IRegion documentChanged2(DocumentEvent e) {
+
+    try {
+
+      IDocument d = e.getDocument();
+      Position[] category = d.getPositions(fPositionCategory);
+      IRegion line = d.getLineInformationOfOffset(e.getOffset());
+      int reparseStart = line.getOffset();
+      int partitionStart = -1;
+      String contentType = null;
+      int newLength = e.getText() == null ? 0 : e.getText().length();
+
+      int first = d.computeIndexInCategory(fPositionCategory, reparseStart);
+      if (first > 0) {
+        TypedPosition partition = (TypedPosition) category[first - 1];
+        if (partition.includes(reparseStart)) {
+          partitionStart = partition.getOffset();
+          contentType = partition.getType();
+          if (e.getOffset() == partition.getOffset() + partition.getLength())
+            reparseStart = partitionStart;
+          --first;
+        } else if (reparseStart == e.getOffset() && reparseStart == partition.getOffset() + partition.getLength()) {
+          partitionStart = partition.getOffset();
+          contentType = partition.getType();
+          reparseStart = partitionStart;
+          --first;
+        } else {
+          partitionStart = partition.getOffset() + partition.getLength();
+          contentType = IDocument.DEFAULT_CONTENT_TYPE;
+        }
+      }
+
+      fPositionUpdater.update(e);
+      for (int i = first; i < category.length; i++) {
+        Position p = category[i];
+        if (p.isDeleted) {
+          rememberDeletedOffset(e.getOffset());
+          break;
+        }
+      }
+      category = d.getPositions(fPositionCategory);
+
+      
+      fHTMLScanner.setPartialRange(d, reparseStart, d.getLength() - reparseStart, contentType, partitionStart);
+
+      int lastScannedPosition = reparseStart;
+      IToken token = fHTMLScanner.nextToken();
+
+      while (!token.isEOF()) {
+
+        contentType = getTokenContentType(token);
+
+        if (!isSupportedContentType(contentType)) {
+          token = fHTMLScanner.nextToken();
+          continue;
+        }
+
+        int start = fHTMLScanner.getTokenOffset();
+        int length = fHTMLScanner.getTokenLength();
+
+        lastScannedPosition = start + length - 1;
+
+        // remove all affected positions
+        while (first < category.length) {
+          TypedPosition p = (TypedPosition) category[first];
+          if (lastScannedPosition >= p.offset + p.length
+              || (p.overlapsWith(start, length) && (!d.containsPosition(fPositionCategory, start, length) || !contentType.equals(p
+                  .getType())))) {
+
+            rememberRegion(p.offset, p.length);
+            d.removePosition(fPositionCategory, p);
+            ++first;
+
+          } else
+            break;
+        }
+
+        // if position already exists and we have scanned at least the
+        // area covered by the event, we are done
+        if (d.containsPosition(fPositionCategory, start, length)) {
+          if (lastScannedPosition >= e.getOffset() + newLength)
+            return createRegion();
+          ++first;
+        } else {
+          // insert the new type position
+          try {
+            d.addPosition(fPositionCategory, new TypedPosition(start, length, contentType));
+            rememberRegion(start, length);
+          } catch (BadPositionCategoryException x) {
+          } catch (BadLocationException x) {
+          }
+        }
+
+        token = fHTMLScanner.nextToken();
+      }
+
+      // remove all positions behind lastScannedPosition since there aren't any further types
+      if (lastScannedPosition != reparseStart) {
+        // if this condition is not met, nothing has been scanned because of a deletion
+        ++lastScannedPosition;
+      }
+      first = d.computeIndexInCategory(fPositionCategory, lastScannedPosition);
+
+      TypedPosition p;
+      while (first < category.length) {
+        p = (TypedPosition) category[first++];
+        d.removePosition(fPositionCategory, p);
+        rememberRegion(p.offset, p.length);
+      }
+
+    } catch (BadPositionCategoryException x) {
+      // should never happen on connected documents
+    } catch (BadLocationException x) {
+    }
+
+    return createRegion();
+  }
+
+  /**
+   * Returns the position in the partitoner's position category which is close to the given offset. This is, the position has either
+   * an offset which is the same as the given offset or an offset which is smaller than the given offset. This method profits from
+   * the knowledge that a partitioning is a ordered set of disjoint position.
+   * 
+   * @param offset
+   *          the offset for which to search the closest position
+   * @return the closest position in the partitioner's category
+   */
+  protected TypedPosition findClosestPosition(int offset) {
+
+    try {
+
+      int index = fDocument.computeIndexInCategory(fPositionCategory, offset);
+      Position[] category = fDocument.getPositions(fPositionCategory);
+
+      if (category.length == 0)
+        return null;
+
+      if (index < category.length) {
+        if (offset == category[index].offset)
+          return (TypedPosition) category[index];
+      }
+
+      if (index > 0)
+        index--;
+
+      return (TypedPosition) category[index];
+
+    } catch (BadPositionCategoryException x) {
+    } catch (BadLocationException x) {
+    }
+
+    return null;
+  }
+
+  /*
+   * @see IDocumentPartitioner#getContentType(int)
+   */
+  public String getContentType(int offset) {
+
+    TypedPosition p = findClosestPosition(offset);
+    if (p != null && p.includes(offset))
+      return p.getType();
+
+    return IDocument.DEFAULT_CONTENT_TYPE;
+  }
+
+  /*
+   * @see IDocumentPartitioner#getPartition(int)
+   */
+  public ITypedRegion getPartition(int offset) {
+
+    try {
+
+      Position[] category = fDocument.getPositions(fPositionCategory);
+
+      if (category == null || category.length == 0)
+        return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+
+      int index = fDocument.computeIndexInCategory(fPositionCategory, offset);
+
+      if (index < category.length) {
+
+        TypedPosition next = (TypedPosition) category[index];
+
+        if (offset == next.offset)
+          return new TypedRegion(next.getOffset(), next.getLength(), next.getType());
+
+        if (index == 0)
+          return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE);
+
+        TypedPosition previous = (TypedPosition) category[index - 1];
+        if (previous.includes(offset))
+          return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType());
+
+        int endOffset = previous.getOffset() + previous.getLength();
+        return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE);
+      }
+
+      TypedPosition previous = (TypedPosition) category[category.length - 1];
+      if (previous.includes(offset))
+        return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType());
+
+      int endOffset = previous.getOffset() + previous.getLength();
+      return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE);
+
+    } catch (BadPositionCategoryException x) {
+    } catch (BadLocationException x) {
+    }
+
+    return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+  }
+
+  /*
+   * @see IDocumentPartitioner#computePartitioning(int, int)
+   */
+  public ITypedRegion[] computePartitioning(int offset, int length) {
+    return computePartitioning(offset, length, false);
+  }
+
+  /*
+   * @see IDocumentPartitioner#getLegalContentTypes()
+   */
+  public String[] getLegalContentTypes() {
+    return fLegalContentTypes;
+  }
+
+  public String[] getLegalHTMLContentTypes() {
+    return fLegalHTMLContentTypes;
+  }
+
+  public String[] getLegalPHPContentTypes() {
+    return fLegalPHPContentTypes;
+  }
+
+  /**
+   * Returns whether the given type is one of the legal content types.
+   * 
+   * @param contentType
+   *          the content type to check
+   * @return <code>true</code> if the content type is a legal content type
+   */
+  protected boolean isSupportedContentType(String contentType) {
+    if (contentType != null) {
+      for (int i = 0; i < fLegalContentTypes.length; i++) {
+        if (fLegalHTMLContentTypes[i].equals(contentType))
+          return true;
+      }
+    }
+
+    return false;
+  }
+  
+  /**
+   * Returns whether the given type is one of the legal content types.
+   * 
+   * @param contentType
+   *          the content type to check
+   * @return <code>true</code> if the content type is a legal content type
+   */
+  protected boolean isSupportedHTMLContentType(String contentType) {
+    if (contentType != null) {
+      for (int i = 0; i < fLegalHTMLContentTypes.length; i++) {
+        if (fLegalHTMLContentTypes[i].equals(contentType))
+          return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Returns whether the given type is one of the legal content types.
+   * 
+   * @param contentType
+   *          the content type to check
+   * @return <code>true</code> if the content type is a legal content type
+   */
+  protected boolean isSupportedPHPContentType(String contentType) {
+    if (contentType != null) {
+      for (int i = 0; i < fLegalHTMLContentTypes.length; i++) {
+        if (fLegalHTMLContentTypes[i].equals(contentType))
+          return true;
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Returns a content type encoded in the given token. If the token's data is not <code>null</code> and a string it is assumed
+   * that it is the encoded content type.
+   * 
+   * @param token
+   *          the token whose content type is to be determined
+   * @return the token's content type
+   */
+  protected String getTokenContentType(IToken token) {
+    Object data = token.getData();
+    if (data instanceof String)
+      return (String) data;
+    return null;
+  }
+
+  /* zero-length partition support */
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#getContentType(int)
+   * @since 3.0
+   */
+  public String getContentType(int offset, boolean preferOpenPartitions) {
+    return getPartition(offset, preferOpenPartitions).getType();
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#getPartition(int)
+   * @since 3.0
+   */
+  public ITypedRegion getPartition(int offset, boolean preferOpenPartitions) {
+    ITypedRegion region = getPartition(offset);
+    if (preferOpenPartitions) {
+      if (region.getOffset() == offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) {
+        if (offset > 0) {
+          region = getPartition(offset - 1);
+          if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE))
+            return region;
+        }
+        return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE);
+      }
+    }
+    return region;
+  }
+
+  /*
+   * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#computePartitioning(int, int, boolean)
+   * @since 3.0
+   */
+  public ITypedRegion[] computePartitioning(int offset, int length, boolean includeZeroLengthPartitions) {
+    List list = new ArrayList();
+
+    try {
+
+      int endOffset = offset + length;
+
+      Position[] category = fDocument.getPositions(fPositionCategory);
+
+      TypedPosition previous = null, current = null;
+      int start, end, gapOffset;
+      Position gap = new Position(0);
+
+      int startIndex = getFirstIndexEndingAfterOffset(category, offset);
+      int endIndex = getFirstIndexStartingAfterOffset(category, endOffset);
+      for (int i = startIndex; i < endIndex; i++) {
+
+        current = (TypedPosition) category[i];
+
+        gapOffset = (previous != null) ? previous.getOffset() + previous.getLength() : 0;
+        gap.setOffset(gapOffset);
+        gap.setLength(current.getOffset() - gapOffset);
+        if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length))
+            || (gap.getLength() > 0 && gap.overlapsWith(offset, length))) {
+          start = Math.max(offset, gapOffset);
+          end = Math.min(endOffset, gap.getOffset() + gap.getLength());
+          list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE));
+        }
+
+        if (current.overlapsWith(offset, length)) {
+          start = Math.max(offset, current.getOffset());
+          end = Math.min(endOffset, current.getOffset() + current.getLength());
+          list.add(new TypedRegion(start, end - start, current.getType()));
+        }
+
+        previous = current;
+      }
+
+      if (previous != null) {
+        gapOffset = previous.getOffset() + previous.getLength();
+        gap.setOffset(gapOffset);
+        gap.setLength(fDocument.getLength() - gapOffset);
+        if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length))
+            || (gap.getLength() > 0 && gap.overlapsWith(offset, length))) {
+          start = Math.max(offset, gapOffset);
+          end = Math.min(endOffset, fDocument.getLength());
+          list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE));
+        }
+      }
+
+      if (list.isEmpty())
+        list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE));
+
+    } catch (BadPositionCategoryException x) {
+    }
+
+    TypedRegion[] result = new TypedRegion[list.size()];
+    list.toArray(result);
+    return result;
+  }
+
+  /**
+   * Returns <code>true</code> if the given ranges overlap with or touch each other.
+   * 
+   * @param gap
+   *          the first range
+   * @param offset
+   *          the offset of the second range
+   * @param length
+   *          the length of the second range
+   * @return <code>true</code> if the given ranges overlap with or touch each other
+   * @since 3.0
+   */
+  private boolean overlapsOrTouches(Position gap, int offset, int length) {
+    return gap.getOffset() <= offset + length && offset <= gap.getOffset() + gap.getLength();
+  }
+
+  /**
+   * Returns the index of the first position which ends after the given offset.
+   * 
+   * @param positions
+   *          the positions in linear order
+   * @param offset
+   *          the offset
+   * @return the index of the first position which ends after the offset
+   * 
+   * @since 3.0
+   */
+  private int getFirstIndexEndingAfterOffset(Position[] positions, int offset) {
+    int i = -1, j = positions.length;
+    while (j - i > 1) {
+      int k = (i + j) >> 1;
+      Position p = positions[k];
+      if (p.getOffset() + p.getLength() > offset)
+        j = k;
+      else
+        i = k;
+    }
+    return j;
+  }
+
+  /**
+   * Returns the index of the first position which starts at or after the given offset.
+   * 
+   * @param positions
+   *          the positions in linear order
+   * @param offset
+   *          the offset
+   * @return the index of the first position which starts after the offset
+   * 
+   * @since 3.0
+   */
+  private int getFirstIndexStartingAfterOffset(Position[] positions, int offset) {
+    int i = -1, j = positions.length;
+    while (j - i > 1) {
+      int k = (i + j) >> 1;
+      Position p = positions[k];
+      if (p.getOffset() >= offset)
+        j = k;
+      else
+        i = k;
+    }
+    return j;
+  }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLPartitionScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/HTMLPartitionScanner.java
new file mode 100644 (file)
index 0000000..26a0bcf
--- /dev/null
@@ -0,0 +1,436 @@
+/**
+ * This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * Created on 05.03.2003
+ *
+ * @author Stefan Langer (musk)
+ * @version $Revision: 1.1 $
+ */
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.ui.text.*;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+
+/**
+ * 
+ */
+public class HTMLPartitionScanner implements IPartitionTokenScanner {
+  private static final boolean DEBUG = false;
+
+  private boolean fInString = false;
+  private boolean fInDoubString = false;
+  private IDocument fDocument = null;
+  private int fOffset = -1;
+  private String fContentType = IPHPPartitions.HTML;
+  private String fPrevContentType = IPHPPartitions.HTML;
+  private boolean partitionBorder = false;
+  private int fTokenOffset;
+  private int fEnd = -1;
+  private int fLength;
+  private int fCurrentLength;
+  private int fFileType;
+  private Map tokens = new HashMap();
+
+  public HTMLPartitionScanner() {
+       this(IPHPPartitions.PHP_FILE);
+  }
+  
+  public HTMLPartitionScanner(int fileType) {
+    this.tokens.put(IPHPPartitions.HTML, new Token(IPHPPartitions.HTML));
+    this.tokens.put(
+      IPHPPartitions.HTML_MULTILINE_COMMENT,
+      new Token(IPHPPartitions.HTML_MULTILINE_COMMENT));
+
+    this.tokens.put(IPHPPartitions.SMARTY, new Token(IPHPPartitions.SMARTY));
+    this.tokens.put(
+      IPHPPartitions.SMARTY_MULTILINE_COMMENT,
+      new Token(IPHPPartitions.SMARTY_MULTILINE_COMMENT));
+
+    this.tokens.put(IDocument.DEFAULT_CONTENT_TYPE, new Token(IDocument.DEFAULT_CONTENT_TYPE));
+    fFileType = fileType;
+  }
+
+  private IToken getToken(String type) {
+    fLength = fCurrentLength;
+    if (DEBUG) {
+
+      try {
+        if (fLength <= 0) {
+          int line = fDocument.getLineOfOffset(fOffset);
+          System.err.println("Error at " + line + " offset:" + String.valueOf(fOffset - fDocument.getLineOffset(line)));
+        }
+      } catch (BadLocationException e) { // should never happen
+        // TODO Write stacktrace to log
+        e.printStackTrace();
+      }
+    }
+    Assert.isTrue(fLength > 0, "Partition length <= 0!");
+    fCurrentLength = 0;
+    // String can never cross partition borders so reset string detection
+    fInString = false;
+    fInDoubString = false;
+    IToken token = (IToken) this.tokens.get(type);
+    Assert.isNotNull(token, "Token for type \"" + type + "\" not found!");
+    if (DEBUG) {
+      System.out.println("Partition: fTokenOffset=" + fTokenOffset + " fContentType=" + type + " fLength=" + fLength);
+    }
+    return token;
+  }
+
+  /* (non-Javadoc)
+   * @see org.eclipse.jface.text.rules.IPartitionTokenScanner#setPartialRange(org.eclipse.jface.text.IDocument, int, int, java.lang.String, int)
+   */
+  public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
+    if (DEBUG) {
+      System.out.println("*****");
+      System.out.println("PartialRange: contentType=" + contentType + " partitionOffset=" + partitionOffset);
+    }
+
+    try {
+      if (partitionOffset > -1) {
+        partitionBorder = false;
+        // because of strings we have to parse the whole partition
+        this.setRange(document, partitionOffset, offset - partitionOffset + length);
+        // sometimes we get a wrong partition so we retrieve the partition
+        // directly from the document
+        fContentType = fDocument.getContentType(partitionOffset);
+      } else
+        this.setRange(document, offset, length);
+
+    } catch (BadLocationException e) {
+      // should never happen
+      // TODO print stack trace to log
+      // fall back just scan the whole document again
+      this.setRange(document, 0, fDocument.getLength());
+    }
+
+  }
+
+  /* (non-Javadoc)
+   * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
+   */
+  public int getTokenLength() {
+    return fLength;
+  }
+
+  /* (non-Javadoc)
+   * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
+   */
+  public int getTokenOffset() {
+    return fTokenOffset;
+  }
+
+  /* (non-Javadoc)
+   * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
+   */
+  public IToken nextToken() {
+    int c;
+
+    // check if we are not allready at the end of the
+    // file
+    if ((c = read()) == ICharacterScanner.EOF) {
+      partitionBorder = false;
+      return Token.EOF;
+    } else
+      unread();
+
+    if (partitionBorder) {
+      fTokenOffset = fOffset;
+      partitionBorder = false;
+    }
+
+    while ((c = read()) != ICharacterScanner.EOF) {
+      switch (c) {
+        case '<' :
+          if ( checkPattern(new char[] { '!', '-', '-' })) { // return previouse partition
+            if (fContentType != IPHPPartitions.HTML_MULTILINE_COMMENT && fCurrentLength > 4) {
+              unread(4);
+              IToken token = getToken(fContentType);
+              fContentType = IPHPPartitions.HTML_MULTILINE_COMMENT;
+              return token;
+            } else
+              fContentType = IPHPPartitions.HTML_MULTILINE_COMMENT;
+
+            fTokenOffset = fOffset - 4;
+            fCurrentLength = 4;
+          }
+          break;
+        case '-' :
+          if (fContentType == IPHPPartitions.HTML_MULTILINE_COMMENT
+            && checkPattern(new char[] { '-', '>' })) {
+            fContentType = IPHPPartitions.HTML;
+            partitionBorder = true;
+            return getToken(IPHPPartitions.HTML_MULTILINE_COMMENT);
+          }
+          break;
+        case '{' : // SMARTY code starts here ?
+          if (fFileType == IPHPPartitions.SMARTY_FILE) {
+            if ((c = read()) == '*') {
+              if (DEBUG) {
+                System.out.println(
+                  "SMARTYDOC_TOKEN start "
+                    + fTokenOffset
+                    + " fContentType="
+                    + fContentType
+                    + " fLength="
+                    + fLength
+                    + " fOffset="
+                    + fOffset
+                    + " fCurrentLength="
+                    + fCurrentLength);
+              }
+              if (fContentType != IPHPPartitions.SMARTY_MULTILINE_COMMENT && fCurrentLength > 2) {
+                // SMARTY doc code starts here 
+                unread(2);
+                IToken token = getToken(fContentType);
+                fContentType = IPHPPartitions.SMARTY_MULTILINE_COMMENT;
+                return token;
+                //              } else if (fContentType == IPHPPartitionScannerConstants.HTML && fOffset == 2) {
+                //                fContentType = IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT;
+              } else { // if (fContentType == IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT) {
+                fContentType = IPHPPartitions.SMARTY_MULTILINE_COMMENT;
+                fTokenOffset = fOffset - 2;
+                fCurrentLength = 2;
+              }
+              break;
+            }
+            if (DEBUG) {
+              System.out.println(
+                "SMARTY_TOKEN start "
+                  + fTokenOffset
+                  + " fContentType="
+                  + fContentType
+                  + " fLength="
+                  + fLength
+                  + " fOffset="
+                  + fOffset);
+            }
+            if (c != ICharacterScanner.EOF) {
+               unread();
+            }
+            if (fContentType != IPHPPartitions.SMARTY && fCurrentLength > 1) {
+              unread(1);
+              IToken token = getToken(fContentType);
+              fContentType = IPHPPartitions.SMARTY;
+              return token;
+              //            } else if (fContentType == IPHPPartitionScannerConstants.HTML && fOffset==1) {
+              //              fContentType = IPHPPartitionScannerConstants.SMARTY;
+            } else {
+              fContentType = IPHPPartitions.SMARTY;
+              fTokenOffset = fOffset - 1;
+              fCurrentLength = 1;
+            }
+          }
+          break;
+        case '}' : // SMARTY code ends here ?
+          if (fFileType == IPHPPartitions.SMARTY_FILE && fContentType == IPHPPartitions.SMARTY) {
+            if (DEBUG) {
+              System.out.println(
+                "SMARTY_TOKEN end "
+                  + fTokenOffset
+                  + " fContentType="
+                  + fContentType
+                  + " fLength="
+                  + fLength
+                  + " fOffset="
+                  + fOffset);
+            }
+            fContentType = IPHPPartitions.HTML;
+            partitionBorder = true;
+            return getToken(IPHPPartitions.SMARTY);
+          }
+          break;
+//        case '/' :
+//          if (!isInString(IPHPPartitions.PHP_PARTITIONING) && (c = read()) == '*') { // MULTINE COMMENT JAVASCRIPT, CSS, PHP
+//            if (fContentType == IPHPPartitions.PHP_PARTITIONING && fCurrentLength > 2) {
+//              unread(2);
+//              IToken token = getToken(fContentType);
+//              fContentType = IPHPPartitions.PHP_PHPDOC_COMMENT;
+//              return token;
+//            } else if (fContentType == IPHPPartitions.PHP_PHPDOC_COMMENT) {
+//              fTokenOffset = fOffset - 2;
+//              fCurrentLength = 2;
+//            }
+//
+//          } else if (!isInString(IPHPPartitions.PHP_PARTITIONING) && c != ICharacterScanner.EOF)
+//            unread();
+//          break;
+        case '*' :
+          if (fFileType == IPHPPartitions.SMARTY_FILE && (c = read()) == '}') {
+            if (DEBUG) {
+              System.out.println(
+                "SMARTYDOC_TOKEN end "
+                  + fTokenOffset
+                  + " fContentType="
+                  + fContentType
+                  + " fLength="
+                  + fLength
+                  + " fOffset="
+                  + fOffset);
+            }
+            if (fContentType == IPHPPartitions.SMARTY_MULTILINE_COMMENT) {
+              fContentType = IPHPPartitions.HTML;
+              partitionBorder = true;
+              return getToken(IPHPPartitions.SMARTY_MULTILINE_COMMENT);
+            }
+          } 
+          break;
+        case '\'' :
+          if (!fInDoubString)
+            fInString = !fInString;
+          break;
+        case '"' :
+          // toggle String mode
+          if (!fInString)
+            fInDoubString = !fInDoubString;
+          break;
+      }
+    } // end of file reached but we have to return the
+    // last partition.
+    return getToken(fContentType);
+  }
+  /* (non-Javadoc)
+   * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(org.eclipse.jface.text.IDocument, int, int)
+   */
+  public void setRange(IDocument document, int offset, int length) {
+    if (DEBUG) {
+      System.out.println("SET RANGE: offset=" + offset + " length=" + length);
+    }
+
+    fDocument = document;
+    fOffset = offset;
+    fTokenOffset = offset;
+    fCurrentLength = 0;
+    fLength = 0;
+    fEnd = fOffset + length;
+    fInString = false;
+    fInDoubString = false;
+    fContentType = IPHPPartitions.HTML;
+    //        String[] prev = getPartitionStack(offset);
+  }
+
+  private int read() {
+    try {
+      if (fOffset < fEnd) {
+        fCurrentLength++;
+        return fDocument.getChar(fOffset++);
+      }
+      return ICharacterScanner.EOF;
+    } catch (BadLocationException e) {
+      // should never happen
+      // TODO write stacktrace to log
+      fOffset = fEnd;
+      return ICharacterScanner.EOF;
+    }
+  }
+
+  private void unread() {
+    --fOffset;
+    --fCurrentLength;
+  }
+
+  private void unread(int num) {
+    fOffset -= num;
+    fCurrentLength -= num;
+  }
+
+  private boolean checkPattern(char[] pattern) {
+    return checkPattern(pattern, false);
+  }
+
+  /**
+   * Check if next character sequence read from document is equals to 
+   * the provided pattern. Pattern is read from left to right until the 
+   * first character read doesn't match. If this happens all read characters are
+   * unread.
+   * @param pattern The pattern to check.
+   * @return <code>true</code> if pattern is equals else returns <code>false</code>.
+   */
+  private boolean checkPattern(char[] pattern, boolean ignoreCase) {
+    int prevOffset = fOffset;
+    int prevLength = fCurrentLength;
+    for (int i = 0; i < pattern.length; i++) {
+      int c = read();
+
+      if (c == ICharacterScanner.EOF || !letterEquals(c, pattern[i], ignoreCase)) {
+        fOffset = prevOffset;
+        fCurrentLength = prevLength;
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  private boolean letterEquals(int test, char letter, boolean ignoreCase) {
+    if (test == letter)
+      return true;
+    else if (ignoreCase && Character.isLowerCase(letter) && test == Character.toUpperCase(letter))
+      return true;
+    else if (ignoreCase && Character.isUpperCase(letter) && test == Character.toLowerCase(letter))
+      return true;
+
+    return false;
+  }
+
+  /**
+   * Checks wether the offset is in a <code>String</code> and the specified 
+   * contenttype is the current content type.
+   * Strings are delimited, mutual exclusive, by a " or by a '.
+   * 
+   * @param contentType The contenttype to check.
+   * @return <code>true</code> if the current offset is in a string else 
+   *                   returns false.
+   */
+  private boolean isInString(String contentType) {
+    if (fContentType == contentType)
+      return (fInString || fInDoubString);
+    else
+      return false;
+  }
+
+  /**
+   * Returns the previouse partition stack for the given offset.
+   * 
+   * @param offset The offset to return the previouse partitionstack for.
+   * 
+   * @return The stack as a string array.
+   */
+  private String[] getPartitionStack(int offset) {
+    ArrayList types = new ArrayList();
+    int tmpOffset = 0;
+    try {
+      ITypedRegion region = fDocument.getPartition(offset);
+      tmpOffset = region.getOffset();
+      while (tmpOffset - 1 > 0) {
+        region = fDocument.getPartition(tmpOffset - 1);
+        tmpOffset = region.getOffset();
+        types.add(0, region.getType());
+      }
+    } catch (BadLocationException e) {
+      if (DEBUG) {
+        e.printStackTrace();
+      }
+    }
+
+    String[] retVal = new String[types.size()];
+
+    retVal = (String[]) types.toArray(retVal);
+    return retVal;
+  }
+
+}
index 0e657f7..5e324f1 100644 (file)
@@ -15,7 +15,6 @@ import java.util.ArrayList;
 import java.util.List;
 
 import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
-import net.sourceforge.phpdt.internal.ui.text.CombinedWordRule;
 import net.sourceforge.phpdt.ui.text.IColorManager;
 import net.sourceforge.phpeclipse.IPreferenceConstants;
 import net.sourceforge.phpeclipse.phpeditor.PHPSyntaxRdr;
@@ -428,8 +427,8 @@ public class PHPCodeScanner extends AbstractJavaScanner {
     wordRule.addWord("return", token);
 
 //  Add rule for operators and brackets (at the end !)
-       token= getToken(IPreferenceConstants.PHP_OPERATOR);
-       rules.add(new OperatorRule(token));
+       token= getToken(IPreferenceConstants.PHP_OPERATOR);
+       rules.add(new OperatorRule(token));
        
     rules.add(wordRule);
     
index a38b36d..8ea69f7 100644 (file)
@@ -589,7 +589,7 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
           IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault()
               .getIndexManager(project);
           SortedMap sortedMap = indexManager.getIdentifierMap();
-          declarationEngine = new DeclarationEngine(contextType,
+          declarationEngine = new DeclarationEngine(project, contextType,
               lastSignificantToken, file);
           declarationEngine.complete(viewer, offset, sortedMap);
           declarationResults = declarationEngine.getResults();
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDocumentPartitioner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDocumentPartitioner.java
new file mode 100644 (file)
index 0000000..c408f3b
--- /dev/null
@@ -0,0 +1,93 @@
+/**********************************************************************
+Copyright (c) 2002  Widespace, OU  and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://solareclipse.sourceforge.net/legal/cpl-v10.html
+
+Contributors:
+       Igor Malinin - initial contribution
+
+$Id: PHPDocumentPartitioner.java,v 1.1 2004-09-02 18:32:34 jsurfer Exp $
+**********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.ui.text.rules.FlatNode;
+import net.sourceforge.phpeclipse.ui.text.rules.MultiViewPartitioner;
+import net.sourceforge.phpeclipse.ui.text.rules.ViewNode;
+
+import org.eclipse.jface.text.Assert;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.IPartitionTokenScanner;
+
+
+/**
+ * 
+ * 
+ * @author Igor Malinin
+ */
+public class PHPDocumentPartitioner extends MultiViewPartitioner {
+       public static final String PHP_TEMPLATE_DATA = "__php_template_data";
+       public static final String PHP_SCRIPT_CODE = "__php_script_code";
+
+       private IPartitionTokenScanner scriptScanner;
+
+       public PHPDocumentPartitioner(
+               IPartitionTokenScanner scanner, IPartitionTokenScanner scriptScanner
+       ) {
+               super(scanner);
+
+               this.scriptScanner = scriptScanner;
+       }
+
+       protected FlatNode createNode(String type, int offset, int length) {
+               if (type.equals(PHPPartitionScanner.PHP_SCRIPTING_AREA) 
+               ) {
+                   if (DEBUG) {
+                     Assert.isTrue(offset>=0);
+                   }
+                       ViewNode node = new ViewNode(type);
+                       node.offset = offset;
+                       node.length = length;
+                       return node;
+               }
+
+               return super.createNode(type, offset, length);
+       }
+
+       /*
+        * @see net.sf.solareclipse.text.rules.DocumentViewPartitioner#createPartitioner(String)
+        */
+       protected IDocumentPartitioner createPartitioner(String contentType) {
+               if (contentType == null) {
+//                     return JavaTextTools.createHTMLPartitioner();
+                       return PHPeclipsePlugin.getDefault().getJavaTextTools()
+                       .getXMLTextTools().createXMLPartitioner();
+               }
+             
+               if (contentType.equals(PHPPartitionScanner.PHP_SCRIPTING_AREA)
+               ) {
+                       return PHPeclipsePlugin.getDefault().getJavaTextTools().createPHPPartitioner();
+               }
+               return null;
+       }
+
+       /*
+        * @see net.sf.solareclipse.text.rules.DocumentViewPartitioner#getContentType(String, String)
+        */
+       protected String getContentType(String parent, String view) {
+               if (parent == null) {
+                       if (view == IDocument.DEFAULT_CONTENT_TYPE) {
+                               return PHP_TEMPLATE_DATA;
+                       }
+               } else {
+                       if (view == IDocument.DEFAULT_CONTENT_TYPE) {
+                               return PHP_SCRIPT_CODE;
+                       }
+               }
+
+               return super.getContentType(parent, view);
+       }
+}
index 2cb2eb9..8d0de49 100644 (file)
@@ -1,25 +1,26 @@
-/**
- * This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * Created on 05.03.2003
- *
- * @author Stefan Langer (musk)
- * @version $Revision: 1.24 $
- */
+/**********************************************************************
+ Copyright (c) 2002  Widespace, OU  and others.
+ All rights reserved.   This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://solareclipse.sourceforge.net/legal/cpl-v10.html
+
+ Contributors:
+ Igor Malinin - initial contribution
+
+ $Id: PHPPartitionScanner.java,v 1.25 2004-09-02 18:32:34 jsurfer Exp $
+ **********************************************************************/
 package net.sourceforge.phpeclipse.phpeditor.php;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
-import net.sourceforge.phpdt.internal.ui.text.*;
+import net.sourceforge.phpeclipse.ui.text.rules.AbstractPartitioner;
 
+import org.eclipse.core.internal.indexing.AbstractPagePolicy;
 import org.eclipse.jface.text.Assert;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.ITypedRegion;
 import org.eclipse.jface.text.rules.ICharacterScanner;
 import org.eclipse.jface.text.rules.IPartitionTokenScanner;
 import org.eclipse.jface.text.rules.IToken;
@@ -27,478 +28,362 @@ import org.eclipse.jface.text.rules.Token;
 
 /**
  * 
+ * 
+ * @author Igor Malinin
  */
 public class PHPPartitionScanner implements IPartitionTokenScanner {
-  private static final boolean DEBUG = false;
-
-  private boolean fInString = false;
-  private boolean fInDoubString = false;
-  private IDocument fDocument = null;
-  private int fOffset = -1;
-  private String fContentType = IPHPPartitions.HTML;
-  private String fPrevContentType = IPHPPartitions.HTML;
-  private boolean partitionBorder = false;
-  private int fTokenOffset;
-  private int fEnd = -1;
-  private int fLength;
-  private int fCurrentLength;
-  private int fFileType;
-  private Map tokens = new HashMap();
+  //   public static final String JSP_DIRECTIVE = "__jsp_directive";
+  //   public static final String JSP_COMMENT = "__jsp_comment";
+  //// public static final String JSP_TAG = "__jsp_tag";
+  //   public static final String JSP_DECLARATION = "__jsp_declaration";
+  public static final String PHP_SCRIPTING_AREA = "__php_scripting_area ";
 
-  public PHPPartitionScanner() {
-       this(IPHPPartitions.PHP_FILE);
-  }
-  
-  public PHPPartitionScanner(int fileType) {
-    this.tokens.put(IPHPPartitions.PHP_PARTITIONING, new Token(IPHPPartitions.PHP_PARTITIONING));
-    this.tokens.put(IPHPPartitions.PHP_STRING_DQ, new Token(IPHPPartitions.PHP_STRING_DQ));
-    this.tokens.put(
-      IPHPPartitions.PHP_PHPDOC_COMMENT,
-      new Token(IPHPPartitions.PHP_PHPDOC_COMMENT));
-    this.tokens.put(IPHPPartitions.HTML, new Token(IPHPPartitions.HTML));
-    this.tokens.put(
-      IPHPPartitions.HTML_MULTILINE_COMMENT,
-      new Token(IPHPPartitions.HTML_MULTILINE_COMMENT));
-
-    this.tokens.put(IPHPPartitions.SMARTY, new Token(IPHPPartitions.SMARTY));
-    this.tokens.put(
-      IPHPPartitions.SMARTY_MULTILINE_COMMENT,
-      new Token(IPHPPartitions.SMARTY_MULTILINE_COMMENT));
-
-    this.tokens.put(IDocument.DEFAULT_CONTENT_TYPE, new Token(IDocument.DEFAULT_CONTENT_TYPE));
-    fFileType = fileType;
-  }
+  //   public static final String JSP_EXPRESSION = "__jsp_expression";
 
-  private IToken getToken(String type) {
-    fLength = fCurrentLength;
-    if (DEBUG) {
+  public static final int STATE_DEFAULT = 0;
 
-      try {
-        if (fLength <= 0) {
-          int line = fDocument.getLineOfOffset(fOffset);
-          System.err.println("Error at " + line + " offset:" + String.valueOf(fOffset - fDocument.getLineOffset(line)));
-        }
-      } catch (BadLocationException e) { // should never happen
-        // TODO Write stacktrace to log
-        e.printStackTrace();
-      }
-    }
-    Assert.isTrue(fLength > 0, "Partition length <= 0!");
-    fCurrentLength = 0;
-    // String can never cross partition borders so reset string detection
-    fInString = false;
-    fInDoubString = false;
-    IToken token = (IToken) this.tokens.get(type);
-    Assert.isNotNull(token, "Token for type \"" + type + "\" not found!");
-    if (DEBUG) {
-      System.out.println("Partition: fTokenOffset=" + fTokenOffset + " fContentType=" + type + " fLength=" + fLength);
-    }
-    return token;
-  }
+  //   public static final int STATE_TAG = 1;
+  //   public static final int STATE_SCRIPT = 2;
 
-  /* (non-Javadoc)
-   * @see org.eclipse.jface.text.rules.IPartitionTokenScanner#setPartialRange(org.eclipse.jface.text.IDocument, int, int, java.lang.String, int)
-   */
-  public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
-    if (DEBUG) {
-      System.out.println("*****");
-      System.out.println("PartialRange: contentType=" + contentType + " partitionOffset=" + partitionOffset);
-    }
+  private IDocument document;
 
-    try {
-      if (partitionOffset > -1) {
-        partitionBorder = false;
-        // because of strings we have to parse the whole partition
-        this.setRange(document, partitionOffset, offset - partitionOffset + length);
-        // sometimes we get a wrong partition so we retrieve the partition
-        // directly from the document
-        fContentType = fDocument.getContentType(partitionOffset);
-      } else
-        this.setRange(document, offset, length);
+  private int begin;
 
-    } catch (BadLocationException e) {
-      // should never happen
-      // TODO print stack trace to log
-      // fall back just scan the whole document again
-      this.setRange(document, 0, fDocument.getLength());
-    }
+  private int end;
 
-  }
+  private int offset;
 
-  /* (non-Javadoc)
-   * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
-   */
-  public int getTokenLength() {
-    return fLength;
-  }
+  private int length;
 
-  /* (non-Javadoc)
-   * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
-   */
-  public int getTokenOffset() {
-    return fTokenOffset;
+  private int position;
+
+  private int state;
+
+  private Map tokens = new HashMap();
+
+  public PHPPartitionScanner() {
   }
 
-  /* (non-Javadoc)
+  /*
    * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
    */
   public IToken nextToken() {
-    int c;
+    offset += length;
+
+    /*
+     * switch (state) { case STATE_TAG: return nextTagToken(); }
+     */
+
+    switch (read()) {
+    case ICharacterScanner.EOF:
+      state = STATE_DEFAULT;
+      return getToken(null);
+
+    case '<':
+      switch (read()) {
+      case ICharacterScanner.EOF:
+        state = STATE_DEFAULT;
+        return getToken(null);
+
+      case '?': // <%SCRIPLET <%@DIRECTIVE <%!DECLARATION <%=EXPRESSION <%--COMMENT
+        int ch = read();
+        //                                              if (Character.isWhitespace((char)ch)) {
+        //                                                return nextJSPToken(PHP_SCRIPTING_AREA);
+        //                                              }
+        switch (ch) {
+        case ICharacterScanner.EOF:
+          state = STATE_DEFAULT;
+          return getToken(PHP_SCRIPTING_AREA);
+
+        //                                                     case '-': // <%- <%--COMMENT
+        //                                                             switch (read()) {
+        //                                                                     case ICharacterScanner.EOF:
+        //                                                                     case '-': // <%--
+        //                                                                             return nextCommentToken();
+        //                                                             }
+        //
+        //                                                             break;
+        }
 
-    // check if we are not allready at the end of the
-    // file
-    if ((c = read()) == ICharacterScanner.EOF) {
-      partitionBorder = false;
-      return Token.EOF;
-    } else
-      unread();
+        return scanUntilPHPEndToken(PHP_SCRIPTING_AREA);
+      }
 
-    if (partitionBorder) {
-      fTokenOffset = fOffset;
-      partitionBorder = false;
+      unread();
     }
 
-    while ((c = read()) != ICharacterScanner.EOF) {
-      switch (c) {
-        case '<' :
-          if (!isInString(IPHPPartitions.PHP_PARTITIONING)
-            && fContentType != IPHPPartitions.PHP_PHPDOC_COMMENT
-            && checkPattern(new char[] { '?', 'p', 'h', 'p' }, true)) {
-            if (fContentType != IPHPPartitions.PHP_PARTITIONING && fCurrentLength > 5) {
-              unread(5);
-              IToken token = getToken(fContentType);
-              // save previouse contenttype
-              //TODO build stack for previouse contenttype 
-              fPrevContentType = fContentType;
-
-              fContentType = IPHPPartitions.PHP_PARTITIONING;
-
-              return token;
-            } else
-              fContentType = IPHPPartitions.PHP_PARTITIONING;
-
-            // remember offset of this partition
-            fTokenOffset = fOffset - 5;
-            fCurrentLength = 5;
-          } else if (
-            !isInString(IPHPPartitions.PHP_PARTITIONING)
-              && fContentType != IPHPPartitions.PHP_PHPDOC_COMMENT
-              && checkPattern(new char[] { '?' }, false)) {
-            if (fContentType != IPHPPartitions.PHP_PARTITIONING && fCurrentLength > 2) {
-              unread(2);
-              IToken token = getToken(fContentType);
-              // save previouse contenttype
-              fPrevContentType = fContentType;
-              fContentType = IPHPPartitions.PHP_PARTITIONING;
-              return token;
-            } else
-              fContentType = IPHPPartitions.PHP_PARTITIONING;
-            // remember offset of this partition
-            fTokenOffset = fOffset - 2;
-            fCurrentLength = 2;
-          } else if (
-            !isInString(IPHPPartitions.PHP_PARTITIONING)
-              && (fContentType != IPHPPartitions.PHP_PARTITIONING) // BUG #769044
-              && (fContentType != IPHPPartitions.PHP_PHPDOC_COMMENT) // BUG #769044
-              && checkPattern(new char[] { '!', '-', '-' })) { // return previouse partition
-            if (fContentType != IPHPPartitions.HTML_MULTILINE_COMMENT && fCurrentLength > 4) {
-              unread(4);
-              IToken token = getToken(fContentType);
-              fContentType = IPHPPartitions.HTML_MULTILINE_COMMENT;
-              return token;
-            } else
-              fContentType = IPHPPartitions.HTML_MULTILINE_COMMENT;
-
-            fTokenOffset = fOffset - 4;
-            fCurrentLength = 4;
-          }
-          break;
-        case '?' :
-          if (!isInString(IPHPPartitions.PHP_PARTITIONING) && fContentType == IPHPPartitions.PHP_PARTITIONING) {
-            if ((c = read()) == '>') {
-              if (fPrevContentType != null)
-                fContentType = fPrevContentType;
-              else
-                fContentType = IPHPPartitions.HTML;
-              partitionBorder = true;
-              return getToken(IPHPPartitions.PHP_PARTITIONING);
-            } else if (c != ICharacterScanner.EOF)
-              unread();
-          }
-          break;
-        case '-' :
-          if (!isInString(IPHPPartitions.PHP_PARTITIONING)
-            && fContentType == IPHPPartitions.HTML_MULTILINE_COMMENT
-            && checkPattern(new char[] { '-', '>' })) {
-            fContentType = IPHPPartitions.HTML;
-            partitionBorder = true;
-            return getToken(IPHPPartitions.HTML_MULTILINE_COMMENT);
-          }
-          break;
-        case '{' : // SMARTY code starts here ?
-          if (fFileType == IPHPPartitions.SMARTY_FILE) {
-            if ((c = read()) == '*') {
-              if (DEBUG) {
-                System.out.println(
-                  "SMARTYDOC_TOKEN start "
-                    + fTokenOffset
-                    + " fContentType="
-                    + fContentType
-                    + " fLength="
-                    + fLength
-                    + " fOffset="
-                    + fOffset
-                    + " fCurrentLength="
-                    + fCurrentLength);
-              }
-              if (fContentType != IPHPPartitions.SMARTY_MULTILINE_COMMENT && fCurrentLength > 2) {
-                // SMARTY doc code starts here 
-                unread(2);
-                IToken token = getToken(fContentType);
-                fContentType = IPHPPartitions.SMARTY_MULTILINE_COMMENT;
-                return token;
-                //              } else if (fContentType == IPHPPartitionScannerConstants.HTML && fOffset == 2) {
-                //                fContentType = IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT;
-              } else { // if (fContentType == IPHPPartitionScannerConstants.SMARTY_MULTILINE_COMMENT) {
-                fContentType = IPHPPartitions.SMARTY_MULTILINE_COMMENT;
-                fTokenOffset = fOffset - 2;
-                fCurrentLength = 2;
-              }
-              break;
-            }
-            if (DEBUG) {
-              System.out.println(
-                "SMARTY_TOKEN start "
-                  + fTokenOffset
-                  + " fContentType="
-                  + fContentType
-                  + " fLength="
-                  + fLength
-                  + " fOffset="
-                  + fOffset);
-            }
-            if (c != ICharacterScanner.EOF) {
-               unread();
-            }
-            if (fContentType != IPHPPartitions.SMARTY && fCurrentLength > 1) {
-              unread(1);
-              IToken token = getToken(fContentType);
-              fContentType = IPHPPartitions.SMARTY;
-              return token;
-              //            } else if (fContentType == IPHPPartitionScannerConstants.HTML && fOffset==1) {
-              //              fContentType = IPHPPartitionScannerConstants.SMARTY;
-            } else {
-              fContentType = IPHPPartitions.SMARTY;
-              fTokenOffset = fOffset - 1;
-              fCurrentLength = 1;
-            }
-          }
-          break;
-        case '}' : // SMARTY code ends here ?
-          if (fFileType == IPHPPartitions.SMARTY_FILE && fContentType == IPHPPartitions.SMARTY) {
-            if (DEBUG) {
-              System.out.println(
-                "SMARTY_TOKEN end "
-                  + fTokenOffset
-                  + " fContentType="
-                  + fContentType
-                  + " fLength="
-                  + fLength
-                  + " fOffset="
-                  + fOffset);
-            }
-            fContentType = IPHPPartitions.HTML;
-            partitionBorder = true;
-            return getToken(IPHPPartitions.SMARTY);
-          }
-          break;
-        case '/' :
-          if (!isInString(IPHPPartitions.PHP_PARTITIONING) && (c = read()) == '*') { // MULTINE COMMENT JAVASCRIPT, CSS, PHP
-            if (fContentType == IPHPPartitions.PHP_PARTITIONING && fCurrentLength > 2) {
-              unread(2);
-              IToken token = getToken(fContentType);
-              fContentType = IPHPPartitions.PHP_PHPDOC_COMMENT;
-              return token;
-            } else if (fContentType == IPHPPartitions.PHP_PHPDOC_COMMENT) {
-              fTokenOffset = fOffset - 2;
-              fCurrentLength = 2;
-            }
-
-          } else if (!isInString(IPHPPartitions.PHP_PARTITIONING) && c != ICharacterScanner.EOF)
-            unread();
+    loop: while (true) {
+      switch (read()) {
+      case ICharacterScanner.EOF:
+        state = STATE_DEFAULT;
+        return getToken(null);
+
+      case '<':
+        switch (read()) {
+        case ICharacterScanner.EOF:
+          state = STATE_DEFAULT;
+          return getToken(null);
+
+        case '?':
+          unread();
           break;
-        case '*' :
-          if (!isInString(IPHPPartitions.PHP_PARTITIONING) && (c = read()) == '/') {
-            if (fContentType == IPHPPartitions.PHP_PHPDOC_COMMENT) {
-              fContentType = IPHPPartitions.PHP_PARTITIONING;
-              partitionBorder = true;
-              return getToken(IPHPPartitions.PHP_PHPDOC_COMMENT);
-            } else if (fContentType == IPHPPartitions.CSS_MULTILINE_COMMENT) {
-            } else if (fContentType == IPHPPartitions.JS_MULTILINE_COMMENT) {
-            }
-          } else if (fFileType == IPHPPartitions.SMARTY_FILE && (c = read()) == '}') {
-            if (DEBUG) {
-              System.out.println(
-                "SMARTYDOC_TOKEN end "
-                  + fTokenOffset
-                  + " fContentType="
-                  + fContentType
-                  + " fLength="
-                  + fLength
-                  + " fOffset="
-                  + fOffset);
-            }
-            if (fContentType == IPHPPartitions.SMARTY_MULTILINE_COMMENT) {
-              fContentType = IPHPPartitions.HTML;
-              partitionBorder = true;
-              return getToken(IPHPPartitions.SMARTY_MULTILINE_COMMENT);
-            }
-          } else if (!isInString(IPHPPartitions.PHP_PARTITIONING) && c != ICharacterScanner.EOF) {
-            unread();
-          }
+
+        case '<':
+          unread();
+
+        default:
+          continue loop;
+        }
+
+        unread();
+
+        state = STATE_DEFAULT;
+        return getToken(null);
+      }
+    }
+  }
+
+  private IToken scanUntilPHPEndToken(String token) {
+    int ch = read();
+    while (true) {
+      switch (ch) {
+      case ICharacterScanner.EOF:
+        state = STATE_DEFAULT;
+        return getToken(token);
+      case '"': // double quoted string
+        // read until end of double quoted string
+        readUntilEscaped('"');
+        break;
+      case '\'': // single quoted string
+        // read until end of single quoted string
+        readUntilEscaped('\'');
+        break;
+      case '/': // comment start?
+        ch = read();
+        switch (ch) {
+        case ICharacterScanner.EOF:
           break;
-        case '\'' :
-          if (!fInDoubString)
-            fInString = !fInString;
+        case '/':
+          // read until end of line
+          readSingleLine();
           break;
-        case '"' :
-          // toggle String mode
-          if (!fInString)
-            fInDoubString = !fInDoubString;
+        case '*':
+          // read until end of comment
+          readMultiLineComment();
           break;
+        default:
+          continue;
+        }
+        break;
+      case '#': // line comment
+        // read until end of line
+        readSingleLine();
+        break;
+      case '?':
+        ch = read();
+        switch (ch) {
+        case ICharacterScanner.EOF:
+        case '>':
+          state = STATE_DEFAULT;
+          return getToken(token);
+
+        case '?':
+          continue;
+        }
       }
-    } // end of file reached but we have to return the
-    // last partition.
-    return getToken(fContentType);
+
+      ch = read();
+    }
   }
-  /* (non-Javadoc)
-   * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(org.eclipse.jface.text.IDocument, int, int)
-   */
-  public void setRange(IDocument document, int offset, int length) {
-    if (DEBUG) {
-      System.out.println("SET RANGE: offset=" + offset + " length=" + length);
+
+  //   private IToken nextCommentToken() {
+  //           int ch = read();
+  //           loop: while (true) {
+  //                   switch (ch) {
+  //                           case ICharacterScanner.EOF:
+  //                                   break loop;
+  //
+  //                           case '-': // - --%>
+  //                                   ch = read();
+  //                                   switch (ch) {
+  //                                           case ICharacterScanner.EOF:
+  //                                                   break loop;
+  //
+  //                                           case '-': // -- --%>
+  //                                                   ch = read();
+  //                                                   switch (ch) {
+  //                                                           case ICharacterScanner.EOF:
+  //                                                                   break loop;
+  //
+  //                                                           case '%': // --% --%>
+  //                                                                   ch = read();
+  //                                                                   switch (ch) {
+  //                                                                           case ICharacterScanner.EOF:
+  //                                                                           case '>':
+  //                                                                                   break loop;
+  //                                                                   }
+  //
+  //                                                                   continue loop;
+  //
+  //                                                           case '-': // --- ---%>
+  //                                                                   unread();
+  //                                                                   continue loop;
+  //                                                   }
+  //
+  //                                                   ch = read();
+  //                                                   continue loop;
+  //                                   }
+  //                   }
+  //
+  //                   ch = read();
+  //           }
+  //
+  //           return getToken(JSP_COMMENT);
+  //   }
+
+  private IToken getToken(String type) {
+    length = position - offset;
+
+    if (length == 0) {
+      return Token.EOF;
+    }
+
+    if (type == null) {
+      return Token.UNDEFINED;
+    }
+
+    IToken token = (IToken) tokens.get(type);
+    if (token == null) {
+      token = new Token(type);
+      tokens.put(type, token);
     }
 
-    fDocument = document;
-    fOffset = offset;
-    fTokenOffset = offset;
-    fCurrentLength = 0;
-    fLength = 0;
-    fEnd = fOffset + length;
-    fInString = false;
-    fInDoubString = false;
-    fContentType = IPHPPartitions.HTML;
-    //        String[] prev = getPartitionStack(offset);
+    return token;
   }
 
   private int read() {
-    try {
-      if (fOffset < fEnd) {
-        fCurrentLength++;
-        return fDocument.getChar(fOffset++);
-      }
+    if (position >= end) {
       return ICharacterScanner.EOF;
+    }
+
+    try {
+      return document.getChar(position++);
     } catch (BadLocationException e) {
-      // should never happen
-      // TODO write stacktrace to log
-      fOffset = fEnd;
+      --position;
       return ICharacterScanner.EOF;
     }
   }
 
-  private void unread() {
-    --fOffset;
-    --fCurrentLength;
+  private void readUntilEscaped(char ch) {
+    if (position >= end) {
+      return;
+    }
+    try {
+      while (true) {
+        if (document.getChar(position++) == ch) {
+          if (position < 2 || document.getChar(position - 2) != '\\') {
+            break;
+          }
+        }
+      }
+    } catch (BadLocationException e) {
+      --position;
+      return;
+    }
   }
 
-  private void unread(int num) {
-    fOffset -= num;
-    fCurrentLength -= num;
-  }
+  private void readSingleLine() {
+    if (position >= end) {
+      return;
+    }
+    try {
+      while (document.getChar(position++) != '\n') {
 
-  private boolean checkPattern(char[] pattern) {
-    return checkPattern(pattern, false);
+      }
+    } catch (BadLocationException e) {
+      --position;
+      return;
+    }
   }
 
-  /**
-   * Check if next character sequence read from document is equals to 
-   * the provided pattern. Pattern is read from left to right until the 
-   * first character read doesn't match. If this happens all read characters are
-   * unread.
-   * @param pattern The pattern to check.
-   * @return <code>true</code> if pattern is equals else returns <code>false</code>.
-   */
-  private boolean checkPattern(char[] pattern, boolean ignoreCase) {
-    int prevOffset = fOffset;
-    int prevLength = fCurrentLength;
-    for (int i = 0; i < pattern.length; i++) {
-      int c = read();
-
-      if (c == ICharacterScanner.EOF || !letterEquals(c, pattern[i], ignoreCase)) {
-        fOffset = prevOffset;
-        fCurrentLength = prevLength;
-        return false;
+  private void readMultiLineComment() {
+    if (position >= end) {
+      return;
+    }
+    try {
+      char ch;
+      while (true) {
+        ch = document.getChar(position++);
+        if (ch == '*') {
+          if (document.getChar(position) == '/') {
+            position++;
+            break;
+          }
+        }
       }
+    } catch (BadLocationException e) {
+      --position;
+      return;
     }
-
-    return true;
   }
 
-  private boolean letterEquals(int test, char letter, boolean ignoreCase) {
-    if (test == letter)
-      return true;
-    else if (ignoreCase && Character.isLowerCase(letter) && test == Character.toUpperCase(letter))
-      return true;
-    else if (ignoreCase && Character.isUpperCase(letter) && test == Character.toLowerCase(letter))
-      return true;
+  private void unread() {
+    --position;
+  }
 
-    return false;
+  /*
+   * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
+   */
+  public int getTokenOffset() {
+    if (AbstractPartitioner.DEBUG) {
+      Assert.isTrue(offset >= 0, Integer.toString(offset));
+    }
+    return offset;
   }
 
-  /**
-   * Checks wether the offset is in a <code>String</code> and the specified 
-   * contenttype is the current content type.
-   * Strings are delimited, mutual exclusive, by a " or by a '.
-   * 
-   * @param contentType The contenttype to check.
-   * @return <code>true</code> if the current offset is in a string else 
-   *                   returns false.
+  /*
+   * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
    */
-  private boolean isInString(String contentType) {
-    if (fContentType == contentType)
-      return (fInString || fInDoubString);
-    else
-      return false;
+  public int getTokenLength() {
+    return length;
   }
 
-  /**
-   * Returns the previouse partition stack for the given offset.
-   * 
-   * @param offset The offset to return the previouse partitionstack for.
-   * 
-   * @return The stack as a string array.
+  /*
+   * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(IDocument, int, int)
    */
-  private String[] getPartitionStack(int offset) {
-    ArrayList types = new ArrayList();
-    int tmpOffset = 0;
-    try {
-      ITypedRegion region = fDocument.getPartition(offset);
-      tmpOffset = region.getOffset();
-      while (tmpOffset - 1 > 0) {
-        region = fDocument.getPartition(tmpOffset - 1);
-        tmpOffset = region.getOffset();
-        types.add(0, region.getType());
-      }
-    } catch (BadLocationException e) {
-      if (DEBUG) {
-        e.printStackTrace();
-      }
-    }
+  public void setRange(IDocument document, int offset, int length) {
+    this.document = document;
+    this.begin = offset;
+    this.end = offset + length;
 
-    String[] retVal = new String[types.size()];
+    this.offset = offset;
+    this.position = offset;
+    this.length = 0;
+  }
 
-    retVal = (String[]) types.toArray(retVal);
-    return retVal;
+  /*
+   * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
+   */
+  public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
+    state = STATE_DEFAULT;
+    //    if (partitionOffset > -1) {
+    //         int delta= offset - partitionOffset;
+    //         if (delta > 0) {
+    //                 this.setRange(document, partitionOffset, length + delta);
+    //                 return;
+    //         }
+    // }
+    setRange(document, partitionOffset, length);
   }
 
-}
+  //   private boolean isContinuationPartition(IDocument document, int offset) {
+  //           try {
+  //                   String type = document.getContentType(offset - 1);
+  //
+  //                   if (type != IDocument.DEFAULT_CONTENT_TYPE) {
+  //                           return true;
+  //                   }
+  //           } catch (BadLocationException e) {}
+  //
+  //           return false;
+  //   }
+}
\ No newline at end of file
index f97ae34..7363fd9 100644 (file)
@@ -9,13 +9,14 @@
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package net.sourceforge.phpeclipse.views.browser;
+import net.sourceforge.phpeclipse.webbrowser.internal.WebBrowser;
+import net.sourceforge.phpeclipse.webbrowser.internal.WebBrowserUIPlugin;
+import net.sourceforge.phpeclipse.webbrowser.internal.WebBrowserUtil;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.Browser;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.part.ViewPart;
-import org.eclipse.webbrowser.internal.WebBrowser;
-import org.eclipse.webbrowser.internal.WebBrowserUIPlugin;
-import org.eclipse.webbrowser.internal.WebBrowserUtil;
 /**
  * <code>BrowserView</code> is a simple demonstration of the SWT Browser
  * widget. It consists of a workbench view and tab folder where each tab in the