cdt/cdt_6_0_x/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesManager.java
changeset 51 49c226a8748e
parent 45 70f756c14af3
child 52 42077b7eab6e
--- a/cdt/cdt_6_0_x/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesManager.java	Tue Aug 04 14:00:13 2009 -0500
+++ b/cdt/cdt_6_0_x/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/ExecutablesManager.java	Wed Aug 05 17:35:39 2009 -0500
@@ -11,50 +11,29 @@
 
 package org.eclipse.cdt.debug.core.executables;
 
-import java.text.DateFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
-import org.eclipse.cdt.core.model.CoreModel;
-import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
-import org.eclipse.cdt.core.settings.model.ICProjectDescription;
-import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener;
 import org.eclipse.cdt.debug.core.CDebugCorePlugin;
+import org.eclipse.cdt.debug.internal.core.executables.ExecutablesChangeEvent;
 import org.eclipse.cdt.debug.internal.core.executables.StandardExecutableImporter;
+import org.eclipse.cdt.debug.internal.core.executables.StandardExecutableProvider;
 import org.eclipse.cdt.debug.internal.core.executables.StandardSourceFileRemapping;
 import org.eclipse.cdt.debug.internal.core.executables.StandardSourceFilesProvider;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.IExtension;
-import org.eclipse.core.runtime.IExtensionPoint;
-import org.eclipse.core.runtime.IExtensionRegistry;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.PlatformObject;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubMonitor;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.osgi.service.debug.DebugOptions;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
+import org.eclipse.debug.core.DebugPlugin;
 
 /**
  * The Executables Manager maintains a collection of executables built by all of
@@ -64,78 +43,28 @@
  * @author Ken Ryall
  * 
  */
-public class ExecutablesManager extends PlatformObject implements IResourceChangeListener, ICProjectDescriptionListener {
+public class ExecutablesManager extends PlatformObject {
 
-	private static final String EXECUTABLES_MANAGER_DEBUG_TRACING = CDebugCorePlugin.PLUGIN_ID + "EXECUTABLES_MANAGER_DEBUG_TRACING"; //$NON-NLS-1$
-		
-	private Map<IProject, IProjectExecutablesProvider> executablesProviderMap = new HashMap<IProject, IProjectExecutablesProvider>();
-	private Map<IProject, List<Executable>> executablesMap = new HashMap<IProject, List<Executable>>();
-	private List<IExecutablesChangeListener> changeListeners = Collections.synchronizedList(new ArrayList<IExecutablesChangeListener>());
-	private List<IProjectExecutablesProvider> executableProviders;
-	private List<ISourceFilesProvider> sourceFileProviders;
-	private List<ISourceFileRemapping> sourceFileRemappings;
-	private List<IExecutableImporter> executableImporters;
-	
-	private boolean DEBUG;
+	private final HashMap<String, Executable> executables = new HashMap<String, Executable>();
+	private final List<IExecutablesChangeListener> changeListeners = Collections.synchronizedList(new ArrayList<IExecutablesChangeListener>());
+	private final List<ISourceFileRemapping> sourceFileRemappings = Collections.synchronizedList(new ArrayList<ISourceFileRemapping>());
+	private final List<IExecutableProvider> executableProviders = Collections.synchronizedList(new ArrayList<IExecutableProvider>());
+	private final List<ISourceFilesProvider> sourceFileProviders = Collections.synchronizedList(new ArrayList<ISourceFilesProvider>());
+	private final List<IExecutableImporter> executableImporters = Collections.synchronizedList(new ArrayList<IExecutableImporter>());
+	private boolean refreshNeeded = true;
+	private boolean tempDisableRefresh = false;
 	
 	private final Job refreshJob = new Job("Get Executables") {
 
 		@Override
 		public IStatus run(IProgressMonitor monitor) {
-
-			trace("Get Executables job started at "
-					+ getStringFromTimestamp(System.currentTimeMillis()));
-
-			List<IProject> projects = getProjectsToCheck();
-
-			SubMonitor subMonitor = SubMonitor
-					.convert(monitor, projects.size());
-
-			for (IProject project : projects) {
-				if (subMonitor.isCanceled()) {
-					trace("Get Executables job cancelled at "
-							+ getStringFromTimestamp(System.currentTimeMillis()));
-					return Status.CANCEL_STATUS;
-				}
-
-				subMonitor.subTask("Checking project: " + project.getName());
-
-				// get the executables provider for this project
-				IProjectExecutablesProvider provider = getExecutablesProviderForProject(project);
-				if (provider != null) {
-					trace("Getting executables for project: "
-							+ project.getName() + " using "
-							+ provider.toString());
-
-					// store the list of executables for this project
-					synchronized (executablesMap) {
-						executablesMap.put(project, provider.getExecutables(
-								project, subMonitor.newChild(1,
-										SubMonitor.SUPPRESS_NONE)));
-					}
-				}
-			}
-
-			// notify the listeners
-			synchronized (changeListeners) {
-				for (IExecutablesChangeListener listener : changeListeners) {
-					listener.executablesListChanged();
-				}
-			}
-
-			trace("Get Executables job finished at "
-					+ getStringFromTimestamp(System.currentTimeMillis()));
-
+			refreshExecutables(monitor);
 			return Status.OK_STATUS;
 		}
 	};
 
 	private static ExecutablesManager executablesManager = null;
-	
-	/**
-	* Get the executables manager instance
-	* @return the executables manager
-	*/
+
 	public static ExecutablesManager getExecutablesManager() {
 		if (executablesManager == null)
 			executablesManager = new ExecutablesManager();
@@ -143,130 +72,126 @@
 	}
 
 	public ExecutablesManager() {
-		// check if debugging is enabled
-		BundleContext context = CDebugCorePlugin.getDefault().getBundle()
-				.getBundleContext();
-		if (context != null) {
-			ServiceReference reference = CDebugCorePlugin.getDefault()
-					.getBundle().getBundleContext().getServiceReference(
-							DebugOptions.class.getName());
-			if (reference != null) {
-				DebugOptions service = (DebugOptions) context
-						.getService(reference);
-				if (service != null) {
-					try {
-						DEBUG = service.getBooleanOption(
-								EXECUTABLES_MANAGER_DEBUG_TRACING, false);
-					} finally {
-						// we have what we want - release the service
-						context.ungetService(reference);
-					}
-				}
-			}
-		}
-
-		refreshJob.setPriority(Job.SHORT);
-
-		// load the extension points
-		loadExecutableProviderExtensions();
-		loadSoureFileProviderExtensions();
-		loadSoureRemappingExtensions();
-		loadExecutableImporterExtensions();
-
-		// add the standard providers
-		executableProviders.add(0, new StandardExecutableProvider());
-		sourceFileProviders.add(0, new StandardSourceFilesProvider());
-		sourceFileRemappings.add(0, new StandardSourceFileRemapping());
-		executableImporters.add(0, new StandardExecutableImporter());
-
-		// listen for events we're interested in
-		ResourcesPlugin.getWorkspace().addResourceChangeListener(
-				this,
-				IResourceChangeEvent.POST_CHANGE
-						| IResourceChangeEvent.POST_BUILD);
-		CoreModel.getDefault().getProjectDescriptionManager()
-				.addCProjectDescriptionListener(this,
-						CProjectDescriptionEvent.DATA_APPLIED);
-
-		// schedule a refresh so we get up to date
-		scheduleRefresh();
-
+		addSourceFileRemapping(new StandardSourceFileRemapping());
+		addExecutableImporter(new StandardExecutableImporter());
+		addExecutablesProvider(new StandardExecutableProvider());
+		addSourceFilesProvider(new StandardSourceFilesProvider());
 	}
 
-	/**
-	* Adds an executable listener
-	* @param listener the listener to add
-	*/
 	public void addExecutablesChangeListener(IExecutablesChangeListener listener) {
 		changeListeners.add(listener);
 	}
 
-	/**
-	* Removes an executable listener
-	* @param listener the listener to remove
-	*/
 	public void removeExecutablesChangeListener(IExecutablesChangeListener listener) {
 		changeListeners.remove(listener);
 	}
 
-	
+	public void addSourceFileRemapping(ISourceFileRemapping remapping) {
+		sourceFileRemappings.add(remapping);
+	}
+
+	public void removeSourceFileRemapping(ISourceFileRemapping remapping) {
+		sourceFileRemappings.remove(remapping);
+	}
+
+	public void addExecutableImporter(IExecutableImporter importer) {
+		executableImporters.add(importer);
+	}
+
+	public void removeExecutableImporter(IExecutableImporter importer) {
+		executableImporters.remove(importer);
+	}
+
+	public void addExecutablesProvider(IExecutableProvider provider) {
+		executableProviders.add(provider);
+	}
+
+	/**
+	 * @since 6.0
+	 */
+	public void addSourceFilesProvider(ISourceFilesProvider provider) {
+		sourceFileProviders.add(provider);
+	}
 
 	/**
-	* Gets the list of executables in the workspace.
-	* @return the list of executables which may be empty
-	*/
-	public Collection<Executable> getExecutables() {	
-		trace("getExecutables called at " + getStringFromTimestamp(System.currentTimeMillis()));
-		List<Executable> executables = new ArrayList<Executable>();
+	 * @since 6.0
+	 */
+	public void removeSourceFilesProvider(ISourceFilesProvider provider) {
+		sourceFileProviders.remove(provider);
+	}
+
+	public void removeExecutablesProvider(IExecutableProvider provider) {
+		executableProviders.remove(provider);
+	}
+
+	public IStatus refreshExecutables(IProgressMonitor monitor) {
+		if (tempDisableRefresh) {
+			return Status.OK_STATUS;
+		}
+
+		
+		synchronized (executables) {
+			HashMap<String, Executable> oldList = new HashMap<String, Executable>(executables);
+			executables.clear();
+
+			IExecutableProvider[] exeProviders = getExecutableProviders();
+
+			Arrays.sort(exeProviders, new Comparator<IExecutableProvider>() {
 
-		synchronized (executablesMap) {
-			for (List<Executable> exes : executablesMap.values()) {
-				for (Executable exe : exes) {
-					if (!executables.contains(exe)) {
-						executables.add(exe);
-					}
+				public int compare(IExecutableProvider arg0, IExecutableProvider arg1) {
+					int p0 = arg0.getPriority();
+					int p1 = arg1.getPriority();
+					if (p0 > p1)
+						return 1;
+					if (p0 < p1)
+						return -1;
+					return 0;
+				}});
 
+			refreshNeeded = false;
+			monitor.beginTask("Refresh Executables", exeProviders.length);
+			for (IExecutableProvider provider : exeProviders) {
+				Executable[] exes = provider.getExecutables(new SubProgressMonitor(monitor, 1));
+				for (Executable executable : exes) {
+					executables.put(executable.getPath().toOSString(), executable);
+				}
+			}
+			monitor.done();
+
+			synchronized (changeListeners) {
+				Collection<Executable> newExes = executables.values();
+				Executable[] exeArray = newExes.toArray(new Executable[newExes.size()]);
+				Collection<Executable> oldExes = oldList.values();
+				Executable[] oldArray = oldExes.toArray(new Executable[oldExes.size()]);				
+				for (IExecutablesChangeListener listener : changeListeners) {
+					listener.executablesChanged(new ExecutablesChangeEvent(oldArray, exeArray));
 				}
 			}
 		}
 
-		trace("getExecutables returned at " + getStringFromTimestamp(System.currentTimeMillis()));
+		return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
+	}
+
+	public Executable[] getExecutables() {
+		if (refreshNeeded) {
+			try {
+				refreshJob.schedule();
+				refreshJob.join();
+			} catch (InterruptedException e) {
+				DebugPlugin.log( e );
+			}
+		}
 		
-		return executables;
-
+		synchronized (executables)
+		{
+			Collection<Executable> exes = executables.values();
+			return exes.toArray(new Executable[exes.size()]);
+		}
 	}
 
 	/**
-	* Gets the collection of executables for the given project
-	* @param project the project
-	* @return collection of executables which may be empty
-	*/
-	public Collection<Executable> getExecutablesForProject(IProject project) {
-		List<Executable> executables = new ArrayList<Executable>();
-
-		synchronized (executablesMap) {
-			List<Executable> exes = executablesMap.get(project);
-			if (exes != null) {
-				for (Executable exe : exes) {
-					if (!executables.contains(exe)) {
-						executables.add(exe);
-					}
-				}
-			}
-		}
-		return executables;
-	}
-			
-
-	/**
-	* Attempt to remap the path to the given source file in the given executable using
-	* source file mapping extensions
-	* @param executable the executable
-	* @param filePath the absolute path to the source file
-	* @return the new path to the source file, which was remapped if possible
-	*
-	* @since 6.0
-	*/
+	 * @since 6.0
+	 */
 	public String remapSourceFile(Executable executable, String filePath) {
 		synchronized (sourceFileRemappings) {
 			for (ISourceFileRemapping remapping : sourceFileRemappings) {
@@ -278,64 +203,45 @@
 		return filePath;
 	}
 
-	/**
-	* Import the given executables into the manager
-	* @param fileNames the absolute paths of the executables to import
-	* @param monitor progress monitor
-	*/
-	public void importExecutables(final String[] fileNames,
-			IProgressMonitor monitor) {
+	public void importExecutables(final String[] fileNames, IProgressMonitor monitor) {
 		boolean handled = false;
-		monitor.beginTask("Import Executables", executableImporters.size());
-		synchronized (executableImporters) {
-			Collections.sort(executableImporters,
-					new Comparator<IExecutableImporter>() {
-
-						public int compare(IExecutableImporter arg0,
-								IExecutableImporter arg1) {
-							int p0 = arg0.getPriority(fileNames);
-							int p1 = arg1.getPriority(fileNames);
-							if (p0 < p1)
-								return 1;
-							if (p0 > p1)
-								return -1;
-							return 0;
-						}
-					});
+		try {
+			
+			tempDisableRefresh = true;
+			monitor.beginTask("Import Executables", executableImporters.size());
+			synchronized (executableImporters) {
+				Collections.sort(executableImporters, new Comparator<IExecutableImporter>() {
 
-			for (IExecutableImporter importer : executableImporters) {
-				if (handled || monitor.isCanceled()) {
-					break;
-				}
-			}
-		}
+					public int compare(IExecutableImporter arg0, IExecutableImporter arg1) {
+						int p0 = arg0.getPriority(fileNames);
+						int p1 = arg1.getPriority(fileNames);
+						if (p0 < p1)
+							return 1;
+						if (p0 > p1)
+							return -1;
+						return 0;
+					}});
 
-		scheduleRefresh();
-	}
-							
-	/**
-	 * Determines if the given executable is currently known by the manager
-	 * 
-	 * @param exePath
-	 *            the absolute path to the executable
-	 * @return true if the manager knows about it, false otherwise
-	 */
-	public boolean executableExists(IPath exePath) {
-		synchronized (executablesMap) {
-			for (List<Executable> exes : executablesMap.values()) {
-				for (Executable exe : exes) {
-					if (exe.getPath().equals(exePath)) {
-						return true;
-
+				for (IExecutableImporter importer : executableImporters) {
+					handled = importer.importExecutables(fileNames, new SubProgressMonitor(monitor, 1));
+					if (handled || monitor.isCanceled()) {
+						break;
 					}
 				}
 			}
 
+		} finally {
+			tempDisableRefresh = false;
 		}
-
-		return false;
+		
+		if (handled)
+			refreshExecutables(monitor);
+		monitor.done();
 	}
 
+	public ISourceFileRemapping[] getSourceFileRemappings() {
+		return sourceFileRemappings.toArray(new ISourceFileRemapping[sourceFileRemappings.size()]);
+	}
 
 	public IExecutableProvider[] getExecutableProviders() {
 		return executableProviders.toArray(new IExecutableProvider[executableProviders.size()]);
@@ -348,17 +254,31 @@
 		return sourceFileProviders.toArray(new ISourceFilesProvider[sourceFileProviders.size()]);
 	}
 
+	public IExecutableImporter[] getExecutableImporters() {
+		return executableImporters.toArray(new IExecutableImporter[executableImporters.size()]);
+	}
+
+	public void scheduleRefresh(IExecutableProvider provider, long delay) {
+		refreshNeeded = true;
+		refreshJob.schedule(delay);
+	}
+
+	public boolean refreshNeeded() {
+		return refreshNeeded;
+	}
+	
+	public boolean executableExists(IPath exePath) {
+		synchronized (executables) {
+			return executables.containsKey(exePath.toOSString());			
+		}
+	}
+
 	/**
-	* Get the list of source files for the given executable
-	* @param executable the executable
-	* @param monitor progress monitor
-	* @return an array of source files which may be empty
-	*/
-	public String[] getSourceFiles(final Executable executable, IProgressMonitor monitor) {
-			String[] result = new String[0];
-			trace("getSourceFiles called at " + getStringFromTimestamp(System.currentTimeMillis()) + " for " + executable.getPath().toOSString());
-
-
+	 * @since 6.0
+	 */
+	public String[] getSourceFiles(final Executable executable,
+			IProgressMonitor monitor) {
+		String[] result = new String[0];
 		synchronized (sourceFileProviders) {
 			Collections.sort(sourceFileProviders, new Comparator<ISourceFilesProvider>() {
 
@@ -375,467 +295,67 @@
 			monitor.beginTask("Finding source files in " + executable.getName(), sourceFileProviders.size());
 			for (ISourceFilesProvider provider : sourceFileProviders) {
 				String[] sourceFiles = provider.getSourceFiles(executable, new SubProgressMonitor(monitor, 1));
-				if (sourceFiles.length > 0) {
+				if (sourceFiles.length > 0)
+				{
 					result = sourceFiles;
-					trace("getSourceFiles got " + sourceFiles.length + " files from " + provider.toString());
 					break;
 				}
 			}
-			
-			trace("getSourceFiles returned at " + getStringFromTimestamp(System.currentTimeMillis()));
-
 			monitor.done();
 		}
 		return result;
 	}
 
 	/**
-	* Removes the given executables
-	* @param executables the array of executables to be removed
-	* @param monitor progress monitor
-	* @return IStatus of the operation
-	* 
-	* @since 6.0
-	*/
-	public IStatus removeExecutables(Executable[] executables,
-			IProgressMonitor monitor) {
-		MultiStatus status = new MultiStatus(CDebugCorePlugin.PLUGIN_ID,
-				IStatus.WARNING,
-				"Couldn't remove all of the selected executables", null);
+	 * @since 6.0
+	 */
+	public IStatus removeExecutables(Executable[] executables, IProgressMonitor monitor) {
+		IExecutableProvider[] exeProviders = getExecutableProviders();
+
+		IStatus result = Status.OK_STATUS;
+		
+		Arrays.sort(exeProviders, new Comparator<IExecutableProvider>() {
 
-		monitor.beginTask("Remove Executables", executables.length);
+			public int compare(IExecutableProvider arg0, IExecutableProvider arg1) {
+				int p0 = arg0.getPriority();
+				int p1 = arg1.getPriority();
+				if (p0 > p1)
+					return 1;
+				if (p0 < p1)
+					return -1;
+				return 0;
+			}
+		});
 
+		MultiStatus combinedStatus = new MultiStatus(CDebugCorePlugin.PLUGIN_ID, IStatus.WARNING, "Couldn't remove all of the selected executables", null);
+		refreshNeeded = false;
+		monitor.beginTask("Remove Executables", exeProviders.length);
 		for (Executable executable : executables) {
-			IProjectExecutablesProvider provider = getExecutablesProviderForProject(executable
-					.getProject());
-			if (provider != null) {
-				IStatus result = provider.removeExecutable(executable,
-						new SubProgressMonitor(monitor, 1));
-				if (result.isOK()) {
-					// remove the exe from the list
-					List<Executable> exes = executablesMap.get(executable
-							.getProject());
-					if (exes != null) {
-						exes.remove(executable);
-					}
-				} else {
-					status.add(result);
-				}
+			boolean handled = false;
+			IStatus rmvStatus = Status.OK_STATUS;;
+			for (IExecutableProvider provider : exeProviders) {
+				if (!handled)
+				{
+					rmvStatus = provider.removeExecutable(executable, new SubProgressMonitor(monitor, 1));
+					handled = rmvStatus.getSeverity() == IStatus.OK;
+				}				
+			}
+			if (!handled)
+			{
+				combinedStatus.add(rmvStatus);
+				result = combinedStatus;
 			}
 		}
-
-		// notify listeners that the list has changed. only do this if at least
-		// one delete succeeded.
-		if (status.getChildren().length != executables.length) {
-			synchronized (changeListeners) {
-				for (IExecutablesChangeListener listener : changeListeners) {
-					listener.executablesListChanged();
-				}
-			}
-		}
-
-		return status;
+		monitor.done();
+		
+		return result;
 	}
 
 	/**
-	* Refresh the list of executables for the given projects
-	* @param projects the list of projects, or null.  if null or the list
-	* is empty, all projects will be refreshed.
-	*/
-	public void refresh(List<IProject> projects) {
-		if (projects == null || projects.size() == 0) {
-			// clear the entire cache
-			executablesMap.clear();
-		} else {
-			for (IProject project : projects) {
-				executablesMap.remove(project);
-			}
-		}
-
-		scheduleRefresh();
-
-	}
-
-	public void resourceChanged(IResourceChangeEvent event) {
-
-		synchronized (executablesMap) {
-			// project needs to be refreshed after a build/clean as the binary
-			// may
-			// be added/removed/renamed etc.
-			if (event.getType() == IResourceChangeEvent.POST_BUILD) {
-				Object obj = event.getSource();
-				if (obj != null && obj instanceof IProject) {
-					if (executablesMap.containsKey(obj)) {
-						List<Executable> executables = executablesMap
-								.remove(obj);
-
-						trace("Scheduling refresh because project "
-								+ ((IProject) obj).getName()
-								+ " built or cleaned");
-
-						scheduleRefresh();
-
-						// notify the listeners that these executables have
-						// possibly changed
-						if (executables != null && executables.size() > 0) {
-							synchronized (changeListeners) {
-								for (IExecutablesChangeListener listener : changeListeners) {
-									listener.executablesChanged(executables);
-								}
-							}
-						}
-					}
-				}
-				return;
-			}
-
-			// refresh when projects are opened or closed. note that deleted
-			// projects are handled later in this method. new projects are
-			// handled
-			// in handleEvent. resource changed events always start at the
-			// workspace
-			// root, so projects are the next level down
-			boolean refreshNeeded = false;
-			IResourceDelta[] projects = event.getDelta().getAffectedChildren();
-			for (IResourceDelta projectDelta : projects) {
-				if ((projectDelta.getFlags() & IResourceDelta.OPEN) != 0) {
-					if (projectDelta.getKind() == IResourceDelta.CHANGED) {
-						// project was opened or closed
-						if (executablesMap.containsKey(projectDelta
-								.getResource())) {
-							executablesMap.remove(projectDelta.getResource());
-						}
-						refreshNeeded = true;
-					}
-				}
-			}
-
-			if (refreshNeeded) {
-				trace("Scheduling refresh because project(s) opened or closed");
-
-				scheduleRefresh();
-				return;
-			}
-
-			try {
-				event.getDelta().accept(new IResourceDeltaVisitor() {
-
-					public boolean visit(IResourceDelta delta)
-							throws CoreException {
-						if (delta.getKind() == IResourceDelta.ADDED
-								|| delta.getKind() == IResourceDelta.REMOVED) {
-							IResource deltaResource = delta.getResource();
-							if (deltaResource != null) {
-								boolean refresh = false;
-								if (delta.getKind() == IResourceDelta.REMOVED
-										&& deltaResource instanceof IProject) {
-									// project deleted
-									if (executablesMap
-											.containsKey(deltaResource)) {
-										executablesMap.remove(deltaResource);
-										refresh = true;
-
-										trace("Scheduling refresh because project "
-												+ deltaResource.getName()
-												+ " deleted");
-									}
-								} else {
-									// see if a binary has been added/removed
-									IPath resourcePath = deltaResource
-											.getLocation();
-									if (resourcePath != null
-											&& Executable
-													.isExecutableFile(resourcePath)) {
-										if (executablesMap
-												.containsKey(deltaResource
-														.getProject())) {
-											executablesMap.remove(deltaResource
-													.getProject());
-											refresh = true;
-
-											trace("Scheduling refresh because a binary was added/removed");
-										}
-									}
-								}
-
-								if (refresh) {
-									scheduleRefresh();
-									return false;
-								}
-							}
-						}
-						return true;
-					}
-				});
-			} catch (CoreException e) {
-			}
-		}
-	}
-
-	public void handleEvent(CProjectDescriptionEvent event) {
-		// this handles the cases where the active build configuration changes,
-		// and when new projects are created or loaded at startup.
-		boolean refresh = false;
-
-		int eventType = event.getEventType();
-
-		if (eventType == CProjectDescriptionEvent.DATA_APPLIED) {
-
-			synchronized (executablesMap) {
-				// see if the active build config has changed
-				ICProjectDescription newDesc = event
-						.getNewCProjectDescription();
-				ICProjectDescription oldDesc = event
-						.getOldCProjectDescription();
-				if (oldDesc != null && newDesc != null) {
-					String newConfigName = newDesc.getActiveConfiguration()
-							.getName();
-					String oldConfigName = oldDesc.getActiveConfiguration()
-							.getName();
-					if (!newConfigName.equals(oldConfigName)) {
-						if (executablesMap.containsKey(newDesc.getProject())) {
-							executablesMap.remove(newDesc.getProject());
-							refresh = true;
-
-							trace("Scheduling refresh because active build configuration changed");
-						}
-					}
-				} else if (newDesc != null && oldDesc == null) {
-					// project just created
-					refresh = true;
-
-					trace("Scheduling refresh because project "
-							+ newDesc.getProject().getName() + " created");
-				}
-			}
-		}
-
-		if (refresh) {
-			scheduleRefresh();
-		}
-	}
-
-	private List<IProject> getProjectsToCheck() {
-
-		List<IProject> projects = new ArrayList<IProject>();
-
-		synchronized (executablesMap) {
-			// look for any CDT projects not in our cache
-			for (IProject project : ResourcesPlugin.getWorkspace().getRoot()
-					.getProjects()) {
-				if (!executablesMap.containsKey(project)) {
-					if (CoreModel.hasCNature(project)) {
-						projects.add(project);
-					}
-				}
-			}
-		}
-
-		return projects;
+	 * @since 6.0
+	 */
+	public void setRefreshNeeded(boolean refresh) {
+		refreshNeeded = true;
 	}
 
-	private void scheduleRefresh() {
-		trace("scheduleRefresh called at "
-				+ getStringFromTimestamp(System.currentTimeMillis()));
-
-		refreshJob.cancel();
-		refreshJob.schedule();
-	}
-
-	private IProjectExecutablesProvider getExecutablesProviderForProject(
-			IProject project) {
-		IProjectExecutablesProvider provider = executablesProviderMap
-				.get(project);
-		if (provider == null) {
-			// not cached yet. get the list of project natures from the
-			// providers and
-			// pick the one with the closest match
-			try {
-				IProjectDescription description = project.getDescription();
-				int mostNaturesMatched = 0;
-				for (IProjectExecutablesProvider exeProvider : executableProviders) {
-					List<String> natures = exeProvider.getProjectNatures();
-
-					int naturesMatched = 0;
-					for (String nature : description.getNatureIds()) {
-						if (natures.contains(nature)) {
-							naturesMatched++;
-						}
-					}
-
-					if (naturesMatched > mostNaturesMatched) {
-						provider = exeProvider;
-						mostNaturesMatched = naturesMatched;
-					}
-				}
-
-				// cache it
-				executablesProviderMap.put(project, provider);
-
-			} catch (CoreException e) {
-				e.printStackTrace();
-			}
-		}
-
-		return provider;
-	}
-
-	private void loadExecutableProviderExtensions() {
-		executableProviders = Collections
-				.synchronizedList(new ArrayList<IProjectExecutablesProvider>());
-
-		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
-		IExtensionPoint extensionPoint = extensionRegistry
-				.getExtensionPoint(CDebugCorePlugin.PLUGIN_ID
-						+ ".ExecutablesProvider"); //$NON-NLS-1$
-		IExtension[] extensions = extensionPoint.getExtensions();
-
-		for (int i = 0; i < extensions.length; i++) {
-			IExtension extension = extensions[i];
-			IConfigurationElement[] elements = extension
-					.getConfigurationElements();
-			IConfigurationElement element = elements[0];
-
-			boolean failed = false;
-			try {
-				Object extObject = element.createExecutableExtension("class"); //$NON-NLS-1$
-				if (extObject instanceof IProjectExecutablesProvider) {
-					executableProviders
-							.add((IProjectExecutablesProvider) extObject);
-				} else {
-					failed = true;
-				}
-			} catch (CoreException e) {
-				failed = true;
-			}
-
-			if (failed) {
-				CDebugCorePlugin
-						.log("Unable to load ExecutablesProvider extension from "
-								+ extension.getContributor().getName());
-			}
-		}
-	}
-
-	private void loadSoureFileProviderExtensions() {
-		sourceFileProviders = Collections
-				.synchronizedList(new ArrayList<ISourceFilesProvider>());
-
-		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
-		IExtensionPoint extensionPoint = extensionRegistry
-				.getExtensionPoint(CDebugCorePlugin.PLUGIN_ID
-						+ ".SourceFilesProvider"); //$NON-NLS-1$
-		IExtension[] extensions = extensionPoint.getExtensions();
-
-		for (int i = 0; i < extensions.length; i++) {
-			IExtension extension = extensions[i];
-			IConfigurationElement[] elements = extension
-					.getConfigurationElements();
-			IConfigurationElement element = elements[0];
-
-			boolean failed = false;
-			try {
-				Object extObject = element.createExecutableExtension("class"); //$NON-NLS-1$
-				if (extObject instanceof ISourceFilesProvider) {
-					sourceFileProviders.add((ISourceFilesProvider) extObject);
-				} else {
-					failed = true;
-				}
-			} catch (CoreException e) {
-				failed = true;
-			}
-
-			if (failed) {
-				CDebugCorePlugin
-						.log("Unable to load SourceFilesProvider extension from "
-								+ extension.getContributor().getName());
-			}
-		}
-	}
-
-	private void loadSoureRemappingExtensions() {
-		sourceFileRemappings = Collections
-				.synchronizedList(new ArrayList<ISourceFileRemapping>());
-
-		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
-		IExtensionPoint extensionPoint = extensionRegistry
-				.getExtensionPoint(CDebugCorePlugin.PLUGIN_ID
-						+ ".SourceRemappingProvider"); //$NON-NLS-1$
-		IExtension[] extensions = extensionPoint.getExtensions();
-
-		for (int i = 0; i < extensions.length; i++) {
-			IExtension extension = extensions[i];
-			IConfigurationElement[] elements = extension
-					.getConfigurationElements();
-			IConfigurationElement element = elements[0];
-
-			boolean failed = false;
-			try {
-				Object extObject = element.createExecutableExtension("class"); //$NON-NLS-1$
-				if (extObject instanceof ISourceFileRemapping) {
-					sourceFileRemappings.add((ISourceFileRemapping) extObject);
-				} else {
-					failed = true;
-				}
-			} catch (CoreException e) {
-				failed = true;
-			}
-
-			if (failed) {
-				CDebugCorePlugin
-						.log("Unable to load SourceRemappingProvider extension from "
-								+ extension.getContributor().getName());
-			}
-		}
-	}
-
-	private void loadExecutableImporterExtensions() {
-		executableImporters = Collections
-				.synchronizedList(new ArrayList<IExecutableImporter>());
-
-		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
-		IExtensionPoint extensionPoint = extensionRegistry
-				.getExtensionPoint(CDebugCorePlugin.PLUGIN_ID
-						+ ".ExecutablesImporter"); //$NON-NLS-1$
-		IExtension[] extensions = extensionPoint.getExtensions();
-
-		for (int i = 0; i < extensions.length; i++) {
-			IExtension extension = extensions[i];
-			IConfigurationElement[] elements = extension
-					.getConfigurationElements();
-			IConfigurationElement element = elements[0];
-
-			boolean failed = false;
-			try {
-				Object extObject = element.createExecutableExtension("class"); //$NON-NLS-1$
-				if (extObject instanceof IExecutableImporter) {
-					executableImporters.add((IExecutableImporter) extObject);
-				} else {
-					failed = true;
-				}
-			} catch (CoreException e) {
-				failed = true;
-			}
-
-			if (failed) {
-				CDebugCorePlugin
-						.log("Unable to load ExecutablesImporter extension from "
-								+ extension.getContributor().getName());
-			}
-		}
-	}
-
-	private void trace(String msg) {
-		if (DEBUG) {
-			// TODO use Logger?
-			System.out.println(msg);
-		}
-	}
-
-	private String getStringFromTimestamp(long timestamp) {
-		return DateFormat.getTimeInstance(DateFormat.MEDIUM).format(
-				new Date(timestamp));
-	}
-}
-
-	
\ No newline at end of file
+}
\ No newline at end of file