[326602] Auto activation does not work in javascript regions in webpages
[326817] [editor] Leading and trailing HTML style comments in a JS region are not syntax highlighted as expected
[326818] [validation] Text after HTML style comment in JavaScript region marked as validation error
diff --git a/bundles/org.eclipse.wst.jsdt.web.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.jsdt.web.ui/META-INF/MANIFEST.MF
index 6fee1c7..9f0c0e6 100644
--- a/bundles/org.eclipse.wst.jsdt.web.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.jsdt.web.ui/META-INF/MANIFEST.MF
@@ -2,11 +2,12 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name.0
 Bundle-SymbolicName: org.eclipse.wst.jsdt.web.ui; singleton:=true
-Bundle-Version: 1.0.302.qualifier
+Bundle-Version: 1.0.303.qualifier
 Bundle-Activator: org.eclipse.wst.jsdt.web.ui.internal.JsUIPlugin
 Bundle-Vendor: %Bundle-Vendor.0
 Bundle-Localization: plugin
 Export-Package: org.eclipse.wst.jsdt.web.ui;x-internal:=true,
+ org.eclipse.wst.jsdt.web.ui.contentassist,
  org.eclipse.wst.jsdt.web.ui.internal;x-internal:=true,
  org.eclipse.wst.jsdt.web.ui.internal.autoedit;x-internal:=true,
  org.eclipse.wst.jsdt.web.ui.internal.contentassist;x-internal:=true,
diff --git a/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/StructuredTextViewerConfigurationJSDT.java b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/StructuredTextViewerConfigurationJSDT.java
index a1d8070..825550e 100644
--- a/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/StructuredTextViewerConfigurationJSDT.java
+++ b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/StructuredTextViewerConfigurationJSDT.java
@@ -11,9 +11,12 @@
 package org.eclipse.wst.jsdt.web.ui;
 
 import org.eclipse.jface.text.IAutoEditStrategy;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
 import org.eclipse.jface.text.source.ISourceViewer;
 import org.eclipse.wst.html.core.text.IHTMLPartitions;
 import org.eclipse.wst.html.ui.StructuredTextViewerConfigurationHTML;
+import org.eclipse.wst.jsdt.web.core.text.IJsPartitions;
+import org.eclipse.wst.jsdt.web.ui.contentassist.JSDTStructuredContentAssistProcessor;
 import org.eclipse.wst.jsdt.web.ui.internal.autoedit.AutoEditStrategyForJs;
 
 /**
@@ -54,4 +57,32 @@
 			return super.getAutoEditStrategies(sourceViewer, contentType);
 		}
 	}
+	
+	/**
+	 * @see org.eclipse.wst.html.ui.StructuredTextViewerConfigurationHTML#getContentAssistProcessors(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
+	 */
+	protected IContentAssistProcessor[] getContentAssistProcessors(
+			ISourceViewer sourceViewer, String partitionType) {
+		
+		IContentAssistProcessor[] processors;
+		
+		if(isJavascriptPartitionType(partitionType)) {
+			IContentAssistProcessor processor = new JSDTStructuredContentAssistProcessor(
+					this.getContentAssistant(), partitionType, sourceViewer);
+			processors = new IContentAssistProcessor[]{processor};
+		} else {
+			processors = super.getContentAssistProcessors(sourceViewer, partitionType);
+		} 
+		
+		return processors;
+	}
+	
+	/**
+	 * @param partitionTypeID check to see if this partition type ID is for a Javascript partition type
+	 * @return <code>true</code> if the given partiton type is a Javascript partition type,
+	 * <code>false</code> otherwise
+	 */
+	private static boolean isJavascriptPartitionType(String partitionTypeID) {
+		return IJsPartitions.HtmlJsPartition.equals(partitionTypeID);
+	}
 }
diff --git a/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/contentassist/JSDTStructuredContentAssistProcessor.java b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/contentassist/JSDTStructuredContentAssistProcessor.java
new file mode 100644
index 0000000..f677cb4
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/contentassist/JSDTStructuredContentAssistProcessor.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.web.ui.contentassist;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.wst.jsdt.ui.PreferenceConstants;
+import org.eclipse.wst.sse.ui.contentassist.StructuredContentAssistProcessor;
+
+/**
+ * <p>Content assist processor for Javascript regions so that autoactivation will work in those regions.</p>
+ * 
+ * <p><b>NOTE:</b> This class does not check that the given partition type is a javascript region, it just
+ * assumes it is, so the instantiator of this class must be sure they want the given partition type to be
+ * treated as if it was Javascript.</p>
+ */
+public class JSDTStructuredContentAssistProcessor extends StructuredContentAssistProcessor {
+	/** auto activation characters */
+	private char[] fCompletionPropoaslAutoActivationCharacters;
+
+	/**
+	 * @param assistant {@link ContentAssistant} to use
+	 * @param partitionTypeID the Javascript partition type this processor is for
+	 * @param viewer {@link ITextViewer} this processor is acting in
+	 */
+	public JSDTStructuredContentAssistProcessor(ContentAssistant assistant,
+			String partitionTypeID, ITextViewer viewer) {
+		super(assistant, partitionTypeID, viewer, PreferenceConstants.getPreferenceStore());
+		
+		//get the current user preference
+		getAutoActivationCharacterPreferences();
+	}
+	
+	/**
+	 * @see org.eclipse.wst.sse.ui.contentassist.StructuredContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+	 */
+	public char[] getCompletionProposalAutoActivationCharacters() {
+		return this.fCompletionPropoaslAutoActivationCharacters;
+	}
+	
+	/**
+	 * @see org.eclipse.wst.sse.ui.contentassist.StructuredContentAssistProcessor#propertyChange(
+	 * 	org.eclipse.jface.util.PropertyChangeEvent)
+	 */
+	public void propertyChange(PropertyChangeEvent event) {
+		String property = event.getProperty();
+		if(property.equals(PreferenceConstants.CODEASSIST_AUTOACTIVATION) ||
+				property.equals(PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVA)) {
+			
+			getAutoActivationCharacterPreferences();
+		}
+	}
+	
+	/**
+	 * <p>Gets the auto activation character user preferences for Javascript and stores them for later use</p>
+	 */
+	private void getAutoActivationCharacterPreferences() {
+		IPreferenceStore store = getPreferenceStore();
+		
+		boolean doAuto = store.getBoolean(PreferenceConstants.CODEASSIST_AUTOACTIVATION);
+		if (doAuto) {
+			fCompletionPropoaslAutoActivationCharacters =
+				store.getString(PreferenceConstants.CODEASSIST_AUTOACTIVATION_TRIGGERS_JAVA).toCharArray();
+		} else {
+			fCompletionPropoaslAutoActivationCharacters = null;
+		}
+	}
+}
diff --git a/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/format/FormattingStrategyJSDT.java b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/format/FormattingStrategyJSDT.java
index 6ff69e0..6993d66 100644
--- a/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/format/FormattingStrategyJSDT.java
+++ b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/format/FormattingStrategyJSDT.java
@@ -56,14 +56,8 @@
 * (repeatedly) as the API evolves.
 */
 public class FormattingStrategyJSDT extends ContextBasedFormattingStrategy {
-	private static final String XML_COMMENT_START = "<!--"; //$NON-NLS-1$
-	private static final String XML_COMMENT_END = "//-->"; //$NON-NLS-1$
-	
-	/** matches on <!-- at beginning of script region */
-	private static final Pattern START_PATTERN = Pattern.compile("(\\A(\\s*<!--))");
-	
-	/** matches on //--> or --> at end of script region */
-	private static final Pattern END_PATTERN = Pattern.compile("(((//\\s*)?-->\\s*)\\z)");
+	/** matches on //--> at end of script region */
+	private static final Pattern END_PATTERN = Pattern.compile("((//.*-->\\s*)\\z)");
 	
 	private static final int regionStartIndentLevel = 1;
 	/** Documents to be formatted by this strategy */
@@ -114,17 +108,18 @@
 				String postText = lineDelim;
 
 				//find start comment tag
-				Matcher matcher = START_PATTERN.matcher(jsTextNotTranslated);
+				Pattern startPattern = Pattern.compile("(\\A(\\s*<!--.*(" + lineDelim + ")?))");
+				Matcher matcher = startPattern.matcher(jsTextNotTranslated);
 				if(matcher.find()) {
-					jsTextNotTranslated = matcher.replaceAll("");
-					preText = lineDelim + XML_COMMENT_START;
+					jsTextNotTranslated = matcher.replaceFirst("");
+					preText = lineDelim + matcher.group().trim();
 				}
 				
 				//find end tag
 				matcher = END_PATTERN.matcher(jsTextNotTranslated);
 				if(matcher.find()) {
-					jsTextNotTranslated = matcher.replaceAll("");
-					postText = lineDelim + XML_COMMENT_END + lineDelim;
+					jsTextNotTranslated = matcher.replaceFirst("");
+					postText = lineDelim + matcher.group().trim() + lineDelim;
 				}
 				
 				//replace the text in the document with the none-translated JS text but without HTML leading and trailing comments
diff --git a/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/IStyleConstantsJSDT.java b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/IStyleConstantsJSDT.java
index 625fec6..6ec51cb 100644
--- a/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/IStyleConstantsJSDT.java
+++ b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/IStyleConstantsJSDT.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -22,5 +22,6 @@
 	String JAVA_DEFAULT = "default"; //$NON-NLS-1$
 	String JAVA_KEYWORD = "keyword"; //$NON-NLS-1$
 	String JAVA_SINGLE_LINE_COMMENT = "single_line_comment"; //$NON-NLS-1$
+	String JAVA_MULTI_LINE_COMMENT = "multi_line_comment"; //$NON-NLS-1$
 	String JAVA_STRING = "string"; //$NON-NLS-1$
 }
diff --git a/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/JSDTCodeScanner.java b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/JSDTCodeScanner.java
index f74f1b0..d6d50e3 100644
--- a/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/JSDTCodeScanner.java
+++ b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/JSDTCodeScanner.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -14,13 +14,17 @@
 import java.util.List;
 
 import org.eclipse.jface.text.rules.EndOfLineRule;
+import org.eclipse.jface.text.rules.ICharacterScanner;
 import org.eclipse.jface.text.rules.IRule;
 import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
 import org.eclipse.jface.text.rules.MultiLineRule;
+import org.eclipse.jface.text.rules.PatternRule;
 import org.eclipse.jface.text.rules.SingleLineRule;
 import org.eclipse.jface.text.rules.Token;
 import org.eclipse.jface.text.rules.WordRule;
 import org.eclipse.wst.jsdt.web.core.javascript.JsDataTypes;
+import org.eclipse.wst.xml.ui.internal.style.IStyleConstantsXML;
 
 /**
 *
@@ -37,8 +41,10 @@
 	private IToken fDefaultToken;
 	private IToken fKeywordToken;
 	private IToken fSingleLineCommentToken;
+	private IToken fMultiLineCommentToken;
 	private IToken fStringToken;
 	private IToken fTypeToken;
+	private IToken fHTMLCommentBorderToken;
 	
 	/**
 	 * Creates a Java code scanner
@@ -50,9 +56,9 @@
 	public void initializeRules() {
 		List rules = new ArrayList();
 		// Add rule for multiple line comments.
-		rules.add(new MultiLineRule("/*", "*/", fSingleLineCommentToken));//$NON-NLS-1$ //$NON-NLS-2$
+		rules.add(new MultiLineRule("/*", "*/", fMultiLineCommentToken));//$NON-NLS-1$ //$NON-NLS-2$
 		// Add rule for single line comments.
-		rules.add(new EndOfLineRule("//", fSingleLineCommentToken));//$NON-NLS-1$
+		rules.add(new NoneInclusiveEndSequenceSingleLineRule("//", "-->", fSingleLineCommentToken));//$NON-NLS-1$
 		// Add rule for strings and character constants.
 		rules.add(new SingleLineRule("\"", "\"", fStringToken, '\\'));//$NON-NLS-2$//$NON-NLS-1$
 		rules.add(new SingleLineRule("'", "'", fStringToken, '\\'));//$NON-NLS-2$//$NON-NLS-1$
@@ -70,6 +76,13 @@
 			wordRule.addWord(JSDTCodeScanner.fgConstants[i], fTypeToken);
 		}
 		rules.add(wordRule);
+		
+		//add word rule for HTML style comment delimiters
+		rules.add(new WordRule(new HTMLCommentDetector(), this.fHTMLCommentBorderToken));
+		
+		//add rule for text after leading HTML comment delimiter
+		rules.add(new NoneInclusiveStartSequenceEndOfLineRule("<!--", this.fSingleLineCommentToken));
+		
 		IRule[] result = new IRule[rules.size()];
 		rules.toArray(result);
 		setRules(result);
@@ -83,8 +96,121 @@
 			fStringToken = new Token(data);
 		} else if (tokenKey == IStyleConstantsJSDT.JAVA_SINGLE_LINE_COMMENT) {
 			fSingleLineCommentToken = new Token(data);
+		} else if (tokenKey == IStyleConstantsJSDT.JAVA_MULTI_LINE_COMMENT) {
+			fMultiLineCommentToken = new Token(data);
 		} else if (tokenKey == IStyleConstantsJSDT.JAVA_DEFAULT) {
 			fDefaultToken = new Token(data);
+		} else if(tokenKey == IStyleConstantsXML.COMMENT_BORDER) {
+			fHTMLCommentBorderToken = new Token(data);
+		}
+	}
+	
+	/**
+	 * <p>Detector for HTML comment delimiters.</p>
+	 */
+	private static class HTMLCommentDetector implements IWordDetector {
+
+		/**
+		 * @see IWordDetector#isWordStart(char)
+		 */
+		public boolean isWordStart(char c) {
+			return (c == '<' || c == '-');
+		}
+
+		/**
+		 * @see IWordDetector#isWordPart(char)
+		 */
+		public boolean isWordPart(char c) {
+			return (c == '-' || c == '!' || c == '>');
+		}
+	}
+	
+	/**
+	 * <p>Same as a {@link SingleLineRule} except the given end sequence is not counted as part of the match.</p>
+	 * 
+	 * @see SingleLineRule
+	 */
+	private static class NoneInclusiveEndSequenceSingleLineRule extends SingleLineRule {
+
+		/**
+		 * @param startSequence start sequence included in rule match
+		 * @param endSequence end sequence that will end this rule but will not be counted as part of the match
+		 * @param token to return on a match by this rule
+		 */
+		public NoneInclusiveEndSequenceSingleLineRule(String startSequence, String endSequence, IToken token) {
+			super(startSequence, endSequence, token);
+		}
+
+		/**
+		 * <p>If the end sequence is detected then scanner is rewind to just before the end sequence,
+		 * otherwise acts the same as {@link PatternRule#endSequenceDetected}</p>
+		 * 
+		 * @see PatternRule#endSequenceDetected
+		 */
+		protected boolean endSequenceDetected(ICharacterScanner scanner) {
+			boolean success = super.endSequenceDetected(scanner);
+			if(success) {
+				for (int length = this.fEndSequence.length-1; length > 0; length--) {
+					scanner.unread();
+				}
+				
+				if(this.sequenceDetected(scanner, this.fEndSequence, false)) {
+					for (int length = this.fEndSequence.length; length > 0; length--) {
+						scanner.unread();
+					}
+				}
+			}
+			return success;
+		}
+	}
+	
+	/**
+	 * <p>Same as an {@link EndOfLineRule} except the given start sequence is not counted as part of the match.</p>
+	 * 
+	 * @see EndOfLineRule
+	 */
+	private static class NoneInclusiveStartSequenceEndOfLineRule extends EndOfLineRule {
+
+		/**
+		 * @param startSequence start sequence the identifies the start of this match but is not counted as part of the match
+		 * @param token to return on a match by this rule
+		 */
+		public NoneInclusiveStartSequenceEndOfLineRule(String startSequence, IToken token) {
+			super(startSequence, token);
+		}
+		
+		/**
+		 * <p>Same as overridden function except unreads the scanner back the length of the start sequence
+		 * since the start sequence is not counted as part of the match.</p>
+		 * 
+		 * @see org.eclipse.jface.text.rules.PatternRule#doEvaluate(org.eclipse.jface.text.rules.ICharacterScanner, boolean)
+		 */
+		protected IToken doEvaluate(ICharacterScanner scanner, boolean resume) {
+			if (resume) {
+				if (endSequenceDetected(scanner))
+					return fToken;
+			} else {
+				//unread the length of the start sequence since it is not counted as part of the match
+				for(int i = 0; i < this.fStartSequence.length && scanner.getColumn() >= 0; ++i) {
+					scanner.unread();
+				}
+
+				int c= scanner.read();
+				if (c == fStartSequence[0]) {
+					if (sequenceDetected(scanner, fStartSequence, false)) {
+						if (endSequenceDetected(scanner))
+							return fToken;
+					}
+				}
+				
+				//be sure to re-read the length of the start sequence if we did not match
+				for(int i = 0; i < this.fStartSequence.length && scanner.getColumn() >= 0; ++i) {
+					scanner.read();
+				}
+			}
+
+			scanner.unread();
+			return Token.UNDEFINED;
 		}
 	}
 }
diff --git a/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/LineStyleProviderForJSDT.java b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/LineStyleProviderForJSDT.java
index fe6ad6d..75357fc 100644
--- a/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/LineStyleProviderForJSDT.java
+++ b/bundles/org.eclipse.wst.jsdt.web.ui/src/org/eclipse/wst/jsdt/web/ui/internal/style/java/LineStyleProviderForJSDT.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -24,11 +24,12 @@
 import org.eclipse.swt.custom.StyleRange;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.RGB;
-import org.eclipse.wst.html.ui.internal.style.IStyleConstantsHTML;
+import org.eclipse.wst.html.ui.internal.HTMLUIPlugin;
 import org.eclipse.wst.jsdt.ui.PreferenceConstants;
 import org.eclipse.wst.jsdt.web.ui.internal.JsUIPlugin;
 import org.eclipse.wst.jsdt.web.ui.internal.style.IStyleConstantsJs;
 import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
+import org.eclipse.wst.sse.ui.internal.preferences.ui.ColorHelper;
 import org.eclipse.wst.sse.ui.internal.provisional.style.AbstractLineStyleProvider;
 import org.eclipse.wst.sse.ui.internal.provisional.style.LineStyleProvider;
 import org.eclipse.wst.xml.ui.internal.style.IStyleConstantsXML;
@@ -67,17 +68,17 @@
 	 * 
 	 * @param colorKey
 	 */
-	private void addJavaTextAttribute(String colorKey) {
-		IPreferenceStore store = getJavaColorPreferences();
-		if (store != null && colorKey != null) {
+	protected void addTextAttribute(String colorKey) {
+		IPreferenceStore javaStore = getJavaColorPreferences();
+		if (javaStore != null && colorKey != null) {
 			TextAttribute ta = null;
 			if (colorKey == IStyleConstantsJSDT.JAVA_KEYWORD) {
 				// keyword
-				RGB foreground = PreferenceConverter.getColor(store, PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR);
-				boolean bold = store.getBoolean(PreferenceConstants.EDITOR_JAVA_KEYWORD_BOLD);
-				boolean italics = store.getBoolean(PreferenceConstants.EDITOR_JAVA_KEYWORD_ITALIC);
-				boolean strikethrough = store.getBoolean(PreferenceConstants.EDITOR_JAVA_KEYWORD_STRIKETHROUGH);
-				boolean underline = store.getBoolean(PreferenceConstants.EDITOR_JAVA_KEYWORD_UNDERLINE);
+				RGB foreground = PreferenceConverter.getColor(javaStore, PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR);
+				boolean bold = javaStore.getBoolean(PreferenceConstants.EDITOR_JAVA_KEYWORD_BOLD);
+				boolean italics = javaStore.getBoolean(PreferenceConstants.EDITOR_JAVA_KEYWORD_ITALIC);
+				boolean strikethrough = javaStore.getBoolean(PreferenceConstants.EDITOR_JAVA_KEYWORD_STRIKETHROUGH);
+				boolean underline = javaStore.getBoolean(PreferenceConstants.EDITOR_JAVA_KEYWORD_UNDERLINE);
 				int style = SWT.NORMAL;
 				if (bold) {
 					style = style | SWT.BOLD;
@@ -94,11 +95,11 @@
 				ta = createTextAttribute(foreground, null, style);
 			} else if (colorKey == IStyleConstantsJSDT.JAVA_STRING) {
 				// string
-				RGB foreground = PreferenceConverter.getColor(store, PreferenceConstants.EDITOR_STRING_COLOR);
-				boolean bold = store.getBoolean(PreferenceConstants.EDITOR_STRING_BOLD);
-				boolean italics = store.getBoolean(PreferenceConstants.EDITOR_STRING_ITALIC);
-				boolean strikethrough = store.getBoolean(PreferenceConstants.EDITOR_STRING_STRIKETHROUGH);
-				boolean underline = store.getBoolean(PreferenceConstants.EDITOR_STRING_UNDERLINE);
+				RGB foreground = PreferenceConverter.getColor(javaStore, PreferenceConstants.EDITOR_STRING_COLOR);
+				boolean bold = javaStore.getBoolean(PreferenceConstants.EDITOR_STRING_BOLD);
+				boolean italics = javaStore.getBoolean(PreferenceConstants.EDITOR_STRING_ITALIC);
+				boolean strikethrough = javaStore.getBoolean(PreferenceConstants.EDITOR_STRING_STRIKETHROUGH);
+				boolean underline = javaStore.getBoolean(PreferenceConstants.EDITOR_STRING_UNDERLINE);
 				int style = SWT.NORMAL;
 				if (bold) {
 					style = style | SWT.BOLD;
@@ -115,11 +116,32 @@
 				ta = createTextAttribute(foreground, null, style);
 			} else if (colorKey == IStyleConstantsJSDT.JAVA_SINGLE_LINE_COMMENT) {
 				// single line comment
-				RGB foreground = PreferenceConverter.getColor(store, PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR);
-				boolean bold = store.getBoolean(PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_BOLD);
-				boolean italics = store.getBoolean(PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_ITALIC);
-				boolean strikethrough = store.getBoolean(PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_STRIKETHROUGH);
-				boolean underline = store.getBoolean(PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_UNDERLINE);
+				RGB foreground = PreferenceConverter.getColor(javaStore, PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR);
+				boolean bold = javaStore.getBoolean(PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_BOLD);
+				boolean italics = javaStore.getBoolean(PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_ITALIC);
+				boolean strikethrough = javaStore.getBoolean(PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_STRIKETHROUGH);
+				boolean underline = javaStore.getBoolean(PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_UNDERLINE);
+				int style = SWT.NORMAL;
+				if (bold) {
+					style = style | SWT.BOLD;
+				}
+				if (italics) {
+					style = style | SWT.ITALIC;
+				}
+				if (strikethrough) {
+					style = style | TextAttribute.STRIKETHROUGH;
+				}
+				if (underline) {
+					style = style | TextAttribute.UNDERLINE;
+				}
+				ta = createTextAttribute(foreground, null, style);
+			} else if (colorKey == IStyleConstantsJSDT.JAVA_MULTI_LINE_COMMENT) {
+				// multi line comment
+				RGB foreground = PreferenceConverter.getColor(javaStore, PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_COLOR);
+				boolean bold = javaStore.getBoolean(PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_BOLD);
+				boolean italics = javaStore.getBoolean(PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_ITALIC);
+				boolean strikethrough = javaStore.getBoolean(PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_STRIKETHROUGH);
+				boolean underline = javaStore.getBoolean(PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_UNDERLINE);
 				int style = SWT.NORMAL;
 				if (bold) {
 					style = style | SWT.BOLD;
@@ -136,11 +158,11 @@
 				ta = createTextAttribute(foreground, null, style);
 			} else if (colorKey == IStyleConstantsJSDT.JAVA_DEFAULT) {
 				// default
-				RGB foreground = PreferenceConverter.getColor(store, PreferenceConstants.EDITOR_JAVA_DEFAULT_COLOR);
-				boolean bold = store.getBoolean(PreferenceConstants.EDITOR_JAVA_DEFAULT_BOLD);
-				boolean italics = store.getBoolean(PreferenceConstants.EDITOR_JAVA_DEFAULT_ITALIC);
-				boolean strikethrough = store.getBoolean(PreferenceConstants.EDITOR_JAVA_DEFAULT_STRIKETHROUGH);
-				boolean underline = store.getBoolean(PreferenceConstants.EDITOR_JAVA_DEFAULT_UNDERLINE);
+				RGB foreground = PreferenceConverter.getColor(javaStore, PreferenceConstants.EDITOR_JAVA_DEFAULT_COLOR);
+				boolean bold = javaStore.getBoolean(PreferenceConstants.EDITOR_JAVA_DEFAULT_BOLD);
+				boolean italics = javaStore.getBoolean(PreferenceConstants.EDITOR_JAVA_DEFAULT_ITALIC);
+				boolean strikethrough = javaStore.getBoolean(PreferenceConstants.EDITOR_JAVA_DEFAULT_STRIKETHROUGH);
+				boolean underline = javaStore.getBoolean(PreferenceConstants.EDITOR_JAVA_DEFAULT_UNDERLINE);
 				int style = SWT.NORMAL;
 				if (bold) {
 					style = style | SWT.BOLD;
@@ -155,6 +177,36 @@
 					style = style | TextAttribute.UNDERLINE;
 				}
 				ta = createTextAttribute(foreground, null, style);
+			} else if(colorKey == IStyleConstantsXML.COMMENT_BORDER ||
+					colorKey == IStyleConstantsJs.JSP_CONTENT) {
+				
+				/** @see AbstractLineStyleProvider#addTextAttribute */
+				ta = (TextAttribute)getTextAttributes().get(colorKey);
+				String prefString = getHTMLColorPreferences().getString(colorKey);
+				String[] stylePrefs = ColorHelper.unpackStylePreferences(prefString);
+				if (stylePrefs != null) {
+					RGB foreground = ColorHelper.toRGB(stylePrefs[0]);
+					RGB background = ColorHelper.toRGB(stylePrefs[1]);
+					boolean bold = Boolean.valueOf(stylePrefs[2]).booleanValue();
+					boolean italic = Boolean.valueOf(stylePrefs[3]).booleanValue();
+					boolean strikethrough = Boolean.valueOf(stylePrefs[4]).booleanValue();
+					boolean underline = Boolean.valueOf(stylePrefs[5]).booleanValue();
+					int style = SWT.NORMAL;
+					if (bold) {
+						style = style | SWT.BOLD;
+					}
+					if (italic) {
+						style = style | SWT.ITALIC;
+					}
+					if (strikethrough) {
+						style = style | TextAttribute.STRIKETHROUGH;
+					}
+					if (underline) {
+						style = style | TextAttribute.UNDERLINE;
+					}
+
+					ta = createTextAttribute(foreground, background, style);
+				}
 			}
 			if (ta != null) {
 				getTextAttributes().put(colorKey, ta);
@@ -200,6 +252,10 @@
 		return PreferenceConstants.getPreferenceStore();
 	}
 	
+	private IPreferenceStore getHTMLColorPreferences() {
+		return HTMLUIPlugin.getDefault().getPreferenceStore();
+	}
+	
 	/**
 	 * Returns a text attribute encoded in the given token. If the token's data
 	 * is not <code>null</code> and a text attribute it is assumed that it is
@@ -223,52 +279,42 @@
 	
 	protected void handlePropertyChange(PropertyChangeEvent event) {
 		String styleKey = null;
-		String javaStyleKey = null;
 		if (event != null) {
 			String prefKey = event.getProperty();
 			// check if preference changed is a style preference
-			if (IStyleConstantsHTML.SCRIPT_AREA_BORDER.equals(prefKey)) {
-				styleKey = IStyleConstantsHTML.SCRIPT_AREA_BORDER;
-			} else if (IStyleConstantsXML.TAG_ATTRIBUTE_NAME.equals(prefKey)) {
-				styleKey = IStyleConstantsXML.TAG_ATTRIBUTE_NAME;
-			} else if (IStyleConstantsXML.TAG_ATTRIBUTE_VALUE.equals(prefKey)) {
-				styleKey = IStyleConstantsXML.TAG_ATTRIBUTE_VALUE;
-			} else if (IStyleConstantsJs.JSP_CONTENT.equals(prefKey)) {
-				styleKey = IStyleConstantsJs.JSP_CONTENT;
+			if(IStyleConstantsXML.COMMENT_BORDER.equals(prefKey)) {
+				styleKey = IStyleConstantsXML.COMMENT_BORDER;
+			} else if(IStyleConstantsXML.COMMENT_TEXT.equals(prefKey)) {
+				styleKey = IStyleConstantsXML.COMMENT_TEXT;
 			} else if (PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR.equals(prefKey) || (PreferenceConstants.EDITOR_JAVA_KEYWORD_BOLD.equals(prefKey)) || (PreferenceConstants.EDITOR_JAVA_KEYWORD_ITALIC.equals(prefKey))) {
-				javaStyleKey = IStyleConstantsJSDT.JAVA_KEYWORD;
+				styleKey = IStyleConstantsJSDT.JAVA_KEYWORD;
 			} else if (PreferenceConstants.EDITOR_STRING_COLOR.equals(prefKey) || (PreferenceConstants.EDITOR_STRING_BOLD.equals(prefKey)) || (PreferenceConstants.EDITOR_STRING_ITALIC.equals(prefKey))) {
-				javaStyleKey = IStyleConstantsJSDT.JAVA_STRING;
+				styleKey = IStyleConstantsJSDT.JAVA_STRING;
 			} else if (PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR.equals(prefKey) || (PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_BOLD.equals(prefKey)) || (PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_ITALIC.equals(prefKey))) {
-				javaStyleKey = IStyleConstantsJSDT.JAVA_SINGLE_LINE_COMMENT;
+				styleKey = IStyleConstantsJSDT.JAVA_SINGLE_LINE_COMMENT;
+			} else if (PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_COLOR.equals(prefKey) || (PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_BOLD.equals(prefKey)) || (PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_ITALIC.equals(prefKey))) {
+				styleKey = IStyleConstantsJSDT.JAVA_MULTI_LINE_COMMENT;
 			} else if (PreferenceConstants.EDITOR_JAVA_DEFAULT_COLOR.equals(prefKey) || (PreferenceConstants.EDITOR_JAVA_DEFAULT_BOLD.equals(prefKey)) || (PreferenceConstants.EDITOR_JAVA_DEFAULT_ITALIC.equals(prefKey))) {
-				javaStyleKey = IStyleConstantsJSDT.JAVA_DEFAULT;
+				styleKey = IStyleConstantsJSDT.JAVA_DEFAULT;
 			}
 		}
 		if (styleKey != null) {
 			// overwrite style preference with new value
 			addTextAttribute(styleKey);
-		}
-		if (javaStyleKey != null) {
-			// overwrite style preference with new value
-			addJavaTextAttribute(javaStyleKey);
+			fRecHighlighter.refreshDisplay();
 			fScanner.initializeRules();
 		}
-		if (styleKey != null || javaStyleKey != null) {
-			// force a full update of the text viewer
-			super.getHighlighter().refreshDisplay();
-		}
 	}
 	
 	protected void loadColors() {
-		addTextAttribute(IStyleConstantsHTML.SCRIPT_AREA_BORDER);
-		addTextAttribute(IStyleConstantsXML.TAG_ATTRIBUTE_NAME);
-		addTextAttribute(IStyleConstantsXML.TAG_ATTRIBUTE_VALUE);
+		addTextAttribute(IStyleConstantsXML.COMMENT_BORDER);
+		addTextAttribute(IStyleConstantsXML.COMMENT_TEXT);
 		addTextAttribute(IStyleConstantsJs.JSP_CONTENT);
-		addJavaTextAttribute(IStyleConstantsJSDT.JAVA_KEYWORD);
-		addJavaTextAttribute(IStyleConstantsJSDT.JAVA_STRING);
-		addJavaTextAttribute(IStyleConstantsJSDT.JAVA_SINGLE_LINE_COMMENT);
-		addJavaTextAttribute(IStyleConstantsJSDT.JAVA_DEFAULT);
+		addTextAttribute(IStyleConstantsJSDT.JAVA_KEYWORD);
+		addTextAttribute(IStyleConstantsJSDT.JAVA_STRING);
+		addTextAttribute(IStyleConstantsJSDT.JAVA_SINGLE_LINE_COMMENT);
+		addTextAttribute(IStyleConstantsJSDT.JAVA_MULTI_LINE_COMMENT);
+		addTextAttribute(IStyleConstantsJSDT.JAVA_DEFAULT);
 		fScanner.initializeRules();
 	}
 	
@@ -325,6 +371,7 @@
 	protected void registerPreferenceManager() {
 		getColorPreferences().addPropertyChangeListener(fPreferenceListener);
 		getJavaColorPreferences().addPropertyChangeListener(fPreferenceListener);
+		this.getHTMLColorPreferences().addPropertyChangeListener(fPreferenceListener);
 	}
 	
 	public void release() {
@@ -335,5 +382,6 @@
 	protected void unRegisterPreferenceManager() {
 		getColorPreferences().removePropertyChangeListener(fPreferenceListener);
 		getJavaColorPreferences().removePropertyChangeListener(fPreferenceListener);
+		this.getHTMLColorPreferences().removePropertyChangeListener(fPreferenceListener);
 	}
 }
\ No newline at end of file