/*******************************************************************************
 * Copyright (c) 2010, 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.core.indexing;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.ISaveParticipant;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.sse.core.internal.Logger;

/**
 * <p>
 * A generic class for implementing a resource index manager. It is important
 * to note that this only provides the framework for managing an index, not
 * actually indexing. The subtle difference is that the manager is in charge
 * of paying attention to all of the resource actions that take place in the
 * workspace and filtering those actions down to simple actions that need to
 * be performed on whatever index this manager is managing.
 * </p>
 * 
 * <p>
 * The manager does its very best to make sure the index is always consistent,
 * even if resource events take place when the manager is not running. In the
 * event that the manager determines it has missed, lost, or corrupted any
 * resource change events that have occurred before, during, or after its
 * activation or deactivation then the manager will inspect the entire
 * workspace to insure the index it is managing is consistent.
 * </p>
 * 
 * <p>
 * This class and its contents are <b>PROVISIONAL</b>. They can and very likely will
 * change prior to finalization in the next main release.
 * </p>
 * 
 */
public abstract class AbstractIndexManager {
	
	/** Used to encode path bytes in case they contain double byte characters */
	private static final String ENCODING_UTF16 = "utf16"; //$NON-NLS-1$
	
	/** Default time to wait for other tasks to finish */
	private static final int WAIT_TIME = 300;
	
	/**
	 * <p>Used to report progress on jobs where the total work to complete is unknown.
	 * The created effect is a progress bar that moves but that will never complete.</p>
	 */
	private static final int UNKNOWN_WORK = 100;
	
	/** The amount of events to batch up before sending them off to the processing job*/
	private static final int BATCH_UP_AMOUNT = 100;
	
	/** If this file exists then a full workspace re-processing is needed */ 
	private static final String RE_PROCESS_FILE_NAME = ".re-process"; //$NON-NLS-1$
	
	/** Common error message to log */
	private static final String LOG_ERROR_INDEX_INVALID =
		"Index may become invalid, incomplete, or enter some other inconsistent state."; //$NON-NLS-1$
	
	/** State: manager is stopped */
	private static final byte STATE_DISABLED = 0;
	
	/** State: manager is running */
	private static final byte STATE_ENABLED = 1;
	
	/** Action: add to index */
	protected static final byte ACTION_ADD = 0;
	
	/** Action: remove from index */
	protected static final byte ACTION_REMOVE = 1;
	
	/** Action: add to index caused by move operation */
	protected static final byte ACTION_ADD_MOVE_FROM = 2;
	
	/** Action: remove from index caused by move operation */
	protected static final byte ACTION_REMOVE_MOVE_TO = 3;
	
	/** Source: action originated from resource change event */
	protected static final byte SOURCE_RESOURCE_CHANGE = 0;
	
	/** Source: action originated from workspace scan */
	protected static final byte SOURCE_WORKSPACE_SCAN = 1;
	
	/** Source: action originated from saved state */
	protected static final byte SOURCE_SAVED_STATE = 2;
	
	/** Source: preserved resources to index */
	protected static final byte SOURCE_PRESERVED_RESOURCES_TO_INDEX = 3;
	
	/** the name of this index manager */
	private String fName;
	
	/** Message to use when manager is running */
	private String fMessage_Running;
	
	/** Message to use when manager is initializing */
	private String fMessage_Initializing;
	
	/**
	 * <p>Message to use when manager is processing files.
	 * Should contain one parameter to be filled in with the number of files to process.</p>
	 */
	private String fMessage_ProcessingFiles;
	
	/** {@link IResourceChangeListener} to listen for file changes */
	private ResourceChangeListener fResourceChangeListener;
	
	/** The {@link Job} that does all of the indexing */
	private ResourceEventProcessingJob fResourceEventProcessingJob;
	
	/** A {@link Job} to search the workspace for all files */
	private Job fWorkspaceVisitorJob;
	
	/**
	 * <p>Current state of the manager</p>
	 * 
	 * @see #STATE_DISABLED
	 * @see #STATE_ENABLED
	 */
	private volatile byte fState;
	
	/** used to prevent manager from starting and stopping at the same time */
	private Object fStartStopLock = new Object();
	
	/** <code>true</code> if the manager is currently starting, <code>false</code> otherwise */
	private boolean fStarting;

	/**
	 * <p>Creates the manager with a given name.</p>
	 * 
	 * @param name This will be pre-pended to progress reporting messages and thus should
	 * be translated
	 * 
	 * @param messageRunning Message to use when manager is running. Should be user readable.
	 * @param messagegInitializing Message to use when manager is initializing. Should be user readable.
	 * @param messageProcessingFiles Message to use when manager is processing files.
	 * Should contain two parameters to be filled in with the number of files to process, and
	 * the file currently being processed.
	 * Should be user readable.
	 */
	
	protected AbstractIndexManager(String name, String messageRunning,
			String messagegInitializing, String messageProcessingFiles) {
		
		this.fMessage_Running = messageRunning;
		this.fMessage_ProcessingFiles = messageProcessingFiles;
		this.fMessage_Initializing = messagegInitializing;
		
		this.fName = name;
		this.fState = STATE_DISABLED;
		this.fResourceChangeListener = new ResourceChangeListener();
		this.fResourceEventProcessingJob = new ResourceEventProcessingJob();
		this.fStarting = false;
	}
	
	/**
	 * <p>Starts up the {@link AbstractIndexManager}.  If a {@link IResourceDelta}
	 * is provided then it is assumed that all other files in the workspace
	 * have already been index and thus only those in the provided
	 * {@link IResourceDelta} will be processed.  Else if the provided
	 * {@link IResourceDelta} is <code>null</code> it is assumed no files
	 * have been indexed yet so the entire workspace will be searched for
	 * files to be indexed.</p>
	 * 
	 * <p>If {@link IResourceDelta} is provided this will block until that delta
	 * has finished processing.  If no {@link IResourceDelta} provided then a
	 * separate job will be created to process the entire workspace and this method
	 * will return without waiting for that job to complete</p>
	 * 
	 * <p>Will block until {@link #stop()} has finished running if it is
	 * currently running</p>
	 * 
	 * @param savedStateDelta the delta from a saved state, if <code>null</code>
	 * then the entire workspace will be searched for files to index, else
	 * only files in this {@link IResourceDelta} will be indexed
	 * @param monitor This action can not be canceled but this monitor will be used
	 * to report progress
	 */
	public final void start(IResourceDelta savedStateDelta, IProgressMonitor monitor) {
		SubMonitor progress = SubMonitor.convert(monitor);
		synchronized (this.fStartStopLock) {
			this.fStarting = true;
			
			try {
				if(this.fState == STATE_DISABLED) {
					//report status
					progress.beginTask(this.fName, 2);
					
					//start listening for resource change events
					this.fResourceChangeListener.start();
					
					//check to see if a full re-index is required
					boolean forcedFullReIndexNeeded = this.isForcedFullReIndexNeeded();
					
					/* start the indexing job only loading preserved state if not doing full index
					 * if failed loading preserved state then force full re-index
					 */
					forcedFullReIndexNeeded = !this.fResourceEventProcessingJob.start(!forcedFullReIndexNeeded,
							progress.newChild(1));
					progress.setWorkRemaining(1);
					
					//don't bother processing saved delta if forced full re-index is needed
					if(!forcedFullReIndexNeeded) {
						/* if there is a delta attempt to process it
						 * else need to do a full workspace index
						 */
						if(savedStateDelta != null) {
							forcedFullReIndexNeeded = false;
							try {
								//deal with reporting progress
								SubMonitor savedStateProgress = progress.newChild(1, SubMonitor.SUPPRESS_NONE);
								
								//process delta
								ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(savedStateProgress,
										AbstractIndexManager.SOURCE_SAVED_STATE);
								savedStateDelta.accept(visitor);
								
								//process any remaining batched up resources to index
								visitor.processBatchedResourceEvents();
							} catch (CoreException e) {
								forcedFullReIndexNeeded = true;
								Logger.logException(this.fName + ": Could not process saved state. " + //$NON-NLS-1$
										"Forced to do a full workspace re-index.", e); //$NON-NLS-1$
							}
						} else {
							forcedFullReIndexNeeded = true;
						}
					}
					progress.worked(1);
					
					//if need to process the entire workspace do so in another job
					if(forcedFullReIndexNeeded){
						this.fWorkspaceVisitorJob = new WorkspaceVisitorJob();
						this.fWorkspaceVisitorJob.schedule();
					}
					
					//update state
					this.fState = STATE_ENABLED;
				}
			} finally {
				this.fStarting = false;
				progress.done();
			}
		}
	}
	
	/**
	 * <p>Safely shuts down the manager.</p>
	 * 
	 * <p>This will block until the {@link #start(IResourceDelta, IProgressMonitor)} has
	 * finished (if running).  Also until the current resource event has finished being
	 * processed.  Finally it will block until the events still to be processed by
	 * the processing job have been preserved to be processed on the next call to
	 * {@link #start(IResourceDelta, IProgressMonitor)}.</p>
	 * 
	 * <p>If at any point during this shut down processes something goes wrong the
	 * manager will be sure that on the next call to {@link #start(IResourceDelta, IProgressMonitor)}
	 * the entire workspace will be re-processed.</p>
	 * 
	 * @throws InterruptedException
	 */
	public final void stop() throws InterruptedException {
		synchronized (this.fStartStopLock) {
			if(this.fState != STATE_DISABLED) {
				
				//stop listening for events, and wait for the current event to finish
				this.fResourceChangeListener.stop();
				
				// if currently visiting entire workspace, give up and try again next load
				boolean forceFullReIndexNextStart = false;
				if(this.fWorkspaceVisitorJob != null) {
					if (this.fWorkspaceVisitorJob.getState() != Job.NONE) {
						this.fWorkspaceVisitorJob.cancel();
						
						this.forceFullReIndexNextStart();
						forceFullReIndexNextStart = true;
					}
				}
				
				//stop the indexing job, only preserve if not already forcing a re-index
				forceFullReIndexNextStart = !this.fResourceEventProcessingJob.stop(!forceFullReIndexNextStart);
				
				//if preserving failed, then force re-index
				if(forceFullReIndexNextStart) {
					this.forceFullReIndexNextStart();
				}
				
				//update status
				this.fState = STATE_DISABLED;
			}
		}
	}
	
	/**
	 * @return the name of this indexer
	 */
	protected String getName() {
		return this.fName;
	}
	
	/**
	 * <p>Should be called by a client of the index this manager manages before the index
	 * is accessed, assuming the client wants an index consistent with the latest
	 * resource changes.</p>
	 * 
	 * <p>The supplied monitor will be used to supply user readable progress as the manager
	 * insures the index has been given all the latest resource events.  This monitor
	 * may be canceled, but if it is the state of the index is not guaranteed to be
	 * consistent with the latest resource change events.</p>
	 * 
	 * @param monitor Used to report user readable progress as the manager insures the
	 * index is consistent with the latest resource events.  This monitor can be canceled
	 * to stop waiting for consistency but then no guaranty is made about the consistency
	 * of the index in relation to unprocessed resource changes
	 * 
	 * @return <code>true</code> if the wait finished successfully and the manager is consistent,
	 * <code>false</code> otherwise, either an error occurred while waiting for the manager
	 * or the monitor was canceled
	 * 
	 * @throws InterruptedException This can happen when waiting for other jobs
	 */
	public final boolean waitForConsistent(IProgressMonitor monitor) {
		boolean success = true;
		boolean interupted = false;
		SubMonitor progress = SubMonitor.convert(monitor);
		
		//set up the progress of waiting
		int remainingWork = 4;
		progress.beginTask(this.fMessage_Running,remainingWork);
		
		//wait for start up
		if(this.fStarting && !monitor.isCanceled()) {
			SubMonitor startingProgress = progress.newChild(1);
			startingProgress.subTask(this.fMessage_Initializing);
			while(this.fStarting && !monitor.isCanceled()) {
				//this creates a never ending progress that still moves forward
				startingProgress.setWorkRemaining(UNKNOWN_WORK);
				startingProgress.newChild(1).worked(1);
				try {
					Thread.sleep(WAIT_TIME);
				} catch (InterruptedException e) {
					interupted = true;
				}
			}
		}
		progress.setWorkRemaining(--remainingWork);
		
		//wait for workspace visiting job
		if(this.fWorkspaceVisitorJob != null && this.fWorkspaceVisitorJob.getState() != Job.NONE && !monitor.isCanceled()) {
			SubMonitor workspaceVisitorProgress = progress.newChild(1);
			workspaceVisitorProgress.subTask(this.fMessage_Initializing);
			while(this.fWorkspaceVisitorJob.getState() != Job.NONE && !monitor.isCanceled()) {
				//this creates a never ending progress that still moves forward
				workspaceVisitorProgress.setWorkRemaining(UNKNOWN_WORK);
				workspaceVisitorProgress.newChild(1).worked(1);
				try {
					Thread.sleep(WAIT_TIME);
				} catch (InterruptedException e) {
					interupted = true;
				}
			}
		}
		progress.setWorkRemaining(--remainingWork);
		
		//wait for the current resource event
		if(this.fResourceChangeListener.isProcessingEvents() && !monitor.isCanceled()) {
			SubMonitor workspaceVisitorProgress = progress.newChild(1);
			workspaceVisitorProgress.subTask(this.fMessage_Running);
			while(this.fResourceChangeListener.isProcessingEvents() && !monitor.isCanceled()) {
				workspaceVisitorProgress.setWorkRemaining(UNKNOWN_WORK);
				workspaceVisitorProgress.newChild(1).worked(1);
				try {
					this.fResourceChangeListener.waitForCurrentEvent(WAIT_TIME);
				} catch (InterruptedException e) {
					interupted = true;
				}
			}
		}
		progress.setWorkRemaining(--remainingWork);
		
		//wait for all files to be indexed
		if(this.fResourceEventProcessingJob.getNumResourceEventsToProcess() != 0 && !monitor.isCanceled()) {
			SubMonitor indexingProgress = progress.newChild(1);
			int prevNumResrouces;
			int numResources = this.fResourceEventProcessingJob.getNumResourceEventsToProcess();
			while(numResources != 0 && !monitor.isCanceled()) {
				//update the progress indicator
				indexingProgress.subTask(NLS.bind(this.fMessage_ProcessingFiles, "" + numResources)); //$NON-NLS-1$
				indexingProgress.setWorkRemaining(numResources);
				prevNumResrouces = numResources;
				numResources = this.fResourceEventProcessingJob.getNumResourceEventsToProcess();
				int numProcessed = prevNumResrouces - numResources;
				indexingProgress.worked(numProcessed > 0 ? numProcessed : 0);
				
				//give the index some time to do some indexing
				try {
					this.fResourceEventProcessingJob.waitForConsistant(WAIT_TIME);
				} catch (InterruptedException e) {
					interupted = true;
				}
			}
		}
		progress.setWorkRemaining(--remainingWork);
		
		if(monitor.isCanceled()) {
			success = false;
		}
		
		//reset the interrupted flag if we were interrupted
		if(interupted) {
			Thread.currentThread().interrupt();
		}
		
		progress.done();
		return success;
	}
	
	/**
	 * <p>Called for each {@link IResource} given in a resource delta.  If the resource
	 * type is a file then used to determine if that file should be processed by the manager,
	 * if the resource type is a project or directory then it is used to determine if the children
	 * of the project or directory should be processed looking for file resources.</p>
	 * 
	 * <p><b>NOTE:</b> Even if <code>true</code> is returned for a directory resource that
	 * only means the children of the directory should be inspected for possible files to index.
	 * Directories themselves can not be managed in order to add to an index.</p>
	 * 
	 * @param type the {@link IResource#getType()} result of the resource to possibly index
	 * @param path the full {@link IPath} to the resource to possibly index
	 * @return <code>true</code> If the resource with the given <code>type</code> and
	 * <code>path</code> should either itself be indexed, or its children should be indexed,
	 * <code>false</code> if neither the described resource or any children should be indexed
	 */
	protected abstract boolean isResourceToIndex(int type, IPath path);
	
	/**
	 * <p>Called for each {@link ResourceEvent} gathered by the various sources and processed
	 * by the {@link ResourceEventProcessingJob}.  The implementation of this method
	 * should use the given information to update the index this manager is managing.</p>
	 * 
	 * @param source The source that reported this resource event
	 * @param action The action to be taken on the given <code>resource</code>
	 * @param resource The index should perform the given <code>action</code> on this
	 * resource
	 * @param movePath If the given <code>action</code> is {@link AbstractIndexManager#ACTION_ADD_MOVE_FROM}
	 * or {@link AbstractIndexManager#ACTION_REMOVE_MOVE_TO} then this field will not be
	 * null and reports the path the given <code>resource</code> was either moved from or
	 * moved to respectively.
	 * 
	 * @see AbstractIndexManager#SOURCE_RESOURCE_CHANGE
	 * @see AbstractIndexManager#SOURCE_SAVED_STATE
	 * @see AbstractIndexManager#SOURCE_WORKSPACE_SCAN
	 * @see AbstractIndexManager#SOURCE_PRESERVED_RESOURCES_TO_INDEX
	 * 
	 * @see AbstractIndexManager#ACTION_ADD
	 * @see AbstractIndexManager#ACTION_REMOVE
	 * @see AbstractIndexManager#ACTION_ADD_MOVE_FROM
	 * @see AbstractIndexManager#ACTION_REMOVE_MOVE_TO
	 */
	protected abstract void performAction(byte source, byte action, IResource resource,
			IPath movePath);
	
	/**
	 * <p>Gets the working location of the manager. This is where any relevant
	 * state can be persisted.</p>
	 * 
	 * @return the working location of the manager
	 */
    protected abstract IPath getWorkingLocation();
	
	/**
	 * <p>Next time the manager starts up force a full workspace index</p>
	 */
	private void forceFullReIndexNextStart() {
		IPath reIndexPath =
			AbstractIndexManager.this.getWorkingLocation().append(RE_PROCESS_FILE_NAME);
		File file = new File(reIndexPath.toOSString());
		try {
			file.createNewFile();
		} catch (IOException e) {
			Logger.logException(this.fName + ": Could not create file to tell manager to" + //$NON-NLS-1$
					" do a full re-index on next load. " + //$NON-NLS-1$
					AbstractIndexManager.LOG_ERROR_INDEX_INVALID, e);
		}
	}
	
	/**
	 * @return <code>true</code> if a full workspace index is needed as dictated by
	 * a previous call to {@link #forceFullReIndexNextStart()}, <code>false</code>
	 * otherwise
	 */
	private boolean isForcedFullReIndexNeeded() {
		boolean forcedFullReIndexNeeded = false;
		IPath reIndexPath =
			AbstractIndexManager.this.getWorkingLocation().append(RE_PROCESS_FILE_NAME);
		File file = new File(reIndexPath.toOSString());
		if(file.exists()) {
			file.delete();
			forcedFullReIndexNeeded = true;
		}
		
		return forcedFullReIndexNeeded;
	}
	
	/**
	 * <p>A system {@link Job} used to visit all of the files in the workspace
	 * looking for files to index.</p>
	 * 
	 * <p>This should only have to be done once per workspace on the first load,
	 * but if it fails or a SavedState can not be retrieved on a subsequent
	 * workspace load then this will have to be done again.</p>
	 */
	private class WorkspaceVisitorJob extends Job {
		/**
		 * <p>Default constructor that sets up this job as a system job</p>
		 */
		protected WorkspaceVisitorJob() {
			super(AbstractIndexManager.this.fMessage_Initializing);
			
			this.setUser(false);
			this.setSystem(true);
			this.setPriority(Job.LONG);
		}
		
		/**
		 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
		 */
		protected IStatus run(IProgressMonitor monitor) {
			try {
				//update status
				monitor.beginTask(AbstractIndexManager.this.fMessage_Initializing,
						IProgressMonitor.UNKNOWN);
				
				//visit the workspace
				WorkspaceVisitor visitor = new WorkspaceVisitor(monitor);
				ResourcesPlugin.getWorkspace().getRoot().accept(visitor, IResource.NONE);
				
				//process any remaining batched up resources to index
				visitor.processBatchedResourceEvents();
			} catch(CoreException e) {
				Logger.logException(AbstractIndexManager.this.fName +
						": Failed visiting entire workspace for initial index. " + //$NON-NLS-1$
						AbstractIndexManager.LOG_ERROR_INDEX_INVALID, e);
			}
			
			IStatus status;
			if(monitor.isCanceled()) {
				status = Status.CANCEL_STATUS;
			} else {
				status = Status.OK_STATUS;
			}
			
			monitor.done();
			return status;
		}
		
		/**
		 * <p>An {@link IResourceProxyVisitor} used to visit all of the files in the
		 * workspace looking for files to add to the index.</p>
		 * 
		 * <p><b>NOTE: </b>After this visitor is used {@link WorkspaceVisitor#processBatchedResourceEvents()
		 * must be called to flush out the last of the {@link ResourceEvent}s produced
		 * by this visitor.</p>
		 */
		private class WorkspaceVisitor implements IResourceProxyVisitor {
			/** {@link IProgressMonitor} used to report status and check for cancellation */
			private SubMonitor fProgress;
			
			/**
			 * {@link Map}&lt{@link IResource}, {@link ResourceEvent}&gt
			 * <p>Map of resources events created and batched up by this visitor.
			 * These events are periodical be sent off to the
			 * {@link ResourceEventProcessingJob} but need to be sent off
			 * one final time after this visitor finishes it work.</p>
			 * 
			 * @see #processBatchedResourceEvents()
			 */
			private Map fBatchedResourceEvents;
			
			/**
			 * <p>Default constructor</p>
			 * @param monitor used to report status and allow this visitor to be canceled
			 */
			protected WorkspaceVisitor(IProgressMonitor monitor) {
				this.fProgress = SubMonitor.convert(monitor);
				this.fBatchedResourceEvents = new LinkedHashMap(BATCH_UP_AMOUNT);
			}

			/**
			 * <p>As long as the monitor is not canceled visit each file in the workspace
			 * that should be visited.</p>
			 * 
			 * @see org.eclipse.core.resources.IResourceProxyVisitor#visit(org.eclipse.core.resources.IResourceProxy)
			 * @see AbstractIndexManager#shouldVisit(String)
			 */
			public boolean visit(IResourceProxy proxy) throws CoreException {
				this.fProgress.subTask(proxy.getName());
				
				boolean visitChildren = false;
				
				/* if not canceled or a hidden resource then process file
				 * else don't visit children
				 */
				if(!this.fProgress.isCanceled()) {
					/* if root node always visit children
					 * else ask manager implementation if resource and its children should be visited 
					 */
					IPath path = proxy.requestFullPath();
					if (proxy.isDerived()) { // Do not include derived resources
						visitChildren = false;
					} else if(path.isRoot()) { //$NON-NLS-1$
						visitChildren = true;
					} else if(isResourceToIndex(proxy.getType(), path)) {
						if(proxy.getType() == IResource.FILE) {
							//add the file to be indexed
							IFile file = (IFile) proxy.requestResource();
							if(file.exists()) {
								this.fBatchedResourceEvents.put(file, new ResourceEvent(
										AbstractIndexManager.SOURCE_WORKSPACE_SCAN,
										AbstractIndexManager.ACTION_ADD,
										null));
							}
						}
						visitChildren = true;
					}
				}
				
				//batch up resource changes before sending them out
				if(this.fBatchedResourceEvents.size() >= BATCH_UP_AMOUNT) {
					this.processBatchedResourceEvents();
				}
				
				return visitChildren;
			}
			
			/**
			 * <p>Sends any batched up resource events created by this visitor to the
			 * {@link ResourceEventProcessingJob}.<p>
			 * 
			 * <p><b>NOTE:</b> This will be called every so often as the visitor is
			 * visiting resources but needs to be called a final time by the user of
			 * this visitor to be sure the final events are sent off</p>
			 */
			protected void processBatchedResourceEvents() {
				AbstractIndexManager.this.fResourceEventProcessingJob.addResourceEvents(
						this.fBatchedResourceEvents);
				this.fBatchedResourceEvents.clear();
			}
		}
	}
	
	/**
	 * <p>Used to listen to resource change events in the workspace.  These events
	 * are batched up and then passed onto the {@link ResourceEventProcessingJob}.</p>
	 */
	private class ResourceChangeListener implements IResourceChangeListener {
		/**
		 * <p>The number of events currently being processed by this listener.</p>
		 * <p>Use the {@link #fEventsBeingProcessedLock} when reading or writing this field</p>
		 * 
		 * @see #fEventsBeingProcessedLock
		 */
		private volatile int fEventsBeingProcessed;
		
		/**
		 * Lock to use when reading or writing {@link #fEventsBeingProcessed}
		 * 
		 * @see #fEventsBeingProcessed
		 */
		private final Object fEventsBeingProcessedLock = new Object();
		
		/**
		 * <p>Current state of this listener</p>
		 * 
		 * @see AbstractIndexManager#STATE_DISABLED
		 * @see AbstractIndexManager#STATE_ENABLED
		 */
		private volatile byte fState;
		
		/**
		 * <p>Default constructor</p>
		 */
		protected ResourceChangeListener() {
			this.fState = STATE_DISABLED;
			this.fEventsBeingProcessed = 0;
		}
		
		/**
		 * <p>Start listening for resource change events</p>
		 */
		protected void start() {
			this.fState = STATE_ENABLED;
			ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
		}
		
		/**
		 * <p>Stop listening for resource change events and if already processing
		 * an event then wait for that processing to finish</p>
		 * 
		 * @throws InterruptedException waiting for a current event to finish processing
		 * could be interrupted
		 */
		protected void stop() throws InterruptedException {
			ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
			
			//wait indefinitely for current event to finish processing
			this.waitForCurrentEvent(0);
			
			this.fState = STATE_DISABLED;
		}
		
		/**
		 * <p>Blocks until either the current resource event has been processed or
		 * until the given timeout has passed.</p>
		 * 
		 * @param timeout block until either this timeout elapses (0 means never to timeout)
		 * or the current resource change event finishes being processed
		 * 
		 * @throws InterruptedException This can happen when waiting for a lock
		 */
		protected void waitForCurrentEvent(int timeout) throws InterruptedException {
			synchronized (this.fEventsBeingProcessedLock) {
				if(this.fEventsBeingProcessed != 0) {
					this.fEventsBeingProcessedLock.wait(timeout);
				}
			}
		}
		
		/**
		 * @return <code>true</code> if this listener is currently processing any
		 * events, <code>false</code> otherwise.
		 */
		protected boolean isProcessingEvents() {
			return this.fEventsBeingProcessed != 0;
		}
		
		/**
		 * <p>Process a resource change event.  If it is a pre-close or pre-delete then
		 * the {@link ResourceEventProcessingJob} is paused so it does not try to
		 * process resources that are about to be deleted.  The {@link ResourceDeltaVisitor}
		 * is used to actually process the event.</p>
		 * 
		 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
		 * @see ResourceDeltaVisitor
		 */
		public void resourceChanged(IResourceChangeEvent event) {
			try {
				//update the number of events being processed
				synchronized (this.fEventsBeingProcessedLock) {
					++this.fEventsBeingProcessed;
				}
				
				if(this.fState == STATE_ENABLED) {
					switch(event.getType()) {
						case IResourceChangeEvent.PRE_CLOSE:
						case IResourceChangeEvent.PRE_DELETE:{
							//pre-close or pre-delete pause the persister job so it does not interfere
							AbstractIndexManager.this.fResourceEventProcessingJob.pause();
							break;
						}
						case IResourceChangeEvent.POST_BUILD:
						case IResourceChangeEvent.POST_CHANGE: {
							//post change start up the indexer job and process the delta
							AbstractIndexManager.this.fResourceEventProcessingJob.unPause();
							
							// only analyze the full (starting at root) delta hierarchy
							IResourceDelta delta = event.getDelta();
							if (delta != null && delta.getFullPath().toString().equals("/")) { //$NON-NLS-1$
								try {
									//use visitor to visit all children
									ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(
											AbstractIndexManager.SOURCE_RESOURCE_CHANGE);
									delta.accept(visitor, false);
									
									//process any remaining batched up resources to index
									visitor.processBatchedResourceEvents();
								} catch (CoreException e) {
									Logger.logException(AbstractIndexManager.this.fName +
											": Failed visiting resrouce change delta. " + //$NON-NLS-1$
											AbstractIndexManager.LOG_ERROR_INDEX_INVALID, e);
								}
							}
							break;
						}
					}
				} else {
					Logger.log(Logger.ERROR, "A resource change event came in after " + //$NON-NLS-1$
							AbstractIndexManager.this.fName + " shut down. This should never " + //$NON-NLS-1$
							"ever happen, but if it does the index may now be inconsistant."); //$NON-NLS-1$
				}
			} finally {
				//no matter how we exit be sure to update the number of events being processed
				synchronized (this.fEventsBeingProcessedLock) {
					--this.fEventsBeingProcessed;
					
					//if currently not events being processed, then notify
					if(this.fEventsBeingProcessed == 0) {
						this.fEventsBeingProcessedLock.notifyAll();
					}
				}
			}
		}
	}
	
	/**
	 * <p>Used to visit {@link IResourceDelta}s from both the {@link IResourceChangeListener}
	 * and from a {@link ISaveParticipant} given to {@link AbstractIndexManager#start(IResourceDelta, IProgressMonitor)}.
	 * The resource events are batched into groups of {@link AbstractIndexManager#BATCH_UP_AMOUNT}
	 * before being passed onto the {@link ResourceEventProcessingJob}.</p>
	 * 
	 * <p><b>NOTE 1: </b> This class is intended for one time use, thus a new instance should
	 * be instantiated each time this visitor is needed to process a new {@link IResourceDelta}.</p>
	 * 
	 * <p><b>NOTE 2: </b> Be sure to call {@link ResourceDeltaVisitor#processBatchedResourceEvents()}
	 * after using this visitor to be sure any remaining events get passed onto the
	 * {@link ResourceEventProcessingJob}.</p>
	 * 
	 * @see ResourceDeltaVisitor#processBatchedResourceEvents()
	 */
	private class ResourceDeltaVisitor implements IResourceDeltaVisitor {
		/** {@link IProgressMonitor} used to report status */
		private SubMonitor fProgress;
		
		/**
		 * <p>The source that should be used when sending resource events to the
		 * {@link ResourceEventProcessingJob}.</p>
		 * 
		 * @see AbstractIndexManager#SOURCE_SAVED_STATE
		 * @see AbstractIndexManager#SOURCE_RESOURCE_CHANGE
		 */
		private byte fSource;
		
		/**
		 * <p>Due to the nature of a visitor it has no way of knowing the total amount
		 * of work it has to do but it can start to predict it based on the number of
		 * children of each event it processes and whether it plans on visiting those
		 * children</p>
		 */
		private int fPredictedWorkRemaining;
		
		/**
		 * {@link Map}&lt{@link IResource}, {@link ResourceEvent}&gt
		 * <p>Map of resources events created and batched up by this visitor.
		 * These events are periodical be sent off to the
		 * {@link ResourceEventProcessingJob} but need to be sent off
		 * one final time after this visitor finishes it work.</p>
		 * 
		 * @see #processBatchedResourceEvents()
		 */
		private Map fBatchedResourceEvents;
		
		/**
		 * <p>Creates a visitor that will create resource events based on the resources
		 * it visits and using the given source as the source of the events.</p>
		 * 
		 * @param source The source of the events that should be used when creating
		 * resource events from visited resources
		 * 
		 * @see AbstractIndexManager#SOURCE_RESOURCE_CHANGE
		 * @see AbstractIndexManager#SOURCE_SAVED_STATE
		 */
		protected ResourceDeltaVisitor(byte source) {
			this(SubMonitor.convert(null), source);
		}
		
		/**
		 * <p>Creates a visitor that will create resource events based on the resources
		 * it visits and using the given source as the source of the events and
		 * report its status to the given progress as best it can as it visits
		 * resources.</p>
		 * 
		 * <p><b>NOTE:</b> While the {@link SubMonitor} is provided to report status the
		 * visitor will not honor any cancellation requests.</p>
		 * 
		 * @param progress Used to report status. This visitor can <b>not</b> be
		 * canceled
		 * @param source The source of the events that should be used when creating
		 * resource events from visited resources
		 * 
		 * @see AbstractIndexManager#SOURCE_RESOURCE_CHANGE
		 * @see AbstractIndexManager#SOURCE_SAVED_STATE
		 */
		protected ResourceDeltaVisitor(SubMonitor progress, byte source) {
			this.fProgress = progress;
			this.fSource = source;
			this.fBatchedResourceEvents = new LinkedHashMap(BATCH_UP_AMOUNT);
			this.fPredictedWorkRemaining = 1;
		}
		
		/**
		 * <p>Transforms each {@link IResourceDelta} into a {@link ResourceEvent}.
		 * Batches up these {@link ResourceEvent}s and then passes them onto the
		 * {@link ResourceEventProcessingJob}.</p>
		 * 
		 * <p><b>NOTE 1: </b> Be sure to call {@link ResourceDeltaVisitor#processBatchedResourceEvents()}
		 * after using this visitor to be sure any remaining events get passed onto the
		 * {@link ResourceEventProcessingJob}.</p>
		 * 
		 * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
		 * @see #processBatchedResourceEvents()
		 */
		public boolean visit(IResourceDelta delta) throws CoreException {
			//report status
			this.fProgress.subTask(
					NLS.bind(AbstractIndexManager.this.fMessage_ProcessingFiles,
							"" + fPredictedWorkRemaining, delta.getFullPath().toString())); //$NON-NLS-1$
			
			//process delta if resource not hidden
			boolean visitChildren = false;
			
			/* if root node always visit its children
			 * else ask manager implementation if resource and its children should be visited 
			 */
			if (delta.getResource().isDerived()) { // Do not include derived resources
				visitChildren = false;
			} else if(delta.getFullPath().isRoot()) { //$NON-NLS-1$
				visitChildren = true;
			} else {
				IResource resource = delta.getResource();
	
				//check if should index resource or its children
				if(isResourceToIndex(resource.getType(), resource.getFullPath())) {
					if(resource.getType() == IResource.FILE) {
					
						switch (delta.getKind()) {
							case IResourceDelta.CHANGED : {
								/* ignore any change that is not a CONTENT, REPLACED, TYPE,
								 * or MOVE_FROM change
								 */
								if( !((delta.getFlags() & IResourceDelta.CONTENT) != 0) &&
										!((delta.getFlags() & IResourceDelta.REPLACED) != 0) &&
										!((delta.getFlags() & IResourceDelta.TYPE) != 0) &&
										!(((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0))) {
									
									break;
								}
							}
							//$FALL-THROUGH$ it is intended that sometimes a change will fall through to add
							case IResourceDelta.ADDED : {
								if((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
									//create add move from action
									this.fBatchedResourceEvents.put(resource, new ResourceEvent(
											this.fSource,
											AbstractIndexManager.ACTION_ADD_MOVE_FROM,
											delta.getMovedFromPath()));
		
								} else {
									//create add action
									this.fBatchedResourceEvents.put(resource, new ResourceEvent(
											this.fSource,
											AbstractIndexManager.ACTION_ADD,
											null));
								}
								
								break;
							}
							case IResourceDelta.REMOVED : {
								if((delta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
									//create remove move to action
									this.fBatchedResourceEvents.put(resource, new ResourceEvent(
											this.fSource,
											AbstractIndexManager.ACTION_REMOVE_MOVE_TO,
											delta.getMovedToPath()));
								} else {
									//create remove action
									this.fBatchedResourceEvents.put(resource, new ResourceEvent(
											this.fSource,
											AbstractIndexManager.ACTION_REMOVE,
											null));
								}
								break;
							}
						}
					}//end is file
					
					visitChildren = true;
				} else {
					visitChildren = false;
				}
					
				
				
				//deal with trying to report progress
				if(visitChildren) {
					this.fPredictedWorkRemaining += delta.getAffectedChildren().length;
				}
				this.fProgress.setWorkRemaining(this.fPredictedWorkRemaining);
				this.fProgress.worked(1);
				--this.fPredictedWorkRemaining;
				
				//batch up resource changes before sending them out
				if(this.fBatchedResourceEvents.size() >= BATCH_UP_AMOUNT) {
					this.processBatchedResourceEvents();
				}
			}
			
			return visitChildren;
		}
		
		/**
		 * <p>Sends any batched up resource events created by this visitor to the
		 * {@link ResourceEventProcessingJob}.<p>
		 * 
		 * <p><b>NOTE:</b> This will be called every so often as the visitor is
		 * visiting resources but needs to be called a final time by the user of
		 * this visitor to be sure the final events are sent off</p>
		 */
		protected void processBatchedResourceEvents() {
			AbstractIndexManager.this.fResourceEventProcessingJob.addResourceEvents(
					this.fBatchedResourceEvents);
			this.fBatchedResourceEvents.clear();
		}
	}
	
	/**
	 * <p>Collects {@link ResourceEvent}s from the different sources and then processes
	 * each one by calling {@link AbstractIndexManager#performAction(byte, byte, IResource, IPath)}
	 * for each {@link ResourceEvent}.</p>
	 * 
	 * @see AbstractIndexManager#performAction(byte, byte, IResource, IPath)
	 */
	private class ResourceEventProcessingJob extends Job {
		/** Length to delay when scheduling job */
		private static final int DELAY = 500;
		
		/**
		 * <p>Name of the file where resource events still to index
		 * will be preserved for the next start up.</p>
		 */
		private static final String PRESERVED_RESOURCE_EVENTS_TO_PROCESS_FILE_NAME = ".preservedResourceEvents";  //$NON-NLS-1$
		
		/**
		 * <p>This needs to be updated if {@link #preserveReceivedResourceEvents()} ever
		 * changes how it persists resource events so that {@link #loadPreservedReceivedResourceEvents(SubMonitor)}
		 * knows when opening a file that the format is of the current version and if not
		 * knows it does not know how to read the older version.</p>
		 * 
		 * @see #preserveReceivedResourceEvents()
		 * @see #loadPreservedReceivedResourceEvents(SubMonitor)
		 */
		private static final long serialVersionUID = 1L;
		
		/** Whether this job has been paused or not */
		private volatile boolean fIsPaused;
		
		/**
		 * {@link Map}&lt{@link IResource}, {@link ResourceEvent}&gt
		 * <p>The list of resources events to be processed</p>
		 */
		private Map fResourceEvents;
		
		/** Lock used when accessing {@link #fBatchedResourceEvents} */
		private final Object fResourceEventsLock = new Object();
		
		/**
		 * Locked used for allowing other jobs to wait on this job.  This job
		 * will notify those waiting on this lock whenever it is done processing
		 * all resource events it currently knows about.
		 * 
		 * @see #waitForConsistant(int)
		 */
		private final Object fToNotifyLock = new Object();
		
		/**
		 * <p>Sets up this job as a long running system job</p>
		 */
		protected ResourceEventProcessingJob() {
			super(AbstractIndexManager.this.fMessage_Running);
			
			//set this up as a long running system job
			this.setUser(false);
			this.setSystem(true);
			this.setPriority(Job.LONG);
			
			this.fIsPaused = false;
			this.fResourceEvents = new LinkedHashMap();
		}
		
		/**
		 * <p>Loads any preserved {@link ResourceEvent}s from the last time {@link #stop(boolean)}
		 * was invoked and schedules the job to be run</p>
		 * 
		 * <p><b>NOTE: </b>Should be used instead of of calling {@link Job#schedule()}
		 * because this method also takes care of loading preserved state.</p>
		 * 
		 * @param loadPreservedResourceEvents <code>true</code> if should load any
		 * preserved {@link ResourceEvent}s from the last time {@link #stop(boolean)}
		 * was invoked
		 * 
		 * @return <code>true</code> if either <code>loadPreservedResourceEvents</code>
		 * was false or there was success in loading the preserved {@link ResourceEvent}s.
		 * If <code>false</code> then some {@link ResourceEvent}s may have been loosed
		 * and to insure index consistency with the workspace a full workspace  re-index
		 * is needed.
		 * 
		 * @see #stop(boolean)
		 */
		protected synchronized boolean start(boolean loadPreservedResourceEvents, 
				SubMonitor progress) {
			
			boolean successLoadingPreserved = true;
			
			//attempt to load preserved resource events if requested
			if(!loadPreservedResourceEvents) {
				File preservedResourceEventsFile = this.getPreservedResourceEventsFile();
				preservedResourceEventsFile.delete();
			} else {
				successLoadingPreserved = this.loadPreservedReceivedResourceEvents(progress);
			}
			
			//start up the job
			this.schedule();
			
			return successLoadingPreserved;
		}
		
		/**
		 * <p>Immediately stops the job and preserves any {@link ResourceEvent}s in the queue
		 * to be processed by not yet processed if requested</p>
		 * 
		 * @param preserveResourceEvents <code>true</code> to preserve any {@link ResourceEvent}s
		 * in the queue yet to be processed, <code>false</code> otherwise
		 * 
		 * @return <code>true</code> if either <code>preserveResourceEvents</code> is 
		 * <code>false</code> or if there was success in preserving the {@link ResourceEvent}s
		 * yet to be processed.  If <code>false</code> then the preserving failed and a
		 * full workspace re-processing is needed the next time the manager is started
		 * 
		 * @throws InterruptedException This could happen when trying to cancel or join 
		 * the job in progress, but it really shouldn't
		 * 
		 * @see #start(boolean, SubMonitor)
		 */
		protected synchronized boolean stop(boolean preserveResourceEvents) throws InterruptedException {
			//this will not block indefinitely because it is known this job can be canceled
			this.cancel();
			this.join();
			
			//preserve if requested, else be sure no preserve file is left over for next start
			boolean success = true;
			if(preserveResourceEvents && this.hasResourceEventsToProcess()) {
				success = this.preserveReceivedResourceEvents();
			} else {
				this.getPreservedResourceEventsFile().delete();
			}
			
			return success;
		}
		
		/**
		 * @return <code>true</code> if job is currently running or paused
		 * 
		 * @see #pause()
		 * @see #unPause()
		 */
		protected synchronized boolean isProcessing() {
			return this.getState() != Job.NONE || this.fIsPaused;
		}
		
		/**
		 * <p>Un-pauses this job.  This has no effect if the job is already running.</p>
		 * <p>This should be used in place of {@link Job#schedule()} to reset state
		 * caused by calling {@link #pause()}</p>
		 * 
		 * @see #pause()
		 */
		protected synchronized void unPause() {
			this.fIsPaused = false;
			
			//get the job running again depending on its current state
			if(this.getState() == Job.SLEEPING) {
				this.wakeUp(DELAY);
			} else {
				this.schedule(DELAY);
			}
		}
		
		/**
		 * <p>Pauses this job, even if it is running</p>
		 * <p>This should be used in place of {@link Job#sleep()} because {@link Job#sleep()}
		 * will not pause a job that is already running but calling this will pause this job
		 * even if it is running. {@link #unPause()} must be used to start this job again</p>
		 * 
		 * @see #unPause()
		 */
		protected synchronized void pause() {
			//if job is already running this will force it to pause
			this.fIsPaused = true;
			
			//this only works if the job is not running
			this.sleep();
		}
		
		/**
		 * <p>Adds a batch of {@link ResourceEvent}s to the queue of events to be processed.
		 * Will also un-pause the job if it is not already running</p>
		 * 
		 * @param resourceEvents {@link Map}&lt{@link IResource}, {@link ResourceEvent}&gt
		 * A batch of {@link ResourceEvent}s to be processed
		 * 
		 * @see #addResourceEvent(ResourceEvent)
		 * @see #unPause()
		 */
		protected void addResourceEvents(Map resourceEvents) {
			Iterator iter = resourceEvents.keySet().iterator();
			while(iter.hasNext()) {
				IResource resource = (IResource)iter.next();
				ResourceEvent resourceEvent = (ResourceEvent)resourceEvents.get(resource);
				addResourceEvent(resource, resourceEvent);
			}
			
			//un-pause the processor if it is not already running
			if(!isProcessing()) {
				this.unPause();
			}
		}
		
		/**
		 * <p>Gets the number of {@link ResourceEvent}s left to process by this job. This
		 * count is only valid for the exact moment it is returned because events are
		 * constantly being added and removed from the queue of events to process</p>
		 * 
		 * @return the number of {@link ResourceEvent}s left to process
		 */
		protected int getNumResourceEventsToProcess() {
			return this.fResourceEvents.size();
		}
		
		/**
		 * <p>Blocks until either the given timeout elapses (0 means never to timeout), or
		 * there are currently no {@link ResourceEvent}s to process or being processed
		 * by this job</p>
		 * 
		 * @param timeout block until either this timeout elapses (0 means never to timeout)
		 * or there are currently no {@link ResourceEvent}s to process or being processed
		 * by this job
		 * 
		 * @throws InterruptedException This can happen when waiting for a lock
		 */
		protected void waitForConsistant(int timeout) throws InterruptedException {
			if(hasResourceEventsToProcess() || isProcessing()) {
				synchronized (this.fToNotifyLock) {
					this.fToNotifyLock.wait(timeout);
				}
			}
		}
		
		/**
		 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
		 */
		protected IStatus run(IProgressMonitor monitor) {
			try {
				//report status
				SubMonitor progress = SubMonitor.convert(monitor);
				
				while(!this.fIsPaused && !monitor.isCanceled() && this.hasResourceEventsToProcess()) {
					//report status
					progress.setTaskName(NLS.bind(AbstractIndexManager.this.fMessage_ProcessingFiles,
									"" + getNumResourceEventsToProcess())); //$NON-NLS-1$
					progress.setWorkRemaining(getNumResourceEventsToProcess());
					
					//get the next event to process
					ResourceEvent resourceEvent = null;
					IResource resource = null;
					synchronized (this.fResourceEventsLock) {
						resource = (IResource) this.fResourceEvents.keySet().iterator().next();
						resourceEvent = (ResourceEvent)this.fResourceEvents.remove(resource);
					}
					
					//report status
					monitor.subTask(resource.getName());
					
					//perform action safely
					final byte source = resourceEvent.fSource;
					final byte action = resourceEvent.fAction;
					final IResource finResource = resource;
					final IPath movePath = resourceEvent.fMovePath;
					SafeRunner.run(new ISafeRunnable() {
						public void run() throws Exception {
							AbstractIndexManager.this.performAction(source, action,
									finResource, movePath);
						}
	
						public void handleException(Throwable e) {
							Logger.logException("Error while performing an update to the index. " + //$NON-NLS-1$
									AbstractIndexManager.LOG_ERROR_INDEX_INVALID, e);
						}
					});
					
					//report progress
					progress.worked(1);
					
					//avoid dead locks
					Job.getJobManager().currentJob().yieldRule(monitor);
				}
				
				//done work
				monitor.done();
			} finally {
				//want to be sure we notify no matter how we exit
				this.notifyIfConsistant();
			}
			
			/* if canceled then return CANCEL,
			 * else if done or paused return OK
			 */
			IStatus exitStatus;
			if(monitor.isCanceled()) {
				exitStatus = Status.CANCEL_STATUS;
			} else {
				exitStatus = Status.OK_STATUS;
			}
			
			return exitStatus;
		}
		
		/**
		 * <p>If resource not already scheduled to be processed, schedule it
		 * else if resource already scheduled to be processed, update the action only if
		 * the new action comes from a resource change event.</p>
		 * 
		 * <p>Ignore other sources for updating existing resource events because all other
		 * sources are "start-up" type sources and thus only {@link ResourceEvent} with a
		 * source of a resource change event trump existing events.</p>
		 * 
		 * @param resourceEvent {@link ResourceEvent} to be processed by this job
		 */
		private void addResourceEvent(IResource resource, ResourceEvent resourceEvent) {
			
			synchronized (this.fResourceEventsLock) {
				/* if resource not already scheduled to be processed, schedule it
				 * else if resource already scheduled to be processed, update the action only if
				 * 		the new action comes from a resource change event
				 */
				if(!this.fResourceEvents.containsKey(resource)) {
					this.fResourceEvents.put(resource, resourceEvent);
				} else if(resourceEvent.fSource == AbstractIndexManager.SOURCE_RESOURCE_CHANGE) {
					((ResourceEvent)this.fResourceEvents.get(resource)).fAction = resourceEvent.fAction;
				} else {
					//Purposely ignoring all other resource events
				}
			}
		}
		
		/**
		 * @return <code>true</code> if there are any resources to process,
		 * <code>false</code> otherwise
		 */
		private boolean hasResourceEventsToProcess() {
			return !this.fResourceEvents.isEmpty();
		}
		
		/**
		 * <p>Preserves all of the resource events that have been received by this
		 * manager but not yet processed</p>
		 * 
		 * <p>If this operation was successful then the next time the manager starts
		 * it can load these events and process them.  If it was not successful then a
		 * full re-processing of the entire workspace will need to take place to be
		 * sure the index is consistent.</p>
		 * 
		 * <p><b>NOTE:</b> If this method changes how it preserves these events then
		 * {@link #serialVersionUID} will need to be incremented so that the manager
		 * does not attempt to load an old version of the file that may exist in a users
		 * workspace.  Also {@link #loadPreservedReceivedResourceEvents(SubMonitor)} will
		 * have to be updated to load the new file structure.</p>
		 * 
		 * @return <code>true</code> if successfully preserved the resource events that
		 * have been received by not yet processed, <code>false</code> otherwise
		 * 
		 * @see #serialVersionUID
		 * @see #loadPreservedReceivedResourceEvents(SubMonitor)
		 */
		private boolean preserveReceivedResourceEvents() {
			File preservedResourceEventsFile = this.getPreservedResourceEventsFile();
			boolean success = true;
			
			synchronized (this.fResourceEventsLock) {
				DataOutputStream dos = null;
				try {
					//if file already exists delete it
					if(preservedResourceEventsFile.exists()) {
						preservedResourceEventsFile.delete();
						preservedResourceEventsFile.createNewFile();
					}
					
					//create output objects
					FileOutputStream fos = new FileOutputStream(preservedResourceEventsFile);
					BufferedOutputStream bos = new BufferedOutputStream(fos);
					dos = new DataOutputStream(bos);
					
					//write serial version
					dos.writeLong(serialVersionUID);
					
					//write size
					dos.writeInt(this.getNumResourceEventsToProcess());
					
					//write out all the information needed to restore the resource events to process
					Iterator iter = this.fResourceEvents.keySet().iterator();
					while(iter.hasNext()) {
						IResource resource = (IResource)iter.next();
						ResourceEvent resourceEvent = (ResourceEvent)this.fResourceEvents.get(resource);
						
						if(resourceEvent.fSource != AbstractIndexManager.SOURCE_WORKSPACE_SCAN) {
							//write out information
							dos.writeByte(resourceEvent.fAction);
							dos.writeByte(resource.getType());
							byte[] pathBytes = resource.getFullPath().toString().getBytes(ENCODING_UTF16);
							dos.write(pathBytes);
							dos.writeByte('\0');
							if(resourceEvent.fMovePath != null) {
								dos.writeBytes(resourceEvent.fMovePath.toPortableString());
							}
							dos.writeByte('\0');
						}
					}
					
					this.fResourceEvents.clear();
					
					dos.flush();
				} catch (FileNotFoundException e) {
					Logger.logException(AbstractIndexManager.this.fName +
							": Exception while opening file to preserve resrouces to index.", //$NON-NLS-1$
							e);
					success = false;
				} catch (IOException e) {
					Logger.logException(AbstractIndexManager.this.fName +
							": Exception while writing to file to preserve resrouces to index.", //$NON-NLS-1$
							e);
					success = false;
				} finally {
					//be sure to close output
					if(dos != null) {
						try {
							dos.close();
						} catch (IOException e) {
							Logger.logException(AbstractIndexManager.this.fName +
									": Exception while closing file with preserved resources to index.", //$NON-NLS-1$
									e);
							success = false;
						}
					}
				}
				
				//if failed, for consistency must do a full re-process next workspace load
				if(!success) {
					preservedResourceEventsFile.delete();
				}
			}
			
			return success;
		}
		
		/**
		 * <p>Loads the received resource events that were preserved during the manager's
		 * last shut down so they can be processed now</p>
		 * 
		 * <p>If this operation is not successful then a full re-processing of the
		 * entire workspace is needed to be sure the index is consistent.</p>
		 * 
		 * @param progress used to report status of loading the preserved received resource events
		 * @return <code>true</code> if the loading of the preserved received resource events
		 * was successful, <code>false</code> otherwise.
		 * 
		 * @see #serialVersionUID
		 * @see #preserveReceivedResourceEvents()
		 */
		private boolean loadPreservedReceivedResourceEvents(SubMonitor progress) {
			progress.subTask(AbstractIndexManager.this.fMessage_Initializing);
			
			boolean success = true;
			File preservedResourceEventsFile = this.getPreservedResourceEventsFile();
			
			if(preservedResourceEventsFile.exists()) {
				Map preservedResourceEvents = null;
				
				DataInputStream dis = null;
				try {
					FileInputStream fis = new FileInputStream(preservedResourceEventsFile);
					BufferedInputStream bis = new BufferedInputStream(fis);
					dis = new DataInputStream(bis);
					
					//check serial version first
					long preservedSerialVersionUID = dis.readLong();
					if(preservedSerialVersionUID == serialVersionUID) {
						
						//read each record
						int numberOfRecords = dis.readInt();
						preservedResourceEvents = new LinkedHashMap(numberOfRecords);
						progress.setWorkRemaining(numberOfRecords);
						for(int i = 0; i < numberOfRecords; ++i) {
							//action is first byte
							byte action = dis.readByte();
							
							//file type is the next byte 
							byte fileType = dis.readByte();
							
							//resource location are the next bytes
							ByteArrayOutputStream resourceLocoationBOS = new ByteArrayOutputStream();
							byte b = dis.readByte();
							while(b != '\0') {
								resourceLocoationBOS.write(b);
								b = dis.readByte();
							}
							
							//move path are the next bytes
							ByteArrayOutputStream movePathBOS = new ByteArrayOutputStream();
							b = dis.readByte();
							while(b != '\0') {
								movePathBOS.write(b);
								b = dis.readByte();
							}
							
							//get the resource
							IResource resource = null;
							IPath resourcePath = new Path(new String(resourceLocoationBOS.toByteArray(), ENCODING_UTF16));
							if(!resourcePath.isRoot() && !resourcePath.toString().equals("")) { //$NON-NLS-1$
								if(fileType == IResource.FILE) {
									resource =
										ResourcesPlugin.getWorkspace().getRoot().getFile(resourcePath);
								} else {
									resource =
										ResourcesPlugin.getWorkspace().getRoot().getFolder(resourcePath);
								}	
							} else {
								Logger.log(Logger.WARNING, "The AbstractIndexManager " +
										AbstractIndexManager.this.fName +
										" attempted to load an invlaid preserved resource event:\n" +
										"(" + resourcePath + ")");
							}
							
							//get the move path
							IPath movePath = null;
							if(movePathBOS.size() != 0) {
								movePath = new Path(new String(movePathBOS.toByteArray(), ENCODING_UTF16));
							}
							
							//add the object to the list of of preserved resources
							preservedResourceEvents.put(resource, new ResourceEvent(
									AbstractIndexManager.SOURCE_PRESERVED_RESOURCES_TO_INDEX,
									action, movePath));
							
							progress.worked(1);
						}	
					} else {
						success = false;
					}
				} catch (FileNotFoundException e) {
					Logger.logException(AbstractIndexManager.this.fName +
							": Exception while opening file to read preserved resources to index. Index manager will recover by re-indexing workspace.", //$NON-NLS-1$
							e);
					success = false;
				} catch (IOException e) {
					Logger.logException(AbstractIndexManager.this.fName +
							": Exception while reading from file of preserved resources to index. Index manager will recover by re-indexing workspace.", //$NON-NLS-1$
							e);
					success = false;
				} catch(Exception e) {
					//Purposely catching all exceptions here so that index manager can recover gracefully
					Logger.logException(AbstractIndexManager.this.fName +
							": Unexpected exception while reading from file of preserved resources to index. Index manager will recover by re-indexing workspace.", //$NON-NLS-1$
							e);
					success = false;
				} finally {
					if(dis != null) {
						try {
							dis.close();
						} catch (IOException e) {
							Logger.logException(AbstractIndexManager.this.fName +
									": Exception while closing file of preserved resources" + //$NON-NLS-1$
									" to index that was just read.  This should have no" + //$NON-NLS-1$
									" effect on the consistency of the index.", //$NON-NLS-1$
									e);
						}
					}
				}
				
				//if success loading preserved then add to master list
				if(success) {
					synchronized (this.fResourceEventsLock) {
						Iterator iter = preservedResourceEvents.keySet().iterator();
						while(iter.hasNext()) {
							IResource resource = (IResource)iter.next();
							ResourceEvent event = (ResourceEvent)preservedResourceEvents.get(resource);
							this.fResourceEvents.put(resource, event);
						}
					}
				} else {
					//failed reading file, so delete it
					preservedResourceEventsFile.delete();
				}
			}
			
			progress.done();
			return success;
		}
		
		/**
		 * @return {@link File} that contains any resource events received but not processed
		 * by this manager the last time it shutdown. This file may or may not actually
		 * exist.
		 * 
		 * @see #preserveReceivedResourceEvents()
		 * @see #loadPreservedReceivedResourceEvents(SubMonitor)
		 */
		private File getPreservedResourceEventsFile() {
			IPath preservedResroucesToIndexPath =
				AbstractIndexManager.this.getWorkingLocation().append(
						PRESERVED_RESOURCE_EVENTS_TO_PROCESS_FILE_NAME);
			return new File(preservedResroucesToIndexPath.toOSString());
		}
		
		/**
		 * <p>If all resource events have been processed 
		 */
		private void notifyIfConsistant() {
			if(!this.hasResourceEventsToProcess()) {
				synchronized (this.fToNotifyLock) {
					this.fToNotifyLock.notifyAll();
				}
			}
		}
	}
	
	/**
	 * <p>Represents a resource that was discovered by this manager.  Contains
	 * all the information this manager and the index needs to know about this
	 * resource.  Such has how the manager was notified about this resource and
	 * the type of action occurring on the resource.</p>
	 */
	private static class ResourceEvent {
		/**
		 * <p>The source of this resource event</p>
		 * 
		 * @see AbstractIndexManager#SOURCE_RESOURCE_CHANGE
		 * @see AbstractIndexManager#SOURCE_SAVED_STATE
		 * @see AbstractIndexManager#SOURCE_WORKSPACE_SCAN
		 * @see AbstractIndexManager#SOURCE_PRESERVED_RESOURCES_TO_INDEX
		 */
		protected byte fSource;
		
		/**
		 * <p>The action that the index should take with this resource</p>
		 *
		 * @see AbstractIndexManager#ACTION_ADD
		 * @see AbstractIndexManager#ACTION_REMOVE
		 * @see AbstractIndexManager#ACTION_ADD_MOVE_FROM
		 * @see AbstractIndexManager#ACTION_REMOVE_MOVE_TO
		 */
		protected byte fAction;
		
		/**
		 * 
		 * <p>If the {@link #fAction} is {@link AbstractIndexManager#ACTION_ADD_MOVE_FROM} or
		 * {@link AbstractIndexManager#ACTION_REMOVE_MOVE_TO} then this field will have the
		 * path the resource was moved from or moved to. Else this field will be <code>null</code></p>
		 * 
		 * <p><b>NOTE: </b>Maybe <code>null</code>.</p>
		 * 
		 * @see AbstractIndexManager#ACTION_ADD_MOVE_FROM
		 * @see AbstractIndexManager#ACTION_REMOVE_MOVE_TO
		 */
		protected IPath fMovePath;
		
		/**
		 * <p>Creates a resource event that the index needs to react to in some way</p>
		 * 
		 * @param source source that the manager used to learn of this resource
		 * @param action action the index should take on this resource
		 * @param resource resource that the index should know about
		 * @param movePath if action is {@link AbstractIndexManager#ACTION_ADD_MOVE_FROM} or
		 * {@link AbstractIndexManager#ACTION_REMOVE_MOVE_TO} then this should be the path the
		 * resource was moved from or moved to respectively, else should be <code>null</code>
		 * 
		 * @see AbstractIndexManager#SOURCE_RESOURCE_CHANGE
		 * @see AbstractIndexManager#SOURCE_SAVED_STATE
		 * @see AbstractIndexManager#SOURCE_WORKSPACE_SCAN
		 * @see AbstractIndexManager#SOURCE_PRESERVED_RESOURCES_TO_INDEX
		 * 
		 * @see AbstractIndexManager#ACTION_ADD
		 * @see AbstractIndexManager#ACTION_REMOVE
		 * @see AbstractIndexManager#ACTION_ADD_MOVE_FROM
		 * @see AbstractIndexManager#ACTION_REMOVE_MOVE_TO
		 */
		protected ResourceEvent(byte source, byte action, IPath movePath) {
			this.fSource = source;
			this.fAction = action;
			this.fMovePath = movePath;
		}
	}
}