update task tags for separate source folder, new preferences, naming
diff --git a/bundles/org.eclipse.wst.sse.core/.classpath b/bundles/org.eclipse.wst.sse.core/.classpath
index 2b58554..ff3758b 100644
--- a/bundles/org.eclipse.wst.sse.core/.classpath
+++ b/bundles/org.eclipse.wst.sse.core/.classpath
@@ -2,6 +2,7 @@
 <classpath>
 	<classpathentry kind="src" path="src-encoding"/>
 	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="src-tasktags"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="output" path="bin"/>
diff --git a/bundles/org.eclipse.wst.sse.core/.options b/bundles/org.eclipse.wst.sse.core/.options
index 5979bbb..a02573f 100644
--- a/bundles/org.eclipse.wst.sse.core/.options
+++ b/bundles/org.eclipse.wst.sse.core/.options
@@ -8,6 +8,7 @@
 org.eclipse.wst.sse.core/tasks=false
 org.eclipse.wst.sse.core/tasks/detection=false
 org.eclipse.wst.sse.core/tasks/job=false
+org.eclipse.wst.sse.core/tasks/preferences=false
 org.eclipse.wst.sse.core/tasks/overalltime=false
 org.eclipse.wst.sse.core/tasks/registry=false
 org.eclipse.wst.sse.core/tasks/time=false
diff --git a/bundles/org.eclipse.wst.sse.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.sse.core/META-INF/MANIFEST.MF
index 07bf36a..65bb971 100644
--- a/bundles/org.eclipse.wst.sse.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.sse.core/META-INF/MANIFEST.MF
@@ -26,6 +26,7 @@
  org.eclipse.wst.sse.core.internal.provisional.events,
  org.eclipse.wst.sse.core.internal.provisional.exceptions,
  org.eclipse.wst.sse.core.internal.provisional.model,
+ org.eclipse.wst.sse.core.internal.provisional.tasks,
  org.eclipse.wst.sse.core.internal.provisional.text,
  org.eclipse.wst.sse.core.internal.tasks,
  org.eclipse.wst.sse.core.internal.text,
diff --git a/bundles/org.eclipse.wst.sse.core/build.properties b/bundles/org.eclipse.wst.sse.core/build.properties
index 754c646..10350e7 100644
--- a/bundles/org.eclipse.wst.sse.core/build.properties
+++ b/bundles/org.eclipse.wst.sse.core/build.properties
@@ -11,7 +11,8 @@
 #     
 ###############################################################################
 source.. = src-encoding/,\
-                   src/
+           src/,\
+           src-tasktags/
 bin.includes = plugin.xml,\
                plugin.properties,\
                .options,\
diff --git a/bundles/org.eclipse.wst.sse.core/plugin.xml b/bundles/org.eclipse.wst.sse.core/plugin.xml
index aab15a6..00a03fc 100644
--- a/bundles/org.eclipse.wst.sse.core/plugin.xml
+++ b/bundles/org.eclipse.wst.sse.core/plugin.xml
@@ -2,7 +2,7 @@
 <?eclipse version="3.0"?>
 <plugin>
 
-    
+
 <!-- deprecated -->
    <extension-point id="adaptOnCreateFactory" name="%Adapt_On_Create_Factory_Extension.name"/>
    <extension-point id="documentTypes" name="%Document_Types_Extension.name"/>
@@ -15,6 +15,7 @@
 	-->
    <extension-point id="cssprofile" name="%CSS_Profile_Extension.name"/>
    <extension-point id="commentElementHandler" name="%Comment_Element_Handler_Extension.name"/>
+
 <!-- this plug-in provides support for this extension point -->
    <extension-point id="modelHandler" name="%Model_Handler_Extension.name"/>
    <extension-point id="formatProcessors" name="%Format_Processors_Extension_Point.name" schema="schema/formatProcessors.exsd"/>
@@ -28,7 +29,9 @@
     	<persistent value="true"/>
 	</extension>
 	
-	
-
+<!-- Make sure default preference values are set at runtime -->
+	<extension point="org.eclipse.core.runtime.preferences">
+		<initializer class="org.eclipse.wst.sse.core.internal.preferences.PreferenceInitializer"/>
+	</extension>
 	
 </plugin>
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/ITaskScannerDelegate.java b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/provisional/tasks/IFileTaskScanner.java
similarity index 61%
rename from bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/ITaskScannerDelegate.java
rename to bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/provisional/tasks/IFileTaskScanner.java
index 27e03b7..1b9d9f0 100644
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/ITaskScannerDelegate.java
+++ b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/provisional/tasks/IFileTaskScanner.java
@@ -10,12 +10,14 @@
  *     Jens Lukowski/Innoopract - initial renaming/restructuring
  *     
  *******************************************************************************/
-package org.eclipse.wst.sse.core.internal.tasks;
+package org.eclipse.wst.sse.core.internal.provisional.tasks;
+
+import java.util.Map;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
+import org.eclipse.wst.sse.core.internal.SSECorePlugin;
 
 /**
  * Delegates for the main Task Scanner. Delegates may be contributed using the
@@ -24,14 +26,33 @@
  * call the startup() method, scan(), and then shutdown() in sequence. Scanner
  * instances will be reused across projects but are not shared per content
  * type. Delegates should not hold on to references to models or resources
- * after shutdown().
+ * after shutdown() and should take care not to leak memory or resources.
  */
-public interface ITaskScannerDelegate {
-	IStatus scan(IFile file, IProgressMonitor monitor);
+public interface IFileTaskScanner {
+	String TASK_MARKER_ID = SSECorePlugin.ID + ".task"; //$NON-NLS-1$;
+
+	/**
+	 * Requests that the list of automatically discovered tasks for the given
+	 * file be updated. Once completed, the list of tasks should correspond
+	 * exactly to the file's contents.
+	 * 
+	 * @param file -
+	 *            the file to be scanned
+	 * @param taskTags -
+	 *            the list of task tags for which to scan
+	 * @param monitor -
+	 *            a progress monitor
+	 * @return an array of maps containing the attributes for task markers to
+	 *         be created
+	 */
+	Map[] scan(IFile file, TaskTag[] taskTags, IProgressMonitor monitor);
 
 	/**
 	 * Notifies the delegate that scanning is done for now. Resources held
 	 * from startup should now be released.
+	 * 
+	 * @param project -
+	 *            the project that was just scanned
 	 */
 	void shutdown(IProject project);
 
@@ -41,7 +62,8 @@
 	 * expensive configuration for the given project.
 	 * 
 	 * @param project -
-	 *            the project that's about to be scanned
+	 *            the project that is about to be scanned
+	 * 
 	 */
 	void startup(IProject project);
 }
diff --git a/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/provisional/tasks/TaskTag.java b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/provisional/tasks/TaskTag.java
new file mode 100644
index 0000000..8035358
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/provisional/tasks/TaskTag.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2005 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.sse.core.internal.provisional.tasks;
+
+import org.eclipse.core.resources.IMarker;
+
+public final class TaskTag {
+
+	public static final int PRIORITY_HIGH = IMarker.PRIORITY_HIGH;
+	public static final int PRIORITY_LOW = IMarker.PRIORITY_LOW;
+	public static final int PRIORITY_NORMAL = IMarker.PRIORITY_NORMAL;
+
+	private int fPriority = PRIORITY_NORMAL;
+	private String fTag = null;
+
+	public TaskTag(String tag, int priority) {
+		super();
+		fTag = tag;
+		fPriority = priority;
+	}
+
+	public int getPriority() {
+		return fPriority;
+	}
+
+	public String getTag() {
+		return fTag;
+	}
+
+	public String toString() {
+		return getTag() + ":" + getPriority();
+	}
+}
diff --git a/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/FileTaskScannerRegistryReader.java b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/FileTaskScannerRegistryReader.java
new file mode 100644
index 0000000..d78354f
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/FileTaskScannerRegistryReader.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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
+ *     Jens Lukowski/Innoopract - initial renaming/restructuring
+ *     
+ *******************************************************************************/
+package org.eclipse.wst.sse.core.internal.tasks;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.core.runtime.content.IContentTypeManager;
+import org.eclipse.wst.sse.core.internal.Logger;
+import org.eclipse.wst.sse.core.internal.SSECorePlugin;
+import org.eclipse.wst.sse.core.internal.provisional.tasks.IFileTaskScanner;
+import org.eclipse.wst.sse.core.internal.util.StringUtils;
+
+public class FileTaskScannerRegistryReader {
+	private class ScannerInfo {
+		String fId;
+		IFileTaskScanner fScanner;
+
+		ScannerInfo(String id, IFileTaskScanner scanner) {
+			super();
+			fId = id;
+			fScanner = scanner;
+		}
+
+		public boolean equals(Object obj) {
+			return obj instanceof ScannerInfo && fId.equals(((ScannerInfo) obj).fId);
+		}
+
+		public String getId() {
+			return fId;
+		}
+
+		public IFileTaskScanner getScanner() {
+			return fScanner;
+		}
+	}
+
+	private static final boolean _debugReader = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks/registry")); //$NON-NLS-1$ //$NON-NLS-2$
+
+	private static FileTaskScannerRegistryReader _instance = null;
+
+	public static FileTaskScannerRegistryReader getInstance() {
+		if (_instance == null) {
+			_instance = new FileTaskScannerRegistryReader();
+		}
+		return _instance;
+	}
+
+	private String ATT_CLASS = "class"; //$NON-NLS-1$
+
+	private String ATT_CONTENT_TYPES = "contentTypeIds"; //$NON-NLS-1$
+
+	private String ATT_ID = "id"; //$NON-NLS-1$
+
+	private IConfigurationElement[] fScannerElements;
+
+	// a mapping from content types to ScannerInfo instances
+	private Map fScannerInfos = null;
+
+	private String NAME_SCANNER = "scanner"; //$NON-NLS-1$
+
+	private String SCANNER_EXTENSION_POINT_ID = SSECorePlugin.ID + ".taskscanner"; //$NON-NLS-1$
+
+	private FileTaskScannerRegistryReader() {
+		super();
+	}
+
+	IFileTaskScanner[] getFileTaskScanners(IContentType[] contentTypes) {
+		if (fScannerElements == null) {
+			readRegistry();
+		}
+
+		List scannerInfos = new ArrayList(1);
+
+		for (int i = 0; i < contentTypes.length; i++) {
+			ScannerInfo[] scannerInfosForContentType = (ScannerInfo[]) fScannerInfos.get(contentTypes[i].getId());
+			if (scannerInfosForContentType == null) {
+				scannerInfosForContentType = loadScanners(contentTypes[i]);
+			}
+			// only add non-duplicate scanners
+			for (int j = 0; j < scannerInfosForContentType.length; j++) {
+				if (!scannerInfos.contains(scannerInfosForContentType[j])) {
+					scannerInfos.add(scannerInfosForContentType[j]);
+				}
+			}
+		}
+		IFileTaskScanner[] scanners = new IFileTaskScanner[scannerInfos.size()];
+		for (int i = 0; i < scanners.length; i++) {
+			scanners[i] = ((ScannerInfo) scannerInfos.get(i)).getScanner();
+		}
+		return scanners;
+	}
+
+	public String[] getSupportedContentTypeIds() {
+		if (fScannerElements == null) {
+			readRegistry();
+		}
+
+		// find the relevant extensions
+		List types = new ArrayList(0);
+		IConfigurationElement[] scannerElements = fScannerElements;
+		for (int j = 0; j < scannerElements.length; j++) {
+			if (!scannerElements[j].getName().equals(NAME_SCANNER))
+				continue;
+			String[] contentTypeIds = StringUtils.unpack(scannerElements[j].getAttribute(ATT_CONTENT_TYPES));
+			for (int i = 0; i < contentTypeIds.length; i++) {
+				if (!types.contains(contentTypeIds[i])) {
+					types.add(contentTypeIds[i]);
+				}
+			}
+		}
+
+		return (String[]) types.toArray(new String[types.size()]);
+	}
+
+	private ScannerInfo[] loadScanners(IContentType contentType) {
+		List elements = new ArrayList(0);
+		ScannerInfo[] scannerInfos = null;
+		IConfigurationElement[] delegateElements = fScannerElements;
+		if (contentType != null) {
+			IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
+			for (int j = 0; j < delegateElements.length; j++) {
+				if (!delegateElements[j].getName().equals(NAME_SCANNER))
+					continue;
+				String[] supportedContentTypeIds = StringUtils.unpack(delegateElements[j].getAttribute(ATT_CONTENT_TYPES));
+				IContentType[] supportedContentTypes = new IContentType[supportedContentTypeIds.length];
+				for (int k = 0; k < supportedContentTypeIds.length; k++) {
+					supportedContentTypes[k] = contentTypeManager.getContentType(supportedContentTypeIds[k].trim());
+				}
+				for (int k = 0; k < supportedContentTypeIds.length; k++) {
+					// allow subtypes to be returned as well
+					if (supportedContentTypes[k] != null && contentType.isKindOf(supportedContentTypes[k])) {
+						elements.add(delegateElements[j]);
+					}
+				}
+			}
+			// instantiate and save the scanners
+			List scannerInfoList = new ArrayList(elements.size());
+			for (int i = 0; i < elements.size(); i++) {
+				try {
+					IFileTaskScanner scanner = (IFileTaskScanner) ((IConfigurationElement) elements.get(i)).createExecutableExtension(ATT_CLASS);
+					if (scanner != null) {
+						scannerInfoList.add(new ScannerInfo(((IConfigurationElement) elements.get(i)).getAttribute(ATT_ID), scanner));
+					}
+				}
+				catch (CoreException e) {
+					Logger.logException("Non-fatal exception creating task scanner for " + contentType.getId(), e); //$NON-NLS-1$
+				}
+			}
+			scannerInfos = (ScannerInfo[]) scannerInfoList.toArray(new ScannerInfo[scannerInfoList.size()]);
+			fScannerInfos.put(contentType.getId(), scannerInfos);
+			if (_debugReader) {
+				System.out.println("Created " + scannerInfos.length + " task scanner for " + contentType.getId()); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		}
+		return scannerInfos;
+	}
+
+	private void readRegistry() {
+		fScannerInfos = new HashMap();
+		// Just remember the elements, so plugins don't have to be activated,
+		// unless extension attributes match those of interest
+		IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(SCANNER_EXTENSION_POINT_ID);
+		if (point != null) {
+			fScannerElements = point.getConfigurationElements();
+		}
+	}
+}
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScannerDelegate.java b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/StructuredFileTaskScanner.java
similarity index 68%
rename from bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScannerDelegate.java
rename to bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/StructuredFileTaskScanner.java
index 9899248..c24ce94 100644
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScannerDelegate.java
+++ b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/StructuredFileTaskScanner.java
@@ -21,75 +21,55 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
-import java.util.StringTokenizer;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRunnable;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.content.IContentDescription;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.Document;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.wst.sse.core.internal.Logger;
-import org.eclipse.wst.sse.core.internal.SSECorePlugin;
 import org.eclipse.wst.sse.core.internal.document.DocumentReader;
 import org.eclipse.wst.sse.core.internal.ltk.modelhandler.IModelHandler;
 import org.eclipse.wst.sse.core.internal.ltk.parser.RegionParser;
 import org.eclipse.wst.sse.core.internal.ltk.parser.StructuredDocumentRegionHandler;
 import org.eclipse.wst.sse.core.internal.ltk.parser.StructuredDocumentRegionParser;
 import org.eclipse.wst.sse.core.internal.modelhandler.ModelHandlerRegistry;
-import org.eclipse.wst.sse.core.internal.preferences.CommonModelPreferenceNames;
 import org.eclipse.wst.sse.core.internal.provisional.document.IEncodedDocument;
+import org.eclipse.wst.sse.core.internal.provisional.tasks.IFileTaskScanner;
+import org.eclipse.wst.sse.core.internal.provisional.tasks.TaskTag;
 import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
 import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
 import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
 import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
-import org.eclipse.wst.sse.core.internal.util.StringUtils;
 
 /**
  * A delegate to create IMarker.TASKs for "todos" and similiar comments.
  */
-public abstract class TaskScannerDelegate implements ITaskScannerDelegate {
-
-	public static class TaskTag {
-		public int priority;
-		public String text;
-
-		public TaskTag(String taskText, int taskPriority) {
-			this.text = taskText;
-			this.priority = taskPriority;
-		}
-	}
+public abstract class StructuredFileTaskScanner implements IFileTaskScanner {
 
 	private static final boolean _debug = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks")); //$NON-NLS-1$ //$NON-NLS-2$
 	protected static final boolean _debugPerf = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks/time")); //$NON-NLS-1$ //$NON-NLS-2$
 
-	public static String getTaskMarkerType() {
-		return SSECorePlugin.ID + ".task"; //$NON-NLS-1$
-	}
-
 	// the list of attributes for the new tasks for the current file
-	protected List fNewMarkerAttributes = null;
+	protected List fNewMarkerAttributeMaps = null;
 
-	private TaskTag[] fTaskTags = null;
 	List oldMarkers = null;
 	private long time0;
 
-	public TaskScannerDelegate() {
+	public StructuredFileTaskScanner() {
 		super();
-		fNewMarkerAttributes = new ArrayList();
+		fNewMarkerAttributeMaps = new ArrayList();
 		if (_debug) {
 			System.out.println(getClass().getName() + " instance created"); //$NON-NLS-1$
 		}
@@ -108,7 +88,8 @@
 		attributes.put(IMarker.CHAR_START, new Integer(startOffset));
 		attributes.put(IMarker.CHAR_END, new Integer(startOffset + length));
 		attributes.put(IMarker.MESSAGE, text);
-		attributes.put(IMarker.USER_EDITABLE, Boolean.FALSE);
+		attributes.put(IMarker.USER_EDITABLE, Boolean.TRUE);
+		attributes.put("org.eclipse.ui.part.IShowInTarget", new String[]{""});
 
 		switch (priority) {
 			case IMarker.PRIORITY_HIGH : {
@@ -127,30 +108,6 @@
 		return attributes;
 	}
 
-	protected void createNewMarkers(IFile file, IProgressMonitor monitor) {
-		final IFile finalFile = file;
-		if (file.isAccessible() && fNewMarkerAttributes.size() > 0) {
-			if (_debug) {
-				System.out.println("" + fNewMarkerAttributes.size() + " tasks for " + file.getFullPath()); //$NON-NLS-1$ //$NON-NLS-2$
-			}
-			try {
-				IWorkspaceRunnable r = new IWorkspaceRunnable() {
-					public void run(IProgressMonitor progressMonitor) throws CoreException {
-						for (int i = 0; i < fNewMarkerAttributes.size(); i++) {
-							IMarker marker = finalFile.createMarker(getMarkerType());
-							marker.setAttributes((Map) fNewMarkerAttributes.get(i));
-						}
-					}
-				};
-				finalFile.getWorkspace().run(r, null, IWorkspace.AVOID_UPDATE, monitor);
-				fNewMarkerAttributes.clear();
-			}
-			catch (CoreException e1) {
-				Logger.logException(e1);
-			}
-		}
-	}
-
 	private String detectCharset(IFile file) {
 		if (file.getType() == IResource.FILE && file.isAccessible()) {
 			IContentDescription d = null;
@@ -161,8 +118,10 @@
 					return d.getCharset();
 			}
 			catch (CoreException e) {
-				// should not be possible given the accessible and file type
-				// check above
+				/*
+				 * should not be possible given the accessible and file type
+				 * check above
+				 */
 			}
 			InputStream contents = null;
 			try {
@@ -197,7 +156,7 @@
 	 * @param documentRegion
 	 * @param comment
 	 */
-	protected void findTasks(IDocument document, IStructuredDocumentRegion documentRegion, ITextRegion comment) {
+	protected void findTasks(IDocument document, TaskTag[] taskTags, IStructuredDocumentRegion documentRegion, ITextRegion comment) {
 		if (isCommentRegion(documentRegion, comment)) {
 			int startOffset = documentRegion.getStartOffset(comment);
 			int endOffset = documentRegion.getTextEndOffset(comment);
@@ -210,19 +169,18 @@
 					int end = Math.min(endOffset, line.getOffset() + line.getLength());
 					int length = end - begin;
 
-					// TODO: improve our search algorithm; use search or
-					// regionMatch?
+					/* XXX: This generates a lot of garbage objects */
 
 					String commentedText = getCommentedText(document, begin, length);
+					String comparisonText = commentedText.toLowerCase(Locale.ENGLISH);
 
-					for (int i = 0; i < fTaskTags.length; i++) {
-						int tagIndex = commentedText.indexOf(fTaskTags[i].text);
+					for (int i = 0; i < taskTags.length; i++) {
+						int tagIndex = comparisonText.indexOf(taskTags[i].getTag().toLowerCase(Locale.ENGLISH));
 						if (tagIndex >= 0) {
 							String markerDescription = commentedText.substring(tagIndex);
 							int markerOffset = begin + tagIndex;
 							int markerLength = end - markerOffset;
-							fNewMarkerAttributes.add(createInitialMarkerAttributes(markerDescription, lineNumber, markerOffset, markerLength, fTaskTags[i].priority));
-							break;
+							fNewMarkerAttributeMaps.add(createInitialMarkerAttributes(markerDescription, lineNumber, markerOffset, markerLength, taskTags[i].getPriority()));
 						}
 					}
 				}
@@ -233,7 +191,7 @@
 		}
 	}
 
-	private void findTasks(IFile file, IProgressMonitor monitor) {
+	private void findTasks(IFile file, final TaskTag[] taskTags, IProgressMonitor monitor) {
 		try {
 			IModelHandler handler = ModelHandlerRegistry.getInstance().getHandlerFor(file);
 
@@ -255,7 +213,7 @@
 							ITextRegionList regions = documentRegion.getRegions();
 							for (int j = 0; j < regions.size(); j++) {
 								ITextRegion comment = regions.get(j);
-								findTasks(textDocument, documentRegion, comment);
+								findTasks(textDocument, taskTags, documentRegion, comment);
 							}
 							// disconnect the document regions
 							if (documentRegion.getPrevious() != null) {
@@ -282,7 +240,7 @@
 						ITextRegionList regions = documentRegion.getRegions();
 						for (int j = 0; j < regions.size(); j++) {
 							ITextRegion comment = regions.get(j);
-							findTasks(document, documentRegion, comment);
+							findTasks(document, taskTags, documentRegion, comment);
 						}
 						documentRegion = documentRegion.getNext();
 					}
@@ -293,7 +251,7 @@
 			Logger.logException("Exception with " + file.getFullPath().toString(), e); //$NON-NLS-1$
 		}
 		catch (CharacterCodingException e) {
-			Logger.log(Logger.INFO, "TaskScannerDelegate encountered CharacterCodingException reading " + file.getFullPath().toOSString()); //$NON-NLS-1$
+			Logger.log(Logger.INFO, "StructuredFileTaskScanner encountered CharacterCodingException reading " + file.getLocation()); //$NON-NLS-1$
 		}
 		catch (IOException e) {
 			Logger.logException(e);
@@ -304,78 +262,23 @@
 		return document.get(begin, length);
 	}
 
-
-	final protected String getMarkerType() {
-		return SSECorePlugin.ID + ".task"; //$NON-NLS-1$
-	}
-
 	protected abstract boolean isCommentRegion(IStructuredDocumentRegion region, ITextRegion textRegion);
 
-	private void loadTags() {
-		if (_debug) {
-			System.out.println(this + " loadPreference()"); //$NON-NLS-1$
-		}
-		String tagsString = SSECorePlugin.getDefault().getPluginPreferences().getString(CommonModelPreferenceNames.TASK_TAG_TAGS);
-		String prioritiesString = SSECorePlugin.getDefault().getPluginPreferences().getString(CommonModelPreferenceNames.TASK_TAG_PRIORITIES);
-
-		List list = new ArrayList();
-		StringTokenizer toker = null;
-		if (tagsString.length() > 0) {
-			toker = new StringTokenizer(tagsString, ","); //$NON-NLS-1$
-			while (toker.hasMoreTokens()) {
-				// since we're separating the values with ',', escape ',' in
-				// the
-				// values
-				list.add(StringUtils.replace(toker.nextToken(), "&comma;", ",").trim()); //$NON-NLS-1$ //$NON-NLS-2$
-			}
-		}
-		String[] tags = (String[]) list.toArray(new String[0]);
-		list.clear();
-
-		if (prioritiesString.length() > 0) {
-			toker = new StringTokenizer(prioritiesString, ","); //$NON-NLS-1$
-			int i = 0;
-			while (toker.hasMoreTokens() && i < tags.length) {
-				Integer number = null;
-				try {
-					number = Integer.valueOf(toker.nextToken().trim());
-				}
-				catch (NumberFormatException e) {
-					number = new Integer(IMarker.PRIORITY_NORMAL);
-				}
-				if (i < tags.length) {
-					list.add(new TaskTag(tags[i++], number.intValue()));
-				}
-			}
-		}
-		fTaskTags = (TaskTag[]) list.toArray(new TaskTag[0]);
-	}
-
-	public IStatus scan(IFile file, IProgressMonitor monitor) {
+	public synchronized Map[] scan(IFile file, TaskTag[] taskTags, IProgressMonitor monitor) {
+		fNewMarkerAttributeMaps.clear();
 		if (monitor.isCanceled() || !shouldScan(file)) {
-			return Status.OK_STATUS;
+			return new Map[0];
 		}
 		if (_debugPerf) {
 			time0 = System.currentTimeMillis();
 		}
-		if (fTaskTags.length > 0) {
-			try {
-				// Delete old Task markers
-				file.deleteMarkers(getMarkerType(), true, IResource.DEPTH_ZERO);
-			}
-			catch (CoreException e) {
-				Logger.logException("exception deleting old tasks", e); //$NON-NLS-1$ 
-			}
-			// on a clean build, don't add new Tasks
-			// if (kind != IncrementalProjectBuilder.CLEAN_BUILD) {
-			findTasks(file, monitor);
-			createNewMarkers(file, monitor);
-			// }
+		if (taskTags.length > 0) {
+			findTasks(file, taskTags, monitor);
 		}
 		if (_debugPerf) {
 			System.out.println("" + (System.currentTimeMillis() - time0) + "ms for " + file.getLocation()); //$NON-NLS-1$ //$NON-NLS-2$
 		}
-		return Status.OK_STATUS;
+		return (Map[]) fNewMarkerAttributeMaps.toArray(new Map[fNewMarkerAttributeMaps.size()]);
 	}
 
 	/**
@@ -417,7 +320,6 @@
 		if (_debug) {
 			System.out.println(this + " shutdown for " + project.getName()); //$NON-NLS-1$
 		}
-		fTaskTags = null;
 	}
 
 	public void startup(IProject project) {
@@ -427,7 +329,6 @@
 		if (_debugPerf) {
 			time0 = System.currentTimeMillis();
 		}
-		loadTags();
 		if (_debugPerf) {
 			System.out.println("" + (System.currentTimeMillis() - time0) + "ms loading prefs for " + project.getName()); //$NON-NLS-1$ //$NON-NLS-2$
 		}
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/ScanningJob.java b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/TaskScanningJob.java
similarity index 73%
rename from bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/ScanningJob.java
rename to bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/TaskScanningJob.java
index a9a9cf5..a46b5cb 100644
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/ScanningJob.java
+++ b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/TaskScanningJob.java
@@ -27,14 +27,13 @@
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.wst.sse.core.internal.SSECoreMessages;
 import org.eclipse.wst.sse.core.internal.SSECorePlugin;
-import org.eclipse.wst.sse.core.internal.preferences.CommonModelPreferenceNames;
 import org.eclipse.wst.sse.core.internal.util.StringUtils;
 import org.osgi.framework.Bundle;
 
 /**
  * Queueing Job for processing deltas and projects.
  */
-class ScanningJob extends Job {
+class TaskScanningJob extends Job {
 	public static final boolean _debugJob = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks/job"));
 	static final String TASK_TAG_PROJECTS_ALREADY_SCANNED = "task-tag-projects-already-scanned"; //$NON-NLS-1$
 	private List fQueue = null;
@@ -42,42 +41,39 @@
 	/** symbolic name for OSGI framework */
 	private final String OSGI_FRAMEWORK_ID = "org.eclipse.osgi"; //$NON-NLS-1$
 
-	ScanningJob() {
+	TaskScanningJob() {
 		super(SSECoreMessages.TaskScanner_0);
 		fQueue = new ArrayList();
 		setPriority(Job.DECORATE);
 		setSystem(false);
 
-		SSECorePlugin.getDefault().getPluginPreferences().setDefault(CommonModelPreferenceNames.TASK_TAG_PROJECTS_IGNORED, "");
 		SSECorePlugin.getDefault().getPluginPreferences().setDefault(TASK_TAG_PROJECTS_ALREADY_SCANNED, "");
 	}
 
 	synchronized void addDelta(IResourceDelta delta) {
-		if (!isIgnoredProject(delta)) {
-			fQueue.add(delta);
-			if (_debugJob) {
-				String kind = null;
-				switch (delta.getKind()) {
-					case IResourceDelta.ADDED :
-						kind = " [IResourceDelta.ADDED]"; //$NON-NLS-1$
-						break;
-					case IResourceDelta.CHANGED :
-						kind = " [IResourceDelta.CHANGED]"; //$NON-NLS-1$
-						break;
-					case IResourceDelta.REMOVED :
-						kind = " [IResourceDelta.REMOVED]"; //$NON-NLS-1$
-						break;
-					case IResourceDelta.ADDED_PHANTOM :
-						kind = " [IResourceDelta.ADDED_PHANTOM]"; //$NON-NLS-1$
-						break;
-					case IResourceDelta.REMOVED_PHANTOM :
-						kind = " [IResourceDelta.REMOVED_PHANTOM]"; //$NON-NLS-1$
-						break;
-				}
-				System.out.println("Adding delta " + delta.getFullPath() + kind);
+		fQueue.add(delta);
+		if (_debugJob) {
+			String kind = null;
+			switch (delta.getKind()) {
+				case IResourceDelta.ADDED :
+					kind = " [IResourceDelta.ADDED]"; //$NON-NLS-1$
+					break;
+				case IResourceDelta.CHANGED :
+					kind = " [IResourceDelta.CHANGED]"; //$NON-NLS-1$
+					break;
+				case IResourceDelta.REMOVED :
+					kind = " [IResourceDelta.REMOVED]"; //$NON-NLS-1$
+					break;
+				case IResourceDelta.ADDED_PHANTOM :
+					kind = " [IResourceDelta.ADDED_PHANTOM]"; //$NON-NLS-1$
+					break;
+				case IResourceDelta.REMOVED_PHANTOM :
+					kind = " [IResourceDelta.REMOVED_PHANTOM]"; //$NON-NLS-1$
+					break;
 			}
-			schedule(100);
+			System.out.println("Adding delta " + delta.getFullPath() + kind);
 		}
+		schedule(100);
 	}
 
 	synchronized void addProject(IProject project) {
@@ -103,24 +99,16 @@
 		// R3 spec.
 		boolean shuttingDown = Platform.getBundle(OSGI_FRAMEWORK_ID).getState() == Bundle.STOPPING;
 		if (_debugJob && shuttingDown) {
-			System.out.println("ScanningJob: system is shutting down!"); //$NON-NLS-1$
+			System.out.println("TaskScanningJob: system is shutting down!"); //$NON-NLS-1$
 		}
 		return shuttingDown;
 	}
 
 	private boolean isEnabledProject(IResource project) {
-		String[] projectsIgnored = StringUtils.unpack(SSECorePlugin.getDefault().getPluginPreferences().getString(CommonModelPreferenceNames.TASK_TAG_PROJECTS_IGNORED));
 		String[] projectsScanned = StringUtils.unpack(SSECorePlugin.getDefault().getPluginPreferences().getString(TASK_TAG_PROJECTS_ALREADY_SCANNED));
 
 		boolean shouldScan = true;
 		String name = project.getName();
-		for (int j = 0; shouldScan && j < projectsIgnored.length; j++) {
-			if (projectsIgnored[j].equals(name)) {
-				if (_debugJob)
-					System.out.println("Scanning Job ignoring " + project.getName());
-				shouldScan = false;
-			}
-		}
 		for (int j = 0; shouldScan && j < projectsScanned.length; j++) {
 			if (projectsScanned[j].equals(name)) {
 				if (_debugJob)
@@ -131,23 +119,6 @@
 		return shouldScan;
 	}
 
-	private boolean isIgnoredProject(IResourceDelta delta) {
-		IResource resource = delta.getResource();
-		boolean ignore = false;
-		if (resource.getType() == IResource.PROJECT) {
-			String[] projectsIgnored = StringUtils.unpack(SSECorePlugin.getDefault().getPluginPreferences().getString(CommonModelPreferenceNames.TASK_TAG_PROJECTS_IGNORED));
-			String name = resource.getName();
-			for (int j = 0; !ignore && j < projectsIgnored.length; j++) {
-				if (projectsIgnored[j].equals(name)) {
-					if (_debugJob)
-						System.out.println("Scanning Job ignoring " + resource.getName());
-					ignore = true;
-				}
-			}
-		}
-		return ignore;
-	}
-
 	synchronized List retrieveQueue() {
 		List queue = fQueue;
 		fQueue = new ArrayList();
@@ -155,10 +126,6 @@
 	}
 
 	protected IStatus run(IProgressMonitor monitor) {
-		if (frameworkIsShuttingDown())
-			return Status.OK_STATUS;
-
-		validateRememberedProjectList(CommonModelPreferenceNames.TASK_TAG_PROJECTS_IGNORED);
 		validateRememberedProjectList(TASK_TAG_PROJECTS_ALREADY_SCANNED);
 
 		IStatus status = null;
@@ -177,13 +144,15 @@
 		IProgressMonitor scanMonitor = null;
 		while (!currentQueue.isEmpty()) {
 			Object o = currentQueue.remove(0);
+			if (frameworkIsShuttingDown())
+				return Status.OK_STATUS;
 			try {
 				scanMonitor = new SubProgressMonitor(monitor, 1);
 				if (o instanceof IResourceDelta) {
-					TaskScanner.getInstance().scan((IResourceDelta) o, scanMonitor);
+					WorkspaceTaskScanner.getInstance().scan((IResourceDelta) o, scanMonitor);
 				}
 				else if (o instanceof IProject) {
-					TaskScanner.getInstance().scan((IProject) o, scanMonitor);
+					WorkspaceTaskScanner.getInstance().scan((IProject) o, scanMonitor);
 					String[] projectsPreviouslyScanned = StringUtils.unpack(SSECorePlugin.getDefault().getPluginPreferences().getString(TASK_TAG_PROJECTS_ALREADY_SCANNED));
 					String[] updatedProjects = new String[projectsPreviouslyScanned.length + 1];
 					updatedProjects[projectsPreviouslyScanned.length] = ((IResource) o).getName();
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScanningScheduler.java b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/TaskScanningScheduler.java
similarity index 69%
rename from bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScanningScheduler.java
rename to bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/TaskScanningScheduler.java
index 5e57985..ce8156f 100644
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScanningScheduler.java
+++ b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/TaskScanningScheduler.java
@@ -11,6 +11,9 @@
  *******************************************************************************/
 package org.eclipse.wst.sse.core.internal.tasks;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IResourceChangeEvent;
@@ -22,6 +25,8 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.wst.sse.core.internal.Logger;
 import org.eclipse.wst.sse.core.internal.SSECorePlugin;
+import org.eclipse.wst.sse.core.internal.provisional.tasks.IFileTaskScanner;
+import org.eclipse.wst.sse.core.internal.util.StringUtils;
 
 public class TaskScanningScheduler {
 	private class ListenerVisitor implements IResourceChangeListener, IResourceDeltaVisitor {
@@ -60,12 +65,26 @@
 
 	private static TaskScanningScheduler scheduler;
 
-
-	public static void refreshAll() {
-		SSECorePlugin.getDefault().getPluginPreferences().setValue(ScanningJob.TASK_TAG_PROJECTS_ALREADY_SCANNED, ""); //$NON-NLS-1$
+	public static void refresh() {
+		SSECorePlugin.getDefault().getPluginPreferences().setValue(TaskScanningJob.TASK_TAG_PROJECTS_ALREADY_SCANNED, ""); //$NON-NLS-1$
 		scheduler.enqueue(ResourcesPlugin.getWorkspace().getRoot());
 	}
 
+	public static void refresh(IProject project) {
+		String[] projectNames = StringUtils.unpack(SSECorePlugin.getDefault().getPluginPreferences().getString(TaskScanningJob.TASK_TAG_PROJECTS_ALREADY_SCANNED)); //$NON-NLS-1$
+		List freshProjectList = new ArrayList();
+		for (int i = 0; i < projectNames.length; i++) {
+			if (!projectNames[i].equals(project.getName())) {
+				freshProjectList.add(projectNames[i]);
+			}
+		}
+		String freshProjects = StringUtils.pack((String[]) freshProjectList.toArray(new String[freshProjectList.size()]));
+		SSECorePlugin.getDefault().getPluginPreferences().setValue(TaskScanningJob.TASK_TAG_PROJECTS_ALREADY_SCANNED, freshProjects); //$NON-NLS-1$
+
+		scheduler.enqueue(project);
+	}
+
+
 	/**
 	 * Only for use by SSECorePlugin class
 	 */
@@ -91,17 +110,31 @@
 		scheduler.enqueue(ResourcesPlugin.getWorkspace().getRoot());
 	}
 
-	ScanningJob fJob = null;
+	TaskScanningJob fJob = null;
 
 	ListenerVisitor visitor = null;
 
 	private TaskScanningScheduler() {
 		super();
-		fJob = new ScanningJob();
+		fJob = new TaskScanningJob();
 		visitor = new ListenerVisitor();
 	}
 
+	void enqueue(IProject project) {
+		try {
+			project.deleteMarkers(IFileTaskScanner.TASK_MARKER_ID, true, IResource.DEPTH_INFINITE);
+		}
+		catch (CoreException e) {
+		}
+		fJob.addProject(project);
+	}
+
 	void enqueue(IWorkspaceRoot root) {
+		try {
+			root.deleteMarkers(IFileTaskScanner.TASK_MARKER_ID, true, IResource.DEPTH_INFINITE);
+		}
+		catch (CoreException e) {
+		}
 		IProject[] allProjects = root.getProjects();
 		for (int i = 0; i < allProjects.length; i++) {
 			fJob.addProject(allProjects[i]);
diff --git a/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/TaskTagPreferenceKeys.java b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/TaskTagPreferenceKeys.java
new file mode 100644
index 0000000..bb3e305
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/TaskTagPreferenceKeys.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2005 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.sse.core.internal.tasks;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.wst.sse.core.internal.SSECorePlugin;
+
+public final class TaskTagPreferenceKeys {
+	public static final String TASK_TAG_CONTENTTYPES_IGNORED = "ignored-contentTypes"; //$NON-NLS-1$
+	public static final String TASK_TAG_ENABLE = "enabled"; //$NON-NLS-1$
+	public static final String TASK_TAG_NODE = SSECorePlugin.ID + IPath.SEPARATOR + "task-tags"; //$NON-NLS-1$
+	public static final String TASK_TAG_PER_PROJECT = "use-project-settings"; //$NON-NLS-1$
+	public static final String TASK_TAG_PRIORITIES = "taskPriorities"; //$NON-NLS-1$
+	public static final String TASK_TAG_TAGS = "taskTags"; //$NON-NLS-1$
+}
diff --git a/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/WorkspaceTaskScanner.java b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/WorkspaceTaskScanner.java
new file mode 100644
index 0000000..8d31ff6
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.core/src-tasktags/org/eclipse/wst/sse/core/internal/tasks/WorkspaceTaskScanner.java
@@ -0,0 +1,427 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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
+ *     Jens Lukowski/Innoopract - initial renaming/restructuring
+ *     
+ *******************************************************************************/
+package org.eclipse.wst.sse.core.internal.tasks;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.core.runtime.content.IContentTypeManager;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IPreferencesService;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.wst.sse.core.internal.Logger;
+import org.eclipse.wst.sse.core.internal.provisional.tasks.IFileTaskScanner;
+import org.eclipse.wst.sse.core.internal.provisional.tasks.TaskTag;
+import org.eclipse.wst.sse.core.internal.util.StringUtils;
+
+/**
+ * Dispatcher for scanning based on deltas and requested projects
+ */
+class WorkspaceTaskScanner {
+	private static final boolean _debug = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks")); //$NON-NLS-1$ //$NON-NLS-2$
+	private static final boolean _debugContentTypeDetection = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks/detection")); //$NON-NLS-1$ //$NON-NLS-2$
+	private static final boolean _debugOverallPerf = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks/overalltime")); //$NON-NLS-1$ //$NON-NLS-2$
+	private static final boolean _debugPreferences = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks/preferences")); //$NON-NLS-1$ //$NON-NLS-2$
+
+	private static WorkspaceTaskScanner _instance = null;
+
+	static synchronized WorkspaceTaskScanner getInstance() {
+		if (_instance == null) {
+			_instance = new WorkspaceTaskScanner();
+		}
+		return _instance;
+	}
+
+	static String getTaskMarkerType() {
+		return IFileTaskScanner.TASK_MARKER_ID;
+	}
+
+	private List fActiveScanners = null;
+	private IContentType[] fCurrentIgnoreContentTypes = null;
+	private TaskTag[] fCurrentTaskTags = null;
+	private FileTaskScannerRegistryReader registry = null;
+
+	private long time0;
+
+
+	/**
+	 * 
+	 */
+	private WorkspaceTaskScanner() {
+		super();
+		registry = FileTaskScannerRegistryReader.getInstance();
+		fActiveScanners = new ArrayList();
+		fCurrentTaskTags = new TaskTag[0];
+		fCurrentIgnoreContentTypes = new IContentType[0];
+	}
+
+	private IContentType[] detectContentTypes(IResource resource) {
+		IContentType[] types = null;
+		if (resource.getType() == IResource.FILE && resource.isAccessible()) {
+			types = Platform.getContentTypeManager().findContentTypesFor(resource.getName());
+			if (types.length == 0) {
+				IContentDescription d = null;
+				try {
+					// optimized description lookup, might not succeed
+					d = ((IFile) resource).getContentDescription();
+					if (d != null) {
+						types = new IContentType[]{d.getContentType()};
+					}
+				}
+				catch (CoreException e) {
+					/*
+					 * should not be possible given the accessible and file
+					 * type check above
+					 */
+				}
+			}
+			if (types == null) {
+				types = Platform.getContentTypeManager().findContentTypesFor(resource.getName());
+			}
+			if (_debugContentTypeDetection) {
+				if (types.length > 0) {
+					if (types.length > 1) {
+						System.out.println(resource.getFullPath() + ": " + "multiple based on name (probably hierarchical)"); //$NON-NLS-1$ //$NON-NLS-2$
+					}
+					for (int i = 0; i < types.length; i++) {
+						System.out.println(resource.getFullPath() + " matched: " + types[i].getId()); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+		return types;
+	}
+
+	/**
+	 * @param resource
+	 * @return
+	 */
+	private IProject getProject(IResource resource) {
+		IProject project = null;
+		if (resource.getType() == IResource.PROJECT) {
+			project = (IProject) resource;
+		}
+		else {
+			project = resource.getProject();
+		}
+		return project;
+	}
+
+	private boolean init(IResource resource) {
+		IProject project = getProject(resource);
+
+		IPreferencesService preferencesService = Platform.getPreferencesService();
+		IScopeContext[] lookupOrder = new IScopeContext[]{new ProjectScope(project), new InstanceScope(), new DefaultScope()};
+
+		boolean proceed = preferencesService.getBoolean(TaskTagPreferenceKeys.TASK_TAG_NODE, TaskTagPreferenceKeys.TASK_TAG_ENABLE, false, lookupOrder);
+
+		if (_debugPreferences) {
+			System.out.println(getClass().getName() + " scan of " + resource.getFullPath() + ":" + proceed); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+
+		if (proceed) {
+			String[] tags = StringUtils.unpack(preferencesService.getString(TaskTagPreferenceKeys.TASK_TAG_NODE, TaskTagPreferenceKeys.TASK_TAG_TAGS, null, lookupOrder));
+			String[] priorities = StringUtils.unpack(preferencesService.getString(TaskTagPreferenceKeys.TASK_TAG_NODE, TaskTagPreferenceKeys.TASK_TAG_PRIORITIES, null, lookupOrder));
+			String[] currentIgnoreContentTypeIDs = StringUtils.unpack(preferencesService.getString(TaskTagPreferenceKeys.TASK_TAG_NODE, TaskTagPreferenceKeys.TASK_TAG_CONTENTTYPES_IGNORED, null, lookupOrder));
+			if (_debugPreferences) {
+				System.out.print(getClass().getName() + " tags: "); //$NON-NLS-1$
+				for (int i = 0; i < tags.length; i++) {
+					if (i > 0) {
+						System.out.print(","); //$NON-NLS-1$
+					}
+					System.out.print(tags[i]);
+				}
+				System.out.println();
+				System.out.print(getClass().getName() + " priorities: "); //$NON-NLS-1$
+				for (int i = 0; i < priorities.length; i++) {
+					if (i > 0) {
+						System.out.print(","); //$NON-NLS-1$
+					}
+					System.out.print(priorities[i]);
+				}
+				System.out.println();
+				System.out.print(getClass().getName() + " ignored content types: "); //$NON-NLS-1$
+				for (int i = 0; i < currentIgnoreContentTypeIDs.length; i++) {
+					if (i > 0) {
+						System.out.print(","); //$NON-NLS-1$
+					}
+					System.out.print(currentIgnoreContentTypeIDs[i]);
+				}
+				System.out.println();
+			}
+			fCurrentIgnoreContentTypes = new IContentType[currentIgnoreContentTypeIDs.length];
+			IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
+			for (int i = 0; i < currentIgnoreContentTypeIDs.length; i++) {
+				fCurrentIgnoreContentTypes[i] = contentTypeManager.getContentType(currentIgnoreContentTypeIDs[i]);
+			}
+			int max = Math.min(tags.length, priorities.length);
+			fCurrentTaskTags = new TaskTag[max];
+			for (int i = 0; i < max; i++) {
+				int priority = TaskTag.PRIORITY_NORMAL;
+				try {
+					priority = Integer.parseInt(priorities[i]);
+				}
+				catch (NumberFormatException e) {
+					// default to normal priority
+				}
+				fCurrentTaskTags[i] = new TaskTag(tags[i], priority);
+			}
+		}
+		return proceed;
+	}
+
+	void internalScan(final IProject project, final IResource resource, final IProgressMonitor scanMonitor) {
+		if (scanMonitor.isCanceled())
+			return;
+		try {
+			String name = resource.getName();
+			if (!resource.isDerived() && !resource.isPhantom() && !resource.isTeamPrivateMember() && name.length() != 0 && name.charAt(0) != '.') {
+				if ((resource.getType() & IResource.FOLDER) > 0 || (resource.getType() & IResource.PROJECT) > 0) {
+					SubProgressMonitor childMonitor = new SubProgressMonitor(scanMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+					IResource[] children = ((IContainer) resource).members();
+					childMonitor.beginTask("", children.length); //$NON-NLS-1$
+					for (int i = 0; i < children.length; i++) {
+						internalScan(project, children[i], childMonitor);
+					}
+					childMonitor.done();
+				}
+				else if ((resource.getType() & IResource.FILE) > 0) {
+					scanFile(project, fCurrentTaskTags, (IFile) resource, scanMonitor);
+					scanMonitor.worked(1);
+				}
+			}
+			else {
+				scanMonitor.worked(1);
+
+			}
+			scanMonitor.done();
+		}
+		catch (CoreException e) {
+			Logger.logException(e);
+		}
+	}
+
+	void internalScan(IResourceDelta delta, final IProgressMonitor monitor) {
+		if (monitor.isCanceled())
+			return;
+		try {
+			String name = delta.getFullPath().lastSegment();
+			IResource resource = delta.getResource();
+			if (!resource.isDerived() && !resource.isPhantom() && !resource.isTeamPrivateMember() && name.length() != 0 && name.charAt(0) != '.') {
+				if ((resource.getType() & IResource.FOLDER) > 0 || (resource.getType() & IResource.PROJECT) > 0) {
+					IResourceDelta[] children = delta.getAffectedChildren();
+					if (name.length() != 0 && name.charAt(0) != '.' && children.length > 0) {
+						SubProgressMonitor childMonitor = new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+						childMonitor.beginTask("", children.length); //$NON-NLS-1$
+						for (int i = children.length - 1; i >= 0; i--) {
+							internalScan(children[i], new SubProgressMonitor(childMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
+						}
+						childMonitor.done();
+					}
+					else {
+						monitor.worked(1);
+					}
+				}
+				else if ((resource.getType() & IResource.FILE) > 0) {
+					if ((delta.getKind() & IResourceDelta.ADDED) > 0 || ((delta.getKind() & IResourceDelta.CHANGED) > 0 && (delta.getFlags() & IResourceDelta.CONTENT) > 0)) {
+						IFile file = (IFile) resource;
+						scanFile(file.getProject(), fCurrentTaskTags, file, monitor);
+					}
+					monitor.worked(1);
+				}
+			}
+			else {
+				monitor.worked(1);
+			}
+		}
+		catch (Exception e) {
+			monitor.done();
+			Logger.logException(e);
+		}
+	}
+
+	private void replaceMarkers(final IFile file, final Map markerAttributes[], IProgressMonitor monitor) {
+		final IFile finalFile = file;
+		if (file.isAccessible()) {
+			try {
+				IWorkspaceRunnable r = new IWorkspaceRunnable() {
+					public void run(IProgressMonitor progressMonitor) throws CoreException {
+						try {
+							// Delete old Task markers
+							file.deleteMarkers(getTaskMarkerType(), true, IResource.DEPTH_ZERO);
+						}
+						catch (CoreException e) {
+							Logger.logException("exception deleting old tasks", e); //$NON-NLS-1$ 
+						}
+						if (markerAttributes != null && markerAttributes.length > 0) {
+							if (_debug) {
+								System.out.println("" + markerAttributes.length + " tasks for " + file.getFullPath()); //$NON-NLS-1$ //$NON-NLS-2$
+							}
+							for (int i = 0; i < markerAttributes.length; i++) {
+								IMarker marker = finalFile.createMarker(getTaskMarkerType());
+								marker.setAttributes(markerAttributes[i]);
+							}
+						}
+					}
+				};
+				finalFile.getWorkspace().run(r, file, IWorkspace.AVOID_UPDATE, monitor);
+			}
+			catch (CoreException e1) {
+				Logger.logException(e1);
+			}
+		}
+	}
+
+	void scan(final IProject project, final IProgressMonitor scanMonitor) {
+		if (scanMonitor.isCanceled())
+			return;
+		if (_debug) {
+			System.out.println(getClass().getName() + " scanning project " + project.getName()); //$NON-NLS-1$
+		}
+		if (_debugOverallPerf) {
+			time0 = System.currentTimeMillis();
+		}
+		try {
+			scanMonitor.beginTask("", project.members().length); //$NON-NLS-1$
+			if (init(project)) {
+				internalScan(project, project, scanMonitor);
+				shutdownDelegates(project);
+			}
+			scanMonitor.done();
+		}
+		catch (CoreException e) {
+			Logger.logException(e);
+		}
+		if (_debugOverallPerf) {
+			System.out.println("" + (System.currentTimeMillis() - time0) + "ms for " + project.getFullPath()); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+
+
+	void scan(IResourceDelta delta, final IProgressMonitor monitor) {
+		if (monitor.isCanceled())
+			return;
+		if (_debugOverallPerf) {
+			time0 = System.currentTimeMillis();
+		}
+		monitor.beginTask("", 1); //$NON-NLS-1$
+		if (init(delta.getResource())) {
+			internalScan(delta, monitor);
+			shutdownDelegates(delta.getResource().getProject());
+		}
+		monitor.done();
+		if (_debugOverallPerf) {
+			System.out.println("" + (System.currentTimeMillis() - time0) + "ms for " + delta.getFullPath()); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+
+	void scanFile(IProject project, TaskTag[] taskTags, IFile file, IProgressMonitor monitor) {
+		if (monitor.isCanceled())
+			return;
+
+		SubProgressMonitor scannerMonitor = new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+		scannerMonitor.setTaskName(file.getFullPath().toString());
+		List markerAttributes = null;
+		IContentType[] types = detectContentTypes(file);
+		if (types != null) {
+			IFileTaskScanner[] fileScanners = null;
+			if (fCurrentIgnoreContentTypes.length == 0) {
+				fileScanners = registry.getFileTaskScanners(types);
+			}
+			else {
+				List validTypes = new ArrayList();
+				// obtain a filtered list of delegates
+				for (int i = 0; i < types.length; i++) {
+					boolean ignoreContentType = false;
+					for (int j = 0; j < fCurrentIgnoreContentTypes.length; j++) {
+						ignoreContentType = ignoreContentType || types[i].isKindOf(fCurrentIgnoreContentTypes[j]);
+					}
+					if (!ignoreContentType) {
+						validTypes.add(types[i]);
+					}
+				}
+				fileScanners = registry.getFileTaskScanners((IContentType[]) validTypes.toArray(new IContentType[validTypes.size()]));
+			}
+			if (fileScanners.length > 0) {
+				for (int j = 0; fileScanners != null && j < fileScanners.length; j++) {
+					if (scannerMonitor.isCanceled())
+						continue;
+					scannerMonitor.beginTask("", fileScanners.length);
+					try {
+						if (!fActiveScanners.contains(fileScanners[j]) && !monitor.isCanceled()) {
+							fileScanners[j].startup(file.getProject());
+							fActiveScanners.add(fileScanners[j]);
+						}
+						Map[] taskMarkerAttributes = fileScanners[j].scan(file, taskTags, scannerMonitor);
+						/*
+						 * TODO: pool the marker results so there's only one
+						 * operation creating them
+						 */
+						for (int i = 0; i < taskMarkerAttributes.length; i++) {
+							if (markerAttributes == null) {
+								markerAttributes = new ArrayList();
+							}
+							markerAttributes.add(taskMarkerAttributes[i]);
+						}
+						scannerMonitor.worked(1);
+					}
+					catch (Exception e) {
+						Logger.logException(file.getFullPath().toString(), e);
+					}
+				}
+				scannerMonitor.done();
+			}
+			else {
+				monitor.worked(1);
+			}
+		}
+		if (markerAttributes != null) {
+			replaceMarkers(file, (Map[]) markerAttributes.toArray(new Map[markerAttributes.size()]), monitor);
+		}
+		else {
+			replaceMarkers(file, null, monitor);
+		}
+	}
+
+	/**
+	 * 
+	 */
+	private void shutdownDelegates(IProject project) {
+		for (int j = 0; j < fActiveScanners.size(); j++) {
+			try {
+				((IFileTaskScanner) fActiveScanners.get(j)).shutdown(project);
+			}
+			catch (Exception e) {
+				Logger.logException(project.getFullPath().toString(), e);
+			}
+		}
+		fActiveScanners = new ArrayList(1);
+	}
+}
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/preferences/PreferenceInitializer.java b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/preferences/PreferenceInitializer.java
new file mode 100644
index 0000000..d9b1f1e
--- /dev/null
+++ b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/preferences/PreferenceInitializer.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.sse.core.internal.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.wst.sse.core.internal.tasks.TaskTagPreferenceKeys;
+
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+	 */
+	public void initializeDefaultPreferences() {
+		IEclipsePreferences taskTagDefaults = new DefaultScope().getNode(TaskTagPreferenceKeys.TASK_TAG_NODE);
+		taskTagDefaults.putBoolean(TaskTagPreferenceKeys.TASK_TAG_ENABLE, false);
+		taskTagDefaults.put(TaskTagPreferenceKeys.TASK_TAG_TAGS, "TODO,FIXME,XXX"); //$NON-NLS-1$
+		taskTagDefaults.put(TaskTagPreferenceKeys.TASK_TAG_PRIORITIES, "1,2,1"); //$NON-NLS-1$
+		taskTagDefaults.put(TaskTagPreferenceKeys.TASK_TAG_CONTENTTYPES_IGNORED, ""); //$NON-NLS-1$
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScanner.java b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScanner.java
deleted file mode 100644
index 94059ba..0000000
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScanner.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2001, 2004 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
- *     Jens Lukowski/Innoopract - initial renaming/restructuring
- *     
- *******************************************************************************/
-package org.eclipse.wst.sse.core.internal.tasks;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.content.IContentDescription;
-import org.eclipse.core.runtime.content.IContentType;
-import org.eclipse.wst.sse.core.internal.Logger;
-
-/**
- * Dispatcher for scanning based on deltas and requested projects
- */
-class TaskScanner {
-	private static final boolean _debug = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks")); //$NON-NLS-1$ //$NON-NLS-2$
-	private static final boolean _debugContentTypeDetection = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks/detection")); //$NON-NLS-1$ //$NON-NLS-2$
-	private static final boolean _debugOverallPerf = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks/overalltime")); //$NON-NLS-1$ //$NON-NLS-2$
-
-	private static TaskScanner _instance = null;
-
-	static synchronized TaskScanner getInstance() {
-		if (_instance == null) {
-			_instance = new TaskScanner();
-		}
-		return _instance;
-	}
-
-	private List fActiveDelegates = null;
-	private TaskScannerDelegateRegistryReader registry = null;
-	private long time0;
-
-	/**
-	 * 
-	 */
-	private TaskScanner() {
-		super();
-		registry = new TaskScannerDelegateRegistryReader();
-		fActiveDelegates = new ArrayList();
-	}
-
-
-	private IContentType[] detectContentTypes(IResource resource) {
-		IContentType[] types = null;
-		if (resource.getType() == IResource.FILE && resource.isAccessible()) {
-			IContentDescription d = null;
-			try {
-				// optimized description lookup, might not succeed
-				d = ((IFile) resource).getContentDescription();
-				if (d != null) {
-					types = new IContentType[]{d.getContentType()};
-				}
-			}
-			catch (CoreException e) {
-				/*
-				 * should not be possible given the accessible and file type
-				 * check above
-				 */
-			}
-			if (types == null) {
-				types = Platform.getContentTypeManager().findContentTypesFor(resource.getName());
-			}
-			if (_debugContentTypeDetection) {
-				if (types.length > 0) {
-					if (types.length > 1) {
-						System.out.println(resource.getFullPath() + ": " + "multiple based on name (probably hierarchical)"); //$NON-NLS-1$ //$NON-NLS-2$
-					}
-					for (int i = 0; i < types.length; i++) {
-						System.out.println(resource.getFullPath() + " matched: " + types[i].getId()); //$NON-NLS-1$
-					}
-				}
-			}
-		}
-		return types;
-	}
-
-	void internalScan(final IProject project, final IResource resource, final IProgressMonitor scanMonitor) {
-		if (scanMonitor.isCanceled())
-			return;
-		try {
-			String name = resource.getName();
-			if (!resource.isDerived() && !resource.isPhantom() && !resource.isTeamPrivateMember() && name.length() != 0 && name.charAt(0) != '.') {
-				if ((resource.getType() & IResource.FOLDER) > 0 || (resource.getType() & IResource.PROJECT) > 0) {
-					SubProgressMonitor childMonitor = new SubProgressMonitor(scanMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
-					IResource[] children = ((IContainer) resource).members();
-					childMonitor.beginTask("", children.length); //$NON-NLS-1$
-					for (int i = children.length - 1; i >= 0; i--) {
-						internalScan(project, children[i], new SubProgressMonitor(childMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
-					}
-					childMonitor.done();
-				}
-				else if ((resource.getType() & IResource.FILE) > 0) {
-					scanFile(project, (IFile) resource, scanMonitor);
-					scanMonitor.worked(1);
-				}
-			}
-			else {
-				scanMonitor.worked(1);
-
-			}
-			scanMonitor.done();
-		}
-		catch (CoreException e) {
-			Logger.logException(e);
-		}
-	}
-
-	void internalScan(IResourceDelta delta, final IProgressMonitor monitor) {
-		if (monitor.isCanceled())
-			return;
-		try {
-			String name = delta.getFullPath().lastSegment();
-			IResource resource = delta.getResource();
-			if (!resource.isDerived() && !resource.isPhantom() && !resource.isTeamPrivateMember() && name.length() != 0 && name.charAt(0) != '.') {
-				if ((resource.getType() & IResource.FOLDER) > 0 || (resource.getType() & IResource.PROJECT) > 0) {
-					IResourceDelta[] children = delta.getAffectedChildren();
-					if (name.length() != 0 && name.charAt(0) != '.' && children.length > 0) {
-						SubProgressMonitor childMonitor = new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
-						childMonitor.beginTask("", children.length); //$NON-NLS-1$
-						for (int i = children.length - 1; i >= 0; i--) {
-							internalScan(children[i], new SubProgressMonitor(childMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
-						}
-						childMonitor.done();
-					}
-					else {
-						monitor.worked(1);
-					}
-				}
-				else if ((resource.getType() & IResource.FILE) > 0) {
-					if ((delta.getKind() & IResourceDelta.ADDED) > 0 || ((delta.getKind() & IResourceDelta.CHANGED) > 0 && (delta.getFlags() & IResourceDelta.CONTENT) > 0)) {
-						IFile file = (IFile) resource;
-						scanFile(file.getProject(), file, monitor);
-					}
-					monitor.worked(1);
-				}
-			}
-			else {
-				monitor.worked(1);
-			}
-		}
-		catch (Exception e) {
-			monitor.done();
-			Logger.logException(e);
-		}
-	}
-
-	void scan(final IProject project, final IProgressMonitor scanMonitor) {
-		if (scanMonitor.isCanceled())
-			return;
-		if (_debug) {
-			System.out.println(getClass().getName() + " scanning project " + project.getName()); //$NON-NLS-1$
-		}
-		if (_debugOverallPerf) {
-			time0 = System.currentTimeMillis();
-		}
-		try {
-			scanMonitor.beginTask("", project.members().length); //$NON-NLS-1$
-			internalScan(project, project, scanMonitor);
-			shutdownDelegates(project);
-			scanMonitor.done();
-		}
-		catch (CoreException e) {
-			Logger.logException(e);
-		}
-		if (_debugOverallPerf) {
-			System.out.println("" + (System.currentTimeMillis() - time0) + "ms for " + project.getFullPath()); //$NON-NLS-1$ //$NON-NLS-2$
-		}
-	}
-
-	void scan(IResourceDelta delta, final IProgressMonitor monitor) {
-		if (monitor.isCanceled())
-			return;
-		if (_debugOverallPerf) {
-			time0 = System.currentTimeMillis();
-		}
-		monitor.beginTask("", 1); //$NON-NLS-1$
-		internalScan(delta, monitor);
-		shutdownDelegates(delta.getResource().getProject());
-		monitor.done();
-		if (_debugOverallPerf) {
-			System.out.println("" + (System.currentTimeMillis() - time0) + "ms for " + delta.getFullPath()); //$NON-NLS-1$ //$NON-NLS-2$
-		}
-	}
-
-	void scanFile(IProject project, IFile file, IProgressMonitor monitor) {
-		if (monitor.isCanceled())
-			return;
-		ITaskScannerDelegate[] delegates = null;
-		IContentType[] types = detectContentTypes(file);
-		if (types != null) {
-			List allDelegates = new ArrayList();
-			for (int i = 0; i < types.length; i++) {
-				ITaskScannerDelegate[] typeDelegates = registry.getTaskScannerDelegates(types[i].getId());
-				if (typeDelegates != null && typeDelegates.length > 0) {
-					allDelegates.addAll(Arrays.asList(typeDelegates));
-				}
-			}
-			delegates = (ITaskScannerDelegate[]) allDelegates.toArray(new ITaskScannerDelegate[0]);
-			if (delegates.length > 0) {
-				SubProgressMonitor delegateMonitor = new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
-				delegateMonitor.beginTask(file.getFullPath().toString(), delegates.length);
-				for (int j = 0; delegates != null && j < delegates.length; j++) {
-					if (delegateMonitor.isCanceled())
-						continue;
-					try {
-						if (!fActiveDelegates.contains(delegates[j]) && !monitor.isCanceled()) {
-							delegates[j].startup(file.getProject());
-							fActiveDelegates.add(delegates[j]);
-						}
-						delegates[j].scan(file, delegateMonitor);
-						delegateMonitor.worked(1);
-					}
-					catch (Exception e) {
-						Logger.logException(file.getFullPath().toString(), e);
-					}
-				}
-				delegateMonitor.done();
-			}
-			else {
-				monitor.worked(1);
-			}
-		}
-	}
-
-	/**
-	 * 
-	 */
-	private void shutdownDelegates(IProject project) {
-		for (int j = 0; j < fActiveDelegates.size(); j++) {
-			try {
-				((ITaskScannerDelegate) fActiveDelegates.get(j)).shutdown(project);
-			}
-			catch (Exception e) {
-				Logger.logException(project.getFullPath().toString(), e);
-			}
-		}
-		fActiveDelegates = new ArrayList(1);
-	}
-}
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScannerDelegateRegistryReader.java b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScannerDelegateRegistryReader.java
deleted file mode 100644
index 3361506..0000000
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/tasks/TaskScannerDelegateRegistryReader.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2001, 2004 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
- *     Jens Lukowski/Innoopract - initial renaming/restructuring
- *     
- *******************************************************************************/
-package org.eclipse.wst.sse.core.internal.tasks;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtensionPoint;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.content.IContentType;
-import org.eclipse.core.runtime.content.IContentTypeManager;
-import org.eclipse.wst.sse.core.internal.Logger;
-import org.eclipse.wst.sse.core.internal.SSECorePlugin;
-import org.eclipse.wst.sse.core.internal.util.StringUtils;
-
-class TaskScannerDelegateRegistryReader {
-	private static final boolean _debugReader = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/tasks/registry")); //$NON-NLS-1$ //$NON-NLS-2$
-
-	private String ATT_CLASS = "class"; //$NON-NLS-1$
-	private String ATT_CONTENT_TYPES = "contentTypeIds"; //$NON-NLS-1$
-	private String DELEGATE_EXTENSION_POINT_ID = SSECorePlugin.ID + ".taskscanner"; //$NON-NLS-1$
-
-	private IConfigurationElement[] fDelegateElements;
-
-	// a mapping from content types to ITaskScannerDelegate instances
-	private Map fDelegates = null;
-
-	private String NAME_SCANNER = "scanner"; //$NON-NLS-1$
-
-	TaskScannerDelegateRegistryReader() {
-		super();
-	}
-
-	public ITaskScannerDelegate[] getTaskScannerDelegates(String contentTypeID) {
-		if (fDelegateElements == null) {
-			readRegistry();
-		}
-		IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
-		ITaskScannerDelegate[] delegates = (ITaskScannerDelegate[]) fDelegates.get(contentTypeID);
-		if (delegates == null) {
-			// fine the relevant extensions
-			List elements = new ArrayList(0);
-			IConfigurationElement[] delegateElements = fDelegateElements;
-			IContentType contentType = contentTypeManager.getContentType(contentTypeID);
-			if (contentType != null) {
-				for (int j = 0; j < delegateElements.length; j++) {
-					if (!delegateElements[j].getName().equals(NAME_SCANNER))
-						continue;
-					String[] contentTypeIds = StringUtils.unpack(delegateElements[j].getAttribute(ATT_CONTENT_TYPES));
-					IContentType[] contentTypes = new IContentType[contentTypeIds.length];
-					for (int i = 0; i < contentTypeIds.length; i++) {
-						contentTypes[i] = contentTypeManager.getContentType(contentTypeIds[i].trim());
-					}
-					for (int k = 0; k < contentTypeIds.length; k++) {
-						// allow wildcards to be returned as well
-						if (contentTypes[k] != null && contentType.isKindOf(contentTypes[k])) {
-							elements.add(delegateElements[j]);
-						}
-					}
-				}
-				// instantiate and save them
-				List delegateList = new ArrayList(elements.size());
-				for (int i = 0; i < elements.size(); i++) {
-					try {
-						ITaskScannerDelegate delegate = (ITaskScannerDelegate) ((IConfigurationElement) elements.get(i)).createExecutableExtension(ATT_CLASS);
-						if (delegate != null) {
-							delegateList.add(delegate);
-						}
-					}
-					catch (CoreException e) {
-						Logger.logException("Non-fatal exception creating task scanner delegate for " + contentTypeID, e); //$NON-NLS-1$
-					}
-				}
-				delegates = (ITaskScannerDelegate[]) delegateList.toArray(new ITaskScannerDelegate[delegateList.size()]);
-				fDelegates.put(contentTypeID, delegates);
-				if (_debugReader) {
-					System.out.println("Created " + delegates.length + " task scanner delegate for " + contentTypeID); //$NON-NLS-1$ //$NON-NLS-2$
-				}
-			}
-		}
-		return delegates;
-	}
-
-	private void readRegistry() {
-		fDelegates = new HashMap();
-		// Just remember the elements, so plugins don't have to be activated,
-		// unless extension attributes match those of interest
-		IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(DELEGATE_EXTENSION_POINT_ID);
-		if (point != null) {
-			fDelegateElements = point.getConfigurationElements();
-		}
-	}
-}