move resource handling and builder support from ModelPlugin to builder class
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/ModelPlugin.java b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/ModelPlugin.java
index 4abc45a..456debe 100644
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/ModelPlugin.java
+++ b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/ModelPlugin.java
@@ -12,30 +12,13 @@
  *******************************************************************************/
 package org.eclipse.wst.sse.core;
 
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.resources.WorkspaceJob;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPluginDescriptor;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Plugin;
 import org.eclipse.core.runtime.Preferences;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.wst.common.encoding.CommonEncodingPreferenceNames;
-import org.eclipse.wst.sse.core.internal.Logger;
 import org.eclipse.wst.sse.core.internal.builder.StructuredDocumentBuilder;
 import org.eclipse.wst.sse.core.internal.modelhandler.ModelHandlerRegistry;
-import org.eclipse.wst.sse.core.internal.nls.ResourceHandler;
 import org.eclipse.wst.sse.core.preferences.CommonModelPreferenceNames;
 import org.osgi.framework.Bundle;
 
@@ -71,54 +54,10 @@
  * as a parameter ("org.eclipse.wst.sse.core" in the above example).
  */
 public class ModelPlugin extends Plugin implements IModelManagerPlugin {
-	protected static class ProjectChangeListener implements IResourceChangeListener, IResourceDeltaVisitor {
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
-		 */
-		public void resourceChanged(IResourceChangeEvent event) {
-			IResourceDelta delta = event.getDelta();
-			if (delta.getResource() != null) {
-				int resourceType = delta.getResource().getType();
-				if (resourceType == IResource.PROJECT || resourceType == IResource.ROOT) {
-					try {
-						delta.accept(this);
-					} catch (CoreException e) {
-						Logger.logException("Exception managing buildspec list", e); //$NON-NLS-1$
-					}
-				}
-			}
-		}
 
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
-		 */
-		public boolean visit(IResourceDelta delta) throws CoreException {
-			IResource resource = delta.getResource();
-			if (resource != null) {
-				if (resource.getType() == IResource.ROOT)
-					return true;
-				else if (resource.getType() == IResource.PROJECT) {
-					if (delta.getKind() == IResourceDelta.ADDED) {
-						if (_debugResourceChangeListener) {
-							System.out.println("Project " + delta.getResource().getName() + " added to workspace and registering with SDMB");//$NON-NLS-2$//$NON-NLS-1$
-						}
-						StructuredDocumentBuilder.add(new NullProgressMonitor(), (IProject) resource, null);
-					}
-					return false;
-				}
-			}
-			return false;
-		}
-	}
-
-	static final boolean _debugResourceChangeListener = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/resourcechangehandling")); //$NON-NLS-1$ //$NON-NLS-2$
 	static ModelPlugin instance = null;
-	private static final String OFF = "off"; //$NON-NLS-1$
 
+	private static final String OFF = "off"; //$NON-NLS-1$
 	public static final String STRUCTURED_BUILDER = "org.eclipse.wst.sse.core.structuredbuilder"; //$NON-NLS-1$
 
 	public static ModelPlugin getDefault() {
@@ -129,8 +68,6 @@
 		return getDefault().getBundle().getSymbolicName();
 	}
 
-	private ProjectChangeListener changeListener;
-
 	public ModelPlugin() {
 		super();
 		instance = this;
@@ -156,19 +93,24 @@
 				isReady = true;
 				// getInstance is a synchronized static method.
 				modelManager = ModelManagerImpl.getInstance();
-			} else if (state == Bundle.STARTING) {
+			}
+			else if (state == Bundle.STARTING) {
 				try {
 					Thread.sleep(100);
-				} catch (InterruptedException e) {
+				}
+				catch (InterruptedException e) {
 					// ignore, just loop again
 				}
-			} else if (state == Bundle.STOPPING) {
+			}
+			else if (state == Bundle.STOPPING) {
 				isReady = true;
 				modelManager = new NullModelManager();
-			} else if (state == Bundle.UNINSTALLED) {
+			}
+			else if (state == Bundle.UNINSTALLED) {
 				isReady = true;
 				modelManager = new NullModelManager();
-			} else {
+			}
+			else {
 				// not sure about other states, 'resolved', 'installed'
 				isReady = true;
 			}
@@ -211,11 +153,7 @@
 	public void shutdown() throws CoreException {
 		super.shutdown();
 		savePluginPreferences();
-		// Remove the listener from the workspace
-		IWorkspace workspace = ResourcesPlugin.getWorkspace();
-		if (changeListener != null && workspace != null) {
-			workspace.removeResourceChangeListener(changeListener);
-		}
+		StructuredDocumentBuilder.shutdown();
 		FileBufferModelManager.shutdown();
 	}
 
@@ -227,46 +165,14 @@
 	public void startup() throws CoreException {
 		super.startup();
 
-		String build = System.getProperty(STRUCTURED_BUILDER);
-		if (build == null || !build.equalsIgnoreCase(OFF)) {
-			// TODO: always off, until redesigned
-			// doTaskTagProcessing();
-		}
-		// initialize FileBuffer handling
+		// initialize FileBuffer support
 		FileBufferModelManager.startup();
 
+		// allow for explicitly disabling the builder (testing)
+		String build = System.getProperty(STRUCTURED_BUILDER);
+		if (build == null || !build.equalsIgnoreCase(OFF)) {
+			StructuredDocumentBuilder.startup();
+		}
 	}
 
-	// make private if ever used again
-	 void doTaskTagProcessing() {
-		// Must make sure the builder is registered for projects which may
-		// have
-		// been created before this plugin was activated.
-		Job adder = new WorkspaceJob(ResourceHandler.getString("ModelPlugin.0")) { //$NON-NLS-1$
-			public IStatus runInWorkspace(IProgressMonitor monitor) {
-				StructuredDocumentBuilder.add(monitor, ResourcesPlugin.getWorkspace().getRoot(), null);
-				return Status.OK_STATUS;
-			}
-		};
-		adder.setSystem(true);
-		// use SHORT, since once executing,
-		// this job should be quick, since
-		// this is the job that just adds
-		// to the .project files. Its later
-		// that files are scanned for task
-		// tags.
-		adder.setPriority(Job.SHORT);
-		// since we have potential to change several .project files,
-		// we should wait until we can get exclusive access to
-		// whole workspace.
-		// TODO: future re-design should not require this.
-		adder.setRule(ResourcesPlugin.getWorkspace().getRoot());
-		adder.schedule();
-
-		// Register the ProjectChangeListener so that it can add the
-		// builder
-		// to projects as needed
-		changeListener = new ProjectChangeListener();
-		ResourcesPlugin.getWorkspace().addResourceChangeListener(changeListener, IResourceChangeEvent.PRE_BUILD);
-	}
 }
diff --git a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/builder/StructuredDocumentBuilder.java b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/builder/StructuredDocumentBuilder.java
index 8492a01..ee91725 100644
--- a/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/builder/StructuredDocumentBuilder.java
+++ b/bundles/org.eclipse.wst.sse.core/src/org/eclipse/wst/sse/core/internal/builder/StructuredDocumentBuilder.java
@@ -23,12 +23,16 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
 import org.eclipse.core.resources.IResourceDelta;
 import org.eclipse.core.resources.IResourceDeltaVisitor;
 import org.eclipse.core.resources.IResourceVisitor;
 import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExecutableExtension;
@@ -36,10 +40,12 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
 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.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.wst.sse.core.IModelManagerPlugin;
 import org.eclipse.wst.sse.core.ModelPlugin;
 import org.eclipse.wst.sse.core.builder.IBuilderDelegate;
@@ -53,11 +59,57 @@
 	protected static final boolean _debugBuilder = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/builder")); //$NON-NLS-1$ //$NON-NLS-2$
 	protected static final boolean _debugBuilderContentTypeDetection = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/builder/detection")); //$NON-NLS-1$ //$NON-NLS-2$
 	protected static final boolean _debugBuilderPerf = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/builder/time")); //$NON-NLS-1$ //$NON-NLS-2$
-	private static final boolean doValidateEdit = false;
+	private static final boolean performValidateEdit = false;
 
 	protected static IModelManagerPlugin fPlugin = null;
 	private static boolean isGloballyEnabled = true;
 	private static final String OFF = "off"; //$NON-NLS-1$
+	static final boolean _debugResourceChangeListener = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.core/resourcechangehandling")); //$NON-NLS-1$ //$NON-NLS-2$
+
+	protected static class ProjectChangeListener implements IResourceChangeListener, IResourceDeltaVisitor {
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+		 */
+		public void resourceChanged(IResourceChangeEvent event) {
+			IResourceDelta delta = event.getDelta();
+			if (delta.getResource() != null) {
+				int resourceType = delta.getResource().getType();
+				if (resourceType == IResource.PROJECT || resourceType == IResource.ROOT) {
+					try {
+						delta.accept(this);
+					}
+					catch (CoreException e) {
+						Logger.logException("Exception managing buildspec list", e); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
+		 */
+		public boolean visit(IResourceDelta delta) throws CoreException {
+			IResource resource = delta.getResource();
+			if (resource != null) {
+				if (resource.getType() == IResource.ROOT)
+					return true;
+				else if (resource.getType() == IResource.PROJECT) {
+					if (delta.getKind() == IResourceDelta.ADDED) {
+						if (_debugResourceChangeListener) {
+							System.out.println("Project " + delta.getResource().getName() + " added to workspace and registering with SDMB");//$NON-NLS-2$//$NON-NLS-1$
+						}
+						add(new NullProgressMonitor(), (IProject) resource, null);
+					}
+					return false;
+				}
+			}
+			return false;
+		}
+	}
 
 	static {
 		String build = System.getProperty(ModelPlugin.STRUCTURED_BUILDER);
@@ -93,7 +145,7 @@
 				if (!isBuilderPresent && !monitor.isCanceled()) {
 					// validate for edit
 					IStatus status = null;
-					if (doValidateEdit) {
+					if (performValidateEdit) {
 						ISchedulingRule validateEditRule = null;
 						try {
 							if (_debugBuilder) {
@@ -107,11 +159,13 @@
 							if (_debugBuilder) {
 								if (status.isOK()) {
 									System.out.println("ValidateEdit completed for " + descriptionFile.getFullPath().toString()); //$NON-NLS-1$
-								} else {
+								}
+								else {
 									System.out.println("ValidateEdit failed for " + descriptionFile.getFullPath().toString() + " " + status.getMessage()); //$NON-NLS-2$//$NON-NLS-1$
 								}
 							}
-						} finally {
+						}
+						finally {
 							if (validateEditRule != null) {
 								Platform.getJobManager().endRule(validateEditRule);
 							}
@@ -126,7 +180,8 @@
 							newCommands = new ICommand[commands.length + 1];
 							System.arraycopy(commands, 0, newCommands, 0, commands.length);
 							newCommands[commands.length] = newCommand;
-						} else {
+						}
+						else {
 							newCommands = new ICommand[1];
 							newCommands[0] = newCommand;
 						}
@@ -143,29 +198,34 @@
 						// IProgressMonitor.UNKNOWN));
 						try {
 							project.setDescription(description, subMonitorFor(monitor, 1, IProgressMonitor.UNKNOWN));
-						} catch (CoreException e) {
+						}
+						catch (CoreException e) {
 							if (_debugBuilder) {
-								if (doValidateEdit) {
+								if (performValidateEdit) {
 									System.out.println("Description for project \"" + project.getName() + "\" could not be updated despite successful validateEdit"); //$NON-NLS-2$//$NON-NLS-1$
-								} else {
+								}
+								else {
 									System.out.println("Description for project \"" + project.getName() + "\" could not be updated"); //$NON-NLS-2$//$NON-NLS-1$
 								}
 							}
-							if (doValidateEdit) {
+							if (performValidateEdit) {
 								Logger.log(Logger.WARNING, "Description for project \"" + project.getName() + "\" could not be updated despite successful validateEdit"); //$NON-NLS-2$//$NON-NLS-1$					
-							} else {
+							}
+							else {
 								Logger.log(Logger.WARNING, "Description for project \"" + project.getName() + "\" could not be updated"); //$NON-NLS-2$//$NON-NLS-1$					
 							}
 						}
 					}
 				}
-			} else {
+			}
+			else {
 				if (_debugBuilder) {
 					System.out.println("Description for project \"" + project.getName() + "\" could not be updated"); //$NON-NLS-2$//$NON-NLS-1$
 				}
 				Logger.log(Logger.WARNING, "Description for project \"" + project.getName() + "\" could not be updated"); //$NON-NLS-2$//$NON-NLS-1$
 			}
-		} catch (Exception e) {
+		}
+		catch (Exception e) {
 			// if we can't read the information, the project isn't open,
 			// so it can't run auto-validate
 			Logger.logException("Exception caught when adding Model Builder", e); //$NON-NLS-1$
@@ -222,9 +282,10 @@
 	protected BuilderParticipantRegistryReader registry = null;
 
 	private long time0;
+	private IResourceChangeListener changeListener;
 
 	/**
-	 *  
+	 * 
 	 */
 	public StructuredDocumentBuilder() {
 		super();
@@ -243,7 +304,7 @@
 	protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
 		IProject currentProject = getProject();
 		// Currently, just use the Task Tags preference
-		boolean locallyEnabled = isGloballyEnabled && ModelPlugin.getDefault().getPluginPreferences().getBoolean(CommonModelPreferenceNames.TASK_TAG_ENABLE);
+		boolean locallyEnabled = isGloballyEnabled && Platform.getPlugin(IModelManagerPlugin.ID).getPluginPreferences().getBoolean(CommonModelPreferenceNames.TASK_TAG_ENABLE);
 		if (!locallyEnabled || currentProject == null || !currentProject.isAccessible()) {
 			if (_debugBuilderPerf || _debugBuilder) {
 				System.out.println(getClass().getName() + " skipping build of " + currentProject.getName()); //$NON-NLS-1$
@@ -262,7 +323,8 @@
 			// check the kind of delta if one was given
 			if (kind == FULL_BUILD || kind == CLEAN_BUILD || delta == null) {
 				doFullBuild(kind, args, localMonitor, getProject());
-			} else {
+			}
+			else {
 				doIncrementalBuild(kind, args, localMonitor);
 			}
 		}
@@ -273,7 +335,8 @@
 			if (kind == FULL_BUILD || delta == null) {
 				System.out.println(getClass().getName() + " finished FULL build of " + currentProject.getName() //$NON-NLS-1$
 							+ " in " + (System.currentTimeMillis() - time0) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
-			} else {
+			}
+			else {
 				System.out.println(getClass().getName() + " finished INCREMENTAL/CLEAN/AUTO build of " + currentProject.getName() //$NON-NLS-1$
 							+ " in " + (System.currentTimeMillis() - time0) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
 			}
@@ -302,7 +365,8 @@
 						fActiveDelegates.add(delegates[j]);
 					}
 					delegates[j].build((IFile) resource, kind, args, subMonitorFor(monitor, 100));
-				} catch (Exception e) {
+				}
+				catch (Exception e) {
 					Logger.logException(e);
 				}
 			}
@@ -340,7 +404,8 @@
 				if (d != null) {
 					types = new IContentType[]{d.getContentType()};
 				}
-			} catch (CoreException e) {
+			}
+			catch (CoreException e) {
 				// should not be possible given the accessible and file type
 				// check above
 			}
@@ -387,7 +452,8 @@
 						visitorMonitor.worked(1);
 					}
 					return false;
-				} else {
+				}
+				else {
 					return true;
 				}
 			}
@@ -395,13 +461,14 @@
 		};
 		try {
 			project.accept(internalBuilder);
-		} catch (CoreException e) {
+		}
+		catch (CoreException e) {
 			Logger.logException(e);
 		}
 	}
 
 	/**
-	 *  
+	 * 
 	 */
 	protected void doIncrementalBuild(int kind, Map args, IProgressMonitor monitor) {
 		IResourceDelta projectDelta = getDelta(getProject());
@@ -411,7 +478,8 @@
 		if (_debugBuilder) {
 			if (projectDelta != null && projectDelta.getResource() != null) {
 				System.out.println(getClass().getName() + " building " + projectDelta.getResource().getFullPath()); //$NON-NLS-1$
-			} else {
+			}
+			else {
 				System.out.println(getClass().getName() + " building project " + getProject().getName()); //$NON-NLS-1$
 			}
 		}
@@ -431,7 +499,8 @@
 		};
 		try {
 			projectDelta.accept(participantVisitor);
-		} catch (CoreException e) {
+		}
+		catch (CoreException e) {
 			Logger.logException(e);
 		}
 		monitor.worked(1);
@@ -454,16 +523,57 @@
 	}
 
 	/**
-	 *  
+	 * 
 	 */
 	private void shutdownDelegates() {
 		for (int j = 0; j < fActiveDelegates.size(); j++) {
 			try {
 				((IBuilderDelegate) fActiveDelegates.get(j)).shutdown(getProject());
-			} catch (Exception e) {
+			}
+			catch (Exception e) {
 				Logger.logException(e);
 			}
 		}
 		fActiveDelegates = new ArrayList(1);
 	}
+
+	// make private if ever used again
+	void doTaskTagProcessing() {
+		// Must make sure the builder is registered for projects which may
+		// have been created before this plugin was activated.
+		Job adder = new WorkspaceJob(ResourceHandler.getString("ModelPlugin.0")) { //$NON-NLS-1$
+			public IStatus runInWorkspace(IProgressMonitor monitor) {
+				add(monitor, ResourcesPlugin.getWorkspace().getRoot(), null);
+				return Status.OK_STATUS;
+			}
+		};
+		adder.setSystem(true);
+		// use SHORT, since once executing, this job should be quick
+		adder.setPriority(Job.SHORT);
+		// since we have potential to change several .project files,
+		// we should wait until we can get exclusive access to
+		// whole workspace.
+		// TODO: future re-design should not require this.
+		adder.setRule(ResourcesPlugin.getWorkspace().getRoot());
+		adder.schedule();
+
+		// Register the ProjectChangeListener so that it can add the
+		// builder
+		// to projects as needed
+		changeListener = new ProjectChangeListener();
+		ResourcesPlugin.getWorkspace().addResourceChangeListener(changeListener, IResourceChangeEvent.PRE_BUILD);
+	}
+
+	/**
+	 * Only for use by ModelPlugin class
+	 */
+	public static void shutdown() {
+	}
+
+	/**
+	 * Only for use by ModelPlugin class
+	 */
+	public static void startup() {
+		// TODO:disabled for now
+	}
 }