Updated to use most recent JSP indexer code.
diff --git a/bundles/org.eclipse.wst.jsdt.web.core/plugin.xml b/bundles/org.eclipse.wst.jsdt.web.core/plugin.xml
index e33d5b1..82a5c59 100644
--- a/bundles/org.eclipse.wst.jsdt.web.core/plugin.xml
+++ b/bundles/org.eclipse.wst.jsdt.web.core/plugin.xml
@@ -18,11 +18,21 @@
    		<project-facet id="wst.jsdt.web">
 			<label>JavaScript Toolkit</label>
 	  	 	<description>Adds advanced JavaScript editing support.</description>
-	  	 	
 	  	  	<default-version version="1.0"/>
 		</project-facet>
 	
 		<project-facet-version facet="wst.jsdt.web" version="1.0">
+		
+		<constraint>
+			<and>
+			  <or>
+			    <requires facet="jst.web"/>
+			    <requires facet="wst.web"/>
+			  </or>
+			  <conflicts facet="jst.ear"/>	  
+			</and>
+		</constraint>
+		
 		</project-facet-version>
 	
 		<action facet="wst.jsdt.web" type="install" id="wst.jsdt.web.install" version="1.0">
@@ -40,6 +50,7 @@
 	    <facet id="wst.jsdt.web"/>
 	    <runtime-component any="true"/>
 	  </supported>
+
 	</extension>
    
    
diff --git a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/validation/Util.java b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/validation/Util.java
index 92a03a0..e0e7a45 100644
--- a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/validation/Util.java
+++ b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/internal/validation/Util.java
@@ -16,6 +16,7 @@
 public class Util {
 	
 	public static boolean isJsType(String fileName) {
+		if(fileName==null) return false;
 		boolean valid = false;
 		IContentType[] types =getJavascriptContentTypes();
 		int i = 0;
diff --git a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/IndexWorkspaceJob.java b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/IndexWorkspaceJob.java
index 84945d0..47b33c9 100644
--- a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/IndexWorkspaceJob.java
+++ b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/IndexWorkspaceJob.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 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
  *******************************************************************************/
@@ -23,68 +23,70 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Status;
-//import org.eclipse.core.runtime.content.IContentType;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.wst.jsdt.web.core.internal.JsCoreMessages;
 import org.eclipse.wst.jsdt.web.core.internal.validation.Util;
 
 /**
- * Re-indexes the entire workspace. Ensures the JSP Index is in a stable state
- * before performing a search. (like after a crash or if previous indexing was
- * canceled)
+ * Re-indexes the entire workspace.
+ * Ensures the JSP Index is in a stable state before performing a search.
+ * (like after a crash or if previous indexing was canceled)
  * 
  * @author pavery
  */
 public class IndexWorkspaceJob extends Job {
+
 	// for debugging
 	static final boolean DEBUG;
 	static {
-		String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jspindexmanager"); //$NON-NLS-1$
-		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+		String value= Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/jspindexmanager"); //$NON-NLS-1$
+		DEBUG= (value != null) && value.equalsIgnoreCase("true"); //$NON-NLS-1$
 	}
+	
 	/**
-	 * Visitor that retrieves jsp project paths for all jsp files in the
-	 * workspace, and adds the files to be indexed as they are encountered
+	 * Visitor that retrieves jsp project paths for all jsp files in the workspace,
+	 * and adds the files to be indexed as they are encountered
 	 */
 	private class JSPFileVisitor implements IResourceProxyVisitor {
-		private List files = new ArrayList();
+	    private List files = new ArrayList(); 
+		
 		// monitor from the Job
 		IProgressMonitor fInnerMonitor = null;
-		
 		public JSPFileVisitor(IProgressMonitor monitor) {
 			this.fInnerMonitor = monitor;
 		}
 		
-		public final IFile[] getFiles() {
-			return (IFile[]) this.files.toArray(new IFile[this.files.size()]);
-		}
-		
 		public boolean visit(IResourceProxy proxy) throws CoreException {
+			
 			// check job canceled
-			if (this.fInnerMonitor != null && this.fInnerMonitor.isCanceled()) {
+			if ((this.fInnerMonitor != null) && this.fInnerMonitor.isCanceled()) {
 				setCanceledState();
 				return false;
 			}
+			
 			// check search support canceled
-			if (JsSearchSupport.getInstance().isCanceled()) {
+			if(JsSearchSupport.getInstance().isCanceled()) {
 				setCanceledState();
 				return false;
 			}
+			
 			if (proxy.getType() == IResource.FILE) {
+				
 				// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3553
 				// check this before description
 				// check name before actually getting the file (less work)
-				if (Util.isJsType(proxy.getName())) {
+				if(Util.isJsType(proxy.getName())) {
 					IFile file = (IFile) proxy.requestResource();
-					if (file.exists()) {
-						if (IndexWorkspaceJob.DEBUG) {
+					if(file.exists()) {
+						
+						if(DEBUG) {
 							System.out.println("(+) IndexWorkspaceJob adding file: " + file.getName()); //$NON-NLS-1$
 						}
-						// this call will check the ContentTypeDescription, so
-						// don't need to do it here.
-						// JSPSearchSupport.getInstance().addJspFile(file);
+						// this call will check the ContentTypeDescription, so don't need to do it here.
+						//JSPSearchSupport.getInstance().addJspFile(file);
 						this.files.add(file);
 						this.fInnerMonitor.subTask(proxy.getName());
+						
 						// don't search deeper for files
 						return false;
 					}
@@ -92,50 +94,68 @@
 			}
 			return true;
 		}
+		
+		public final IFile[] getFiles() {
+		    return (IFile[])this.files.toArray(new IFile[this.files.size()]);
+		}
 	}
+	
 	//private IContentType fContentTypeJSP = null;
 	
 	public IndexWorkspaceJob() {
-		// pa_TODO may want to say something like "Rebuilding JSP Index" to be
-		// more
-		// descriptive instead of "Updating JSP Index" since they are 2
-		// different things
+		// pa_TODO may want to say something like "Rebuilding JSP Index" to be more
+		// descriptive instead of "Updating JSP Index" since they are 2 different things
 		super(JsCoreMessages.JSPIndexManager_0);
 		setPriority(Job.LONG);
 		setSystem(true);
 	}
-	
 
+//	IContentType getJspContentType() {
+//		if(this.fContentTypeJSP == null)
+//			this.fContentTypeJSP = Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
+//		return this.fContentTypeJSP;
+//	}
 	
+	/**
+	 * @see org eclipse.core.internal.jobs.InternalJob#run(org.eclipse.core.runtime.IProgressMonitor) 
+	 * for similar method
+	 */
 	protected IStatus run(IProgressMonitor monitor) {
+		
 		IStatus status = Status.OK_STATUS;
-		if (monitor.isCanceled()) {
+		
+		if(monitor.isCanceled()) {
 			setCanceledState();
 			return Status.CANCEL_STATUS;
 		}
-		if (IndexWorkspaceJob.DEBUG) {
+		
+		if(DEBUG) {
 			System.out.println(" ^ IndexWorkspaceJob started: "); //$NON-NLS-1$
 		}
+		
 		long start = System.currentTimeMillis();
+		
 		try {
-			JSPFileVisitor visitor = new JSPFileVisitor(monitor);
-			// collect all jsp files
+		    JSPFileVisitor visitor = new JSPFileVisitor(monitor);
+		    // collect all jsp files
 			ResourcesPlugin.getWorkspace().getRoot().accept(visitor, IResource.DEPTH_INFINITE);
 			// request indexing
-			// this is pretty much like faking an entire workspace resource
-			// delta
+			// this is pretty much like faking an entire workspace resource delta
 			JsIndexManager.getInstance().indexFiles(visitor.getFiles());
-		} catch (CoreException e) {
-			if (IndexWorkspaceJob.DEBUG) {
+		}
+		catch (CoreException e) {
+			if(DEBUG) {
 				e.printStackTrace();
 			}
-		} finally {
+		}
+		finally {
 			monitor.done();
 		}
 		long finish = System.currentTimeMillis();
-		if (IndexWorkspaceJob.DEBUG) {
+		if(DEBUG) {
 			System.out.println(" ^ IndexWorkspaceJob finished\n   total time running: " + (finish - start)); //$NON-NLS-1$
 		}
+		
 		return status;
 	}
 	
diff --git a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JSDTSearchDocumentDelegate.java b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JSDTSearchDocumentDelegate.java
index 438d818..f83a6b0 100644
--- a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JSDTSearchDocumentDelegate.java
+++ b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JSDTSearchDocumentDelegate.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 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
  *******************************************************************************/
@@ -17,64 +17,62 @@
 
 
 /**
- * Wrapper method to set getPath() path to be the path of the compilation unit
- * for the jsp file. (since it's a final method, it needs to be set via
- * constructor)
+ * Wrapper method to set getPath() path to be the path of the compilation unit 
+ * for the jsp file. (since it's a final method, it needs to be set via constructor)
  * 
  * @author pavery
  */
-/* Used to extend SearchDocument */
 public class JSDTSearchDocumentDelegate extends JavaSearchDocument {
+	
 	private JsSearchDocument fJSPSearchDoc = null;
 	
 	public JSDTSearchDocumentDelegate(JsSearchDocument jspSearchDoc) {
+		
 		super(jspSearchDoc.getPath(), jspSearchDoc.getParticipant());
 		this.fJSPSearchDoc = jspSearchDoc;
 	}
-	
-	
+
 	public byte[] getByteContents() {
+		
 		return this.fJSPSearchDoc.getByteContents();
 	}
-	
-	
+
 	public char[] getCharContents() {
+		
 		return this.fJSPSearchDoc.getCharContents();
 	}
 	
-	
-	public String getEncoding() {
-		return this.fJSPSearchDoc.getEncoding();
-	}
-	
-	public IFile getFile() {
-		return this.fJSPSearchDoc.getFile();
-	}
-	
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.wst.jsdt.core.search.SearchDocument#getJavaElement()
-	 */
-	
-	public IJavaElement getJavaElement() {
-		return getJspTranslation().getCompilationUnit();
-	}
-	
 	public String getJavaText() {
 		return this.fJSPSearchDoc.getJavaText();
 	}
+
+	public String getEncoding() {
+		
+		return this.fJSPSearchDoc.getEncoding();
+	}
+	
+	public IFile getFile() {
+		
+		return this.fJSPSearchDoc.getFile();
+	}
 	
 	public IJsTranslation getJspTranslation() {
+		
 		return this.fJSPSearchDoc.getJSPTranslation();
 	}
 	
-	
-	public boolean isVirtual() {
-		return true;
-	}
+//	public int getJspOffset(int javaOffset) {
+//		
+//		return this.fJSPSearchDoc.getJspOffset(javaOffset);
+//	}
 	
 	public void release() {
 		this.fJSPSearchDoc.release();
 	}
+	public IJavaElement getJavaElement() {
+		return getJspTranslation().getCompilationUnit();
+	}
+	public boolean isVirtual() {
+		return true;
+	}
 }
diff --git a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsIndexManager.java b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsIndexManager.java
index 2b19077..d80906d 100644
--- a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsIndexManager.java
+++ b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsIndexManager.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 2006 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
  *******************************************************************************/
@@ -31,12 +31,14 @@
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Plugin;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.content.IContentType;
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
 import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.jsdt.core.IJavaProject;
+import org.eclipse.wst.jsdt.core.JavaCore;
 import org.eclipse.wst.jsdt.internal.core.JavaModelManager;
+import org.eclipse.wst.jsdt.internal.core.index.Index;
 import org.eclipse.wst.jsdt.internal.core.search.indexing.IndexManager;
 import org.eclipse.wst.jsdt.web.core.internal.JsCoreMessages;
 import org.eclipse.wst.jsdt.web.core.internal.JsCorePlugin;
@@ -51,12 +53,21 @@
  * @author pavery
  */
 public class JsIndexManager {
+
 	// for debugging
 	// TODO move this to Logger, as we have in SSE
 	static final boolean DEBUG;
-	private static JsIndexManager fSingleton = null;
-	static long fTotalTime = 0;
+	static {
+		String value = Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/jspindexmanager"); //$NON-NLS-1$
+		DEBUG = (value != null) && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+	}
+
 	private static final String PKEY_INDEX_STATE = "jspIndexState"; //$NON-NLS-1$
+
+	private IndexWorkspaceJob indexingJob = new IndexWorkspaceJob();
+
+
+
 	// TODO: consider enumeration for these int constants
 	// set to S_UPDATING once a resource change comes in
 	// set to S_STABLE if:
@@ -64,130 +75,24 @@
 	// - or the ProcessFilesJob completes
 	// set to S_CANCELED if an indexing job is canceled
 	// set to S_REBUILDING if re-indexing the entire workspace
-	/**
-	 * indexing job was canceled in the middle of it, index needs to be rebuilt
-	 */
-	public static final int S_CANCELED = 4;
-	/** entire index is being rebuilt */
-	public static final int S_REBUILDING = 3;
+
 	// the int '0' is reserved for the default value if a preference is not
 	// there
 	/** index is reliable to use */
 	public static final int S_STABLE = 1;
 	/** index is being updated (from a resource delta) */
 	public static final int S_UPDATING = 2;
-	static {
-		String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jspindexmanager"); //$NON-NLS-1$
-		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
-	}
-	
-	public synchronized static JsIndexManager getInstance() {
-		if (JsIndexManager.fSingleton == null) {
-			JsIndexManager.fSingleton = new JsIndexManager();
-		}
-		return JsIndexManager.fSingleton;
-	}
-	// end class JSPResourceVisitor
-	private class IndexJobCoordinator extends JobChangeAdapter {
-		
-		public void aboutToRun(IJobChangeEvent event) {
-			Job jobToCoordinate = event.getJob();
-			if (isJobToAvoid(jobToCoordinate)) {
-				// job will be rescheduled when the job we
-				// are avoiding (eg. build) is done
-				getProcessFilesJob().cancel();
-				// System.out.println("cancel:" + jobToCoordinate.getName());
-			}
-		}
-		
-		
-		public void done(IJobChangeEvent event) {
-			Job jobToCoordinate = event.getJob();
-			if (isJobToAvoid(jobToCoordinate)) {
-				if (getProcessFilesJob().getFiles().length > 0) {
-					getProcessFilesJob().schedule(500);
-					// System.out.println("schedule:" +
-					// jobToCoordinate.getName());
-				}
-			}
-		}
-		
-		private boolean isJobToAvoid(Job jobToCoordinate) {
-			boolean result = false;
-			if (jobToCoordinate.belongsTo(ResourcesPlugin.FAMILY_AUTO_BUILD) || jobToCoordinate.belongsTo(ResourcesPlugin.FAMILY_MANUAL_BUILD) || jobToCoordinate.belongsTo(ResourcesPlugin.FAMILY_AUTO_REFRESH)) {
-				result = true;
-			}
-			return result;
-		}
-	}
-	// end class ProcessFilesJob
-	private class JSPResourceChangeListener implements IResourceChangeListener {
-		/**
-		 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
-		 */
-		public void resourceChanged(IResourceChangeEvent event) {
-			if (isInitializing()) {
-				return;
-			}
-			// ignore resource changes if already rebuilding
-			if (getIndexState() == JsIndexManager.S_REBUILDING) {
-				return;
-			}
-			// previously canceled, needs entire index rebuild
-			if (getIndexState() == JsIndexManager.S_CANCELED) {
-				// rebuildIndex();
-				// just resume indexing
-				getProcessFilesJob().schedule(500);
-				// System.out.println("schedule: resource changed, previously
-				// canceled");
-				return;
-			}
-			IResourceDelta delta = event.getDelta();
-			if (delta != null) {
-				// only care about adds or changes right now...
-				int kind = delta.getKind();
-				boolean added = (kind & IResourceDelta.ADDED) == IResourceDelta.ADDED;
-				boolean changed = (kind & IResourceDelta.CHANGED) == IResourceDelta.CHANGED;
-				if (added || changed) {
-					// only analyze the full (starting at root) delta
-					// hierarchy
-					if (delta.getFullPath().toString().equals("/")) { //$NON-NLS-1$
-						try {
-							JSPResourceVisitor v = getVisitor();
-							// clear from last run
-							v.reset();
-							// count files, possibly do this in a job too...
-							// don't include PHANTOM resources
-							delta.accept(v, false);
-							// process files from this delta
-							IFile[] files = v.getFiles();
-							if (files.length > 0) {
-								/*
-								 * Job change listener should set back to stable
-								 * when finished
-								 */
-								setUpdatingState();
-								// processFiles(files);
-								indexFiles(files);
-							}
-						} catch (CoreException e) {
-							// need to set state here somehow, and reindex
-							// otherwise index will be unreliable
-							if (JsIndexManager.DEBUG) {
-								Logger.logException(e);
-							}
-						} catch (Exception e) {
-							// need to set state here somehow, and reindex
-							// otherwise index will be unreliable
-							if (JsIndexManager.DEBUG) {
-								Logger.logException(e);
-							}
-						}
-					}
-				}
-			}
-		}
-	}
+	/** entire index is being rebuilt */
+	public static final int S_REBUILDING = 3;
+	/**
+	 * indexing job was canceled in the middle of it, index needs to be
+	 * rebuilt
+	 */
+	public static final int S_CANCELED = 4;
+
+	/** symbolic name for OSGI framework */
+	private final String OSGI_FRAMEWORK_ID = "org.eclipse.osgi"; //$NON-NLS-1$
+
 	/**
 	 * Collects JSP files from a resource delta.
 	 */
@@ -195,11 +100,87 @@
 		// using hash map ensures only one of each file
 		// must be reset before every use
 		private HashMap jspFiles = null;
-		
+
 		public JSPResourceVisitor() {
 			this.jspFiles = new HashMap();
 		}
-		
+
+		public boolean visit(IResourceDelta delta) throws CoreException {
+
+			// in case JSP search was canceled (eg. when closing the editor)
+			if (JsSearchSupport.getInstance().isCanceled() || frameworkIsShuttingDown()) {
+				setCanceledState();
+				return false;
+			}
+
+			try {
+				if (!isHiddenResource(delta.getFullPath())) {
+
+					int kind = delta.getKind();
+					boolean added = (kind & IResourceDelta.ADDED) == IResourceDelta.ADDED;
+					boolean isInterestingChange = false;
+					if ((kind & IResourceDelta.CHANGED) == IResourceDelta.CHANGED) {
+						int flags = delta.getFlags();
+						// ignore things like marker changes
+						isInterestingChange = ((flags & IResourceDelta.CONTENT) == IResourceDelta.CONTENT) || ((flags & IResourceDelta.REPLACED) == IResourceDelta.REPLACED);
+					}
+					boolean removed = (kind & IResourceDelta.REMOVED) == IResourceDelta.REMOVED;
+					if (added || isInterestingChange) {
+
+						visitAdded(delta);
+					}
+					else if (removed) {
+						visitRemoved(delta);
+					}
+				}
+			}
+			catch (Exception e) {
+				// need to set state here somehow, and reindex
+				// otherwise index will be unreliable
+				if (DEBUG) {
+					Logger.logException("Delta analysis may not be complete", e); //$NON-NLS-1$
+				}
+			}
+			// if the delta has children, continue to add/remove files
+			return true;
+		}
+
+		private void visitRemoved(IResourceDelta delta) {
+			// handle cleanup
+			if (delta.getResource() != null) {
+				IResource r = delta.getResource();
+				if ((r.getType() == IResource.FOLDER) && r.exists()) {
+					deleteIndex((IFile) r);
+				}
+			}
+		}
+
+		private void visitAdded(IResourceDelta delta) {
+			// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3553
+			// quick check if it's even JSP related to improve
+			// performance
+			// checking name from the delta before getting
+			// resource because it's lighter
+			String filename = delta.getFullPath().lastSegment();
+			if ((filename != null) && Util.isJsType(filename)) {
+				IResource r = delta.getResource();
+				if ((r != null) && r.exists() && (r.getType() == IResource.FILE)) {
+					this.jspFiles.put(r.getFullPath(), r);
+				}
+			}
+		}
+
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=93463
+		private boolean isHiddenResource(IPath p) {
+			String[] segments = p.segments();
+			for (int i = 0; i < segments.length; i++) {
+				if (segments[i].startsWith(".")) {
+					return true;
+				}
+			}
+			return false;
+		}
+
 		private void deleteIndex(IFile folder) {
 			// cleanup index
 			IndexManager im = JavaModelManager.getJavaModelManager().getIndexManager();
@@ -211,86 +192,18 @@
 			File f = indexLocation.toFile();
 			f.delete();
 		}
-		
+
 		public IFile[] getFiles() {
 			return (IFile[]) this.jspFiles.values().toArray(new IFile[this.jspFiles.size()]);
 		}
-		
-		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=93463
-		private boolean isHiddenResource(IPath p) {
-			String[] segments = p.segments();
-			for (int i = 0; i < segments.length; i++) {
-				if (segments[i].startsWith(".")) { //$NON-NLS-1$
-					return true;
-				}
-			}
-			return false;
-		}
-		
+
 		public void reset() {
 			this.jspFiles.clear();
 		}
-		
-		public boolean visit(IResourceDelta delta) throws CoreException {
-			// in case JSP search was canceled (eg. when closing the editor)
-			if (JsSearchSupport.getInstance().isCanceled() || frameworkIsShuttingDown()) {
-				setCanceledState();
-				return false;
-			}
-			try {
-				if (!isHiddenResource(delta.getFullPath())) {
-					int kind = delta.getKind();
-					boolean added = (kind & IResourceDelta.ADDED) == IResourceDelta.ADDED;
-					boolean isInterestingChange = false;
-					if ((kind & IResourceDelta.CHANGED) == IResourceDelta.CHANGED) {
-						int flags = delta.getFlags();
-						// ignore things like marker changes
-						isInterestingChange = (flags & IResourceDelta.CONTENT) == IResourceDelta.CONTENT || (flags & IResourceDelta.REPLACED) == IResourceDelta.REPLACED;
-					}
-					boolean removed = (kind & IResourceDelta.REMOVED) == IResourceDelta.REMOVED;
-					if (added || isInterestingChange) {
-						visitAdded(delta);
-					} else if (removed) {
-						visitRemoved(delta);
-					}
-				}
-			} catch (Exception e) {
-				// need to set state here somehow, and reindex
-				// otherwise index will be unreliable
-				if (JsIndexManager.DEBUG) {
-					Logger.logException("Delta analysis may not be complete", e); //$NON-NLS-1$
-				}
-			}
-			// if the delta has children, continue to add/remove files
-			return true;
-		}
-		
-		private void visitAdded(IResourceDelta delta) {
-			// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3553
-			// quick check if it's even JSP related to improve
-			// performance
-			// checking name from the delta before getting
-			// resource because it's lighter
-			int numSegments = delta.getFullPath().segmentCount();
-			String filename = delta.getFullPath().segment(numSegments - 1);
-			if (Util.isJsType(filename)) {
-				IResource r = delta.getResource();
-				if (r != null && r.exists() && r.getType() == IResource.FILE) {
-					this.jspFiles.put(r.getFullPath(), r);
-				}
-			}
-		}
-		
-		private void visitRemoved(IResourceDelta delta) {
-			// handle cleanup
-			if (delta.getResource() != null) {
-				IResource r = delta.getResource();
-				if (r.getType() == IResource.FOLDER && r.exists()) {
-					deleteIndex((IFile) r);
-				}
-			}
-		}
 	}
+
+	// end class JSPResourceVisitor
+
 	/**
 	 * schedules JSP files for indexing by Java core
 	 */
@@ -298,79 +211,74 @@
 		List fileList = null;
 		// keep track of how many files we've indexed
 		int lastFileCursor = 0;
-		
+
 		ProcessFilesJob(String taskName) {
 			super(taskName);
 			fileList = new ArrayList();
 		}
-		
-		synchronized void clearFiles() {
-			fileList.clear();
-			lastFileCursor = 0;
-			// System.out.println("cleared files");
-		}
-		
-		synchronized IFile[] getFiles() {
-			return (IFile[]) fileList.toArray(new IFile[fileList.size()]);
-		}
-		
-		private boolean isCanceled(IProgressMonitor runMonitor) {
-			boolean canceled = false;
-			// check specific monitor passed into run method (the progress
-			// group in this case)
-			// check main search support canceled
-			if (runMonitor != null && runMonitor.isCanceled()) {
-				canceled = true;
-			} else if (JsSearchSupport.getInstance().isCanceled()) {
-				canceled = true;
-				if (runMonitor != null) {
-					runMonitor.setCanceled(true);
-				}
-			}
-			return canceled;
-		}
-		
+
 		synchronized void process(IFile[] files) {
 			for (int i = 0; i < files.length; i++) {
 				fileList.add(files[i]);
 			}
-			if (JsIndexManager.DEBUG) {
+			if (DEBUG) {
 				System.out.println("JSPIndexManager queuing " + files.length + " files"); //$NON-NLS-2$ //$NON-NLS-1$
 			}
 		}
-		
-		
+
+		synchronized IFile[] getFiles() {
+			return (IFile[]) fileList.toArray(new IFile[fileList.size()]);
+		}
+
+		synchronized void clearFiles() {
+			fileList.clear();
+			lastFileCursor = 0;
+			//System.out.println("cleared files");
+		}
+
 		protected IStatus run(IProgressMonitor monitor) {
 			// System.out.println("indexer monitor" + monitor);
 			if (isCanceled(monitor) || frameworkIsShuttingDown()) {
 				setCanceledState();
 				return Status.CANCEL_STATUS;
 			}
+
 			long start = System.currentTimeMillis();
+
 			try {
 				IFile[] filesToBeProcessed = getFiles();
-				if (JsIndexManager.DEBUG) {
+
+				if (DEBUG) {
 					System.out.println("JSPIndexManager indexing " + filesToBeProcessed.length + " files"); //$NON-NLS-2$ //$NON-NLS-1$
 				}
 				// API indicates that monitor is never null
 				monitor.beginTask("", filesToBeProcessed.length); //$NON-NLS-1$
 				JsSearchSupport ss = JsSearchSupport.getInstance();
 				String processingNFiles = ""; //$NON-NLS-1$
-				for (; lastFileCursor < filesToBeProcessed.length; lastFileCursor++) {
+
+
+				for (;lastFileCursor < filesToBeProcessed.length; lastFileCursor++) {
+
 					if (isCanceled(monitor) || frameworkIsShuttingDown()) {
 						setCanceledState();
 						return Status.CANCEL_STATUS;
 					}
+					IFile file = filesToBeProcessed[lastFileCursor];
 					try {
-						ss.addJspFile(filesToBeProcessed[lastFileCursor]);
-						// JSP Indexer processing n files
-						processingNFiles = NLS.bind(JsCoreMessages.JSPIndexManager_2, new String[] { Integer.toString((filesToBeProcessed.length - lastFileCursor)) });
-						monitor.subTask(processingNFiles + " - " + filesToBeProcessed[lastFileCursor].getName()); //$NON-NLS-1$
-						monitor.worked(1);
-						if (JsIndexManager.DEBUG) {
-							System.out.println("JSPIndexManager Job added file: " + filesToBeProcessed[lastFileCursor].getName()); //$NON-NLS-1$
+						IJavaProject project = JavaCore.create(file.getProject());
+						if (project.exists()) {
+							ss.addJspFile(file);
+							// JSP Indexer processing n files
+							processingNFiles = NLS.bind(JsCoreMessages.JSPIndexManager_2, new String[]{Integer.toString((filesToBeProcessed.length - lastFileCursor))});
+							monitor.subTask(processingNFiles + " - " + file.getName()); //$NON-NLS-1$
+							monitor.worked(1);
+
+							if (DEBUG) {
+								System.out.println("JSPIndexManager Job added file: " + file.getName()); //$NON-NLS-1$
+							}
 						}
-					} catch (Exception e) {
+					}
+					catch (Exception e) {
 						// RATLC00284776
 						// ISSUE: we probably shouldn't be catching EVERY
 						// exception, but
@@ -385,150 +293,187 @@
 						// and only log a certain amt of the same one,
 						// otherwise skip it.
 						if (!frameworkIsShuttingDown()) {
-							String filename = filesToBeProcessed[lastFileCursor] != null ? filesToBeProcessed[lastFileCursor].getFullPath().toString() : ""; //$NON-NLS-1$
+							String filename = file != null ? file.getFullPath().toString() : ""; //$NON-NLS-1$
 							Logger.logException("JSPIndexer problem indexing:" + filename, e); //$NON-NLS-1$
 						}
 					}
 				} // end for
-			} finally {
+			}
+			finally {
 				// just in case something didn't follow API (monitor is null)
 				if (monitor != null) {
 					monitor.done();
 				}
 			}
+
 			// successfully finished, clear files list
 			clearFiles();
+			
 			long finish = System.currentTimeMillis();
 			long diff = finish - start;
-			if (JsIndexManager.DEBUG) {
-				JsIndexManager.fTotalTime += diff;
+			if (DEBUG) {
+				fTotalTime += diff;
 				System.out.println("============================================================================"); //$NON-NLS-1$
-				System.out.println("this time: " + diff + " cumulative time for resource changed: " + JsIndexManager.fTotalTime); //$NON-NLS-1$ //$NON-NLS-2$
+				System.out.println("this time: " + diff + " cumulative time for resource changed: " + fTotalTime); //$NON-NLS-1$ //$NON-NLS-2$
 				System.out.println("============================================================================"); //$NON-NLS-1$
 			}
 			return Status.OK_STATUS;
 		}
+
+		private boolean isCanceled(IProgressMonitor runMonitor) {
+
+			boolean canceled = false;
+			// check specific monitor passed into run method (the progress
+			// group in this case)
+			// check main search support canceled
+			if ((runMonitor != null) && runMonitor.isCanceled()) {
+				canceled = true;
+			} else if (JsSearchSupport.getInstance().isCanceled()) {
+				canceled = true;
+				if (runMonitor != null) {
+					runMonitor.setCanceled(true);
+				}
+			}
+			return canceled;
+		}
+		
 	}
-	private IContentType fContentTypeJSP = null;
-	private JSPResourceVisitor fVisitor = null;
-	private IndexWorkspaceJob indexingJob = new IndexWorkspaceJob();
-	private IndexJobCoordinator indexJobCoordinator;
+
+	// end class ProcessFilesJob
+
+	private static JsIndexManager fSingleton = null;
 	private boolean initialized;
 	private boolean initializing = true;
+
+	private IndexJobCoordinator indexJobCoordinator;
 	private IResourceChangeListener jspResourceChangeListener;
-	/** symbolic name for OSGI framework */
-	private final String OSGI_FRAMEWORK_ID = "org.eclipse.osgi"; //$NON-NLS-1$
+
+	private JSPResourceVisitor fVisitor = null;
+	static long fTotalTime = 0;
+
 	// Job for processing resource delta
 	private ProcessFilesJob processFilesJob = null;
-	
+
 	private JsIndexManager() {
 		processFilesJob = new ProcessFilesJob(JsCoreMessages.JSPIndexManager_0);
 		// only show in verbose mode
 		processFilesJob.setSystem(true);
 		processFilesJob.setPriority(Job.LONG);
 		processFilesJob.addJobChangeListener(new JobChangeAdapter() {
-			
 			public void done(IJobChangeEvent event) {
 				super.done(event);
 				setStableState();
 			}
 		});
 	}
-	
-	/**
-	 * A check to see if the OSGI framework is shutting down.
-	 * 
-	 * @return true if the System Bundle is stopped (ie. the framework is
-	 *         shutting down)
-	 */
-	boolean frameworkIsShuttingDown() {
-		// in the Framework class there's a note:
-		// set the state of the System Bundle to STOPPING.
-		// this must be done first according to section 4.19.2 from the OSGi
-		// R3 spec.
-		boolean shuttingDown = Platform.getBundle(OSGI_FRAMEWORK_ID).getState() == Bundle.STOPPING;
-		if (JsIndexManager.DEBUG && shuttingDown) {
-			System.out.println("JSPIndexManager: system is shutting down!"); //$NON-NLS-1$
-		}
-		return shuttingDown;
-	}
-	
-	IndexWorkspaceJob getIndexingJob() {
-		return indexingJob;
-	}
-	
-	int getIndexState() {
-		return JsCorePlugin.getDefault().getPluginPreferences().getInt(JsIndexManager.PKEY_INDEX_STATE);
-	}
-	
 
-	
-	ProcessFilesJob getProcessFilesJob() {
-		return processFilesJob;
-	}
-	
-	/**
-	 * Package protected for access by inner Job class in resourceChanged(...)
-	 * 
-	 * @return
-	 */
-	JSPResourceVisitor getVisitor() {
-		if (this.fVisitor == null) {
-			this.fVisitor = new JSPResourceVisitor();
+	public synchronized static JsIndexManager getInstance() {
+
+		if (fSingleton == null) {
+			fSingleton = new JsIndexManager();
 		}
-		return this.fVisitor;
+		return fSingleton;
 	}
-	
-	/**
-	 * Creates and schedules a Job to process collected files. All JSP indexing
-	 * should be done through this method or processFiles(IFile file)
-	 * 
-	 * @param files
-	 */
-	final void indexFiles(IFile[] files) {
-		// don't use this rule
-		// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=4931
-		// processFiles.setRule(new IndexFileRule());
-		processFilesJob.process(files);
-	}
-	
+
 	public void initialize() {
-		JsIndexManager singleInstance = JsIndexManager.getInstance();
+
+		JsIndexManager singleInstance = getInstance();
+
+
 		if (!singleInstance.initialized) {
 			singleInstance.initialized = true;
+
 			singleInstance.indexJobCoordinator = new IndexJobCoordinator();
 			singleInstance.jspResourceChangeListener = new JSPResourceChangeListener();
+
 			// added as JobChange listener so JSPIndexManager can be smarter
 			// about when it runs
 			Platform.getJobManager().addJobChangeListener(singleInstance.indexJobCoordinator);
+
 			// add JSPIndexManager to keep JSP Index up to date
 			// listening for IResourceChangeEvent.PRE_DELETE and
 			// IResourceChangeEvent.POST_CHANGE
 			ResourcesPlugin.getWorkspace().addResourceChangeListener(jspResourceChangeListener, IResourceChangeEvent.POST_CHANGE);
+
 			// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5091
 			// makes sure IndexManager is aware of our indexes
 			saveIndexes();
-			rebuildIndexIfNeeded();
+			//rebuildIndexIfNeeded();
 			singleInstance.initializing = false;
+
+		}
+
+	}
+	
+	synchronized void setIndexState(int state) {
+		if (DEBUG) {
+			System.out.println("JSPIndexManager setting index state to: " + state2String(state)); //$NON-NLS-1$
+		}
+		Plugin jspModelPlugin = JsCorePlugin.getDefault();
+		jspModelPlugin.getPluginPreferences().setValue(PKEY_INDEX_STATE, state);
+		jspModelPlugin.savePluginPreferences();
+
+	}
+
+	private String state2String(int state) {
+		String s = "UNKNOWN"; //$NON-NLS-1$
+		switch (state) {
+			case (S_STABLE) :
+				s = "S_STABLE"; //$NON-NLS-1$
+				break;
+			case (S_UPDATING) :
+				s = "S_UPDATING"; //$NON-NLS-1$
+				break;
+			case (S_CANCELED) :
+				s = "S_CANCELED"; //$NON-NLS-1$
+				break;
+			case (S_REBUILDING) :
+				s = "S_REBUILDING"; //$NON-NLS-1$
+				break;
+		}
+		return s;
+	}
+
+	int getIndexState() {
+		return JsCorePlugin.getDefault().getPluginPreferences().getInt(PKEY_INDEX_STATE);
+	}
+
+	void setUpdatingState() {
+		//if (getIndexState() != S_CANCELED)
+		setIndexState(S_UPDATING);
+	}
+
+	void setCanceledState() {
+		setIndexState(JsIndexManager.S_CANCELED);
+	}
+
+	void setStableState() {
+		//if (getIndexState() != S_CANCELED)
+		setIndexState(S_STABLE);
+	}
+
+	void setRebuildingState() {
+		setIndexState(S_REBUILDING);
+	}
+
+	synchronized void rebuildIndexIfNeeded() {
+		if (getIndexState() != S_STABLE) {
+			rebuildIndex();
 		}
 	}
-	
-	boolean isInitializing() {
-		return initializing;
-	}
-	
+
 	void rebuildIndex() {
-		if (JsIndexManager.DEBUG) {
+
+		if (DEBUG) {
 			System.out.println("*** JSP Index unstable, requesting re-indexing"); //$NON-NLS-1$
 		}
+
 		getIndexingJob().addJobChangeListener(new JobChangeAdapter() {
-			
 			public void aboutToRun(IJobChangeEvent event) {
 				super.aboutToRun(event);
 				setRebuildingState();
 			}
-			
-			
+
 			public void done(IJobChangeEvent event) {
 				super.done(event);
 				setStableState();
@@ -538,16 +483,35 @@
 		// we're about to reindex everything anyway
 		getProcessFilesJob().clearFiles();
 		getIndexingJob().schedule();
+
 	}
-	
-	synchronized void rebuildIndexIfNeeded() {
-		if (getIndexState() != JsIndexManager.S_STABLE) {
-			rebuildIndex();
+
+	/**
+	 * Creates and schedules a Job to process collected files. All JSP
+	 * indexing should be done through this method or processFiles(IFile file)
+	 * 
+	 * @param files
+	 */
+	final void indexFiles(IFile[] files) {
+		// don't use this rule
+		// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=4931
+		// processFiles.setRule(new IndexFileRule());
+		processFilesJob.process(files);
+	}
+
+
+	/**
+	 * Package protected for access by inner Job class in resourceChanged(...)
+	 * 
+	 * @return
+	 */
+	JSPResourceVisitor getVisitor() {
+
+		if (this.fVisitor == null) {
+			this.fVisitor = new JSPResourceVisitor();
 		}
+		return this.fVisitor;
 	}
-	
-	// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5091
-	// makes sure IndexManager is aware of our indexes
 	void saveIndexes() {
 		IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
 		IProject[] allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
@@ -579,42 +543,72 @@
 			}
 		}
 	}
-	
-	void setCanceledState() {
-		setIndexState(JsIndexManager.S_CANCELED);
-	}
-	
-	synchronized void setIndexState(int state) {
-		if (JsIndexManager.DEBUG) {
-			System.out.println("JSPIndexManager setting index state to: " + state2String(state)); //$NON-NLS-1$
+	// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5091
+	// makes sure IndexManager is aware of our indexes
+	void saveIndexesORIGINAL() {
+		IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
+		IPath jspModelWorkingLocation = JsSearchSupport.getInstance().getModelJspPluginWorkingLocation();
+
+		File folder = new File(jspModelWorkingLocation.toOSString());
+		String[] files = folder.list();
+		String locay = ""; //$NON-NLS-1$
+		Index index = null;
+		try {
+			for (int i = 0; i < files.length; i++) {
+				if (files[i].toLowerCase().endsWith(".index")) { //$NON-NLS-1$
+					locay = jspModelWorkingLocation.toString() + "/" + files[i]; //$NON-NLS-1$
+					// reuse index file
+					index = new Index(locay, "Index for " + locay, true); //$NON-NLS-1$
+					indexManager.saveIndex(index);
+				}
+			}
 		}
-		Plugin jspModelPlugin = JsCorePlugin.getDefault();
-		jspModelPlugin.getPluginPreferences().setValue(JsIndexManager.PKEY_INDEX_STATE, state);
-		jspModelPlugin.savePluginPreferences();
+		catch (Exception e) {
+			// we should be shutting down, want to shut down quietly
+			if (DEBUG) {
+				e.printStackTrace();
+			}
+		}
 	}
-	
-	void setRebuildingState() {
-		setIndexState(JsIndexManager.S_REBUILDING);
+
+//	IContentType getJspContentType() {
+//		if (this.fContentTypeJSP == null)
+//			this.fContentTypeJSP = Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
+//		return this.fContentTypeJSP;
+//	}
+
+	/**
+	 * A check to see if the OSGI framework is shutting down.
+	 * 
+	 * @return true if the System Bundle is stopped (ie. the framework is
+	 *         shutting down)
+	 */
+	boolean frameworkIsShuttingDown() {
+		// in the Framework class there's a note:
+		// set the state of the System Bundle to STOPPING.
+		// this must be done first according to section 4.19.2 from the OSGi
+		// R3 spec.
+		boolean shuttingDown = Platform.getBundle(OSGI_FRAMEWORK_ID).getState() == Bundle.STOPPING;
+		if (DEBUG && shuttingDown) {
+			System.out.println("JSPIndexManager: system is shutting down!"); //$NON-NLS-1$
+		}
+		return shuttingDown;
 	}
-	
-	void setStableState() {
-		// if (getIndexState() != S_CANCELED)
-		setIndexState(JsIndexManager.S_STABLE);
-	}
-	
-	void setUpdatingState() {
-		// if (getIndexState() != S_CANCELED)
-		setIndexState(JsIndexManager.S_UPDATING);
-	}
-	
+
+
 	public void shutdown() {
+
 		// stop listening
 		ResourcesPlugin.getWorkspace().removeResourceChangeListener(jspResourceChangeListener);
-		// saveIndexes();
+
+
 		// stop any searching
 		JsSearchSupport.getInstance().setCanceled(true);
+
 		// stop listening to jobs
 		Platform.getJobManager().removeJobChangeListener(indexJobCoordinator);
+
+
 		int maxwait = 5000;
 		if (processFilesJob != null) {
 			processFilesJob.cancel();
@@ -622,43 +616,153 @@
 		// attempt to make sure this indexing job is litterally
 		// done before continuing, since we are shutting down
 		waitTillNotRunning(maxwait, processFilesJob);
+
 		if (indexingJob != null) {
 			indexingJob.cancel();
 		}
 		waitTillNotRunning(maxwait, processFilesJob);
 	}
-	
-	private String state2String(int state) {
-		String s = "UNKNOWN"; //$NON-NLS-1$
-		switch (state) {
-			case (JsIndexManager.S_STABLE):
-				s = "S_STABLE"; //$NON-NLS-1$
-			break;
-			case (JsIndexManager.S_UPDATING):
-				s = "S_UPDATING"; //$NON-NLS-1$
-			break;
-			case (JsIndexManager.S_CANCELED):
-				s = "S_CANCELED"; //$NON-NLS-1$
-			break;
-			case (JsIndexManager.S_REBUILDING):
-				s = "S_REBUILDING"; //$NON-NLS-1$
-			break;
-		}
-		return s;
-	}
-	
+
 	private void waitTillNotRunning(int maxSeconds, Job job) {
 		int pauseTime = 10;
 		int maxtries = maxSeconds / pauseTime;
 		int count = 0;
-		while (count++ < maxtries && job.getState() == Job.RUNNING) {
+		while ((count++ < maxtries) && (job.getState() == Job.RUNNING)) {
 			try {
 				Thread.sleep(pauseTime);
 				// System.out.println("count: " + count + " max: " +
 				// maxtries);
-			} catch (InterruptedException e) {
+			}
+			catch (InterruptedException e) {
 				Logger.logException(e);
 			}
 		}
 	}
-}
\ No newline at end of file
+
+	private class IndexJobCoordinator extends JobChangeAdapter {
+		
+		public void aboutToRun(IJobChangeEvent event) {
+			Job jobToCoordinate = event.getJob();
+			if (isJobToAvoid(jobToCoordinate)) {
+				// job will be rescheduled when the job we
+				// are avoiding (eg. build) is done
+				getProcessFilesJob().cancel();
+				//System.out.println("cancel:" + jobToCoordinate.getName());
+			}
+		}
+
+		public void done(IJobChangeEvent event) {
+
+			Job jobToCoordinate = event.getJob();
+			if (isJobToAvoid(jobToCoordinate)) {
+				if (getProcessFilesJob().getFiles().length > 0) {
+					getProcessFilesJob().schedule(500);
+					//System.out.println("schedule:" + jobToCoordinate.getName());
+				}
+					
+
+			}
+		}
+
+		private boolean isJobToAvoid(Job jobToCoordinate) {
+			boolean result = false;
+			if (jobToCoordinate.belongsTo(ResourcesPlugin.FAMILY_AUTO_BUILD) || jobToCoordinate.belongsTo(ResourcesPlugin.FAMILY_MANUAL_BUILD) || jobToCoordinate.belongsTo(ResourcesPlugin.FAMILY_AUTO_REFRESH)) {
+				result = true;
+			}
+			return result;
+
+		}
+
+	}
+
+	private class JSPResourceChangeListener implements IResourceChangeListener {
+
+
+		/**
+		 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
+		 */
+		public void resourceChanged(IResourceChangeEvent event) {
+
+			if (isInitializing()) {
+				return;
+			}
+
+			// ignore resource changes if already rebuilding
+			if (getIndexState() == S_REBUILDING) {
+				return;
+			}
+			// previously canceled, needs entire index rebuild
+			if (getIndexState() == S_CANCELED) {
+				// rebuildIndex();
+				// just resume indexing
+				getProcessFilesJob().schedule(500);
+				//System.out.println("schedule: resource changed, previously canceled");
+				return;
+			}
+
+			IResourceDelta delta = event.getDelta();
+			if (delta != null) {
+				// only care about adds or changes right now...
+				int kind = delta.getKind();
+				boolean added = (kind & IResourceDelta.ADDED) == IResourceDelta.ADDED;
+				boolean changed = (kind & IResourceDelta.CHANGED) == IResourceDelta.CHANGED;
+				if (added || changed) {
+
+					// only analyze the full (starting at root) delta
+					// hierarchy
+					if (delta.getFullPath().toString().equals("/")) { //$NON-NLS-1$
+						try {
+							JSPResourceVisitor v = getVisitor();
+							// clear from last run
+							v.reset();
+							// count files, possibly do this in a job too...
+							// don't include PHANTOM resources
+							delta.accept(v, false);
+
+							// process files from this delta
+							IFile[] files = v.getFiles();
+							if (files.length > 0) {
+								/*
+								 * Job change listener should set back to
+								 * stable when finished
+								 */
+								setUpdatingState();
+								// processFiles(files);
+								indexFiles(files);
+							}
+						}
+						catch (CoreException e) {
+							// need to set state here somehow, and reindex
+							// otherwise index will be unreliable
+							if (DEBUG) {
+								Logger.logException(e);
+							}
+						}
+						catch (Exception e) {
+							// need to set state here somehow, and reindex
+							// otherwise index will be unreliable
+							if (DEBUG) {
+								Logger.logException(e);
+							}
+						}
+					}
+				}
+
+			}
+		}
+
+	}
+
+	IndexWorkspaceJob getIndexingJob() {
+		return indexingJob;
+	}
+
+	ProcessFilesJob getProcessFilesJob() {
+		return processFilesJob;
+	}
+
+	boolean isInitializing() {
+		return initializing;
+	}
+
+}
diff --git a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsPathIndexer.java b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsPathIndexer.java
index 664df65..ec60631 100644
--- a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsPathIndexer.java
+++ b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsPathIndexer.java
@@ -1,14 +1,15 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 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.jsdt.web.core.javascript.search;
+
 import java.util.HashMap;
 
 import org.eclipse.core.resources.IFile;
@@ -19,62 +20,68 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.content.IContentDescription;
 import org.eclipse.wst.jsdt.core.search.IJavaSearchScope;
 import org.eclipse.wst.jsdt.core.search.SearchPattern;
 import org.eclipse.wst.jsdt.web.core.internal.validation.Util;
 
 /**
- * pa_TODO Still need to take into consideration: - focus in workspace - search
- * pattern
+ * pa_TODO Still need to take into consideration:
+ * 	- focus in workspace
+ *  - search pattern
  * 
  * @author pavery
  */
 public class JsPathIndexer {
+
 	// for debugging
 	static final boolean DEBUG;
 	static {
-		String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jspsearch"); //$NON-NLS-1$
-		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+		
+		String value= Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/jspsearch"); //$NON-NLS-1$
+		DEBUG = true;
+		//DEBUG= (value != null) && value.equalsIgnoreCase("true"); //$NON-NLS-1$
 	}
-	// visitor that retrieves jsp project paths for all jsp files in the
-	// workspace
+	
+	// visitor that retrieves jsp project paths for all jsp files in the workspace
 	class JSPFileVisitor implements IResourceProxyVisitor {
 		// hash map forces only one of each file
 		private HashMap fPaths = new HashMap();
-		SearchPattern fPattern = null;
 		IJavaSearchScope fScope = null;
-		
+		SearchPattern fPattern = null;
+
 		public JSPFileVisitor(SearchPattern pattern, IJavaSearchScope scope) {
 			this.fPattern = pattern;
 			this.fScope = scope;
 		}
-		
-		public IPath[] getPaths() {
-			return (IPath[]) fPaths.values().toArray(new IPath[fPaths.size()]);
-		}
-		
+
 		public boolean visit(IResourceProxy proxy) throws CoreException {
-			if (JsSearchSupport.getInstance().isCanceled()) {
+			
+			if(JsSearchSupport.getInstance().isCanceled()) {
 				return false;
 			}
+			
 			if (proxy.getType() == IResource.FILE) {
-				//IContentType contentTypeJSP = Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeIdHtml);
+
+				//IContentType contentTypeJSP = Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
 				// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3553
 				// check this before description
 				// check name before actually getting the file (less work)
-				if (Util.isJsType(proxy.getName())) {
-					IFile file = (IFile) proxy.requestResource();
-					IContentDescription contentDescription = file.getContentDescription();
+				//if(contentTypeJSP.isAssociatedWith(proxy.getName())) {
+				if(Util.isJsType(proxy.getName())){	
+					IFile file = (IFile)proxy.requestResource();
+					//IContentDescription contentDescription = file.getContentDescription();
 					String ctId = null;
-					if (contentDescription != null) {
-						ctId = contentDescription.getContentType().getId();
-					}
-					//if (ContentTypeIdForJSP.ContentTypeIdHtml.equals(ctId)) {
+//					if (contentDescription != null) {
+//						ctId = contentDescription.getContentType().getId();
+//					}
+					//if (ContentTypeIdForJSP.ContentTypeID_JSP.equals(ctId)) {
+					//if(Util.isJsType(file.getName())){
 						if (this.fScope.encloses(proxy.requestFullPath().toString())) {
-							if (JsPathIndexer.DEBUG) {
+	
+							if (DEBUG) {
 								System.out.println("adding selected index path:" + file.getParent().getFullPath()); //$NON-NLS-1$
 							}
+
 							fPaths.put(file.getParent().getFullPath(), JsSearchSupport.getInstance().computeIndexLocation(file.getParent().getFullPath()));
 						}
 					//}
@@ -84,15 +91,22 @@
 			}
 			return true;
 		}
+
+		public IPath[] getPaths() {
+			return (IPath[]) fPaths.values().toArray(new IPath[fPaths.size()]);
+		}
 	}
-	
+
 	public IPath[] getVisibleJspPaths(SearchPattern pattern, IJavaSearchScope scope) {
+
 		JSPFileVisitor jspFileVisitor = new JSPFileVisitor(pattern, scope);
 		try {
 			ResourcesPlugin.getWorkspace().getRoot().accept(jspFileVisitor, 0);
-		} catch (CoreException e) {
+		}
+		catch (CoreException e) {
 			e.printStackTrace();
 		}
 		return jspFileVisitor.getPaths();
 	}
 }
+
diff --git a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchDocument.java b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchDocument.java
index a44f810..0aa3ffa 100644
--- a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchDocument.java
+++ b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchDocument.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 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
  *******************************************************************************/
@@ -13,14 +13,15 @@
 import java.io.IOException;
 
 import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.wst.jsdt.core.search.SearchParticipant;
 import org.eclipse.wst.jsdt.web.core.internal.Logger;
-
 import org.eclipse.wst.jsdt.web.core.javascript.IJsTranslation;
 import org.eclipse.wst.jsdt.web.core.javascript.JsTranslationAdapter;
 import org.eclipse.wst.jsdt.web.core.javascript.JsTranslationAdapterFactory;
@@ -31,23 +32,24 @@
 import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
 import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
 
+
 /**
  * Created with a .jsp file, but should appear to be a .java file for indexing
  * and searching purposes. There are purposely few fields in this class, and
  * those fields are lightweight since it's possible for many JSP search
- * documents to exist in memory at one time (eg. after importing a project with
- * a large number of JSP files)
+ * documents to exist in memory at one time (eg. after importing a project
+ * with a large number of JSP files)
  * 
  * @author pavery
  */
 public class JsSearchDocument {
+
 	private String UNKNOWN_PATH = "**path unknown**"; //$NON-NLS-1$
-	private char[] fCachedCharContents;
-	private String fCUPath = UNKNOWN_PATH;
 	private String fJSPPathString = UNKNOWN_PATH;
-	private long fLastModifiedStamp;
+	private String fCUPath = UNKNOWN_PATH;
 	private SearchParticipant fParticipant = null;
-	
+	private long fLastModifiedStamp;
+	private char[] fCachedCharContents;
 	
 	/**
 	 * @param file
@@ -55,61 +57,40 @@
 	 * @throws CoreException
 	 */
 	public JsSearchDocument(String filePath, SearchParticipant participant) {
+
 		this.fJSPPathString = filePath;
 		this.fParticipant = participant;
 	}
-	
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.wst.jsdt.core.search.SearchDocument#getByteContents()
-	 */
-	public byte[] getByteContents() {
-		// TODO Auto-generated method stub
-		return null;
+
+	public SearchParticipant getParticipant() {
+		return this.fParticipant;
 	}
-	
+
 	/**
-	 * @see org.eclipse.wst.jsdt.core.search.SearchDocument#getCharContents()
+	 * @see org.eclipse.jdt.core.search.SearchDocument#getCharContents()
 	 */
 	public char[] getCharContents() {
-		if (fCachedCharContents == null || isDirty()) {
-			IJsTranslation trans = getJSPTranslation();
-			fCachedCharContents = trans != null ? trans.getJsText().toCharArray() : new char[0];
-			fCUPath = trans.getJavaPath();
+		
+		if((fCachedCharContents == null) || isDirty()) {
+		    IJsTranslation trans = getJSPTranslation();    
+		    fCachedCharContents = trans != null ? trans.getJsText().toCharArray() : new char[0];
+		    fCUPath = trans.getJavaPath();
 		}
 		return fCachedCharContents;
 	}
-	
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.wst.jsdt.core.search.SearchDocument#getEncoding()
-	 */
-	public String getEncoding() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-	
-	public IFile getFile() {
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		IPath jspPath = new Path(this.fJSPPathString);
-		IFile jspFile = root.getFile(jspPath);
-		if (!jspFile.exists()) {
-			// possibly outside workspace
-			jspFile = root.getFileForLocation(jspPath);
-		}
-		return jspFile;
-	}
-	
+
 	public String getJavaText() {
 		return new String(getCharContents());
 	}
-	
+
+	private IModelManager getModelManager() {
+		return StructuredModelManager.getModelManager();
+	}
+
 	/**
-	 * It's not recommended for clients to hold on to this JSPTranslation since
-	 * it's kind of large. If possible, hold on to the JSPSearchDocument, which
-	 * is more of a lightweight proxy.
+	 * It's not recommended for clients to hold on to this JSPTranslation
+	 * since it's kind of large. If possible, hold on to the
+	 * JSPSearchDocument, which is more of a lightweight proxy.
 	 * 
 	 * @return the JSPTranslation for the jsp file, or null if it's an
 	 *         unsupported file.
@@ -120,74 +101,120 @@
 		if (!JsSearchSupport.isJsp(jspFile)) {
 			return translation;
 		}
+
 		IStructuredModel model = null;
 		try {
 			// get existing model for read, then get document from it
-			IModelManager modelManager = StructuredModelManager.getModelManager();
+			IModelManager modelManager = getModelManager();
 			if (modelManager != null) {
-				model = modelManager.getExistingModelForRead(jspFile);
-				if(model==null)
-					model = modelManager.getModelForRead(jspFile);
+				jspFile.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
+				model = modelManager.getModelForRead(jspFile);
 			}
 			// handle unsupported
 			if (model instanceof IDOMModel) {
-				IDOMModel xmlModel = (IDOMModel) model;
-				JsTranslationAdapterFactory factory = new JsTranslationAdapterFactory();
-				xmlModel.getFactoryRegistry().addFactory(factory);
+				IDOMModel xmlModel = (IDOMModel)model;
+				setupAdapterFactory(xmlModel);
 				IDOMDocument doc = xmlModel.getDocument();
 				JsTranslationAdapter adapter = (JsTranslationAdapter) doc.getAdapterFor(IJsTranslation.class);
 				translation = adapter.getJSPTranslation(false);
 			}
-		} catch (IOException e) {
+		}
+		catch (IOException e) {
 			Logger.logException(e);
-		} catch (CoreException e) {
+		}
+		catch (CoreException e) {
 			Logger.logException(e);
-		} catch (UnsupportedCharsetExceptionWithDetail e) {
+		}
+		catch (UnsupportedCharsetExceptionWithDetail e) {
 			// no need to log this. Just consider it an invalid file for our
 			// purposes.
 			// Logger.logException(e);
-		} finally {
+		}
+		finally {
 			if (model != null) {
 				model.releaseFromRead();
 			}
 		}
 		return translation;
 	}
-	
-	public SearchParticipant getParticipant() {
-		return this.fParticipant;
+
+	/**
+	 * add the factory for JSPTranslationAdapter here
+	 * 
+	 * @param sm
+	 */
+	private void setupAdapterFactory(IStructuredModel sm) {
+		JsTranslationAdapterFactory.setupAdapterFactory(sm);
 	}
-	
+
 	/**
 	 * the path to the Java compilation unit
 	 * 
-	 * @see org.eclipse.wst.jsdt.core.search.SearchDocument#getPath()
+	 * @see org.eclipse.jdt.core.search.SearchDocument#getPath()
 	 */
 	public String getPath() {
-		// caching the path since it's expensive to get translation
+	    // caching the path since it's expensive to get translation
 		// important that isDirty() check is second to cache modification stamp
-		if (this.fCUPath == null || isDirty() || this.fCUPath == UNKNOWN_PATH) {
-			IJsTranslation trans = getJSPTranslation();
-			if (trans != null) {
-				try {
-					this.fCUPath = trans.getJavaPath();
-				} catch (RuntimeException ex) {
-					// TODO Auto-generated catch block
-					ex.printStackTrace();
-				}
-				// save since it's expensive to calculate again later
-				fCachedCharContents = trans.getJsText().toCharArray();
-			}
-		}
+	    if((this.fCUPath == null) || isDirty() || (this.fCUPath == UNKNOWN_PATH)) {
+	        IJsTranslation trans = getJSPTranslation();
+	        if(trans != null) {
+	            this.fCUPath = trans.getJavaPath();
+	            // save since it's expensive to calculate again later
+	            fCachedCharContents = trans.getJsText().toCharArray();
+	        }
+	    }
 		return fCUPath != null ? fCUPath : UNKNOWN_PATH;
 	}
+
+//	public int getJspOffset(int javaOffset) {
+//		// copied from JSPTranslation
+//		int result = -1;
+//		int offsetInRange = 0;
+//		Position jspPos, javaPos = null;
+//		IJsTranslation trans = getJSPTranslation();
+//		if (trans != null) {
+//			HashMap java2jspMap = trans.getJava2JspMap();
+//
+//			// iterate all mapped java ranges
+//			Iterator it = java2jspMap.keySet().iterator();
+//			while (it.hasNext()) {
+//				javaPos = (Position) it.next();
+//				// need to count the last position as included
+//				if (!javaPos.includes(javaOffset) && !(javaPos.offset + javaPos.length == javaOffset))
+//					continue;
+//
+//				offsetInRange = javaOffset - javaPos.offset;
+//				jspPos = (Position) java2jspMap.get(javaPos);
+//
+//				if (jspPos != null)
+//					result = jspPos.offset + offsetInRange;
+//				else {
+//					Logger.log(Logger.ERROR, "jspPosition was null!" + javaOffset); //$NON-NLS-1$
+//				}
+//				break;
+//			}
+//		}
+//		return result;
+//	}
+
+	public IFile getFile() {
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IPath jspPath = new Path(this.fJSPPathString);
+		IFile jspFile = root.getFile(jspPath);
+		if (!jspFile.exists()) {
+			// possibly outside workspace
+			jspFile = root.getFileForLocation(jspPath);
+		}
+		return jspFile;
+	}
+
 	
 	private boolean isDirty() {
 		boolean modified = false;
 		IFile f = getFile();
-		if (f != null) {
+		if(f != null) {
 			long currentStamp = f.getModificationStamp();
-			if (currentStamp != fLastModifiedStamp) {
+			if(currentStamp != fLastModifiedStamp) {
 				modified = true;
 			}
 			fLastModifiedStamp = currentStamp;
@@ -196,14 +223,33 @@
 	}
 	
 	public void release() {
-	// nothing to do now since JSPTranslation is created on the fly
+		// nothing to do now since JSPTranslation is created on the fly
 	}
-	
+
 	/**
 	 * for debugging
 	 */
-	
 	public String toString() {
 		return "[JSPSearchDocument:" + this.fJSPPathString + "]"; //$NON-NLS-1$ //$NON-NLS-2$ 
 	}
-}
\ No newline at end of file
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jdt.core.search.SearchDocument#getEncoding()
+	 */
+	public String getEncoding() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jdt.core.search.SearchDocument#getByteContents()
+	 */
+	public byte[] getByteContents() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}
diff --git a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchParticipant.java b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchParticipant.java
index 8421a64..ef5cc74 100644
--- a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchParticipant.java
+++ b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchParticipant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 2006 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
  *******************************************************************************/
@@ -31,80 +31,80 @@
  * @author pavery
  */
 public class JsSearchParticipant extends SearchParticipant {
+
 	// for debugging
-	private static final boolean DEBUG = JsSearchParticipant.calculateValue();
-	
+	private static final boolean DEBUG = calculateValue();
+
 	private static boolean calculateValue() {
-		String value = Platform.getDebugOption("org.eclipse.jstd.jsp.core/debug/jspsearch"); //$NON-NLS-1$
-		boolean debug = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+		String value = Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/jspsearch"); //$NON-NLS-1$
+		boolean debug = (value != null) && value.equalsIgnoreCase("true"); //$NON-NLS-1$
 		return debug;
 	}
-	
-	
-	public String getDescription() {
-		return "Embeded JavaScript"; //$NON-NLS-1$
-	}
-	
-	/**
-	 * @see org.eclipse.wst.jsdt.core.search.SearchParticipant#getDocument(org.eclipse.core.resources.IFile)
-	 */
-	public SearchDocument getDocument(IFile file) {
-		// never gets called?
-		return null;
-	}
-	
+
 	/**
 	 * Important to never return null here or else Java search participation
 	 * will break.
 	 */
-	
 	public SearchDocument getDocument(String documentPath) {
 		SearchDocument sDoc = JsSearchSupport.getInstance().getSearchDocument(documentPath);
+
 		if (sDoc == null) {
 			// return a dummy doc here so search participation doesn't break
 			return new NullSearchDocument(documentPath);
 		}
 		return sDoc;
 	}
-	
-	
+
+	public String getDescription() {
+		return "Embeded JavaScript"; //$NON-NLS-1$
+	}
+
+	public IPath[] selectIndexes(SearchPattern pattern, IJavaSearchScope scope) {
+		JsPathIndexer indexer = new JsPathIndexer();
+		return indexer.getVisibleJspPaths(pattern, scope);
+	}
+
 	public void indexDocument(SearchDocument document, IPath indexPath) {
 		if (!(document instanceof JSDTSearchDocumentDelegate)) {
 			return;
 		}
+
 		// use Java search indexing
 		SearchEngine.getDefaultSearchParticipant().indexDocument(document, indexPath);
 	}
-	
-	
-	public void locateMatches(SearchDocument[] indexMatches, SearchPattern pattern, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor)
-			throws CoreException {
-		if (monitor != null && monitor.isCanceled()) {
+
+	public void locateMatches(SearchDocument[] indexMatches, SearchPattern pattern, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException {
+
+		if ((monitor != null) && monitor.isCanceled()) {
 			return;
 		}
+
 		// filter out null matches
 		List filtered = new ArrayList();
 		SearchDocument match = null;
 		for (int i = 0; i < indexMatches.length; i++) {
-			if (JsSearchParticipant.DEBUG) {
+			if (DEBUG) {
 				System.out.println("found possible matching JavaSearchDocumentDelegate: " + indexMatches[i]); //$NON-NLS-1$
 			}
 			match = indexMatches[i];
 			if (match != null) {
 				// some matches may be null, or if the index is out of date,
 				// the file may not even exist
-				if (match instanceof JSDTSearchDocumentDelegate && ((JSDTSearchDocumentDelegate) match).getFile().exists()) {
+				if ((match instanceof JSDTSearchDocumentDelegate) && ((JSDTSearchDocumentDelegate) match).getFile().exists()) {
 					filtered.add(match);
 				}
 			}
 		}
+
 		indexMatches = (SearchDocument[]) filtered.toArray(new SearchDocument[filtered.size()]);
 		SearchEngine.getDefaultSearchParticipant().locateMatches(indexMatches, pattern, scope, requestor, monitor);
 	}
-	
-	
-	public IPath[] selectIndexes(SearchPattern pattern, IJavaSearchScope scope) {
-		JsPathIndexer indexer = new JsPathIndexer();
-		return indexer.getVisibleJspPaths(pattern, scope);
+
+	/**
+	 * @see org.eclipse.jdt.core.search.SearchParticipant#getDocument(org.eclipse.core.resources.IFile)
+	 */
+	public SearchDocument getDocument(IFile file) {
+		// never gets called?
+		return null;
 	}
-}
\ No newline at end of file
+}
diff --git a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchScope.java b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchScope.java
index a3bfd01..c81d272 100644
--- a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchScope.java
+++ b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchScope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 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
  *******************************************************************************/
@@ -21,66 +21,78 @@
 
 /**
  * Used to constrain JSP/java search to certain paths and elements.
- * 
  * @author pavery
  */
 public class JsSearchScope implements IJavaSearchScope {
+
 	private boolean fEnclosesAll = false;
-	private List fJavaElements = null;
 	private List fResourcePaths = null;
-	
+	private List fJavaElements = null;
+
 	public JsSearchScope() {
 		// empty constructor just returns true for everything
 		// everything is in scope
 		this.fEnclosesAll = true;
 		init();
 	}
-	
-	public JsSearchScope(IJavaElement[] javaElement) {
-		init();
-		fJavaElements.addAll(Arrays.asList(javaElement));
-	}
-	
+
 	public JsSearchScope(String[] resourceStringPath) {
 		init();
 		fResourcePaths.addAll(Arrays.asList(resourceStringPath));
 	}
-	
-	public void addElement(IJavaElement element) {
-		this.fJavaElements.add(element);
+
+	public JsSearchScope(IJavaElement[] javaElement) {
+		init();
+		fJavaElements.addAll(Arrays.asList(javaElement));
 	}
-	
-	public void addPath(String path) {
-		this.fResourcePaths.add(path);
+
+	private void init() {
+		this.fResourcePaths = new ArrayList();
+		this.fJavaElements = new ArrayList();
 	}
-	
-	public boolean encloses(IJavaElement element) {
-		// pa_TOD implement
-		if (this.fEnclosesAll) {
-			return true;
-		}
-		return true;
-	}
-	
-	public boolean encloses(IResourceProxy element) {
-		if (this.fEnclosesAll) {
-			return true;
-		} else if (enclosesPath(element.requestFullPath().toOSString())) {
-			return true;
-		}
-		return true;
-	}
-	
+
 	public boolean encloses(String resourcePathString) {
+
 		if (this.fEnclosesAll) {
 			return true;
 		} else if (enclosesPath(resourcePathString)) {
 			return true;
 		}
+
 		return false;
 	}
-	
+
+	public boolean encloses(IJavaElement element) {
+
+		// pa_TOD implement
+		if (this.fEnclosesAll) {
+			return true;
+		}
+
+		return true;
+	}
+
+	public boolean encloses(IResourceProxy element) {
+
+		if (this.fEnclosesAll) {
+			return true;
+		} else if (enclosesPath(element.requestFullPath().toOSString())) {
+			return true;
+		}
+
+		return true;
+	}
+
+	public void addPath(String path) {
+		this.fResourcePaths.add(path);
+	}
+
+	public void addElement(IJavaElement element) {
+		this.fJavaElements.add(element);
+	}
+
 	private boolean enclosesPath(String possible) {
+
 		String[] paths = (String[]) fResourcePaths.toArray(new String[fResourcePaths.size()]);
 		for (int i = 0; i < paths.length; i++) {
 			if (possible.equals(paths[i])) {
@@ -89,46 +101,34 @@
 		}
 		return false;
 	}
-	
-	public IPath[] enclosingProjectsAndJars() {
-		// pa_TODO
-		return null;
-	}
-	
+
 	public String getDescription() {
-		return "JSPSearchScope"; //$NON-NLS-1$
+
+		return "JavaScript Search Scope"; //$NON-NLS-1$
 	}
-	
+
+	public IPath[] enclosingProjectsAndJars() {
+		return (IPath[]) fResourcePaths.toArray(new IPath[fResourcePaths.size()]);
+	}
+
 	public boolean includesBinaries() {
-		/* TEMP CHANGE BC may 30 */
 		return false;
 	}
-	
+
 	public boolean includesClasspaths() {
-		/* TEMP CHANGE BC may 30 */
 		return false;
 	}
-	
-	private void init() {
-		this.fResourcePaths = new ArrayList();
-		this.fJavaElements = new ArrayList();
-	}
-	
+
 	public void setIncludesBinaries(boolean includesBinaries) {
-	// do nothing
-	}
-	
-	public void setIncludesClasspaths(boolean includesClasspaths) {
-	// do nothing
+		// do nothing
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.wst.jsdt.core.search.IJavaSearchScope#shouldExclude(java.lang.String, java.lang.String)
-	 */
+	public void setIncludesClasspaths(boolean includesClasspaths) {
+		// do nothing
+	}
+
 	public boolean shouldExclude(String container, String resourceName) {
-		// TODO Auto-generated method stub
-		//System.out.println("Unimplemented method:JsSearchScope.shouldExclude"); //$NON-NLS-1$
+		/* auto gen */
 		return false;
 	}
-
-}
\ No newline at end of file
+}
diff --git a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchSupport.java b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchSupport.java
index a81a197..ef19982 100644
--- a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchSupport.java
+++ b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/JsSearchSupport.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 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
  *******************************************************************************/
@@ -15,8 +15,6 @@
 
 import org.eclipse.core.resources.IFile;
 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;
@@ -52,311 +50,467 @@
  * @author pavery
  */
 public class JsSearchSupport {
-	// for debugging
-	static final boolean DEBUG;
-	private static JsSearchSupport singleton = null;
-	static {
-		String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jspsearch"); //$NON-NLS-1$
-		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
-	}
-	
-	/**
-	 * Clients should access the methods of this class via the single instance
-	 * via getInstance()
-	 * 
-	 * @return
-	 */
-	public synchronized static JsSearchSupport getInstance() {
-		if (JsSearchSupport.singleton == null) {
-			JsSearchSupport.singleton = new JsSearchSupport();
-		}
-		return JsSearchSupport.singleton;
-	}
-	
-	// private IPath fJspPluginLocation = null;
-	/**
-	 * Utility method to check if a file is a jsp file (since this is done
-	 * frequently)
-	 */
-	public static boolean isJsp(IFile file) {
-		
-		if (file != null && file.exists()) {
-			return Util.isJsType(file.getName());
-		}
-		return false;
-	}
-	/**
-	 * This operation ensures that the live resource's search markers show up in
-	 * the open editor. It also allows the ability to pass in a ProgressMonitor
-	 */
-	private class SearchJob extends Job implements IJavaSearchConstants {
-		IJavaElement fElement = null;
-		boolean fIsCaseSensitive = false;
-		int fLimitTo = IJavaSearchConstants.ALL_OCCURRENCES;
-		int fMatchMode = SearchPattern.R_PATTERN_MATCH;
-		SearchRequestor fRequestor = null;
-		IJavaSearchScope fScope = null;
-		int fSearchFor = IJavaSearchConstants.FIELD;
-		String fSearchText = ""; //$NON-NLS-1$
-		
-		// constructor w/ java element
-		public SearchJob(IJavaElement element, IJavaSearchScope scope, SearchRequestor requestor) {
-			super(JsCoreMessages.JSP_Search + element.getElementName());
-			this.fElement = element;
-			this.fScope = scope;
-			this.fRequestor = requestor;
-		}
-		
-		// constructor w/ search text
-		public SearchJob(String searchText, IJavaSearchScope scope, int searchFor, int limitTo, int matchMode, boolean isCaseSensitive,
-				SearchRequestor requestor) {
-			super(JsCoreMessages.JSP_Search + searchText);
-			this.fSearchText = searchText;
-			this.fScope = scope;
-			this.fSearchFor = searchFor;
-			this.fLimitTo = limitTo;
-			this.fMatchMode = matchMode;
-			this.fIsCaseSensitive = isCaseSensitive;
-			this.fRequestor = requestor;
-		}
-		
-		
-		public IStatus run(IProgressMonitor jobMonitor) {
-			if (jobMonitor != null && jobMonitor.isCanceled()) {
+
+    // for debugging
+    static final boolean DEBUG;
+    static {
+        String value = Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/jspsearch"); //$NON-NLS-1$
+        DEBUG=true;
+        //  DEBUG = (value != null) && value.equalsIgnoreCase("true"); //$NON-NLS-1$
+    }
+
+    private static JsSearchSupport singleton = null;
+
+    private JsSearchParticipant fParticipant = null;
+
+    private IPath fJspPluginLocation = null;
+
+    // pa_TODO may be slow (esp for indexing entire workspace)
+    private final CRC32 fChecksumCalculator = new CRC32();
+
+    /** main cancel montior for all search support */
+    private final IProgressMonitor fMonitor = new NullProgressMonitor();
+
+    private JsSearchSupport() {
+        // force use of single instance
+    }
+
+    /**
+     * This operation ensures that the live resource's search markers show up in
+     * the open editor. It also allows the ability to pass in a ProgressMonitor
+     */
+    private class SearchJob extends Job implements IJavaSearchConstants {
+
+        String fSearchText = ""; //$NON-NLS-1$
+
+        IJavaSearchScope fScope = null;
+
+        int fSearchFor = FIELD;
+
+        int fLimitTo = ALL_OCCURRENCES;
+
+        int fMatchMode = SearchPattern.R_PATTERN_MATCH;
+
+        boolean fIsCaseSensitive = false;
+
+        SearchRequestor fRequestor = null;
+
+        IJavaElement fElement = null;
+
+        // constructor w/ java element
+        public SearchJob(IJavaElement element, IJavaSearchScope scope, SearchRequestor requestor) {
+
+            super(JsCoreMessages.JSP_Search + element.getElementName());
+            this.fElement = element;
+            this.fScope = scope;
+            this.fRequestor = requestor;
+        }
+
+        // constructor w/ search text
+        public SearchJob(String searchText, IJavaSearchScope scope, int searchFor, int limitTo, int matchMode, boolean isCaseSensitive, SearchRequestor requestor) {
+
+            super(JsCoreMessages.JSP_Search + searchText);
+            this.fSearchText = searchText;
+            this.fScope = scope;
+            this.fSearchFor = searchFor;
+            this.fLimitTo = limitTo;
+            this.fMatchMode = matchMode;
+            this.fIsCaseSensitive = isCaseSensitive;
+            this.fRequestor = requestor;
+        }
+
+        public IStatus run(IProgressMonitor jobMonitor) {
+
+            if ((jobMonitor != null) && jobMonitor.isCanceled()) {
 				return Status.CANCEL_STATUS;
 			}
-			if (JsSearchSupport.getInstance().isCanceled()) {
+            if (JsSearchSupport.getInstance().isCanceled()) {
 				return Status.CANCEL_STATUS;
 			}
-			SearchPattern javaSearchPattern = null;
-			// if an element is available, use that to create search pattern
-			// (eg. LocalVariable)
-			// otherwise use the text and other paramters
-			if (this.fElement != null) {
+
+            SearchPattern javaSearchPattern = null;
+            // if an element is available, use that to create search pattern
+            // (eg. LocalVariable)
+            // otherwise use the text and other paramters
+            if (this.fElement != null) {
 				javaSearchPattern = SearchPattern.createPattern(this.fElement, this.fLimitTo);
 			} else {
 				javaSearchPattern = SearchPattern.createPattern(this.fSearchText, this.fSearchFor, this.fLimitTo, this.fMatchMode);
 			}
-			if (javaSearchPattern != null) {
-				JsSearchParticipant[] participants = { getSearchParticipant() };
-				SearchEngine engine = new SearchEngine();
-				try {
-					if (jobMonitor != null) {
+
+            if (javaSearchPattern != null) {
+                JsSearchParticipant[] participants = { getSearchParticipant() };
+                SearchEngine engine = new SearchEngine();
+                try {
+                    if (jobMonitor != null) {
 						jobMonitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
 					}
-					engine.search(javaSearchPattern, participants, this.fScope, this.fRequestor, jobMonitor);
-				} catch (CoreException e) {
-					if (JsSearchSupport.DEBUG) {
+                    engine.search(javaSearchPattern, participants, this.fScope, this.fRequestor, jobMonitor);
+                } catch (CoreException e) {
+                    if (DEBUG) {
 						Logger.logException(e);
 					}
-				}
-				// non-CoreExceptions will permanently stall the Worker thread
-				catch (Exception e) {
-					if (JsSearchSupport.DEBUG) {
+                }
+                // non-CoreExceptions will permanently stall the Worker thread
+                catch (Exception e) {
+                    if (DEBUG) {
 						Logger.logException(e);
 					}
-				} finally {
-					if (jobMonitor != null) {
+                } finally {
+                    if (jobMonitor != null) {
 						jobMonitor.done();
 					}
-				}
-			}
-			return Status.OK_STATUS;
-		}
-	}
-	// end SearchJob
-	/**
-	 * Runnable forces caller to wait until finished (as opposed to using a Job)
-	 */
-	private class SearchRunnable implements IWorkspaceRunnable, IJavaSearchConstants {
-		IJavaElement fElement = null;
-		boolean fIsCaseSensitive = false;
-		int fLimitTo = IJavaSearchConstants.ALL_OCCURRENCES;
-		int fMatchMode = SearchPattern.R_PATTERN_MATCH;
-		SearchRequestor fRequestor = null;
-		IJavaSearchScope fScope = null;
-		int fSearchFor = IJavaSearchConstants.FIELD;
-		String fSearchText = ""; //$NON-NLS-1$
-		
-		// constructor w/ java element
-		public SearchRunnable(IJavaElement element, IJavaSearchScope scope, SearchRequestor requestor) {
-			this.fElement = element;
-			this.fScope = scope;
-			this.fRequestor = requestor;
-		}
-		
-		// constructor w/ search text
-		public SearchRunnable(String searchText, IJavaSearchScope scope, int searchFor, int limitTo, int matchMode, boolean isCaseSensitive,
-				SearchRequestor requestor) {
-			this.fSearchText = searchText;
-			this.fScope = scope;
-			this.fSearchFor = searchFor;
-			this.fLimitTo = limitTo;
-			this.fMatchMode = matchMode;
-			this.fIsCaseSensitive = isCaseSensitive;
-			this.fRequestor = requestor;
-		}
-		
-		public void run(IProgressMonitor monitor) throws CoreException {
-			if (monitor != null && monitor.isCanceled()) {
+                }
+            }
+            return Status.OK_STATUS;
+        }
+    }
+
+    // end SearchJob
+    /**
+     * Runnable forces caller to wait until finished (as opposed to using a Job)
+     */
+    private class SearchRunnable implements IWorkspaceRunnable, IJavaSearchConstants {
+
+        String fSearchText = ""; //$NON-NLS-1$
+
+        IJavaSearchScope fScope = null;
+
+        int fSearchFor = FIELD;
+
+        int fLimitTo = ALL_OCCURRENCES;
+
+        int fMatchMode = SearchPattern.R_PATTERN_MATCH;
+
+        boolean fIsCaseSensitive = false;
+
+        SearchRequestor fRequestor = null;
+
+        IJavaElement fElement = null;
+
+        // constructor w/ java element
+        public SearchRunnable(IJavaElement element, IJavaSearchScope scope, SearchRequestor requestor) {
+
+            this.fElement = element;
+            this.fScope = scope;
+            this.fRequestor = requestor;
+        }
+
+        // constructor w/ search text
+        public SearchRunnable(String searchText, IJavaSearchScope scope, int searchFor, int limitTo, int matchMode, boolean isCaseSensitive, SearchRequestor requestor) {
+
+            this.fSearchText = searchText;
+            this.fScope = scope;
+            this.fSearchFor = searchFor;
+            this.fLimitTo = limitTo;
+            this.fMatchMode = matchMode;
+            this.fIsCaseSensitive = isCaseSensitive;
+            this.fRequestor = requestor;
+        }
+
+        public void run(IProgressMonitor monitor) throws CoreException {
+
+            if ((monitor != null) && monitor.isCanceled()) {
 				return;
 			}
-			if (JsSearchSupport.getInstance().isCanceled()) {
+            if (JsSearchSupport.getInstance().isCanceled()) {
 				return;
 			}
-			SearchPattern javaSearchPattern = null;
-			// if an element is available, use that to create search pattern
-			// (eg. LocalVariable)
-			// otherwise use the text and other paramters
-			if (this.fElement != null) {
+
+            SearchPattern javaSearchPattern = null;
+            // if an element is available, use that to create search pattern
+            // (eg. LocalVariable)
+            // otherwise use the text and other paramters
+            if (this.fElement != null) {
 				javaSearchPattern = SearchPattern.createPattern(this.fElement, fLimitTo);
 			} else {
 				javaSearchPattern = SearchPattern.createPattern(fSearchText, fSearchFor, fLimitTo, fMatchMode);
 			}
-			if (javaSearchPattern != null) {
-				JsSearchParticipant[] participants = { getSearchParticipant() };
-				SearchEngine engine = new SearchEngine();
-				try {
-					if (monitor != null) {
+
+            if (javaSearchPattern != null) {
+                JsSearchParticipant[] participants = { getSearchParticipant() };
+                SearchEngine engine = new SearchEngine();
+                try {
+                    if (monitor != null) {
 						monitor.beginTask("", 0); //$NON-NLS-1$
 					}
-					engine.search(javaSearchPattern, participants, fScope, fRequestor, monitor);
-				} catch (CoreException e) {
-					Logger.logException(e);
-					// throw e;
-				}
-				// non-CoreExceptions will permanently stall the Worker thread
-				catch (Exception e) {
-					Logger.logException(e);
-				} finally {
-					if (monitor != null) {
+                    engine.search(javaSearchPattern, participants, fScope, fRequestor, monitor);
+                } catch (CoreException e) {
+                    Logger.logException(e);
+                    //throw e;
+                }
+                // non-CoreExceptions will permanently stall the Worker thread
+                catch (Exception e) {
+                    Logger.logException(e);
+                } finally {
+                    if (monitor != null) {
 						monitor.done();
 					}
-				}
-			}
+                }
+            }
+        }
+    }
+
+    // end SearchRunnable
+
+    /**
+     * Clients should access the methods of this class via the single instance
+     * via getInstance()
+     * 
+     * @return
+     */
+    public synchronized static JsSearchSupport getInstance() {
+
+        if (singleton == null) {
+			singleton = new JsSearchSupport();
 		}
-	}
-	// pa_TODO may be slow (esp for indexing entire workspace)
-	private final CRC32 fChecksumCalculator = new CRC32();
-	/** main cancel montior for all search support */
-	private final IProgressMonitor fMonitor = new NullProgressMonitor();
-	// end SearchRunnable
-	private JsSearchParticipant fParticipant = null;
-	
-	private JsSearchSupport() {
-	// force use of single instance
-	}
-	
-	/**
-	 * schedules a search document representing this JSP file for indexing (by
-	 * the java indexer)
-	 * 
-	 * @param file
-	 *            the JSP file
-	 * @return true if indexing was successful, false otherwise
-	 * @throws CoreException
-	 */
-	public SearchDocument addJspFile(IFile file) {
-		if (JsSearchSupport.getInstance().isCanceled() || !file.isAccessible()) {
-			return null;
-		}
-		if (JsSearchSupport.DEBUG) {
+        return singleton;
+    }
+
+    /**
+     * Utility method to check if a file is a jsp file (since this is done
+     * frequently)
+     */
+    public static boolean isJsp(IFile file) {
+    	return Util.isJsType(file.getName());
+    	// (pa) 20051025 removing deep content type check
+    	// because this method is called frequently
+    	// and IO is expensive
+//        boolean isJsp = false;
+//
+//        if (file != null && file.exists()) {
+//        	
+//            IContentType contentTypeJSP = Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
+//            // check this before description, it's less expensive
+//            if (contentTypeJSP.isAssociatedWith(file.getName())) {
+//            	isJsp = true;
+//            }
+//        }
+//
+//        return isJsp;
+    }
+
+    /**
+     * schedules a search document representing this JSP file for indexing (by
+     * the java indexer)
+     * 
+     * @param file
+     *            the JSP file
+     * @return true if indexing was successful, false otherwise
+     * @throws CoreException
+     */
+    public SearchDocument addJspFile(IFile file) {
+        if (JsSearchSupport.getInstance().isCanceled() || !file.isAccessible()) {
+            return null;
+        }
+
+        if (DEBUG) {
 			System.out.println("adding JSP file:" + file.getFullPath()); //$NON-NLS-1$
 		}
-		// create
-		SearchDocument delegate = createSearchDocument(file);
-		// null if not a jsp file
-		if (delegate != null) {
-			try {
-				getSearchParticipant().scheduleDocumentIndexing(delegate, computeIndexLocation(file.getParent().getFullPath()));
-			} catch (Exception e) {
-				// ensure that failure here doesn't keep other documents from
-				// being indexed
-				// if peformed in a batch call (like JSPIndexManager)
-				if (JsSearchSupport.DEBUG) {
+
+        // create
+        SearchDocument delegate = createSearchDocument(file);
+        // null if not a jsp file
+        if (delegate != null) {
+            try {
+                getSearchParticipant().scheduleDocumentIndexing(delegate, computeIndexLocation(file.getParent().getFullPath()));
+            } catch (Exception e) {
+                // ensure that failure here doesn't keep other documents from
+                // being indexed
+                // if peformed in a batch call (like JSPIndexManager)
+                if (DEBUG) {
 					e.printStackTrace();
 				}
-			}
-		}
-		if (JsSearchSupport.DEBUG) {
+            }
+        }
+
+        if (DEBUG) {
 			System.out.println("scheduled" + delegate + "for indexing"); //$NON-NLS-1$ //$NON-NLS-2$
 		}
-		return delegate;
-	}
-	
-	public final IPath computeContainerLocation(IPath indexLocation) {
-		return null;
-	}
-	
-	// This is called from JSPPathIndexer
-	// pa_TODO
-	// how can we make sure participant indexLocations are updated at startup?
-	public final IPath computeIndexLocation(IPath containerPath) {
-		String indexLocation = null;
-		// we don't want to inadvertently use a JDT Index
-		// we want to be sure to use the Index from the JSP location
-		// Object obj = indexLocations.get(containerPath);
-		// if (obj != null) {
-		// indexLocation = (String) obj;
-		// } else {
-		// create index entry
-		String pathString = containerPath.toOSString();
-		this.fChecksumCalculator.reset();
-		this.fChecksumCalculator.update(pathString.getBytes());
-		String fileName = Long.toString(this.fChecksumCalculator.getValue()) + ".index"; //$NON-NLS-1$
-		// this is the only difference from
-		// IndexManager#computeIndexLocation(...)
-		indexLocation = getModelJspPluginWorkingLocation(getProject(containerPath)).append(fileName).toOSString();
-		// pa_TODO need to add to java path too, so JDT search support knows
-		// there should be a non internal way to do this.
-		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=77564
-		JavaModelManager.getJavaModelManager().getIndexManager().indexLocations.put(containerPath, new Path(indexLocation));
-		// }
-		return new Path(indexLocation);
-	}
-	
-	/**
-	 * @param jspFile
-	 * @return SearchDocument if the file is not null, exists, and is a JSP
-	 *         file, otherwise null.
-	 */
-	private SearchDocument createSearchDocument(IFile jspFile) {
-		JSDTSearchDocumentDelegate delegate = null;
-		if (jspFile != null && jspFile.exists() && JsSearchSupport.isJsp(jspFile)) {
-			delegate = new JSDTSearchDocumentDelegate(new JsSearchDocument(jspFile.getFullPath().toString(), getSearchParticipant()));
+
+        return delegate;
+    }
+    
+    /**
+     * Perform a java search w/ the given parameters. Runs in a background Job
+     * (results may still come in after this method call)
+     * 
+     * @param searchText
+     *            the string of text to search on
+     * @param searchFor
+     *            IJavaSearchConstants.TYPE, METHOD, FIELD, PACKAGE, etc...
+     * @param limitTo
+     *            IJavaSearchConstants.DECLARATIONS,
+     *            IJavaSearchConstants.REFERENCES,
+     *            IJavaSearchConstants.IMPLEMENTORS, or
+     *            IJavaSearchConstants.ALL_OCCURRENCES
+     * @param matchMode
+     *            allow * wildcards or not
+     * @param isCaseSensitive
+     * @param requestor
+     *            passed in to accept search matches (and do "something" with
+     *            them)
+     */
+    public void search(String searchText, IJavaSearchScope scope, int searchFor, int limitTo, int matchMode, boolean isCaseSensitive, SearchRequestor requestor) {
+
+        JsIndexManager.getInstance().rebuildIndexIfNeeded();
+
+        SearchJob job = new SearchJob(searchText, scope, searchFor, limitTo, matchMode, isCaseSensitive, requestor);
+        setCanceled(false);
+        job.setUser(true);
+        // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5032
+        // pops up user operation blocked dialog if you perform a long search,
+        // then open a file because it locks the workspace
+        //job.setRule(ResourcesPlugin.getWorkspace().getRoot());
+        job.schedule();
+    }
+
+    /**
+     * Search for an IJavaElement, constrained by the given parameters. Runs in
+     * a background Job (results may still come in after this method call)
+     * 
+     * @param element
+     * @param scope
+     * @param requestor
+     */
+    public void search(IJavaElement element, IJavaSearchScope scope, SearchRequestor requestor) {
+
+        JsIndexManager.getInstance().rebuildIndexIfNeeded();
+
+        SearchJob job = new SearchJob(element, scope, requestor);
+        setCanceled(false);
+        job.setUser(true);
+        // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5032
+        //job.setRule(ResourcesPlugin.getWorkspace().getRoot());
+        job.schedule();
+    }
+
+    /**
+     * Search for an IJavaElement, constrained by the given parameters. Runs in
+     * an IWorkspace runnable (results will be reported by the end of this
+     * method)
+     * 
+     * @param element
+     * @param scope
+     * @param requestor
+     */
+    public void searchRunnable(IJavaElement element, IJavaSearchScope scope, SearchRequestor requestor) {
+
+        JsIndexManager.getInstance().rebuildIndexIfNeeded();
+
+        SearchRunnable searchRunnable = new SearchRunnable(element, scope, requestor);
+        try {
+            setCanceled(false);
+            ResourcesPlugin.getWorkspace().run(searchRunnable, JsSearchSupport.getInstance().getProgressMonitor());
+        } catch (CoreException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * @param jspFile
+     * @return SearchDocument if the file is not null, exists, and is a JSP
+     *         file, otherwise null.
+     */
+    private SearchDocument createSearchDocument(IFile jspFile) {
+
+        JSDTSearchDocumentDelegate delegate = null;
+        if ((jspFile != null) && jspFile.exists() && isJsp(jspFile)) {
+
+            delegate = new JSDTSearchDocumentDelegate(new JsSearchDocument(jspFile.getFullPath().toString(), getSearchParticipant()));
+        }
+        return delegate;
+
+    }
+
+    /**
+     * Centralized place to access JSPSearchDocuments (used by
+     * JSPSearchParticipant and JSPSearchRequestor)
+     * 
+     * @param searchDocPath
+     * @param doc
+     * @return the JSPSearchDocument or null if one is not found
+     */
+    public SearchDocument getSearchDocument(String searchDocPath) {
+         
+        SearchDocument delegate = null;
+        IFile f = fileForCUPath(searchDocPath);
+        if (f != null) {
+            delegate = createSearchDocument(f);
+        } else {
+            // handle failure case... (file deleted maybe?)
+        }
+        return delegate;
+    }
+
+    /**
+     * Unmangles the searchDocPath and returns the corresponding JSP file.
+     * 
+     * @param searchDocPath
+     */
+    private IFile fileForCUPath(String searchDocPath) {
+    
+        String[] split = searchDocPath.split("/"); //$NON-NLS-1$
+        String classname = split[split.length - 1];
+
+        // ignore anything but .java matches (like .class binary matches)
+        if(!searchDocPath.endsWith(".java")) { //$NON-NLS-1$
+            return null;
+        }
+
+        String filePath = JsNameManglerUtil.unmangle(classname);
+       
+        // try absolute path
+        IFile f = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(filePath));
+        // workspace relative then
+        if(f == null) {
+            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=86009
+            // must have a project name as well
+            // which would mean >= 2 path segments
+            IPath path = new Path(filePath);
+            if(path.segmentCount() >= 2) {
+                f = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+            }
+        }
+        return f;
+    }
+
+    JsSearchParticipant getSearchParticipant() {
+
+        if (this.fParticipant == null) {
+			this.fParticipant = new JsSearchParticipant();
 		}
-		return delegate;
-	}
-	
-	/**
-	 * Unmangles the searchDocPath and returns the corresponding JSP file.
-	 * 
-	 * @param searchDocPath
-	 */
-	private IFile fileForCUPath(String searchDocPath) {
-		String[] split = searchDocPath.split("/"); //$NON-NLS-1$
-		String classname = split[split.length - 1];
-		// ignore anything but .java matches (like .class binary matches)
-		if (!searchDocPath.endsWith(".js")) { //$NON-NLS-1$
-			return null;
-		}
-		String filePath = JsNameManglerUtil.unmangle(classname);
-		// try absolute path
-		IFile f = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(filePath));
-		// workspace relative then
-		if (f == null) {
-			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=86009
-			// must have a project name as well
-			// which would mean >= 2 path segments
-			IPath path = new Path(filePath);
-			if (path.segmentCount() >= 2) {
-				f = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
-			}
-		}
-		return f;
-	}
-	
-	// copied from JDT IndexManager
+        return this.fParticipant;
+    }
+
+    // This is called from JSPPathIndexer
+    // pa_TODO
+    //how can we make sure participant indexLocations are updated at startup?
+    public final IPath computeIndexLocation(IPath containerPath) {
+
+        IPath indexLocation = null;
+        // we don't want to inadvertently use a JDT Index
+        // we want to be sure to use the Index from the JSP location
+        //Object obj = indexLocations.get(containerPath);
+        //if (obj != null) {
+        //    indexLocation = (String) obj;
+        //} else {
+            // create index entry
+            String pathString = containerPath.toOSString();
+            this.fChecksumCalculator.reset();
+            this.fChecksumCalculator.update(pathString.getBytes());
+            String fileName = Long.toString(this.fChecksumCalculator.getValue()) + ".index"; //$NON-NLS-1$
+            // this is the only difference from
+            // IndexManager#computeIndexLocation(...)
+            indexLocation = getModelJspPluginWorkingLocation().append(fileName);
+
+            // pa_TODO need to add to java path too, so JDT search support knows
+            // there should be a non internal way to do this.
+            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=77564
+            JavaModelManager.getJavaModelManager().getIndexManager().indexLocations.put(containerPath, indexLocation);
+        //}
+        return indexLocation;
+    }
 	public IPath getModelJspPluginWorkingLocation(IProject project) {
 		if (project == null) {
 			System.out.println("Null project"); //$NON-NLS-1$
@@ -372,139 +526,64 @@
 		}
 		return workingLocationFile;
 	}
-	
-	/**
-	 * JSP Indexing and Search jobs check this
-	 * 
-	 * @return
-	 */
-	public final IProgressMonitor getProgressMonitor() {
-		return this.fMonitor;
-	}
-	
-	private IProject getProject(IPath path) {
-		// Return the project containing the given path
-		IWorkspace workspace = ResourcesPlugin.getWorkspace();
-		IResource resource = workspace.getRoot().findMember(path.toString());
-		if (resource == null) {
-			return null;
+    // copied from JDT IndexManager
+    public IPath getModelJspPluginWorkingLocation() {
+
+        if (this.fJspPluginLocation != null) {
+			return this.fJspPluginLocation;
 		}
-		IProject project = resource.getProject();
-		return project;
-	}
-	
-	/**
-	 * Centralized place to access JSPSearchDocuments (used by
-	 * JSPSearchParticipant and JSPSearchRequestor)
-	 * 
-	 * @param searchDocPath
-	 * @param doc
-	 * @return the JSPSearchDocument or null if one is not found
-	 */
-	public SearchDocument getSearchDocument(String searchDocPath) {
-		SearchDocument delegate = null;
-		IFile f = fileForCUPath(searchDocPath);
-		if (f != null) {
-			delegate = createSearchDocument(f);
-		} else {
-			// handle failure case... (file deleted maybe?)
+
+        // Append the folder name "jspsearch" to keep the state location area cleaner
+        IPath stateLocation = JsCorePlugin.getDefault().getStateLocation().append("jspsearch");
+
+        // pa_TODO workaround for
+        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=62267
+        // copied from IndexManager
+        String device = stateLocation.getDevice();
+        if ((device != null) && (device.charAt(0) == '/')) {
+			stateLocation = stateLocation.setDevice(device.substring(1));
 		}
-		return delegate;
-	}
-	
-	JsSearchParticipant getSearchParticipant() {
-		if (this.fParticipant == null) {
-			this.fParticipant = new JsSearchParticipant();
+
+        // ensure that it exists on disk
+        File folder = new File(stateLocation.toOSString());
+		if (!folder.isDirectory()) {
+			try {
+				folder.mkdir();
+			}
+			catch (SecurityException e) {
+			}
 		}
-		return this.fParticipant;
-	}
-	
-	/**
-	 * JSP Indexing and Search jobs check this
-	 * 
-	 * @return
-	 */
-	public synchronized final boolean isCanceled() {
-		return fMonitor.isCanceled();
-	}
-	
-	/**
-	 * Search for an IJavaElement, constrained by the given parameters. Runs in
-	 * a background Job (results may still come in after this method call)
-	 * 
-	 * @param element
-	 * @param scope
-	 * @param requestor
-	 */
-	public void search(IJavaElement element, IJavaSearchScope scope, SearchRequestor requestor) {
-		JsIndexManager.getInstance().rebuildIndexIfNeeded();
-		SearchJob job = new SearchJob(element, scope, requestor);
-		setCanceled(false);
-		job.setUser(true);
-		// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5032
-		// job.setRule(ResourcesPlugin.getWorkspace().getRoot());
-		job.schedule();
-	}
-	
-	/**
-	 * Perform a java search w/ the given parameters. Runs in a background Job
-	 * (results may still come in after this method call)
-	 * 
-	 * @param searchText
-	 *            the string of text to search on
-	 * @param searchFor
-	 *            IJavaSearchConstants.TYPE, METHOD, FIELD, PACKAGE, etc...
-	 * @param limitTo
-	 *            IJavaSearchConstants.DECLARATIONS,
-	 *            IJavaSearchConstants.REFERENCES,
-	 *            IJavaSearchConstants.IMPLEMENTORS, or
-	 *            IJavaSearchConstants.ALL_OCCURRENCES
-	 * @param matchMode
-	 *            allow * wildcards or not
-	 * @param isCaseSensitive
-	 * @param requestor
-	 *            passed in to accept search matches (and do "something" with
-	 *            them)
-	 */
-	public void search(String searchText, IJavaSearchScope scope, int searchFor, int limitTo, int matchMode, boolean isCaseSensitive, SearchRequestor requestor) {
-		JsIndexManager.getInstance().rebuildIndexIfNeeded();
-		SearchJob job = new SearchJob(searchText, scope, searchFor, limitTo, matchMode, isCaseSensitive, requestor);
-		setCanceled(false);
-		job.setUser(true);
-		// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5032
-		// pops up user operation blocked dialog if you perform a long search,
-		// then open a file because it locks the workspace
-		// job.setRule(ResourcesPlugin.getWorkspace().getRoot());
-		job.schedule();
-	}
-	
-	/**
-	 * Search for an IJavaElement, constrained by the given parameters. Runs in
-	 * an IWorkspace runnable (results will be reported by the end of this
-	 * method)
-	 * 
-	 * @param element
-	 * @param scope
-	 * @param requestor
-	 */
-	public void searchRunnable(IJavaElement element, IJavaSearchScope scope, SearchRequestor requestor) {
-		JsIndexManager.getInstance().rebuildIndexIfNeeded();
-		SearchRunnable searchRunnable = new SearchRunnable(element, scope, requestor);
-		try {
-			setCanceled(false);
-			ResourcesPlugin.getWorkspace().run(searchRunnable, JsSearchSupport.getInstance().getProgressMonitor());
-		} catch (CoreException e) {
-			e.printStackTrace();
-		}
-	}
-	
-	/**
-	 * JSP Indexing and Search jobs check this
-	 * 
-	 * @return
-	 */
-	public synchronized final void setCanceled(boolean cancel) {
-		// System.out.println("search support monitor" + fMonitor);
-		fMonitor.setCanceled(cancel);
-	}
-}
\ No newline at end of file
+
+        return this.fJspPluginLocation = stateLocation;
+    }
+
+    /**
+     * JSP Indexing and Search jobs check this
+     * 
+     * @return
+     */
+    public synchronized final void setCanceled(boolean cancel) {
+    	//System.out.println("search support monitor" + fMonitor);
+        fMonitor.setCanceled(cancel);
+    }
+
+    /**
+     * JSP Indexing and Search jobs check this
+     * 
+     * @return
+     */
+    public synchronized final boolean isCanceled() {
+
+        return fMonitor.isCanceled();
+    }
+
+    /**
+     * JSP Indexing and Search jobs check this
+     * 
+     * @return
+     */
+    public final IProgressMonitor getProgressMonitor() {
+
+        return this.fMonitor;
+    }
+}
diff --git a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/NullSearchDocument.java b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/NullSearchDocument.java
index 3f0dec7..873e560 100644
--- a/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/NullSearchDocument.java
+++ b/bundles/org.eclipse.wst.jsdt.web.core/src/org/eclipse/wst/jsdt/web/core/javascript/search/NullSearchDocument.java
@@ -12,31 +12,32 @@
 
 import org.eclipse.wst.jsdt.core.search.SearchDocument;
 
+
+
 /**
  * An empty servlet, safe for Java search participation
  * 
  * @author pavery
  */
 public class NullSearchDocument extends SearchDocument {
+	
 	StringBuffer fEmptyServletBuffer = null;
 	
 	public NullSearchDocument(String documentPath) {
-		super(documentPath, new JsSearchParticipant());
+		super(documentPath, new JsSearchParticipant()); 
 		this.fEmptyServletBuffer = new StringBuffer();
 	}
 	
-	
 	public byte[] getByteContents() {
 		return this.fEmptyServletBuffer.toString().getBytes();
 	}
 	
-	
 	public char[] getCharContents() {
 		return this.fEmptyServletBuffer.toString().toCharArray();
 	}
 	
-	
 	public String getEncoding() {
 		return null;
 	}
+
 }