Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] open type improvements

This patch provides some improvements to the Open Type action, such as per-file type caching (much faster now) and extra filtering options in the dialog. The non-ui code has also been isolated and moved to org.eclipse.cdt.core.browser.

Cheers
-Chris
Index: browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java,v
retrieving revision 1.1
diff -u -r1.1 OpenTypeAction.java
--- browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java	8 Mar 2004 18:22:31 -0000	1.1
+++ browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java	6 Apr 2004 18:24:32 -0000
@@ -12,16 +12,16 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
+import java.util.Collection;
 
+import org.eclipse.cdt.core.browser.AllTypesCache;
+import org.eclipse.cdt.core.browser.ITypeInfo;
 import org.eclipse.cdt.core.model.CModelException;
 import org.eclipse.cdt.core.model.ICElement;
 import org.eclipse.cdt.core.resources.FileStorage;
 import org.eclipse.cdt.core.search.ICSearchScope;
 import org.eclipse.cdt.core.search.SearchEngine;
 import org.eclipse.cdt.internal.ui.editor.CEditor;
-import org.eclipse.cdt.ui.browser.typeinfo.AllTypesCache;
-import org.eclipse.cdt.ui.browser.typeinfo.ITypeInfo;
-import org.eclipse.cdt.ui.browser.typeinfo.TypeInfoFilter;
 import org.eclipse.cdt.internal.ui.util.EditorUtility;
 import org.eclipse.cdt.internal.ui.util.ExceptionHandler;
 import org.eclipse.cdt.ui.CUIPlugin;
@@ -58,26 +58,26 @@
 	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
 	 */
 	public void run(IAction action) {		
-		final ICSearchScope scope= SearchEngine.createWorkspaceScope();
-		Shell shell= CUIPlugin.getDefault().getActiveWorkbenchShell();
 
-		final ArrayList typeList= new ArrayList();
-		final TypeInfoFilter filter= new TypeInfoFilter();
+		final ICSearchScope scope= SearchEngine.createWorkspaceScope();
+		final int[] kinds= { ICElement.C_NAMESPACE, ICElement.C_CLASS, ICElement.C_STRUCT,
+				ICElement.C_UNION, ICElement.C_ENUMERATION, ICElement.C_TYPEDEF };
+		final Collection typeList= new ArrayList();
 
-		if (AllTypesCache.isCacheUpToDate(filter)) {
+		if (AllTypesCache.isCacheUpToDate()) {
 			// run without progress monitor
-			AllTypesCache.getTypes(scope, filter, null, typeList);
+			AllTypesCache.getTypes(scope, kinds, null, typeList);
 		} else {
-			IRunnableContext runnableContext= new ProgressMonitorDialog(shell);
 			IRunnableWithProgress runnable= new IRunnableWithProgress() {
 				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
-					AllTypesCache.getTypes(scope, filter, monitor, typeList);
+					AllTypesCache.getTypes(scope, kinds, monitor, typeList);
 					if (monitor.isCanceled()) {
 						throw new InterruptedException();
 					}
 				}
 			};
 
+			IRunnableContext runnableContext= new ProgressMonitorDialog(getShell());
 			try {
 				runnableContext.run(true, true, runnable);
 			} catch (InvocationTargetException e) {
@@ -94,13 +94,14 @@
 		if (typeList.isEmpty()) {
 			String title= OpenTypeMessages.getString("OpenTypeAction.notypes.title"); //$NON-NLS-1$
 			String message= OpenTypeMessages.getString("OpenTypeAction.notypes.message"); //$NON-NLS-1$
-			MessageDialog.openInformation(shell, title, message);
+			MessageDialog.openInformation(getShell(), title, message);
 			return;
 		}
-		ITypeInfo[] typeRefs= (ITypeInfo[])typeList.toArray(new ITypeInfo[typeList.size()]);
-			
-		OpenTypeDialog dialog= new OpenTypeDialog(shell);
-		dialog.setElements(typeRefs);
+
+		ITypeInfo[] elements= (ITypeInfo[])typeList.toArray(new ITypeInfo[typeList.size()]);
+
+		OpenTypeDialog dialog= new OpenTypeDialog(getShell());
+		dialog.setElements(elements);
 
 		int result= dialog.open();
 		if (result != IDialogConstants.OK_ID)
@@ -110,28 +111,34 @@
 		if (info == null)
 			return;
 
-		if (!openTypeInEditor(shell, info))
+		if (!openTypeInEditor(info))
 		{
 			// could not find definition
-			String path= info.getFilePath();
-			if (path == null || path.length() == 0)
-				path= OpenTypeMessages.getString("OpenTypeAction.errorNoPath"); //$NON-NLS-1$
+			String pathString= null;
+			IPath path= info.getLocation();
+			if (path != null)
+				pathString= path.toString();
+			else
+				pathString= OpenTypeMessages.getString("OpenTypeAction.errorNoPath"); //$NON-NLS-1$
 			String title= OpenTypeMessages.getString("OpenTypeAction.errorTitle"); //$NON-NLS-1$
-			String message= OpenTypeMessages.getFormattedString("OpenTypeAction.errorMessage", path); //$NON-NLS-1$
-			MessageDialog.openError(shell, title, message);
+			String message= OpenTypeMessages.getFormattedString("OpenTypeAction.errorMessage", pathString); //$NON-NLS-1$
+			MessageDialog.openError(getShell(), title, message);
 		}
 	}
 	
+	protected Shell getShell() {
+		return CUIPlugin.getDefault().getActiveWorkbenchShell();
+	}
+
 	/**
 	 * Opens an editor and displays the selected type.
-	 * @param shell Workbench shell.
 	 * @param info Type to display.
 	 * @return true if succesfully displayed.
 	 */
-	private boolean openTypeInEditor(Shell shell, ITypeInfo info) {
+	private boolean openTypeInEditor(ITypeInfo info) {
 		IResource res= null;
 		IEditorPart editorPart= null;
-		IPath path= info.getLocation();
+		IPath path= info.getPath();
 		ICElement celement= info.getCElement();
 
 		// attempt to locate the resource
Index: browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java,v
retrieving revision 1.1
diff -u -r1.1 OpenTypeDialog.java
--- browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java	8 Mar 2004 18:22:31 -0000	1.1
+++ browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java	6 Apr 2004 18:24:32 -0000
@@ -12,12 +12,6 @@
 package org.eclipse.cdt.internal.ui.browser.opentype;
 
 import org.eclipse.cdt.ui.browser.typeinfo.TypeSelectionDialog;
-import org.eclipse.cdt.ui.CUIPlugin;
-import org.eclipse.jface.dialogs.IDialogSettings;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
 
 /**
@@ -26,128 +20,17 @@
  */
 public class OpenTypeDialog extends TypeSelectionDialog {
 
-	/** The dialog location. */
-	private Point fLocation;
-	/** The dialog size. */
-	private Point fSize;
+	private static final String DIALOG_SETTINGS= OpenTypeDialog.class.getName();
 
 	/**
 	 * Constructs an instance of <code>OpenTypeDialog</code>.
 	 * @param parent  the parent shell.
-	 * @param context the context.
 	 */
 	public OpenTypeDialog(Shell parent) {
 		super(parent);
 		setTitle(OpenTypeMessages.getString("OpenTypeDialog.title")); //$NON-NLS-1$
 		setMessage(OpenTypeMessages.getString("OpenTypeDialog.message")); //$NON-NLS-1$
-		//setFilter(OpenTypeMessages.getString("OpenTypeDialog.filter")); //$NON-NLS-1$
 		setMatchEmptyString(true);
-	}
-	
-	/*
-	 * @see org.eclipse.jface.window.Window#configureShell(Shell)
-	 */
-	protected void configureShell(Shell newShell) {
-		super.configureShell(newShell);
-	}
-
-	/*
-	 * @see Window#close()
-	 */
-	public boolean close() {
-		writeSettings();
-		return super.close();
-	}
-
-	/*
-	 * @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
-	 */
-	protected Control createContents(Composite parent) {
-		Control control= super.createContents(parent);
-		readSettings();
-		return control;
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.window.Window#getInitialSize()
-	 */
-	protected Point getInitialSize() {
-		Point result= super.getInitialSize();
-		if (fSize != null) {
-			result.x= Math.max(result.x, fSize.x);
-			result.y= Math.max(result.y, fSize.y);
-			Rectangle display= getShell().getDisplay().getClientArea();
-			result.x= Math.min(result.x, display.width);
-			result.y= Math.min(result.y, display.height);
-		}
-		return result;
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.window.Window#getInitialLocation(org.eclipse.swt.graphics.Point)
-	 */
-	protected Point getInitialLocation(Point initialSize) {
-		Point result= super.getInitialLocation(initialSize);
-		if (fLocation != null) {
-			result.x= fLocation.x;
-			result.y= fLocation.y;
-			Rectangle display= getShell().getDisplay().getClientArea();
-			int xe= result.x + initialSize.x;
-			if (xe > display.width) {
-				result.x-= xe - display.width; 
-			}
-			int ye= result.y + initialSize.y;
-			if (ye > display.height) {
-				result.y-= ye - display.height; 
-			}
-		}
-		return result;
-	}
-
-	/**
-	 * Initializes itself from the dialog settings with the same state
-	 * as at the previous invocation.
-	 */
-	private void readSettings() {
-		IDialogSettings s= getDialogSettings();
-		try {
-			int x= s.getInt("x"); //$NON-NLS-1$
-			int y= s.getInt("y"); //$NON-NLS-1$
-			fLocation= new Point(x, y);
-			int width= s.getInt("width"); //$NON-NLS-1$
-			int height= s.getInt("height"); //$NON-NLS-1$
-			fSize= new Point(width, height);
-		} catch (NumberFormatException e) {
-			fLocation= null;
-			fSize= null;
-		}
-	}
-
-	/**
-	 * Stores it current configuration in the dialog store.
-	 */
-	private void writeSettings() {
-		IDialogSettings s= getDialogSettings();
-		Point location= getShell().getLocation();
-		s.put("x", location.x); //$NON-NLS-1$
-		s.put("y", location.y); //$NON-NLS-1$
-		Point size= getShell().getSize();
-		s.put("width", size.x); //$NON-NLS-1$
-		s.put("height", size.y); //$NON-NLS-1$
-	}
-
-	/**
-	 * Returns the dialog settings object used to share state
-	 * between several find/replace dialogs.
-	 *
-	 * @return the dialog settings to be used
-	 */
-	private IDialogSettings getDialogSettings() {
-		IDialogSettings settings= CUIPlugin.getDefault().getDialogSettings();
-		String sectionName= getClass().getName();
-		IDialogSettings subSettings= settings.getSection(sectionName);
-		if (subSettings == null)
-			subSettings= settings.addNewSection(sectionName);
-		return subSettings;
+		setDialogSettings(DIALOG_SETTINGS);
 	}
 }
Index: browser/org/eclipse/cdt/internal/ui/browser/util/ArrayUtil.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/ui/browser/util/ArrayUtil.java
diff -N browser/org/eclipse/cdt/internal/ui/browser/util/ArrayUtil.java
--- browser/org/eclipse/cdt/internal/ui/browser/util/ArrayUtil.java	8 Mar 2004 18:22:31 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 QNX Software Systems and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     QNX Software Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.internal.ui.browser.util;
-
-/**
- * A helper class which allows you to perform some
- * simple set operations on int arrays.
- */
-public class ArrayUtil {
-	private ArrayUtil() {
-	}
-
-	// returns true if set contains elem
-	public static boolean contains(int[] set, int elem) {
-		for (int i= 0; i < set.length; ++i) {
-			if (set[i] == elem)
-				return true;
-		}
-		return false;
-	}
-	
-	// returns true if set contains all of subset
-	public static boolean containsAll(int[] set, int[] subset) {
-		for (int i= 0; i < subset.length; ++i) {
-			if (!contains(set, subset[i]))
-				return false;
-		}
-		return true;
-	}
-	
-	// return a copy of fromSet
-	public static int[] clone(int[] fromSet) {
-		int[] newSet= new int[fromSet.length];
-		for (int i= 0; i < fromSet.length; ++i) {
-			newSet[i]= newSet[i];
-		}
-		return newSet;
-	}
-}
Index: browser/org/eclipse/cdt/internal/ui/browser/util/ProgressMonitorMultiWrapper.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/ui/browser/util/ProgressMonitorMultiWrapper.java
diff -N browser/org/eclipse/cdt/internal/ui/browser/util/ProgressMonitorMultiWrapper.java
--- browser/org/eclipse/cdt/internal/ui/browser/util/ProgressMonitorMultiWrapper.java	8 Mar 2004 18:22:31 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,233 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 QNX Software Systems and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     QNX Software Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.internal.ui.browser.util;
-
-import java.util.ArrayList;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
-import org.eclipse.core.runtime.IStatus;
-
-/**
- * A wrapper around multiple progress monitors which forwards
- * <code>IProgressMonitor</code> and <code>IProgressMonitorWithBlocking</code>
- * methods to the wrapped progress monitors.
- */
-public class ProgressMonitorMultiWrapper implements IProgressMonitor, IProgressMonitorWithBlocking {
-
-	private double internalWork;
-	private int totalWork;
-	private int work;
-	private String taskName;
-	private String subtaskName;
-	private boolean isCanceled= false;
-	private boolean blocked= false;
-
-	/** The wrapped progress monitors. */
-	private final ArrayList fProgressMonitors= new ArrayList(2);
-
-	/**
-	 * Creates a new monitor wrapper.
-	 */
-	public ProgressMonitorMultiWrapper() {
-	}
-	
-	/**
-	 * Creates a new monitor wrapper around the given monitor.
-	 */
-	public ProgressMonitorMultiWrapper(IProgressMonitor monitor) {
-		addProgressMonitor(monitor);
-	}
-
-	/* 
-	 * @see IProgressMonitor#beginTask
-	 */
-	public void beginTask(String name, int totalWork) {
-		taskName= name;
-		this.totalWork= totalWork;
-
-		// Clone the monitors since they could remove themselves when called 
-		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
-		for (int i= 0; i < monitors.size(); i++) {
-			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
-			monitor.beginTask(name, totalWork);
-		}
-	}
-	
-	/*
-	 * @see IProgressMonitor#setTaskName
-	 */
-	public void setTaskName(String name) {
-		taskName= name;
-
-		// Clone the monitors since they could remove themselves when called 
-		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
-		for (int i= 0; i < monitors.size(); i++) {
-			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
-			monitor.setTaskName(name);
-		}
-	}
-	
-	/*
-	 * @see IProgressMonitor#subTask
-	 */
-	public void subTask(String name) {
-		subtaskName= name;
-
-		// Clone the monitors since they could remove themselves when called 
-		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
-		for (int i= 0; i < monitors.size(); i++) {
-			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
-			monitor.subTask(name);
-		}
-	}
-	
-	/*
-	 * @see IProgressMonitor#worked
-	 */
-	public void worked(int work) {
-		this.work= work;
-
-		// Clone the monitors since they could remove themselves when called 
-		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
-		for (int i= 0; i < monitors.size(); i++) {
-			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
-			monitor.worked(work);
-		}
-	}
-	
-	/*
-	 * @see IProgressMonitor#internalWorked
-	 */
-	public void internalWorked(double work) {
-		internalWork= work;
-
-		// Clone the monitors since they could remove themselves when called 
-		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
-		for (int i= 0; i < monitors.size(); i++) {
-			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
-			monitor.internalWorked(work);
-		}
-	}
-	
-	/*
-	 * @see IProgressMonitor#done
-	 */
-	public void done() {
-		// Clone the monitors since they could remove themselves when called 
-		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
-		for (int i= 0; i < monitors.size(); i++) {
-			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
-			monitor.done();
-		}
-	}
-	
-	/*
-	 * @see IProgressMonitor#setCanceled
-	 */
-	public void setCanceled(boolean canceled) {
-		isCanceled= canceled;
-
-		// Clone the monitors since they could remove themselves when called 
-		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
-		for (int i= 0; i < monitors.size(); i++) {
-			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
-			monitor.setCanceled(canceled);
-		}
-	}
-
-	/*
-	 * @see IProgressMonitor#isCanceled
-	 */
-	public boolean isCanceled() {
-		// Clone the monitors since they could remove themselves when called 
-		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
-		for (int i= 0; i < monitors.size(); i++) {
-			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
-			isCanceled |= monitor.isCanceled();
-		}
-		return isCanceled;
-	}
-	
-	/*
-	 * @see IProgressMonitor#setBlocked
-	 */
-	public void setBlocked(IStatus reason) {
-		blocked= true;
-
-		// Clone the monitors since they could remove themselves when called 
-		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
-		for (int i= 0; i < monitors.size(); i++) {
-			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
-			if (monitor instanceof IProgressMonitorWithBlocking)
-				 ((IProgressMonitorWithBlocking) monitor).setBlocked(reason);
-		}
-	}
-	
-	/*
-	 * @see IProgressMonitor#clearBlocked
-	 */
-	public void clearBlocked() {
-		blocked= false;
-
-		// Clone the monitors since they could remove themselves when called 
-		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
-		for (int i= 0; i < monitors.size(); i++) {
-			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
-			if (monitor instanceof IProgressMonitorWithBlocking)
-				 ((IProgressMonitorWithBlocking) monitor).clearBlocked();
-		}
-	}
-	
-	/*
-	 * brings monitor up to date
-	 */
-	private void syncUpMonitor(IProgressMonitor monitor) {
-		if (totalWork > 0) {
-			monitor.beginTask(taskName, totalWork);
-			monitor.worked(work);
-			monitor.internalWorked(internalWork);
-			if (subtaskName != null && subtaskName.length() > 0)
-				monitor.subTask(subtaskName);
-			if (blocked && monitor instanceof IProgressMonitorWithBlocking)
-				 ((IProgressMonitorWithBlocking) monitor).setBlocked(null);
-		}
-	}
-	
-	/**
-	 * Adds a monitor to the list of wrapped monitors.
-	 */
-	public synchronized void addProgressMonitor(IProgressMonitor monitor) {
-		if (fProgressMonitors.indexOf(monitor) == -1) {
-			syncUpMonitor(monitor);
-			fProgressMonitors.add(monitor);
-		}
-	}
-	
-	/**
-	 * Removes a monitor from the list of wrapped monitors.
-	 */
-	public synchronized void removeProgressMonitor(IProgressMonitor monitor) {
-		int index = fProgressMonitors.indexOf(monitor);
-		if (index != -1) {
-			fProgressMonitors.remove(index);
-		}
-	}
-
-	/**
-	 * Returns the wrapped progress monitors.
-	 *
-	 * @return the wrapped progress monitors
-	 */
-	public IProgressMonitor[] getWrappedProgressMonitors() {
-		return (IProgressMonitor[]) fProgressMonitors.toArray();
-	}
-}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/AllTypesCache.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/AllTypesCache.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/AllTypesCache.java
--- browser/org/eclipse/cdt/ui/browser/typeinfo/AllTypesCache.java	6 Apr 2004 14:24:08 -0000	1.7
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,483 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *     QNX Software Systems - adapted for use in CDT
- *******************************************************************************/
-package org.eclipse.cdt.ui.browser.typeinfo;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Set;
-
-import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.model.CoreModel;
-import org.eclipse.cdt.core.model.ElementChangedEvent;
-import org.eclipse.cdt.core.model.ICElement;
-import org.eclipse.cdt.core.model.ICElementDelta;
-import org.eclipse.cdt.core.model.IElementChangedListener;
-import org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate;
-import org.eclipse.cdt.core.search.BasicSearchResultCollector;
-import org.eclipse.cdt.core.search.ICSearchConstants;
-import org.eclipse.cdt.core.search.ICSearchPattern;
-import org.eclipse.cdt.core.search.ICSearchScope;
-import org.eclipse.cdt.core.search.IMatch;
-import org.eclipse.cdt.core.search.OrPattern;
-import org.eclipse.cdt.core.search.SearchEngine;
-import org.eclipse.cdt.internal.ui.browser.util.ArrayUtil;
-import org.eclipse.cdt.internal.ui.browser.util.ProgressMonitorMultiWrapper;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.core.runtime.jobs.Job;
-
-/**
- * Manages a search cache for types in the workspace. Instead of returning objects of type <code>ICElement</code>
- * the methods of this class returns a list of the lightweight objects <code>TypeInfo</code>.
- * <P>
- * AllTypesCache runs asynchronously using a background job to rebuild the cache as needed.
- * If the cache becomes dirty again while the background job is running, the job is restarted.
- * <P>
- * If <code>getAllTypes</code> is called in response to a user action, a progress dialog is shown.
- * If called before the background job has finished, getAllTypes waits
- * for the completion of the background job.
- */
-public class AllTypesCache {
-	
-	/**
-	 * Background job for filling the type cache.
-	 * @see org.eclipse.core.runtime.jobs.Job
-	 * @since 3.0
-	 */
-	private static class TypeCacherJob extends Job {
-
-		/**
-		 * An "identity rule" that forces jobs to be queued.
-		 * @see org.eclipse.core.runtime.jobs.ISchedulingRule
-		 * @since 3.0
-		 */
-		final static ISchedulingRule MUTEX_RULE= new ISchedulingRule() {
-			public boolean contains(ISchedulingRule rule) {
-				return rule == this;
-			}
-			public boolean isConflicting(ISchedulingRule rule) {
-				return rule == this;
-			}			
-		};
-
-		/**
-		 * A comparator for simple type names
-		 */
-		private static class TypeNameComparator implements Comparator {
-			public int compare(Object o1, Object o2) {
-				return ((TypeInfo)o1).getName().compareTo(((TypeInfo)o2).getName());
-			}
-		}
-		
-		/**
-		 * A search result collector for type info.
-		 * @see org.eclipse.cdt.core.search.ICSearchResultCollector
-		 */
-		private static class TypeSearchResultCollector extends BasicSearchResultCollector {
-
-			public TypeSearchResultCollector() {
-				super();
-			}
-			
-			public TypeSearchResultCollector(IProgressMonitor monitor) {
-				super(monitor);
-			}
-			
-			public IMatch createMatch(Object fileResource, int start, int end, ISourceElementCallbackDelegate node, IPath realPath )
-			{
-				TypeInfo result= new TypeInfo();
-				return super.createMatch( result, fileResource, start, end, node, realPath);
-			}
-
-			public boolean acceptMatch(IMatch match) throws CoreException {
-				// filter out unnamed structs
-				TypeInfo result= (TypeInfo) match;
-				String name= result.getName();
-				if (name == null || name.length() == 0)
-					return false;
-
-				// make sure we've got a valid type
-				if (!TypeInfo.isValidCElementType(result.getElementType()))
-					return false;
-
-				return super.acceptMatch(match);
-			}
-		}		
-
-		/**
-		 * Constant identifying the job family identifier for the background job.
-		 * @see IJobManager#join(Object, IProgressMonitor)
-		 * @since 3.0
-		 */
-		public static final Object FAMILY= new Object();
-
-		final static Comparator TYPE_COMPARATOR= new TypeNameComparator();
-
-		private ProgressMonitorMultiWrapper progressMonitor;
-		
-		public TypeCacherJob() {
-			super(TypeInfoMessages.getString("TypeCacherJob.jobName")); //$NON-NLS-1$
-			setPriority(BUILD);
-			setSystem(true);
-			//setRule(MUTEX_RULE);
-		}
-
-		/* (non-Javadoc)
-		 * @see org.eclipse.core.internal.jobs.InternalJob#belongsTo(java.lang.Object)
-		 */
-		public boolean belongsTo(Object family) {
-			return family == FAMILY;
-		}
-
-		/* (non-Javadoc)
-		 * @see org.eclipse.core.runtime.jobs.Job#shouldRun()
-		 */
-		public boolean shouldRun() {
-			return isCacheDirty();
-		}
-
-		/* (non-Javadoc)
-		 * @see org.eclipse.core.runtime.jobs.Job#run(IProgressMonitor)
-		 */
-		public IStatus run(IProgressMonitor monitor) {
-			progressMonitor= new ProgressMonitorMultiWrapper(monitor);
-			progressMonitor.beginTask(TypeInfoMessages.getString("TypeCacherJob.taskName"), 100); //$NON-NLS-1$
-
-			SubProgressMonitor subMonitor= new SubProgressMonitor(progressMonitor, 100);
-			TypeSearchResultCollector collector= new TypeSearchResultCollector(subMonitor);
-
-			IWorkspace workspace= CCorePlugin.getWorkspace();
-			if (workspace == null) {
-				return Status.CANCEL_STATUS;
-			}
-
-			ICSearchScope scope= SearchEngine.createWorkspaceScope();
-			SearchEngine engine= new SearchEngine();
-			
-			ICSearchPattern pattern= createSearchPattern();
-			try {
-				flushCache();
-				// start the search engine
-				if (progressMonitor.isCanceled())
-					throw new InterruptedException();
-				engine.search(workspace, pattern, scope, collector, true);
-				if (progressMonitor.isCanceled())
-					throw new InterruptedException();
-				progressMonitor.done();
-			} catch(InterruptedException ex) {
-				return Status.CANCEL_STATUS;
-			} finally {
-				progressMonitor= null;
-			}
-
-			Set searchResults= collector.getSearchResults();
-
-			if (searchResults != null) {
-				TypeInfo[] result= (TypeInfo[]) searchResults.toArray(new TypeInfo[searchResults.size()]);
-				Arrays.sort(result, TYPE_COMPARATOR);
-				setCache(result);
-			}
-			else {
-				TypeInfo[] result= new TypeInfo[0];
-				setCache(result);
-			}
-			return Status.OK_STATUS;
-		}
-
-		/*
-		 * creates a search pattern based on the cache types
-		 */
-		private ICSearchPattern createSearchPattern() {
-			OrPattern pattern= new OrPattern();
-			int[] types= getCacheTypes();
-			for (int i= 0; i < types.length; ++i) {
-				switch (types[i]) {
-					case ICElement.C_NAMESPACE:
-						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.NAMESPACE, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-					break;
-
-					case ICElement.C_CLASS: // fall through
-					case ICElement.C_TEMPLATE_CLASS:
-						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.CLASS, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-					break;
-					
-					case ICElement.C_STRUCT: // fall through
-					case ICElement.C_TEMPLATE_STRUCT:
-						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.STRUCT, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-					break;
-
-					case ICElement.C_UNION: // fall through
-					case ICElement.C_TEMPLATE_UNION:
-						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.UNION, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-					break;
-
-					case ICElement.C_ENUMERATION:
-						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.ENUM, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-					break;
-
-					case ICElement.C_TYPEDEF:
-						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.TYPEDEF, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-					break;
-					
-					default:
-					break;
-				}
-			}
-			return pattern;
-		}
-		
-		/**
-		 * Forwards progress info to the progress monitor and
-		 * blocks until the job is finished.
-		 * 
-		 * @param monitor Optional progress monitor.
-		 * @throws InterruptedException
-		 * 
-		 * @see Job#join
-		 */
-		public void join(IProgressMonitor monitor) throws InterruptedException {
-			if (progressMonitor != null)
-				progressMonitor.addProgressMonitor(monitor);
-			super.join();
-		}
-	}
-
-	/**
-	 * Listener for changes to CModel.
-	 * @see org.eclipse.cdt.core.model.IElementChangedListener
-	 * @since 3.0
-	 */
-	private static class TypeCacheDeltaListener implements IElementChangedListener {
-		/*
-		 * @see IElementChangedListener#elementChanged
-		 */
-		public void elementChanged(ElementChangedEvent event) {
-			//TODO optimization: calculate deltas per file and
-			// update the cache selectively
-			boolean needsFlushing= processDelta(event.getDelta());
-			if (needsFlushing) {
-				// mark cache as dirty and reschedule the
-				// background job
-				setCacheDirty();
-				if (fgJob.getState() == Job.RUNNING)
-					fgJob.cancel();
-				fgJob.setPriority(Job.BUILD);
-				fgJob.schedule();
-			}
-		}
-		
-		/*
-		 * returns true if the cache needs to be flushed
-		 */
-		private boolean processDelta(ICElementDelta delta) {
-			ICElement elem= delta.getElement();
-			int pathEntryChanged= ICElementDelta.F_ADDED_PATHENTRY_SOURCE | ICElementDelta.F_REMOVED_PATHENTRY_SOURCE |
-									ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE | ICElementDelta.F_CHANGED_PATHENTRY_MACRO;
-			boolean isAddedOrRemoved= (delta.getKind() != ICElementDelta.CHANGED)
-			 || ((delta.getFlags() & pathEntryChanged) != 0);
-			
-			switch (elem.getElementType()) {
-				case ICElement.C_MODEL:
-				case ICElement.C_PROJECT:
-				case ICElement.C_CCONTAINER:
-				case ICElement.C_NAMESPACE:
-				case ICElement.C_TEMPLATE_CLASS:
-				case ICElement.C_CLASS:
-				case ICElement.C_STRUCT:
-				case ICElement.C_UNION:
-				case ICElement.C_ENUMERATION:
-				case ICElement.C_TYPEDEF:
-				case ICElement.C_INCLUDE:
-				case ICElement.C_UNIT:
-					if (isAddedOrRemoved) {
-						return true;
-					}				
-					return processChildrenDelta(delta);
-				default:
-					// fields, methods, imports ect
-					return false;
-			}	
-		}
-		
-		private boolean isPossibleStructuralChange(int flags) {
-			return (flags & (ICElementDelta.F_CONTENT | ICElementDelta.F_FINE_GRAINED)) == ICElementDelta.F_CONTENT;
-		}		
-		
-		private boolean processChildrenDelta(ICElementDelta delta) {
-			ICElementDelta[] children= delta.getAffectedChildren();
-			for (int i= 0; i < children.length; i++) {
-				if (processDelta(children[i])) {
-					return true;
-				}
-			}
-			return false;
-		}
-	}
-	
-	private static final int INITIAL_DELAY= 5000;
-	private static final TypeCacherJob fgJob= new TypeCacherJob();
-	private static final TypeCacheDeltaListener fgDeltaListener= new TypeCacheDeltaListener();
-	private static int[] fgCacheTypes= TypeInfo.getAllCElementTypes();
-	private static TypeInfo[] fgCacheData;
-	private static int fgNumberOfCacheFlushes;
-	private static boolean cacheIsDirty= true;
-	
-	/**
-	 * Initializes the AllTypesCache service.
-	 */
-	public static void initialize() {
-		// add delta listener
-		CoreModel.getDefault().addElementChangedListener(fgDeltaListener);
-
-		// schedule job to run after INITIAL_DELAY
-		if (fgJob.getState() != Job.RUNNING) {
-			fgJob.setPriority(Job.BUILD);
-			fgJob.schedule(INITIAL_DELAY);
-		}
-	}
-	
-	/**
-	 * Terminates the service provided by AllTypesCache.
-	 */
-	public static void terminate() {
-		// remove delta listener
-		CoreModel.getDefault().removeElementChangedListener(fgDeltaListener);
-		
-		// terminate background job
-		fgJob.cancel();
-	}
-
-	/*
-	 * Sets the cache contents.
-	 */
-	private static synchronized void setCache(TypeInfo[] cache) {
-		fgCacheData= cache;
-		cacheIsDirty= false;
-	}
-	
-	/*
-	 * Gets the cache contents.
-	 */
-	private static synchronized TypeInfo[] getCache() {
-		return fgCacheData;
-	}
-	
-	/*
-	 * Clears the cache.
-	 */
-	private static synchronized void flushCache() {
-		fgCacheData= null;
-		++fgNumberOfCacheFlushes;
-		cacheIsDirty= true;
-	}
-	
-	/*
-	 * Marks cache as dirty.
-	 */
-	private static synchronized void setCacheDirty() {
-		cacheIsDirty= true;
-	}
-
-	/*
-	 * Tests if cache is dirty.
-	 */
-	private static synchronized boolean isCacheDirty() {
-		return cacheIsDirty;
-	}
-
-	/*
-	 * Sets which types are stored in the cache.
-	 */
-	private static synchronized void setCacheTypes(int[] cElementTypes) {
-		fgCacheTypes= ArrayUtil.clone(cElementTypes);
-	}
-	
-	/*
-	 * Gets types stored in the cache.
-	 */
-	private static synchronized int[] getCacheTypes() {
-		return fgCacheTypes;
-	}
-
-	/**
-	 * Returns all types in the given scope, matching the given filter.
-	 * @param filter Filter for the type info.
-	 * @param monitor Progress monitor.
-	 * @param typesFound The resulting <code>TypeInfo</code> elements are added to this collection
-	 */		
-	public static void getTypes(ICSearchScope scope, ITypeInfoFilter filter, IProgressMonitor monitor, Collection typesFound) {
-		TypeInfo[] allTypes= getAllTypes(filter, monitor);
-		if (allTypes != null) {
-			boolean isWorkspaceScope= scope.equals(SearchEngine.createWorkspaceScope());
-			for (int i= 0; i < allTypes.length; i++) {
-				TypeInfo info= allTypes[i];
-				if (isWorkspaceScope || info.isEnclosed(scope)) {
-					if (filter.match(info))
-						typesFound.add(info);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Returns all types in the workspace. The returned array must not be
-	 * modified. The elements in the array are sorted by simple type name.
-	 */
-	public static TypeInfo[] getAllTypes(ITypeInfoFilter filter, IProgressMonitor monitor) {
-
-		// check if requested types are in cache
-		if (!ArrayUtil.containsAll(getCacheTypes(), filter.getCElementTypes()))
-		{
-			// mark cache dirty and cancel the running job
-			setCacheDirty();
-			if (fgJob.getState() == Job.RUNNING)
-				fgJob.cancel();
-			setCacheTypes(filter.getCElementTypes());
-		}
-		
-		if (isCacheDirty()) {
-			// start job if not already running
-			if (fgJob.getState() != Job.RUNNING) {
-				// boost priority since action was user-initiated
-				fgJob.setPriority(Job.SHORT);
-				fgJob.schedule();
-			}
-
-			// wait for job to finish
-			try {
-				fgJob.join(monitor);
-				if (monitor != null)
-					monitor.done();
-			} catch (InterruptedException ex) {
-				return null;
-			}
-		}
-		return getCache();
-	}
-		
-	/**
-	 * Returns true if the type cache is up to date.
-	 */
-	public static boolean isCacheUpToDate(ITypeInfoFilter filter) {
-		// check if requested types are in cache
-		if (!ArrayUtil.containsAll(getCacheTypes(), filter.getCElementTypes()))
-			return false;
-		return !isCacheDirty();
-	}
-}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfo.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfo.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfo.java
--- browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfo.java	8 Mar 2004 18:22:31 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,76 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 QNX Software Systems and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     QNX Software Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.ui.browser.typeinfo;
-
-import org.eclipse.cdt.core.model.ICElement;
-import org.eclipse.cdt.core.search.ICSearchScope;
-import org.eclipse.cdt.core.search.IMatch;
-
-/**
- * Type information.
- */
-public interface ITypeInfo extends IMatch {
-	
-	/**
-	 * Returns true if type is enclosed in the given scope
-	 */
-	public boolean isEnclosed(ICSearchScope scope);
-
-	/**
-	 * Returns true if the type is a low-level system type.
-	 * e.g. __FILE
-	 */
-	public boolean isSystemType();
-
-	/**
-	 * Gets the enclosing type names.
-	 */
-	public String[] getEnclosingNames();
-
-	/**
-	 * Gets the filename where this type is located.
-	 */
-	public String getFileName();
-	
-	/**
-	 * Gets the file path where this type is located.
-	 */
-	public String getFilePath();
-	
-	/**
-	 * Gets the extension of the file where this type is located.
-	 */
-	public String getFileExtension();
-	
-	/**
-	 * Gets the type qualified name: Includes enclosing type names, but
-	 * not filename. Identifiers are separated by colons.
-	 */
-	public String getQualifiedName();
-
-	/**
-	 * Gets the fully qualified type container name: Filename or
-	 * enclosing type name with filename.
-	 * All identifiers are separated by colons.
-	 */
-	public String getQualifiedParentName();
-	
-	/**
-	 * Gets the fully qualified type name: Includes enclosing type names and
-	 * filename. All identifiers are separated by colons.
-	 */
-	public String getFullyQualifiedName();
-	
-	/**
-	 * Gets the CElement which corresponds to this type.
-	 */
-	public ICElement getCElement();
-}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfoFilter.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfoFilter.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfoFilter.java
--- browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfoFilter.java	8 Mar 2004 18:22:31 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 QNX Software Systems and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     QNX Software Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.ui.browser.typeinfo;
-
-/**
- * Filter for type info.
- */
-public interface ITypeInfoFilter {
-	
-	/**
-	 * Gets the C types handled by this filter.
-	 * 
-	 * @return An array of ICElement types.
-	 * 
-	 */
-	public int[] getCElementTypes();
-
-	/**
-	 * Matches type info against filter.
-	 * 
-	 * @param info The object to filter.
-	 * @return <code>true</code> if successful match.
-	 */
-	public boolean match(ITypeInfo info);
-	/**
-	 * Returns <code>true</code> if <code>info</code> matches the filter.
-	 */
-}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfo.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfo.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfo.java
--- browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfo.java	8 Mar 2004 18:22:31 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,210 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 QNX Software Systems and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     QNX Software Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.ui.browser.typeinfo;
-
-import java.util.ArrayList;
-
-import org.eclipse.cdt.core.model.CoreModel;
-import org.eclipse.cdt.core.model.ICElement;
-import org.eclipse.cdt.core.model.IParent;
-import org.eclipse.cdt.core.search.BasicSearchMatch;
-import org.eclipse.cdt.core.search.ICSearchScope;
-import org.eclipse.cdt.internal.core.index.StringMatcher;
-import org.eclipse.cdt.internal.ui.browser.util.ArrayUtil;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-
-
-/**
- * To change the template for this generated type comment go to
- * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
- */
-public class TypeInfo extends BasicSearchMatch implements ITypeInfo
-{
-	private final static int[] cElementTypes= {
-		ICElement.C_NAMESPACE,
-		ICElement.C_CLASS,
-		ICElement.C_TEMPLATE_CLASS,
-		ICElement.C_STRUCT,
-		ICElement.C_TEMPLATE_STRUCT,
-		ICElement.C_UNION,
-		ICElement.C_TEMPLATE_UNION,
-		ICElement.C_ENUMERATION,
-		ICElement.C_TYPEDEF
-	};
-
-	public static int[] getAllCElementTypes() {
-		return cElementTypes;
-	}
-
-	public static boolean isValidCElementType(int type) {
-		return ArrayUtil.contains(cElementTypes, type);
-	}
-
-	private final static String scopeResolutionOperator= "::"; //$NON-NLS-1$
-	private final static String fileScopeSeparator= " : "; //$NON-NLS-1$
-	private static final StringMatcher fSystemTypeMatcher= new StringMatcher("_*", true, false); //$NON-NLS-1$
-	
-	public TypeInfo() {
-		super();
-	}
-	
-	public boolean isEnclosed(ICSearchScope scope) {
-		return scope.encloses(getFilePath());
-	}
-	
-	public boolean isSystemType() {
-		// recognized low-level system types eg __FILE
-		String[] names= getEnclosingNames();
-		if (names != null) {
-			for (int i= 0; i < names.length; ++i) {
-				if (fSystemTypeMatcher.match(names[i]))
-					return true;
-			}
-		}
-		return fSystemTypeMatcher.match(getName());
-	}
-
-	public String getFileName() {
-		if (resource != null)
-			return resource.getName();
-		else if (path != null)
-			return path.lastSegment();
-		else
-			return null;
-	}
-
-	public String getFilePath() {
-		if (resource != null)
-			return resource.getFullPath().toString();
-		else if (path != null)
-			return path.toString();
-		else
-			return null;
-	}
-
-	public String getFileExtension() {
-		if (resource != null)
-			return resource.getFileExtension();
-		else if (path != null)
-			return path.getFileExtension();
-		else
-			return null;
-	}
-
-	public String getQualifiedParentName() {
-		StringBuffer buf= new StringBuffer();
-		String fileName = getFileName();
-		if (fileName != null && fileName.length() > 0)
-			buf.append(fileName);
-		String parentName = getParentName();
-		if (parentName != null && parentName.length() > 0) {
-			buf.append(fileScopeSeparator); //$NON-NLS-1$
-			buf.append(parentName);
-		}
-		return buf.toString();
-	}
-	
-	public String getFullyQualifiedName() {
-		StringBuffer buf= new StringBuffer();
-		String fileName = getFileName();
-		if (fileName != null && fileName.length() > 0)
-			buf.append(fileName);
-		String parentName = getParentName();
-		if (parentName != null && parentName.length() > 0) {
-			buf.append(fileScopeSeparator); //$NON-NLS-1$
-			buf.append(parentName);
-			buf.append(scopeResolutionOperator); //$NON-NLS-1$
-		}
-		String name = getName();
-		if (name != null && name.length() > 0)
-			buf.append(name);
-		return buf.toString();
-	}
-	
-	public String getQualifiedName() {
-		StringBuffer buf= new StringBuffer();
-		String parentName = getParentName();
-		if (parentName != null && parentName.length() > 0) {
-			buf.append(parentName);
-			buf.append(scopeResolutionOperator); //$NON-NLS-1$
-		}
-		String name = getName();
-		if (name != null && name.length() > 0)
-			buf.append(name);
-		return buf.toString();
-	}
-	
-	public String[] getEnclosingNames() {
-		//TODO pull up this method into BasicSearchMatch
-		//since it already has access to this info
-		String parentName= getParentName();
-		if (parentName == null)
-			return null;
-
-		ArrayList names= new ArrayList(5);
-		int lastIndex= 0;
-		String nextName;
-		int qualifierIndex= parentName.indexOf(scopeResolutionOperator, 0);
-		while (qualifierIndex >= 0) {
-			nextName= parentName.substring(lastIndex, qualifierIndex);
-			lastIndex= qualifierIndex + scopeResolutionOperator.length();
-			names.add(nextName);
-			qualifierIndex= parentName.indexOf(scopeResolutionOperator, lastIndex);
-		}
-		nextName= parentName.substring(lastIndex);
-		names.add(nextName);
-
-		return (String[]) names.toArray(new String[names.size()]);
-	}	
-
-	public String toString() {
-		return getFullyQualifiedName();
-	}
-	
-	private boolean matchesCType(ICElement celement, String name) {
-		if (isValidCElementType(celement.getElementType()))
-			return celement.getElementName().equals(name);
-		return false;
-	}
-	
-	private ICElement findCElement(ICElement celement, String name) {
-		if (matchesCType(celement, name))
-			return celement;
-		else if (celement instanceof IParent) {
-			ICElement[] children = ((IParent)celement).getChildren();
-			for (int i = 0; i < children.length; i++) {
-				if (matchesCType(children[i], name))
-					return children[i];
-			}
-		}
-		return null;
-	}
-	
-	public ICElement getCElement() {
-		if (resource != null && resource.getType() == IResource.FILE) {
-			ICElement parentElement= CoreModel.getDefault().create((IFile)resource);
-			if (parentElement instanceof IParent) {
-				String[] names= getEnclosingNames();
-				if (names != null) {
-					for (int i= 0; i < names.length; ++i) {
-						parentElement= findCElement(parentElement, names[i]);
-						if (parentElement == null)
-							break;
-					}
-				}
-				if (parentElement != null)
-					return findCElement(parentElement, getName());
-			}
-		}
-		return null;
-	}
-}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoFilter.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoFilter.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoFilter.java
--- browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoFilter.java	8 Mar 2004 18:22:31 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 QNX Software Systems and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     QNX Software Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.ui.browser.typeinfo;
-
-import org.eclipse.cdt.internal.ui.browser.util.ArrayUtil;
-
-/**
- * The default type filter.
- */
-public class TypeInfoFilter implements ITypeInfoFilter {
-
-	public int[] getCElementTypes() {
-		return TypeInfo.getAllCElementTypes();
-	}
-	
-	public TypeInfoFilter() {
-	}
-
-	protected boolean hideSystemTypes() {
-		return true;
-	}
-
-	public boolean match(ITypeInfo info) {
-		// check if type is handled
-		if (!ArrayUtil.contains(getCElementTypes(), info.getElementType()))
-			return false;
-
-		// filter out low-level system types eg __FILE
-		//TODO make this a preferences option
-		if (hideSystemTypes() && info.isSystemType())
-			return false;
-
-		return true;
-	}
-}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java,v
retrieving revision 1.2
diff -u -r1.2 TypeInfoLabelProvider.java
--- browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java	30 Mar 2004 21:46:13 -0000	1.2
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java	6 Apr 2004 18:24:32 -0000
@@ -11,9 +11,11 @@
  *******************************************************************************/
 package org.eclipse.cdt.ui.browser.typeinfo;
 
+import org.eclipse.cdt.core.browser.ITypeInfo;
 import org.eclipse.cdt.core.model.CoreModel;
 import org.eclipse.cdt.core.model.ICElement;
 import org.eclipse.cdt.internal.ui.CPluginImages;
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.swt.graphics.Image;
 
@@ -90,32 +92,57 @@
 		}
 
 		if (isSet(SHOW_ROOT_POSTFIX)) {
-			String path= typeRef.getFilePath();
-			if (path != null && path.length() > 0) {
+			IPath path= typeRef.getPath();
+			if (path != null) {
 				buf.append(TypeInfoMessages.getString("TypeInfoLabelProvider.dash"));//$NON-NLS-1$
-				buf.append(path);
+				buf.append(path.toString());
 			}
 		}
 		return buf.toString();				
 	}
 	
-	private Image getFileIcon(ITypeInfo typeRef)
+	/* non java-doc
+	 * @see ILabelProvider#getImage
+	 */	
+	public Image getImage(Object element) {
+		if (!(element instanceof ITypeInfo)) 
+			return super.getImage(element);	
+
+		ITypeInfo typeRef= (ITypeInfo) element;
+		if (isSet(SHOW_TYPE_CONTAINER_ONLY)) {
+			return getContainerIcon(typeRef);
+		} else if (isSet(SHOW_FILENAME_ONLY)) {
+			return getFileIcon(typeRef.getPath());
+		} else {
+			return getTypeIcon(typeRef.getType());
+		}
+	}
+
+	public static Image getContainerIcon(ITypeInfo typeRef)
 	{
-		String ext = typeRef.getFileExtension();
-		if (ext != null) {	
-			String[] exts = CoreModel.getDefault().getHeaderExtensions();
-			for (int i = 0; i < exts.length; i++) {
-				if (exts[i].equalsIgnoreCase(ext)) {
-					return HEADER_ICON;
+		//TODO get enclosing types and parent type icon
+		return getFileIcon(typeRef.getPath());
+	}
+
+	public static Image getFileIcon(IPath path)
+	{
+		if (path != null) {
+			String ext= path.getFileExtension();
+			if (ext != null) {
+				String[] exts = CoreModel.getDefault().getHeaderExtensions();
+				for (int i = 0; i < exts.length; i++) {
+					if (exts[i].equalsIgnoreCase(ext)) {
+						return HEADER_ICON;
+					}
 				}
 			}
 		}
 		return SOURCE_ICON;
 	}
 	
-	private Image getIcon(ITypeInfo typeRef)
+	public static Image getTypeIcon(int type)
 	{
-		switch (typeRef.getElementType())
+		switch (type)
 		{
 		case ICElement.C_NAMESPACE:
 			return NAMESPACE_ICON;
@@ -140,23 +167,6 @@
 
 		default:
 			return CLASS_ICON;
-		}
-	}
-
-	/* non java-doc
-	 * @see ILabelProvider#getImage
-	 */	
-	public Image getImage(Object element) {
-		if (!(element instanceof ITypeInfo)) 
-			return super.getImage(element);	
-
-		ITypeInfo typeRef= (ITypeInfo) element;
-		if (isSet(SHOW_TYPE_CONTAINER_ONLY)) {
-			return getFileIcon(typeRef);
-		} else if (isSet(SHOW_FILENAME_ONLY)) {
-			return getFileIcon(typeRef);
-		} else {
-			return getIcon(typeRef);
 		}
 	}
 }
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.properties
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.properties,v
retrieving revision 1.1
diff -u -r1.1 TypeInfoMessages.properties
--- browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.properties	8 Mar 2004 18:22:31 -0000	1.1
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.properties	6 Apr 2004 18:24:32 -0000
@@ -9,11 +9,16 @@
 # QNX Software Systems - Initial API and implementation
 ###############################################################################
 
-TypeCacherJob.jobName=TypeCache
-TypeCacherJob.taskName=Updating Type Info...
-
 TypeSelectionDialog.lowerLabel=&Qualifier:
 TypeSelectionDialog.upperLabel=&Matching types:
+TypeSelectionDialog.filterLabel=Visible types:
+TypeSelectionDialog.filterNamespaces=namespace
+TypeSelectionDialog.filterClasses=class
+TypeSelectionDialog.filterStructs=struct
+TypeSelectionDialog.filterTypedefs=typedef
+TypeSelectionDialog.filterEnums=enum
+TypeSelectionDialog.filterUnions=union
+TypeSelectionDialog.filterLowLevelTypes=Show low-level types
 
 TypeInfoLabelProvider.default_filename=default
 TypeInfoLabelProvider.dash=\ - 
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java,v
retrieving revision 1.2
diff -u -r1.2 TypeSelectionDialog.java
--- browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java	17 Mar 2004 15:26:34 -0000	1.2
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java	6 Apr 2004 18:24:32 -0000
@@ -12,12 +12,29 @@
 package org.eclipse.cdt.ui.browser.typeinfo;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Comparator;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
+import org.eclipse.cdt.core.browser.*;
+import org.eclipse.cdt.core.model.ICElement;
 import org.eclipse.cdt.internal.ui.util.StringMatcher;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.dialogs.FilteredList;
 import org.eclipse.ui.dialogs.TwoPaneElementSelector;
 
@@ -29,40 +46,70 @@
 
 	private static class TypeFilterMatcher implements FilteredList.FilterMatcher {
 
-		private static final char END_SYMBOL= '<';
-		private static final char ANY_STRING= '*';
-		private final static String scopeResolutionOperator= "::"; //$NON-NLS-1$
+		private static final char END_SYMBOL = '<';
+		private static final char ANY_STRING = '*';
+		private final static String scopeResolutionOperator = "::"; //$NON-NLS-1$
 
 		private StringMatcher fMatcher;
 		private StringMatcher fQualifierMatcher;
 		private StringMatcher fScopedQualifierMatcher;
+		private Collection fVisibleTypes = new HashSet();
+		private boolean fShowLowLevelTypes = false;
 		
 		/*
 		 * @see FilteredList.FilterMatcher#setFilter(String, boolean)
 		 */
 		public void setFilter(String pattern, boolean ignoreCase, boolean ignoreWildCards) {
-			int qualifierIndex= pattern.lastIndexOf(scopeResolutionOperator); //$NON-NLS-1$
+			int qualifierIndex = pattern.lastIndexOf(scopeResolutionOperator);
 
 			// type			
 			if (qualifierIndex == -1) {
-				fQualifierMatcher= null;
-				fScopedQualifierMatcher= null;
-				fMatcher= new StringMatcher(adjustPattern(pattern), ignoreCase, ignoreWildCards);
-				
+				fQualifierMatcher = null;
+				fScopedQualifierMatcher = null;
+				fMatcher = new StringMatcher(adjustPattern(pattern), ignoreCase, ignoreWildCards);
 			// qualified type
 			} else {
-				String pattern1 = pattern.substring(0, qualifierIndex + scopeResolutionOperator.length());
-				fQualifierMatcher= new StringMatcher(adjustPattern(pattern1), ignoreCase, ignoreWildCards);
+				String prefixPattern = pattern.substring(0, qualifierIndex + scopeResolutionOperator.length());
+				fQualifierMatcher = new StringMatcher(adjustPattern(prefixPattern), ignoreCase, ignoreWildCards);
 				StringBuffer buf = new StringBuffer();
 				buf.append(ANY_STRING);
 				buf.append(scopeResolutionOperator);
-				buf.append(pattern1);
-				String pattern2= buf.toString();
-				fScopedQualifierMatcher= new StringMatcher(adjustPattern(pattern2), ignoreCase, ignoreWildCards);
-				String pattern3 = pattern.substring(qualifierIndex + scopeResolutionOperator.length());
-				fMatcher= new StringMatcher(adjustPattern(pattern3), ignoreCase, ignoreWildCards);
+				buf.append(prefixPattern);
+				String scopedPattern = buf.toString();
+				fScopedQualifierMatcher = new StringMatcher(adjustPattern(scopedPattern), ignoreCase, ignoreWildCards);
+				String namePattern = pattern.substring(qualifierIndex + scopeResolutionOperator.length());
+				fMatcher = new StringMatcher(adjustPattern(namePattern), ignoreCase, ignoreWildCards);
 			}
 		}
+		
+		public void setVisibleTypes(Collection visibleTypes) {
+			fVisibleTypes.clear();
+			fVisibleTypes.addAll(visibleTypes);
+		}
+
+		public Collection getVisibleTypes() {
+			return fVisibleTypes;
+		}
+		
+		public void setShowLowLevelTypes(boolean show) {
+			fShowLowLevelTypes = show;
+		}
+
+		public boolean getShowLowLevelTypes() {
+			return fShowLowLevelTypes;
+		}
+
+		private boolean isLowLevelType(ITypeInfo info) { 
+			String[] enclosingNames = info.getEnclosingNames();
+			// filter out low-level system types eg __FILE
+			if (enclosingNames != null) {
+				for (int i = 0; i < enclosingNames.length; ++i) {
+					if (enclosingNames[i].startsWith("_")) //$NON-NLS-1$
+						return true;
+				}
+			}
+			return info.getName().startsWith("_"); //$NON-NLS-1$
+		}
 
 		/*
 		 * @see FilteredList.FilterMatcher#match(Object)
@@ -71,31 +118,37 @@
 			if (!(element instanceof ITypeInfo))
 				return false;
 
-			TypeInfo type= (TypeInfo) element;
+			TypeInfo info = (TypeInfo) element;
+			
+			if (fVisibleTypes != null && !fVisibleTypes.contains(new Integer(info.getType())))
+				return false;
+
+			if (!fShowLowLevelTypes && isLowLevelType(info))
+				return false;
 
-			if (!fMatcher.match(type.getName()))
+			if (!fMatcher.match(info.getName()))
 				return false;
 
 			if (fQualifierMatcher == null)
 				return true;
 			
-			if (fQualifierMatcher.match(type.getQualifiedName()))
+			if (fQualifierMatcher.match(info.getQualifiedName()))
 				return true;
 			else
-				return fScopedQualifierMatcher.match(type.getQualifiedName());
+				return fScopedQualifierMatcher.match(info.getQualifiedName());
 		}
 		
 		private String adjustPattern(String pattern) {
-			int length= pattern.length();
+			int length = pattern.length();
 			if (length > 0) {
 				switch (pattern.charAt(length - 1)) {
 					case END_SYMBOL:
-						pattern= pattern.substring(0, length - 1);
+						pattern = pattern.substring(0, length - 1);
 						break;
 					case ANY_STRING:
 						break;
 					default:
-						pattern= pattern + ANY_STRING;
+						pattern = pattern + ANY_STRING;
 				}
 			}
 			return pattern;
@@ -104,51 +157,384 @@
 	
 	private static class StringComparator implements Comparator {
 	    public int compare(Object left, Object right) {
-	     	String leftString= (String) left;
-	     	String rightString= (String) right;
+	     	String leftString = (String) left;
+	     	String rightString = (String) right;
 	     	
-			int result= leftString.compareToIgnoreCase(rightString);			
+			int result = leftString.compareToIgnoreCase(rightString);			
 			if (result == 0)
-				result= leftString.compareTo(rightString);
+				result = leftString.compareTo(rightString);
 
 			return result;
 	    }
 	}
+
+	private static final String DIALOG_SETTINGS = TypeSelectionDialog.class.getName();
+	private static final String SETTINGS_X_POS = "x"; //$NON-NLS-1$
+	private static final String SETTINGS_Y_POS = "y"; //$NON-NLS-1$
+	private static final String SETTINGS_WIDTH = "width"; //$NON-NLS-1$
+	private static final String SETTINGS_HEIGHT = "height"; //$NON-NLS-1$
+	private static final String SETTINGS_SHOW_NAMESPACES = "show_namespaces"; //$NON-NLS-1$
+	private static final String SETTINGS_SHOW_CLASSES = "show_classes"; //$NON-NLS-1$
+	private static final String SETTINGS_SHOW_STRUCTS = "show_structs"; //$NON-NLS-1$
+	private static final String SETTINGS_SHOW_TYPEDEFS = "show_typedefs"; //$NON-NLS-1$
+	private static final String SETTINGS_SHOW_ENUMS = "show_enums"; //$NON-NLS-1$
+	private static final String SETTINGS_SHOW_UNIONS = "show_unions"; //$NON-NLS-1$
+	private static final String SETTINGS_SHOW_LOWLEVEL = "show_lowlevel"; //$NON-NLS-1$
+
+	private static final TypeInfoLabelProvider fElementRenderer = new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_ONLY);
+	private static final TypeInfoLabelProvider fQualifierRenderer = new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_CONTAINER_ONLY + TypeInfoLabelProvider.SHOW_ROOT_POSTFIX);
 	
+	private static final TypeFilterMatcher fFilterMatcher = new TypeFilterMatcher();
+	private static final StringComparator fStringComparator = new StringComparator();
+
+	private static final int[] fAllTypes = { ICElement.C_NAMESPACE, ICElement.C_CLASS,
+			ICElement.C_STRUCT, ICElement.C_TYPEDEF, ICElement.C_ENUMERATION,
+			ICElement.C_UNION };
+
+	private Set fKnownTypes = new HashSet(fAllTypes.length);
+	private Text fTextWidget;
+	private boolean fSelectFilterText = false;
+	private FilteredList fNewFilteredList;
+	private String fDialogSection;
+	private Point fLocation;
+	private Point fSize;
+ 
 	/**
 	 * Constructs a type selection dialog.
 	 * @param parent  the parent shell.
-	 * @param context the runnable context.
-	 * @param scope   the C search scope.
 	 */
 	public TypeSelectionDialog(Shell parent) {
-		super(parent, new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_ONLY),
-			new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_CONTAINER_ONLY + TypeInfoLabelProvider.SHOW_ROOT_POSTFIX));
+		super(parent, fElementRenderer, fQualifierRenderer);
 		setUpperListLabel(TypeInfoMessages.getString("TypeSelectionDialog.upperLabel")); //$NON-NLS-1$
 		setLowerListLabel(TypeInfoMessages.getString("TypeSelectionDialog.lowerLabel")); //$NON-NLS-1$
+		setVisibleTypes(fAllTypes);
+		setDialogSettings(DIALOG_SETTINGS);
+	}
+	
+	/**
+	 * Sets the filter pattern.
+	 * @param filter the filter pattern.
+	 * @param selectText <code>true</code> if filter text should be initially selected
+	 * @see org.eclipse.ui.dialogs.AbstractElementListSelectionDialog#setFilter(java.lang.String)
+	 */
+	public void setFilter(String filter, boolean selectText) {
+		super.setFilter(filter);
+		fSelectFilterText = selectText;
 	}
 
-	/*
-	 * @see AbstractElementListSelectionDialog#createFilteredList(Composite)
+	/**
+	 * Sets which CElement types are visible in the dialog.
+	 * 
+	 * @param types Array of CElement types.
+	 */
+	public void setVisibleTypes(int[] types) {
+		fKnownTypes.clear();
+		for (int i = 0; i < types.length; ++i) {
+			fKnownTypes.add(new Integer(types[i]));
+		}
+	}
+	
+	/**
+	 * Sets section name to use when storing the dialog settings.
+	 * 
+	 * @param section Name of section.
+	 */
+	public void setDialogSettings(String section) {
+		fDialogSection = section + "Settings"; //$NON-NLS-1$
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.dialogs.AbstractElementListSelectionDialog#createFilterText(org.eclipse.swt.widgets.Composite)
+	 */
+ 	protected Text createFilterText(Composite parent) {
+ 		fTextWidget = super.createFilterText(parent);
+
+		// create type checkboxes below filter text
+ 		createTypeFilterArea(parent);
+		
+ 		return fTextWidget;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.dialogs.AbstractElementListSelectionDialog#createFilteredList(org.eclipse.swt.widgets.Composite)
 	 */
  	protected FilteredList createFilteredList(Composite parent) {
- 		FilteredList list= super.createFilteredList(parent);
- 		
-		fFilteredList.setFilterMatcher(new TypeFilterMatcher());
-		fFilteredList.setComparator(new StringComparator());
+ 		fNewFilteredList = super.createFilteredList(parent);
+		fNewFilteredList.setFilterMatcher(fFilterMatcher);
+		fNewFilteredList.setComparator(fStringComparator);
+		return fNewFilteredList;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.window.Window#create()
+	 */
+	public void create() {
+		super.create();
+		if (!fSelectFilterText)
+			fTextWidget.setSelection(0,0);
+	}
+
+	/*
+	 * @see Window#close()
+	 */
+	public boolean close() {
+		writeSettings(getDialogSettings());
+		return super.close();
+	}
+
+	/*
+	 * @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
+	 */
+	protected Control createContents(Composite parent) {
+		readSettings(getDialogSettings());
+		return super.createContents(parent);
+	}
+
+	/**
+	 * Creates a type filter checkbox.
+	 */
+	private Button createTypeCheckbox(Composite parent, Integer typeObject) {
+		String name;
+		int type = typeObject.intValue();
+		switch (type) {
+			case ICElement.C_NAMESPACE:
+				name = TypeInfoMessages.getString("TypeSelectionDialog.filterNamespaces"); //$NON-NLS-1$
+			break;
+			case ICElement.C_CLASS:
+				name = TypeInfoMessages.getString("TypeSelectionDialog.filterClasses"); //$NON-NLS-1$
+			break;
+			case ICElement.C_STRUCT:
+				name = TypeInfoMessages.getString("TypeSelectionDialog.filterStructs"); //$NON-NLS-1$
+			break;
+			case ICElement.C_TYPEDEF:
+				name = TypeInfoMessages.getString("TypeSelectionDialog.filterTypedefs"); //$NON-NLS-1$
+			break;
+			case ICElement.C_ENUMERATION:
+				name = TypeInfoMessages.getString("TypeSelectionDialog.filterEnums"); //$NON-NLS-1$
+			break;
+			case ICElement.C_UNION:
+				name = TypeInfoMessages.getString("TypeSelectionDialog.filterUnions"); //$NON-NLS-1$
+			break;
+			default:
+				return null;
+		};
+		Image icon = TypeInfoLabelProvider.getTypeIcon(type);
+
+		final Integer fTypeObject = typeObject;
+		Button checkbox = new Button(parent, SWT.CHECK);
+		checkbox.setFont(parent.getFont());
+		checkbox.setText(name);
+		checkbox.setImage(icon);
+		checkbox.setSelection(fFilterMatcher.getVisibleTypes().contains(fTypeObject));
+		checkbox.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				if (e.widget instanceof Button) {
+					Button checkbox = (Button) e.widget;
+					if (checkbox.getSelection())
+						fFilterMatcher.getVisibleTypes().add(fTypeObject);
+					else
+						fFilterMatcher.getVisibleTypes().remove(fTypeObject);
+					updateElements();
+				}
+			}
+		});
+		return checkbox;
+	}
+
+	/**
+	 * Creates an area to filter types.
+	 * 
+	 * @param parent area to create controls in
+	 */
+	private void createTypeFilterArea(Composite parent) {
+		createLabel(parent, TypeInfoMessages.getString("TypeSelectionDialog.filterLabel")); //$NON-NLS-1$
+		
+		Composite upperRow = new Composite(parent, SWT.NONE);
+		RowLayout layout = new RowLayout();
+		layout.spacing = 10;
+		layout.marginTop = 0;
+		layout.marginLeft = 0;
+		upperRow.setLayout(layout);
+
+		// the for loop is here to guarantee we always
+		// create the checkboxes in the same order
+		for (int i = 0; i < fAllTypes.length; ++i) {
+			Integer typeObject = new Integer(fAllTypes[i]);
+			if (fKnownTypes.contains(typeObject))
+				createTypeCheckbox(upperRow, typeObject);
+		}
 		
-		return list;
+		Composite lowerRow = new Composite(parent, SWT.NONE);
+		lowerRow.setLayout(layout);
+
+		String name = TypeInfoMessages.getString("TypeSelectionDialog.filterLowLevelTypes"); //$NON-NLS-1$
+		Button checkbox = new Button(lowerRow, SWT.CHECK);
+		checkbox.setFont(lowerRow.getFont());
+		checkbox.setText(name);
+		checkbox.setSelection(fFilterMatcher.getShowLowLevelTypes());
+		checkbox.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				if (e.widget instanceof Button) {
+					Button button = (Button) e.widget;
+					fFilterMatcher.setShowLowLevelTypes(button.getSelection());
+					updateElements();
+				}
+			}
+		});
+	}
+	
+	/**
+	 * Forces redraw of elements list.
+	 */
+	private void updateElements() {
+		fNewFilteredList.setFilter(fTextWidget.getText());
+	}
+	
+	/**
+	 * Returns the dialog settings object used to save state
+	 * for this dialog.
+	 *
+	 * @return the dialog settings to be used
+	 */
+	protected IDialogSettings getDialogSettings() {
+		IDialogSettings allSettings = CUIPlugin.getDefault().getDialogSettings();
+		IDialogSettings section = allSettings.getSection(fDialogSection);		
+		if (section == null) {
+			section = allSettings.addNewSection(fDialogSection);
+			writeDefaultSettings(section);
+		}
+		return section;
+	}
+	
+	/**
+	 * Stores current configuration in the dialog store.
+	 */
+	protected void writeSettings(IDialogSettings section) {
+		Point location = getShell().getLocation();
+		section.put(SETTINGS_X_POS, location.x);
+		section.put(SETTINGS_Y_POS, location.y);
+
+		Point size = getShell().getSize();
+		section.put(SETTINGS_WIDTH, size.x);
+		section.put(SETTINGS_HEIGHT, size.y);
+
+		section.put(SETTINGS_SHOW_NAMESPACES, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_NAMESPACE)));
+		section.put(SETTINGS_SHOW_CLASSES, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_CLASS)));
+		section.put(SETTINGS_SHOW_STRUCTS, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_STRUCT)));
+		section.put(SETTINGS_SHOW_TYPEDEFS, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_TYPEDEF)));
+		section.put(SETTINGS_SHOW_ENUMS, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_ENUMERATION)));
+		section.put(SETTINGS_SHOW_UNIONS, fFilterMatcher.getVisibleTypes().contains(new Integer(ICElement.C_UNION)));
+		section.put(SETTINGS_SHOW_LOWLEVEL, fFilterMatcher.getShowLowLevelTypes());
 	}
+
+	/**
+	 * Stores default dialog settings.
+	 */
+	protected void writeDefaultSettings(IDialogSettings section) {
+		section.put(SETTINGS_SHOW_NAMESPACES, true); 
+		section.put(SETTINGS_SHOW_CLASSES, true);
+		section.put(SETTINGS_SHOW_STRUCTS, true);
+		section.put(SETTINGS_SHOW_TYPEDEFS, true);
+		section.put(SETTINGS_SHOW_ENUMS, true);
+		section.put(SETTINGS_SHOW_UNIONS, true);
+		section.put(SETTINGS_SHOW_LOWLEVEL, false);
+	}
+
+	/**
+	 * Initializes itself from the dialog settings with the same state
+	 * as at the previous invocation.
+	 */
+	protected void readSettings(IDialogSettings section) {
+		try {
+			int x = section.getInt(SETTINGS_X_POS);
+			int y = section.getInt(SETTINGS_Y_POS);
+			fLocation = new Point(x, y);
+			int width = section.getInt(SETTINGS_WIDTH);
+			int height = section.getInt(SETTINGS_HEIGHT);
+			fSize = new Point(width, height);
+		} catch (NumberFormatException e) {
+			fLocation = null;
+			fSize = null;
+		}
+
+		if (section.getBoolean(SETTINGS_SHOW_NAMESPACES)) {
+			Integer typeObject = new Integer(ICElement.C_NAMESPACE);
+			if (fKnownTypes.contains(typeObject))
+				fFilterMatcher.getVisibleTypes().add(typeObject);
+		}
+		if (section.getBoolean(SETTINGS_SHOW_CLASSES)) {
+			Integer typeObject = new Integer(ICElement.C_CLASS);
+			if (fKnownTypes.contains(typeObject))
+				fFilterMatcher.getVisibleTypes().add(typeObject);
+		}
+		if (section.getBoolean(SETTINGS_SHOW_STRUCTS)) {
+			Integer typeObject = new Integer(ICElement.C_STRUCT);
+			if (fKnownTypes.contains(typeObject))
+				fFilterMatcher.getVisibleTypes().add(typeObject);
+		}
+		if (section.getBoolean(SETTINGS_SHOW_TYPEDEFS)) {
+			Integer typeObject = new Integer(ICElement.C_TYPEDEF);
+			if (fKnownTypes.contains(typeObject))
+				fFilterMatcher.getVisibleTypes().add(typeObject);
+		}
+		if (section.getBoolean(SETTINGS_SHOW_ENUMS)) {
+			Integer typeObject = new Integer(ICElement.C_ENUMERATION);
+			if (fKnownTypes.contains(typeObject))
+				fFilterMatcher.getVisibleTypes().add(typeObject);
+		}
+		if (section.getBoolean(SETTINGS_SHOW_UNIONS)) {
+			Integer typeObject = new Integer(ICElement.C_UNION);
+			if (fKnownTypes.contains(typeObject))
+				fFilterMatcher.getVisibleTypes().add(typeObject);
+		}
+		fFilterMatcher.setShowLowLevelTypes(section.getBoolean(SETTINGS_SHOW_LOWLEVEL));
+	}
+	
+	/* (non-Cdoc)
+	 * @see org.eclipse.jface.window.Window#getInitialSize()
+	 */
+	protected Point getInitialSize() {
+		Point result = super.getInitialSize();
+		if (fSize != null) {
+			result.x = Math.max(result.x, fSize.x);
+			result.y = Math.max(result.y, fSize.y);
+			Rectangle display = getShell().getDisplay().getClientArea();
+			result.x = Math.min(result.x, display.width);
+			result.y = Math.min(result.y, display.height);
+		}
+		return result;
+	}
+	
+	/* (non-Cdoc)
+	 * @see org.eclipse.jface.window.Window#getInitialLocation(org.eclipse.swt.graphics.Point)
+	 */
+	protected Point getInitialLocation(Point initialSize) {
+		Point result = super.getInitialLocation(initialSize);
+		if (fLocation != null) {
+			result.x = fLocation.x;
+			result.y = fLocation.y;
+			Rectangle display = getShell().getDisplay().getClientArea();
+			int xe = result.x + initialSize.x;
+			if (xe > display.width) {
+				result.x -= xe - display.width; 
+			}
+			int ye = result.y + initialSize.y;
+			if (ye > display.height) {
+				result.y -= ye - display.height; 
+			}
+		}
+		return result;
+	}	
 	
 	/*
 	 * @see org.eclipse.ui.dialogs.SelectionStatusDialog#computeResult()
 	 */
 	protected void computeResult() {
-		ITypeInfo selection= (ITypeInfo) getLowerSelectedElement();
+		ITypeInfo selection = (ITypeInfo) getLowerSelectedElement();
 		if (selection == null)
 			return;
 			
-		List result= new ArrayList(1);
+		List result = new ArrayList(1);
 		result.add(selection);
 		setResult(result);
 	}
Index: src/org/eclipse/cdt/ui/CUIPlugin.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java,v
retrieving revision 1.32
diff -u -r1.32 CUIPlugin.java
--- src/org/eclipse/cdt/ui/CUIPlugin.java	5 Apr 2004 19:17:24 -0000	1.32
+++ src/org/eclipse/cdt/ui/CUIPlugin.java	6 Apr 2004 18:24:40 -0000
@@ -21,6 +21,7 @@
 import java.util.Set;
 
 import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.browser.AllTypesCache;
 import org.eclipse.cdt.core.model.CoreModel;
 import org.eclipse.cdt.core.model.ICElement;
 import org.eclipse.cdt.core.model.IWorkingCopy;
@@ -44,7 +45,6 @@
 import org.eclipse.cdt.internal.ui.util.ImageDescriptorRegistry;
 import org.eclipse.cdt.internal.ui.util.ProblemMarkerManager;
 import org.eclipse.cdt.internal.ui.util.Util;
-import org.eclipse.cdt.ui.browser.typeinfo.AllTypesCache;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.ResourcesPlugin;
@@ -338,7 +338,12 @@
 			public void run() {
 				registerAdapters();
 				CPluginImages.initialize();
-				AllTypesCache.initialize();
+				
+				AllTypesCache.initialize(new AllTypesCache.IWorkingCopyProvider() {
+					public IWorkingCopy[] getWorkingCopies() {
+						return CUIPlugin.getSharedWorkingCopies();
+					}
+				});
 			}
 		});
 	}
Index: .classpath
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/.classpath,v
retrieving revision 1.17
diff -u -r1.17 .classpath
--- .classpath	13 Jan 2004 21:25:13 -0000	1.17
+++ .classpath	6 Apr 2004 18:22:36 -0000
@@ -7,6 +7,7 @@
 	<classpathentry kind="src" path="search"/>
 	<classpathentry kind="src" path="dependency"/>
 	<classpathentry kind="src" path="parser"/>
+	<classpathentry kind="src" path="browser"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="output" path="bin"/>
Index: build.properties
===================================================================
RCS file: /home/tools/org.eclipse.cdt.core/build.properties,v
retrieving revision 1.17
diff -u -r1.17 build.properties
--- build.properties	13 Jan 2004 21:25:13 -0000	1.17
+++ build.properties	6 Apr 2004 18:22:36 -0000
@@ -20,6 +20,7 @@
                index/,\
                doc/,\
                dependency/,\
+               browser/,\
                .options
 javadoc.packages = org.eclipse.cdt.core.*,\
                    org.eclipse.cdt.core.index.*,\
@@ -33,5 +34,6 @@
                      src/,\
                      utils/,\
                      search/,\
-                     dependency/
+                     dependency/,\
+                     browser/
 source.cdtparser.jar = parser/
Index: browser/ChangeLog
===================================================================
RCS file: browser/ChangeLog
diff -N browser/ChangeLog
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/ChangeLog	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,2 @@
+2004-04-06 Chris Wiebe
+	initial placement of non-ui code into org.eclipse.cdt.core.browser
Index: browser/org/eclipse/cdt/core/browser/AllTypesCache.java
===================================================================
RCS file: browser/org/eclipse/cdt/core/browser/AllTypesCache.java
diff -N browser/org/eclipse/cdt/core/browser/AllTypesCache.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/core/browser/AllTypesCache.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,295 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.browser;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ElementChangedEvent;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICElementDelta;
+import org.eclipse.cdt.core.model.IElementChangedListener;
+import org.eclipse.cdt.core.model.IWorkingCopy;
+import org.eclipse.cdt.core.search.ICSearchScope;
+import org.eclipse.cdt.core.search.SearchEngine;
+import org.eclipse.cdt.internal.core.browser.cache.TypeCache;
+import org.eclipse.cdt.internal.core.browser.cache.TypeCacherJob;
+import org.eclipse.cdt.internal.core.browser.util.ArrayUtil;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+
+/**
+ * Manages a search cache for types in the workspace. Instead of returning objects of type <code>ICElement</code>
+ * the methods of this class returns a list of the lightweight objects <code>TypeInfo</code>.
+ * <P>
+ * AllTypesCache runs asynchronously using a background job to rebuild the cache as needed.
+ * If the cache becomes dirty again while the background job is running, the job is restarted.
+ * <P>
+ * If <code>getTypes</code> is called in response to a user action, a progress dialog is shown.
+ * If called before the background job has finished, getTypes waits
+ * for the completion of the background job.
+ */
+public class AllTypesCache {
+	
+	private static final int INITIAL_DELAY= 5000;
+	private static TypeCache fgCache;
+	private static TypeCacherJob fgJob;
+	private static TypeCacheDeltaListener fgDeltaListener;
+	
+	/**
+	 * Defines a simple interface in order to provide
+	 * a level of abstraction between the Core and UI
+	 * code.
+	 */
+	public static interface IWorkingCopyProvider {
+		public IWorkingCopy[] getWorkingCopies();
+	}
+	
+	/**
+	 * Initializes the AllTypesCache service.
+	 * 
+	 * @param provider A working copy provider.
+	 */
+	public static void initialize(IWorkingCopyProvider provider) {
+		fgCache= new TypeCache();
+		fgJob= new TypeCacherJob(fgCache, provider);
+		fgDeltaListener= new TypeCacheDeltaListener(fgCache, fgJob);
+		
+		// add delta listener
+		CoreModel.getDefault().addElementChangedListener(fgDeltaListener);
+
+		// schedule job to run after INITIAL_DELAY
+		if (fgJob.getState() != Job.RUNNING) {
+			fgJob.setSearchPaths(null);
+			fgJob.setPriority(Job.BUILD);
+			fgJob.schedule(INITIAL_DELAY);
+		}
+	}
+	
+	/**
+	 * Terminates the service provided by AllTypesCache.
+	 */
+	public static void terminate() {
+		// remove delta listener
+		CoreModel.getDefault().removeElementChangedListener(fgDeltaListener);
+		
+		// terminate background job
+		fgJob.cancel();
+	}
+	
+	/*
+	 * Returns the actual type cache.
+	 */
+	public static TypeCache getCache() {
+		return fgCache;
+	}
+	
+	/**
+	 * Returns true if the type cache is up to date.
+	 */
+	public static boolean isCacheUpToDate() {
+		return !fgCache.isDirty();
+	}
+	
+	/**
+	 * Returns all types in the given scope.
+	 * @param scope The search scope
+	 * @param kinds Array containing CElement types:
+	 * C_NAMESPACE, C_CLASS, C_UNION, C_ENUMERATION, C_TYPEDEF
+	 * @param monitor Progress monitor to display search progress
+	 * @param typesFound The resulting <code>TypeInfo</code> elements are added to this collection
+	 */		
+	public static void getTypes(ICSearchScope scope, int[] kinds, IProgressMonitor monitor, Collection typesFound) {
+		if (!isCacheUpToDate()) {
+			// start job if not already running
+			if (fgJob.getState() != Job.RUNNING) {
+				// boost priority since action was user-initiated
+				fgJob.setSearchPaths(null);
+				fgJob.setPriority(Job.SHORT);
+				fgJob.schedule();
+			}
+			
+			// wait for job to finish
+			try {
+				fgJob.join(monitor);
+				if (monitor != null)
+					monitor.done();
+			} catch (InterruptedException ex) {
+				return;
+			}
+		}
+		
+		boolean isWorkspaceScope= scope.equals(SearchEngine.createWorkspaceScope());
+		for (Iterator typesIter= fgCache.getAllTypes().iterator(); typesIter.hasNext(); ) {
+			ITypeInfo info= (ITypeInfo) typesIter.next();
+			if ( ArrayUtil.contains(kinds, info.getType()) &&
+				(isWorkspaceScope || info.isEnclosed(scope)) ) {
+				typesFound.add(info);
+			}
+		}
+	}
+	
+	/**
+	 * Listener for changes to CModel.
+	 * @see org.eclipse.cdt.core.model.IElementChangedListener
+	 * @since 3.0
+	 */
+	private static class TypeCacheDeltaListener implements IElementChangedListener {
+		
+		private TypeCache fTypeCache;
+		private TypeCacherJob fTypeCacherJob;
+		private Set fPaths= new HashSet(5);
+		private Set fPrefixes= new HashSet(5);
+		private boolean fFlushAll= false;
+		
+		public TypeCacheDeltaListener(TypeCache cache, TypeCacherJob job) {
+			fTypeCache= cache;
+			fTypeCacherJob= job;
+		}
+		
+		/*
+		 * @see IElementChangedListener#elementChanged
+		 */
+		public void elementChanged(ElementChangedEvent event) {
+			fPaths.clear();
+			fPrefixes.clear();
+			fFlushAll= false;
+
+			boolean needsFlushing= processDelta(event.getDelta());
+			if (needsFlushing) {
+				// cancel background job
+				if (fTypeCacherJob.getState() == Job.RUNNING) {
+					// wait for job to finish?
+					try {
+						fTypeCacherJob.cancel();
+						fTypeCacherJob.join();
+					} catch (InterruptedException ex) {
+					}
+				}
+				
+				if (fFlushAll) {
+					// flush the entire cache
+					fTypeCacherJob.setSearchPaths(null);
+					fTypeCache.flushAll();
+				} else {
+					// flush affected files from cache
+					Set searchPaths= new HashSet(10);
+					getPrefixMatches(fPrefixes, searchPaths);
+					searchPaths.addAll(fPaths);
+					fTypeCacherJob.setSearchPaths(searchPaths);
+					fTypeCache.flush(searchPaths);
+				}
+
+				// restart the background job
+				fTypeCacherJob.setPriority(Job.BUILD);
+				fTypeCacherJob.schedule();
+			}
+		}
+		
+		/*
+		 * returns true if the cache needs to be flushed
+		 */
+		private boolean processDelta(ICElementDelta delta) {
+			ICElement elem= delta.getElement();
+			int pathEntryChanged= ICElementDelta.F_ADDED_PATHENTRY_SOURCE | ICElementDelta.F_REMOVED_PATHENTRY_SOURCE |
+									ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE | ICElementDelta.F_CHANGED_PATHENTRY_MACRO;
+			boolean isAddedOrRemoved= (delta.getKind() != ICElementDelta.CHANGED)
+			 || ((delta.getFlags() & pathEntryChanged) != 0);
+			
+			switch (elem.getElementType()) {
+				case ICElement.C_MODEL:
+				{
+					if (isAddedOrRemoved) {
+						// CModel has changed
+						// flush the entire cache
+						fFlushAll= true;
+						return true;
+					}
+					return processDeltaChildren(delta);
+				}
+				
+				case ICElement.C_PROJECT:
+				case ICElement.C_CCONTAINER:
+				{
+					if (isAddedOrRemoved) {
+						// project or folder has changed
+						// flush all files with matching prefix
+						IPath path= elem.getPath();
+						if (path != null)
+							fPrefixes.add(path);
+						return true;
+					}
+					return processDeltaChildren(delta);
+				}
+				
+				case ICElement.C_NAMESPACE:
+				case ICElement.C_TEMPLATE_CLASS:
+				case ICElement.C_CLASS:
+				case ICElement.C_STRUCT:
+				case ICElement.C_UNION:
+				case ICElement.C_ENUMERATION:
+				case ICElement.C_TYPEDEF:
+				case ICElement.C_INCLUDE:
+				case ICElement.C_UNIT:
+				{
+					if (isAddedOrRemoved) {
+						// CElement has changed
+						// flush file from cache
+						IPath path= elem.getPath();
+						if (path != null)
+							fPaths.add(path);
+						return true;
+					}
+					return processDeltaChildren(delta);
+				}
+					
+				default:
+					// fields, methods, imports ect
+					return false;
+			}	
+		}
+
+		private boolean processDeltaChildren(ICElementDelta delta) {
+			ICElementDelta[] children= delta.getAffectedChildren();
+			for (int i= 0; i < children.length; i++) {
+				if (processDelta(children[i])) {
+					return true;
+				}
+			}
+			return false;
+		}
+		
+		private boolean getPrefixMatches(Set prefixes, Set results) {
+			Set pathSet= fTypeCache.getAllFiles();
+			if (pathSet.isEmpty() || prefixes == null || prefixes.isEmpty())
+				return false;
+
+			for (Iterator pathIter= pathSet.iterator(); pathIter.hasNext(); ) {
+				IPath path= (IPath) pathIter.next();
+
+				// find paths which match prefix
+				for (Iterator prefixIter= prefixes.iterator(); prefixIter.hasNext(); ) {
+					IPath prefix= (IPath) prefixIter.next();
+					if (prefix.isPrefixOf(path)) {
+						results.add(path);
+						break;
+					}
+				}
+			}
+
+			return !results.isEmpty();
+		}
+	}	
+}
Index: browser/org/eclipse/cdt/core/browser/ITypeInfo.java
===================================================================
RCS file: browser/org/eclipse/cdt/core/browser/ITypeInfo.java
diff -N browser/org/eclipse/cdt/core/browser/ITypeInfo.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/core/browser/ITypeInfo.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.browser;
+
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.search.ICSearchScope;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * Type information.
+ */
+public interface ITypeInfo {
+
+	/**
+	 * Gets the CElement type.
+	 */
+	public int getType();
+
+	/**
+	 * Gets the type name.
+	 */
+	public String getName();
+
+	/**
+	 * Gets the enclosing type names.
+	 */
+	public String[] getEnclosingNames();
+
+	/**
+	 * Gets the resource where type is located.
+	 */
+	public IResource getResource();
+	
+	/**
+	 * Gets the relative path where type is located.
+	 */
+	public IPath getPath();
+
+	/**
+	 * Gets the absolute path where type is located.
+	 */
+	public IPath getLocation();
+
+	/**
+	 * Gets the start offset of type position.
+	 */
+	public int getStartOffset();
+	
+	/**
+	 * Gets the end offset of type position.
+	 */
+	public int getEndOffset();
+
+	/**
+	 * Returns true if type is enclosed in the given scope
+	 */
+	public boolean isEnclosed(ICSearchScope scope);
+
+	/**
+	 * Gets the filename where this type is located.
+	 */
+	public String getFileName();
+	
+	/**
+	 * Gets the fully qualified type container name: Includes enclosing type names, but
+	 * not filename. Identifiers are separated by colons.
+	 */
+	public String getParentName();
+	
+	/**
+	 * Gets the type qualified name: Includes enclosing type names, but
+	 * not filename. Identifiers are separated by colons.
+	 */
+	public String getQualifiedName();
+
+	/**
+	 * Gets the fully qualified type container name: Filename or
+	 * enclosing type name with filename.
+	 * All identifiers are separated by colons.
+	 */
+	public String getQualifiedParentName();
+	
+	/**
+	 * Gets the fully qualified type name: Includes enclosing type names and
+	 * filename. All identifiers are separated by colons.
+	 */
+	public String getFullyQualifiedName();
+	
+	/**
+	 * Gets the CElement which corresponds to this type.
+	 */
+	public ICElement getCElement();
+
+	/** Gets the include path for this type.
+	 * 
+	 * @param cProject the C Project to use as a reference.
+	 * @return The path to this type, relative to the longest
+	 * matching include path in the given project, or
+	 * <code>null</code> if not found.
+	 */
+	public IPath resolveIncludePath(ICProject cProject);
+}
Index: browser/org/eclipse/cdt/core/browser/TypeInfo.java
===================================================================
RCS file: browser/org/eclipse/cdt/core/browser/TypeInfo.java
diff -N browser/org/eclipse/cdt/core/browser/TypeInfo.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/core/browser/TypeInfo.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,430 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.browser;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IParent;
+import org.eclipse.cdt.core.parser.IScannerInfo;
+import org.eclipse.cdt.core.parser.IScannerInfoProvider;
+import org.eclipse.cdt.core.search.ICSearchScope;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+
+/**
+ * To change the template for this generated type comment go to
+ * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
+ */
+public class TypeInfo implements ITypeInfo, Comparable
+{
+	protected final static String scopeResolutionOperator= "::"; //$NON-NLS-1$
+	protected final static String fileScopeSeparator= " : "; //$NON-NLS-1$
+	private String hashString= null;
+	private int hashCode= 0;
+	private String name= null;
+	private int type= 0;
+	private String[] enclosingNames= null;
+	private IResource resource= null;
+	private IPath path= null;
+	private int startOffset= 0;
+	private int endOffset= 0;
+	private ICElement cElement= null;
+	
+	public TypeInfo(String name, int type, String[] enclosingNames, IResource resource, IPath path, int startOffset, int endOffset) {
+		init(name, type, enclosingNames, resource, path, startOffset, endOffset);
+	}
+
+	public TypeInfo(String fullName, int type, IPath path, int startOffset, int endOffset) {
+		String name= fullName;
+		String parentName= null;
+		int qualifierIndex= fullName.lastIndexOf(scopeResolutionOperator);
+		if (qualifierIndex >= 0) {
+			parentName= fullName.substring(0, qualifierIndex);
+			name= fullName.substring(qualifierIndex+2);
+		}
+		String[] enclosingNames= null;
+		if (parentName != null)
+			enclosingNames= parseScopedName(parentName);
+
+		init(name, type, enclosingNames, null, path, startOffset, endOffset);
+	}
+
+	public TypeInfo(TypeInfo info) {
+		init(info.name, info.type, info.enclosingNames, info.resource, info.path, info.startOffset, info.endOffset);
+	}
+
+	private void init(String name, int type, String[] enclosingNames, IResource resource, IPath path, int startOffset, int endOffset) {
+		this.name= name;
+		this.type= type;
+		if (enclosingNames != null) {
+			this.enclosingNames= new String[enclosingNames.length];
+			System.arraycopy(enclosingNames, 0, this.enclosingNames, 0, enclosingNames.length);
+		}
+		this.resource= resource;
+		if (path == null && resource != null)
+			path= resource.getFullPath();
+		this.path= path;
+		this.startOffset= startOffset;
+		this.endOffset= endOffset;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public int getType() {
+		return type;
+	}
+
+	public String[] getEnclosingNames() {
+		return enclosingNames;
+	}
+
+	public IResource getResource() {
+		return resource;
+	}
+	
+	public IPath getPath() {
+		if (resource != null)
+			return resource.getFullPath();
+		else
+			return path;
+	}
+
+	public IPath getLocation() {
+		if (resource != null)
+			return resource.getLocation();
+		else
+			return path;
+	}
+
+	public int getStartOffset() {
+		return startOffset;
+	}
+
+	public int getEndOffset() {
+		return endOffset;
+	}
+
+	public String getFileName() {
+		if (resource != null)
+			return resource.getName();
+		else if (path != null)
+			return path.lastSegment();
+		else
+			return null;
+	}
+
+	public String getParentName() {
+		if (enclosingNames != null) {
+			StringBuffer buf= new StringBuffer();
+			for (int i= 0; i < enclosingNames.length; ++i) {
+				if (i > 0)
+					buf.append(scopeResolutionOperator);
+				buf.append(enclosingNames[i]);
+			}
+			return buf.toString();
+		}
+		return null;
+	}
+
+	public String getQualifiedParentName() {
+		StringBuffer buf= new StringBuffer();
+		String fileName = getFileName();
+		if (fileName != null)
+			buf.append(fileName);
+		String parentName = getParentName();
+		if (parentName != null) {
+			if (fileName != null)
+				buf.append(fileScopeSeparator);
+			buf.append(parentName);
+		}
+		return buf.toString();
+	}
+	
+	public String getQualifiedName() {
+		StringBuffer buf= new StringBuffer();
+		String parentName = getParentName();
+		if (parentName != null)
+			buf.append(parentName);
+		String name = getName();
+		if (name != null) {
+			if (parentName != null)
+				buf.append(scopeResolutionOperator);
+			buf.append(name);
+		}
+		return buf.toString();
+	}
+	
+	public String getFullyQualifiedName() {
+		StringBuffer buf= new StringBuffer();
+		String fileName = getFileName();
+		if (fileName != null)
+			buf.append(fileName);
+		String parentName = getParentName();
+		if (parentName != null) {
+			if (fileName != null)
+				buf.append(fileScopeSeparator);
+			buf.append(parentName);
+		}
+		String name = getName();
+		if (name != null)
+			if (parentName != null)
+				buf.append(scopeResolutionOperator);
+			else if (fileName != null)
+				buf.append(fileScopeSeparator);
+			buf.append(name);
+		return buf.toString();
+	}
+	
+	public String toString() {
+		return getFullyQualifiedName();
+	}
+	
+	public ICElement getCElement() {
+		if (cElement == null)
+			cElement= resolveCElement();
+		return cElement;
+	}
+
+	private ICElement resolveCElement() {
+		if (resource != null && resource.getType() == IResource.FILE) {
+			ICElement parentElement= CoreModel.getDefault().create((IFile)resource);
+			if (parentElement instanceof IParent) {
+				if (enclosingNames != null) {
+					for (int i= 0; i < enclosingNames.length; ++i) {
+						parentElement= findCElement(parentElement, enclosingNames[i]);
+						if (parentElement == null)
+							break;
+					}
+				}
+				if (parentElement != null)
+					return findCElement(parentElement, name);
+			}
+		}
+		return null;
+	}
+	
+	private ICElement findCElement(ICElement celement, String name) {
+		if (isValidType(celement.getElementType()) && celement.getElementName().equals(name))
+			return celement;
+		
+		if (celement instanceof IParent) {
+			ICElement[] children = ((IParent)celement).getChildren();
+			for (int i = 0; i < children.length; i++) {
+				ICElement child= children[i];
+				if (isValidType(child.getElementType()) && child.getElementName().equals(name))
+					return child;
+			}
+		}
+		return null;
+	}
+
+	public IPath resolveIncludePath(ICProject cProject) {
+		IPath fullPath= getLocation();
+		if (cProject == null || fullPath == null)
+			return null;
+		IProject project= cProject.getProject();
+		IScannerInfoProvider provider= CCorePlugin.getDefault().getScannerInfoProvider(project);
+		if (provider != null) {
+			IScannerInfo info= provider.getScannerInformation(project);
+			if (info != null) {
+				String[] includePaths= info.getIncludePaths();
+				IPath relativePath= null;
+				int mostSegments= 0;
+				for (int i= 0; i < includePaths.length; ++i) {
+					IPath includePath= new Path(includePaths[i]);
+					if (includePath.isPrefixOf(fullPath)) {
+						int segments= includePath.matchingFirstSegments(fullPath);
+						if (segments > mostSegments) {
+							relativePath= fullPath.removeFirstSegments(segments).setDevice(null);
+							mostSegments= segments;
+						}
+					}
+				}
+				return relativePath;
+			}
+		}
+		return null;
+	}
+	
+	public boolean isEnclosed(ICSearchScope scope) {
+		if (scope == null)
+			return false;
+
+		// check if path is in scope
+		IPath path= getPath();
+		if (path != null && scope.encloses(path.toString()))
+			return true;
+		
+		// check include paths of enclosing projects
+		IPath[] projectPaths= scope.enclosingProjects();
+		if (projectPaths != null) {
+			for (int i= 0; i < projectPaths.length; ++i) {
+				IPath projPath= projectPaths[i];
+				ICElement elem= CoreModel.getDefault().create(projPath);
+				if (elem != null && elem instanceof ICProject) {
+					ICProject proj= (ICProject) elem;
+					if (resolveIncludePath(proj) != null)
+						return true;
+					// TODO search referenced projects too?
+					// IProject[] refs= proj.getProject().getReferencedProjects();
+				}
+			}
+		}
+		return false;
+	}
+	
+	public int hashCode() {
+		if (hashString == null) {
+			hashCode= getHashString().hashCode();
+		}
+		return hashCode;
+	}
+	
+	private String getHashString() {
+		if (hashString == null) {
+			StringBuffer buf= new StringBuffer(64);
+
+			IPath path= getLocation();
+			if (path != null)
+				buf.append(path.toString());
+
+			buf.append(" ["); //$NON-NLS-1$
+			buf.append(startOffset);
+			buf.append("-"); //$NON-NLS-1$
+			buf.append(endOffset);
+			buf.append("] "); //$NON-NLS-1$
+			
+			String parentName= getParentName();
+			if (parentName != null && parentName.length() > 0) {
+				buf.append(parentName);
+				buf.append(scopeResolutionOperator);
+			}
+			String name= getName();
+			if (name != null && name.length() > 0)
+				buf.append(name);
+
+			buf.append(":"); //$NON-NLS-1$
+			buf.append(type);
+
+			hashString= buf.toString();
+		}
+		return hashString;
+	}
+	
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+		if (!(obj instanceof TypeInfo)) {
+			return false;
+		}
+		TypeInfo info= (TypeInfo)obj;
+		if (hashCode() != info.hashCode())
+			return false;
+		return getHashString().equals(info.getHashString());
+	}
+	
+	public int compareTo(Object obj) {
+		if (obj == this) {
+			return 0;
+		}
+		if( !(obj instanceof TypeInfo)) {
+			throw new ClassCastException();
+		}
+		TypeInfo info= (TypeInfo)obj;
+		return getHashString().compareTo(info.getHashString());
+	}
+
+	public static boolean isValidType(int type) {
+		switch (type) {
+			case ICElement.C_NAMESPACE:
+			case ICElement.C_CLASS:
+			case ICElement.C_STRUCT:
+			case ICElement.C_UNION:
+			case ICElement.C_ENUMERATION:
+			case ICElement.C_TYPEDEF:
+//			case ICElement.C_TEMPLATE_CLASS:
+//			case ICElement.C_TEMPLATE_STRUCT:
+//			case ICElement.C_TEMPLATE_UNION:
+				return true;
+			
+			default:
+				return false;
+		}
+	}
+	
+	public static String[] parseScopedName(String scopedName) {
+		ArrayList names= new ArrayList(5);
+		int lastIndex= 0;
+		String nextName;
+		int qualifierIndex= scopedName.indexOf(scopeResolutionOperator, 0);
+		while (qualifierIndex >= 0) {
+			nextName= scopedName.substring(lastIndex, qualifierIndex);
+			lastIndex= qualifierIndex + scopeResolutionOperator.length();
+			names.add(nextName);
+			qualifierIndex= scopedName.indexOf(scopeResolutionOperator, lastIndex);
+		}
+		nextName= scopedName.substring(lastIndex);
+		names.add(nextName);
+		return (String[]) names.toArray(new String[names.size()]);
+	}
+	
+	final static private Comparator TYPE_NAME_COMPARATOR= new Comparator() {
+		public int compare(Object o1, Object o2) {
+			return ((ITypeInfo)o1).getName().compareTo(((ITypeInfo)o2).getName());
+		}
+	};
+
+	public static ITypeInfo findType(String name, IPath path, ITypeInfo[] elements) {
+		if (elements == null)
+			return null;
+
+		ITypeInfo key= new TypeInfo(name, 0, path, 0, 0);
+
+		int index= Arrays.binarySearch(elements, key, TYPE_NAME_COMPARATOR);
+		if (index >= 0 && index < elements.length) {
+			for (int i= index - 1; i >= 0; i--) {
+				ITypeInfo curr= elements[i];
+				if (key.getName().equals(curr.getName())) {
+					if (key.getQualifiedName().equals(curr.getQualifiedName())) {
+						return curr;
+					}
+				} else {
+					break;
+				}
+			}
+			for (int i= index; i < elements.length; i++) {
+				ITypeInfo curr= elements[i];
+				if (key.getName().equals(curr.getName())) {
+					if (key.getQualifiedName().equals(curr.getQualifiedName())) {
+						return curr;
+					}
+				} else {
+					break;
+				}
+			}
+		}
+		return null;
+	}
+
+}
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
diff -N browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.browser.cache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.cdt.core.browser.TypeInfo;
+import org.eclipse.core.runtime.IPath;
+
+public class TypeCache {
+
+	private static final int INITIAL_FILE_COUNT= 100;
+	private static final int INITIAL_TYPE_COUNT= INITIAL_FILE_COUNT*20;
+	private final Map fFileMap= new HashMap(INITIAL_FILE_COUNT);
+	private final Map fTypeMap= new HashMap(INITIAL_TYPE_COUNT);
+	private boolean fIsDirty= true;
+	
+	private static final class TypeReference {
+		private TypeInfo fRealInfo= null;
+		private Set fPaths= new HashSet(1);
+
+		public TypeReference(TypeInfo info, IPath path) {
+			fRealInfo= info;
+			fPaths.add(path);
+		}
+		
+		public TypeInfo getInfo() {
+			return fRealInfo;
+		}
+		
+		public void addPath(IPath path) {
+			fPaths.add(path);
+		}
+
+		public void removePath(IPath path) {
+			fPaths.remove(path);
+		}
+		
+		public Collection getPaths() {
+			return fPaths;
+		}
+	};
+
+	public TypeCache() {
+	}
+
+	public synchronized void markAsDirty(boolean dirty) {
+		fIsDirty= dirty;
+	}
+	
+	public synchronized boolean isDirty() {
+		return fIsDirty;
+	}
+
+	public synchronized Set getAllFiles() {
+		return fFileMap.keySet();
+	}
+
+	public synchronized Set getAllTypes() {
+		return fTypeMap.keySet();
+	}
+		
+	private TypeInfo addTypeReference(TypeInfo info, IPath path) {
+		// we use info as a key here. the actual value found in
+		// the map corresponds to the 'real' TypeInfo object with
+		// the same hashCode
+		TypeReference typeRef= (TypeReference) fTypeMap.get(info);
+		if (typeRef == null) {
+			// add this type to cache
+			typeRef= new TypeReference(info, path);
+			fTypeMap.put(info, typeRef);
+		} else if (typeRef.getInfo() != info) {
+			typeRef.addPath(path);
+		}
+		return typeRef.getInfo();
+	}
+
+	private void removeTypeReference(TypeInfo info, IPath path) {
+		// we use info as a key here. the actual value found in
+		// the map corresponds to the 'real' TypeInfo object with
+		// the same hashCode
+		TypeReference typeRef= (TypeReference) fTypeMap.get(info);
+		if (typeRef == null)
+			return;
+		
+		typeRef.removePath(path);
+		for (Iterator i= typeRef.getPaths().iterator(); i.hasNext(); ) {
+			IPath p= (IPath) i.next();
+			fFileMap.remove(p);
+		}
+		fTypeMap.remove(info);
+	}
+
+	public synchronized void insert(IPath path, Collection types) {
+		Collection typeSet= (Collection) fFileMap.get(path);
+		if (typeSet == null)
+			typeSet= new ArrayList(types.size());
+		for (Iterator typesIter= types.iterator(); typesIter.hasNext(); ) {
+			TypeInfo info= (TypeInfo)typesIter.next();
+			TypeInfo newType= addTypeReference(info, path);
+			typeSet.add(newType);
+		}
+		fFileMap.put(path, typeSet);
+	}
+	
+	public synchronized boolean contains(IPath path) {
+		return fFileMap.containsKey(path);
+	}
+
+	public synchronized void flush(IPath path) {
+		Collection typeSet= (Collection) fFileMap.get(path);
+		if (typeSet != null) {
+			for (Iterator typesIter= typeSet.iterator(); typesIter.hasNext(); ) {
+				TypeInfo info= (TypeInfo)typesIter.next();
+				removeTypeReference(info, path);
+			}
+			fFileMap.remove(path);
+		}
+		fIsDirty= true;
+	}
+	
+	public synchronized void flush(Set paths) {
+		if (paths != null) {
+			// flush paths from cache
+			for (Iterator i= paths.iterator(); i.hasNext(); ) {
+				IPath path= (IPath) i.next();
+				flush(path);
+			}
+		}
+	}
+
+	public synchronized void flushAll() {
+		// flush the entire cache
+		fFileMap.clear();
+		fTypeMap.clear();
+		fIsDirty= true;
+	}
+}
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.java
diff -N browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.browser.cache;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class TypeCacheMessages {
+
+	private static final String RESOURCE_BUNDLE= TypeCacheMessages.class.getName();
+
+	private static ResourceBundle fgResourceBundle;
+	static {
+		try {
+			fgResourceBundle = ResourceBundle.getBundle(RESOURCE_BUNDLE);
+		} catch (MissingResourceException x) {
+			fgResourceBundle = null;
+		}
+	}
+
+	private TypeCacheMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return fgResourceBundle.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		} catch (NullPointerException e) {
+			return "#" + key + "#"; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+	
+	public static String getFormattedString(String key, String arg) {
+		return getFormattedString(key, new String[] { arg });
+	}
+	
+	public static String getFormattedString(String key, String[] args) {
+		return MessageFormat.format(getString(key), args);	
+	}	
+}
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.properties
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.properties
diff -N browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.properties
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.properties	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2004 QNX Software Systems Ltd. and others.
+# All rights reserved.   This program and the accompanying materials
+# are made available under the terms of the Common Public License v0.5
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v05.html
+# 
+# Contributors: 
+# QNX Software Systems - Initial API and implementation
+###############################################################################
+
+TypeCacherJob.jobName=TypeCache
+TypeCacherJob.taskName=Updating Type Info...
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java
diff -N browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacherJob.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.browser.cache;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.browser.AllTypesCache.IWorkingCopyProvider;
+import org.eclipse.cdt.core.model.IWorkingCopy;
+import org.eclipse.cdt.core.search.ICSearchConstants;
+import org.eclipse.cdt.core.search.ICSearchScope;
+import org.eclipse.cdt.internal.core.browser.util.DelegatedProgressMonitor;
+import org.eclipse.cdt.internal.core.model.CModelManager;
+import org.eclipse.cdt.internal.core.search.CWorkspaceScope;
+import org.eclipse.cdt.internal.core.search.PatternSearchJob;
+import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+
+
+/**
+ * Background job for filling the type cache.
+ * @see org.eclipse.core.runtime.jobs.Job
+ * @since 3.0
+ */
+public class TypeCacherJob extends Job {
+
+	/**
+	 * An "identity rule" that forces jobs to be queued.
+	 * @see org.eclipse.core.runtime.jobs.ISchedulingRule
+	 * @since 3.0
+	 */
+	final static ISchedulingRule MUTEX_RULE= new ISchedulingRule() {
+		public boolean contains(ISchedulingRule rule) {
+			return rule == this;
+		}
+		public boolean isConflicting(ISchedulingRule rule) {
+			return rule == this;
+		}			
+	};
+	
+	/**
+	 * Constant identifying the job family identifier for the background job.
+	 * @see IJobManager#join(Object, IProgressMonitor)
+	 * @since 3.0
+	 */
+	private static final Object FAMILY= new Object();
+
+	private DelegatedProgressMonitor fProgressMonitor;
+	private Set fSearchPaths= new HashSet(50);
+	private TypeCache fTypeCache;
+	private IWorkingCopyProvider fWorkingCopyProvider;
+
+	public TypeCacherJob(TypeCache cache, IWorkingCopyProvider provider) {
+		super(TypeCacheMessages.getString("TypeCacherJob.jobName")); //$NON-NLS-1$
+		setPriority(BUILD);
+		setSystem(true);
+		//setRule(MUTEX_RULE);
+		fTypeCache= cache;
+		fWorkingCopyProvider= provider;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.internal.jobs.InternalJob#belongsTo(java.lang.Object)
+	 */
+	public boolean belongsTo(Object family) {
+		return family == FAMILY;
+	}
+	
+	public void setSearchPaths(Set paths) {
+		fSearchPaths.clear();
+		if (paths != null)
+			fSearchPaths.addAll(paths);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.jobs.Job#run(IProgressMonitor)
+	 */
+	public IStatus run(IProgressMonitor monitor) {
+		fProgressMonitor= new DelegatedProgressMonitor(monitor);
+		
+		try {
+			search(fProgressMonitor);
+			fProgressMonitor.done();
+		} catch(InterruptedException ex) {
+			return Status.CANCEL_STATUS;
+		} catch (OperationCanceledException ex) {
+			return Status.CANCEL_STATUS;
+		} finally {
+			fProgressMonitor= null;
+		}
+
+		return Status.OK_STATUS;
+	}
+	
+	/**
+	 * Forwards progress info to the progress monitor and
+	 * blocks until the job is finished.
+	 * 
+	 * @param monitor Optional progress monitor.
+	 * @throws InterruptedException
+	 * 
+	 * @see Job#join
+	 */
+	public void join(IProgressMonitor monitor) throws InterruptedException {
+		if (fProgressMonitor != null)
+			fProgressMonitor.addDelegate(monitor);
+		super.join();
+	}
+	
+	private void search(IProgressMonitor monitor) throws InterruptedException {
+
+		monitor.beginTask(TypeCacheMessages.getString("TypeCacherJob.taskName"), 100); //$NON-NLS-1$
+
+		IWorkspace workspace= CCorePlugin.getWorkspace();
+		if (workspace == null)
+			throw new InterruptedException();
+
+		ICSearchScope scope= new CWorkspaceScope();
+		
+		// search for types and #include references
+		TypeSearchPattern pattern= new TypeSearchPattern();
+		for (Iterator pathIter= fSearchPaths.iterator(); pathIter.hasNext(); ) {
+			IPath path= (IPath) pathIter.next();
+			pattern.addDependencySearch(path);
+		}
+		TypeSearchPathCollector pathCollector= new TypeSearchPathCollector();
+		
+		CModelManager modelManager= CModelManager.getDefault();
+		IndexManager indexManager= modelManager.getIndexManager();
+	
+		if (monitor.isCanceled())
+			throw new InterruptedException();
+
+		SubProgressMonitor subMonitor= new SubProgressMonitor(monitor, 5);
+		
+		/* index search */
+		indexManager.performConcurrentJob( 
+			new PatternSearchJob(
+				pattern,
+				scope,
+				pathCollector,
+				indexManager
+			),
+		    ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
+			subMonitor,
+			null );
+		
+		if (monitor.isCanceled())
+			throw new InterruptedException();
+		
+		if (!fSearchPaths.isEmpty()) {
+			// flush all affected files from cache
+			fTypeCache.flush(fSearchPaths);
+			Set dependencyPaths= pathCollector.getDependencyPaths();
+			if (dependencyPaths != null && !dependencyPaths.isEmpty()) {
+				fTypeCache.flush(dependencyPaths);
+			}
+		}
+
+		Set allSearchPaths= pathCollector.getPaths();
+		if (allSearchPaths == null)
+			allSearchPaths= new HashSet();
+		
+		// remove cached files
+		allSearchPaths.removeAll(fTypeCache.getAllFiles());
+		
+		if (monitor.isCanceled())
+			throw new InterruptedException();
+
+		subMonitor= new SubProgressMonitor(monitor, 95);
+		
+		IWorkingCopy[] workingCopies= null;
+		if (fWorkingCopyProvider != null)
+			workingCopies= fWorkingCopyProvider.getWorkingCopies();
+
+		TypeMatchCollector collector= new TypeMatchCollector(fTypeCache, subMonitor);
+		TypeMatchLocator matchLocator= new TypeMatchLocator(collector);
+		matchLocator.locateMatches(allSearchPaths, workspace, workingCopies);
+		
+		if (monitor.isCanceled())
+			throw new InterruptedException();
+
+		fTypeCache.markAsDirty(false);
+		monitor.done();
+	}
+}
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeMatchCollector.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/cache/TypeMatchCollector.java
diff -N browser/org/eclipse/cdt/internal/core/browser/cache/TypeMatchCollector.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeMatchCollector.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.browser.cache;
+
+import java.util.ArrayList;
+
+import org.eclipse.cdt.core.browser.TypeInfo;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public class TypeMatchCollector {
+	private ArrayList results= new ArrayList();
+	private TypeCache typeCache;
+	private IProgressMonitor progressMonitor;
+
+	public TypeMatchCollector(TypeCache cache, IProgressMonitor monitor) {
+		progressMonitor= monitor;
+		typeCache= cache;
+	}
+	
+	public IProgressMonitor getProgressMonitor() {
+		return progressMonitor;
+	}
+
+	public boolean beginParsing(IPath path) {
+		// check if path is in the cache already
+		if (typeCache.contains(path))
+			return false;
+
+		results.clear();
+		return true;
+	}
+
+	public void doneParsing(IPath path) {
+		if (!results.isEmpty()) {
+			// add types to cache
+			typeCache.insert(path, results);
+		}
+	}
+
+	public void acceptType(String name, int type, String[] enclosingNames, IResource resource, IPath path, int startOffset, int endOffset) {
+		// create new type info
+		TypeInfo info= new TypeInfo(name, type, enclosingNames, resource, path, startOffset, endOffset);
+		results.add(info);
+	}
+}
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeMatchLocator.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/cache/TypeMatchLocator.java
diff -N browser/org/eclipse/cdt/internal/core/browser/cache/TypeMatchLocator.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeMatchLocator.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,561 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corp. - Rational Software - initial implementation
+ *     QNX Software Systems - adapted for type search
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.browser.cache;
+
+import java.io.CharArrayReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.IWorkingCopy;
+import org.eclipse.cdt.core.parser.DefaultProblemHandler;
+import org.eclipse.cdt.core.parser.IParser;
+import org.eclipse.cdt.core.parser.IProblem;
+import org.eclipse.cdt.core.parser.IScanner;
+import org.eclipse.cdt.core.parser.IScannerInfo;
+import org.eclipse.cdt.core.parser.IScannerInfoProvider;
+import org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate;
+import org.eclipse.cdt.core.parser.ISourceElementRequestor;
+import org.eclipse.cdt.core.parser.ParserFactory;
+import org.eclipse.cdt.core.parser.ParserFactoryError;
+import org.eclipse.cdt.core.parser.ParserLanguage;
+import org.eclipse.cdt.core.parser.ParserMode;
+import org.eclipse.cdt.core.parser.ParserUtil;
+import org.eclipse.cdt.core.parser.ScannerInfo;
+import org.eclipse.cdt.core.parser.ast.ASTClassKind;
+import org.eclipse.cdt.core.parser.ast.IASTASMDefinition;
+import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTClassReference;
+import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
+import org.eclipse.cdt.core.parser.ast.IASTCodeScope;
+import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
+import org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier;
+import org.eclipse.cdt.core.parser.ast.IASTEnumerationReference;
+import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
+import org.eclipse.cdt.core.parser.ast.IASTEnumeratorReference;
+import org.eclipse.cdt.core.parser.ast.IASTField;
+import org.eclipse.cdt.core.parser.ast.IASTFieldReference;
+import org.eclipse.cdt.core.parser.ast.IASTFunction;
+import org.eclipse.cdt.core.parser.ast.IASTFunctionReference;
+import org.eclipse.cdt.core.parser.ast.IASTInclusion;
+import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
+import org.eclipse.cdt.core.parser.ast.IASTMacro;
+import org.eclipse.cdt.core.parser.ast.IASTMethod;
+import org.eclipse.cdt.core.parser.ast.IASTMethodReference;
+import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
+import org.eclipse.cdt.core.parser.ast.IASTNamespaceReference;
+import org.eclipse.cdt.core.parser.ast.IASTOffsetableNamedElement;
+import org.eclipse.cdt.core.parser.ast.IASTParameterReference;
+import org.eclipse.cdt.core.parser.ast.IASTQualifiedNameElement;
+import org.eclipse.cdt.core.parser.ast.IASTReference;
+import org.eclipse.cdt.core.parser.ast.IASTScope;
+import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation;
+import org.eclipse.cdt.core.parser.ast.IASTTemplateParameterReference;
+import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
+import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTTypedefReference;
+import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
+import org.eclipse.cdt.core.parser.ast.IASTVariable;
+import org.eclipse.cdt.core.parser.ast.IASTVariableReference;
+import org.eclipse.cdt.core.search.ICSearchConstants;
+import org.eclipse.cdt.core.search.ICSearchPattern;
+import org.eclipse.cdt.internal.core.browser.util.PathUtil;
+import org.eclipse.cdt.internal.core.browser.util.SimpleStack;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+
+public class TypeMatchLocator implements ISourceElementRequestor, ICSearchConstants {
+	private ISourceElementCallbackDelegate lastDeclaration;
+	private ICSearchPattern searchPattern;
+	private TypeMatchCollector resultCollector;
+	private IProgressMonitor progressMonitor;
+	private IWorkspaceRoot workspaceRoot= null;
+	private SimpleStack scopeStack= new SimpleStack();
+	private SimpleStack resourceStack= new SimpleStack();
+	private static boolean VERBOSE= false;
+
+	public TypeMatchLocator(TypeMatchCollector collector) {
+		super();
+		searchPattern= new TypeSearchPattern();
+		resultCollector= collector;
+		progressMonitor= collector.getProgressMonitor();
+		if (progressMonitor == null)
+			progressMonitor= new NullProgressMonitor();
+	}
+
+	public boolean acceptProblem(IProblem problem) {
+		return DefaultProblemHandler.ruleOnProblem(problem, ParserMode.COMPLETE_PARSE );
+	}
+	public void acceptUsingDirective(IASTUsingDirective usageDirective) { }
+	public void acceptUsingDeclaration(IASTUsingDeclaration usageDeclaration) {	}
+	public void acceptASMDefinition(IASTASMDefinition asmDefinition) { }
+	public void acceptAbstractTypeSpecDeclaration(IASTAbstractTypeSpecifierDeclaration abstractDeclaration) { }
+	public void enterTemplateDeclaration(IASTTemplateDeclaration declaration) { }
+	public void enterTemplateSpecialization(IASTTemplateSpecialization specialization) { }
+	public void enterTemplateInstantiation(IASTTemplateInstantiation instantiation) { }
+	public void exitTemplateDeclaration(IASTTemplateDeclaration declaration) { }
+	public void exitTemplateSpecialization(IASTTemplateSpecialization specialization) { }
+	public void exitTemplateExplicitInstantiation(IASTTemplateInstantiation instantiation) { }
+	public void acceptParameterReference(IASTParameterReference reference) { }
+	public void acceptTemplateParameterReference(IASTTemplateParameterReference reference) { }
+	public void acceptTypedefReference( IASTTypedefReference reference ) { }
+	public void acceptEnumeratorReference(IASTEnumeratorReference reference) { }
+	public void acceptClassReference(IASTClassReference reference) { }
+	public void acceptNamespaceReference( IASTNamespaceReference reference ) { }
+	public void acceptVariableReference( IASTVariableReference reference ) { }
+	public void acceptFieldReference( IASTFieldReference reference ) { }
+	public void acceptEnumerationReference( IASTEnumerationReference reference ) { }
+	public void acceptFunctionReference( IASTFunctionReference reference ) { }
+	public void acceptMethodReference( IASTMethodReference reference ) { }
+	public void acceptField(IASTField field) { }
+	public void acceptMacro(IASTMacro macro) { }
+	public void acceptVariable(IASTVariable variable) { }
+	public void acceptFunctionDeclaration(IASTFunction function) { }
+	public void acceptMethodDeclaration(IASTMethod method) { }
+	public void enterCodeBlock(IASTCodeScope scope) { }
+	public void exitCodeBlock(IASTCodeScope scope) { }
+	
+	public void acceptTypedefDeclaration(IASTTypedefDeclaration typedef){
+		lastDeclaration = typedef;
+		check( DECLARATIONS, typedef );
+	}
+	
+	public void acceptEnumerationSpecifier(IASTEnumerationSpecifier enumeration){
+		lastDeclaration = enumeration; 
+		check( DECLARATIONS, enumeration );
+	}
+		
+    public void acceptElaboratedForewardDeclaration(IASTElaboratedTypeSpecifier elaboratedType){
+		check( DECLARATIONS, elaboratedType );	
+    }
+
+	public void enterLinkageSpecification(IASTLinkageSpecification linkageSpec){
+		pushScope( linkageSpec );	
+	}
+	public void exitLinkageSpecification(IASTLinkageSpecification linkageSpec){
+		popScope();
+	}
+
+	public void enterCompilationUnit(IASTCompilationUnit compilationUnit) {
+		pushScope( compilationUnit );
+	}
+	public void exitCompilationUnit(IASTCompilationUnit compilationUnit){
+		popScope();
+	}
+	
+	public void enterFunctionBody(IASTFunction function){
+		pushScope( function );
+	}
+	public void exitFunctionBody(IASTFunction function) {
+		popScope();	
+	}
+
+	public void enterMethodBody(IASTMethod method) {
+		pushScope( method );
+	}
+	public void exitMethodBody(IASTMethod method) {
+		popScope();	
+	}
+	
+	public void enterNamespaceDefinition(IASTNamespaceDefinition namespaceDefinition) {
+		lastDeclaration = namespaceDefinition;
+		check( DECLARATIONS, namespaceDefinition );
+		check( DEFINITIONS, namespaceDefinition );
+		pushScope( namespaceDefinition );			
+	}
+	public void exitNamespaceDefinition(IASTNamespaceDefinition namespaceDefinition) {
+		popScope();
+	}
+
+	public void enterClassSpecifier(IASTClassSpecifier classSpecification) {
+		lastDeclaration = classSpecification;
+		check( DECLARATIONS, classSpecification );
+		pushScope( classSpecification );		
+	}
+	public void exitClassSpecifier(IASTClassSpecifier classSpecification) {
+		popScope();
+	}
+
+	public void enterInclusion(IASTInclusion inclusion) {
+		String includePath = inclusion.getFullFileName();
+
+		IPath path = new Path( includePath );
+		IResource resource = null;
+		
+		if (workspaceRoot != null)
+			resource = workspaceRoot.getFileForLocation( path );
+		
+		if (resource == null) {
+			// we need to standardize the paths for external headers
+			path = PathUtil.getCanonicalPath(includePath);
+		}
+		
+		if (resource != null)
+			resourceStack.push(resource);
+		else
+			resourceStack.push(path);
+
+		if (progressMonitor.isCanceled())
+			throw new OperationCanceledException();
+	}
+
+	public void exitInclusion(IASTInclusion inclusion) {
+		resourceStack.pop();
+
+		if (progressMonitor.isCanceled())
+			throw new OperationCanceledException();
+	}
+		
+	protected void report( ISourceElementCallbackDelegate node, int accuracyLevel ){
+		int offset = 0;
+		int end = 0;
+		IASTOffsetableNamedElement offsetable = null;
+		String name = null;
+		int type = 0;
+
+		if( node instanceof IASTReference ){
+			IASTReference reference = (IASTReference) node;
+			offset = reference.getOffset();
+			end = offset + reference.getName().length();
+			if (VERBOSE)
+				verbose("Report Match: " + reference.getName()); //$NON-NLS-1$
+		} else if( node instanceof IASTOffsetableNamedElement ){
+			offsetable= (IASTOffsetableNamedElement) node;
+			offset = offsetable.getNameOffset() != 0 ? offsetable.getNameOffset() 
+														    : offsetable.getStartingOffset();
+			end = offsetable.getNameEndOffset();
+			if( end == 0 ){
+				end = offset + offsetable.getName().length();
+			}
+																					  
+			if (VERBOSE)
+				verbose("Report Match: " + offsetable.getName()); //$NON-NLS-1$
+		}
+
+		if (node instanceof IASTReference)
+			node = lastDeclaration;
+	
+		if (node instanceof IASTReference) {
+			offsetable = (IASTOffsetableNamedElement) ((IASTReference)node).getReferencedElement();
+			name = ((IASTReference)node).getName();
+		} else if (node instanceof IASTOffsetableNamedElement) {
+			offsetable = (IASTOffsetableNamedElement)node;
+			name = offsetable.getName();
+		} else {
+			return;
+		}
+		
+		// skip unnamed structs
+		if (name == null || name.length() == 0)
+			return;
+
+		// skip unused types
+		type= getElementType(offsetable);
+		if (type == 0) {
+			return;
+		}
+		
+		// collect enclosing names
+		String[] enclosingNames = null;
+		if (offsetable instanceof IASTQualifiedNameElement) {
+			String[] names = ((IASTQualifiedNameElement) offsetable).getFullyQualifiedName();
+			if (names != null && names.length > 1) {
+				enclosingNames = new String[names.length-1];
+				System.arraycopy(names, 0, enclosingNames, 0, names.length-1);
+			}
+		}
+
+//		// collect enclosing files
+//		IPath[] enclosingPaths= null;
+//		Object[] sourceRefs= resourceStack.toArray();
+//		// assert(sourceRefs.length > 0)
+//
+//		// walk through resource stack and
+//		// collect enclosing paths
+//		enclosingPaths= new IPath[sourceRefs.length-1];
+//		for (int i= 0; i < sourceRefs.length-1; ++i) {
+//			Object obj= sourceRefs[i];
+//			IPath sourcePath= null;
+//			if (obj instanceof IResource) {
+//				IResource res= (IResource) obj;
+//				enclosingPaths[i]= res.getFullPath();
+//			} else {
+//				enclosingPaths[i]= (IPath) obj;
+//			}
+//		}
+		
+		IResource resource= null;
+		IPath path= null;
+		Object obj= (Object) resourceStack.top();
+		if (obj instanceof IResource)
+			resource= (IResource) obj;
+		else
+			path= (IPath) obj;
+		
+		resultCollector.acceptType(name, type, enclosingNames, resource, path, offset, end);
+	}
+
+	private void check( LimitTo limit, ISourceElementCallbackDelegate node ){
+
+		if (progressMonitor.isCanceled())
+			throw new OperationCanceledException();
+		
+		// skip local declarations
+		IASTScope currentScope= (IASTScope)scopeStack.top();
+		if (currentScope instanceof IASTFunction || currentScope instanceof IASTMethod) {
+			return;
+		}
+
+		// always limit == DECLARATIONS
+//		
+//		if( !searchPattern.canAccept( limit ) )
+//			return;
+			
+		int level = ICSearchPattern.IMPOSSIBLE_MATCH;
+		
+		if( node instanceof IASTReference ){
+			level = searchPattern.matchLevel( ((IASTReference)node).getReferencedElement(), limit );
+		} else  {
+			level = searchPattern.matchLevel(  node, limit );
+		}
+
+		if( level != ICSearchPattern.IMPOSSIBLE_MATCH )
+		{
+			report( node, level );
+		} 
+	}
+	
+	private void pushScope( IASTScope scope ){
+		scopeStack.push(scope);
+
+		if (progressMonitor.isCanceled())
+			throw new OperationCanceledException();
+	}
+	
+	private IASTScope popScope(){
+		IASTScope oldScope= (IASTScope) scopeStack.pop();
+
+		if (progressMonitor.isCanceled())
+			throw new OperationCanceledException();
+
+		return oldScope;
+	}
+ 
+	private static void verbose(String log) {
+	  System.out.println("(" + Thread.currentThread() + ") " + log);  //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#createReader(java.lang.String)
+	 */
+	public Reader createReader(String finalPath) {
+		return ParserUtil.createReader(finalPath);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#parserTimeout()
+	 */
+	public boolean parserTimeout() {
+		return false;
+	}
+
+
+	public void locateMatches(Set searchPaths, IWorkspace workspace, IWorkingCopy[] workingCopies) throws InterruptedException {
+		workspaceRoot= (workspace != null) ? workspace.getRoot() : null;
+		
+		Set searchablePaths= new HashSet(searchPaths);
+		Map workingCopyMap= null;
+
+		if (workingCopies != null && workingCopies.length > 0) {
+			workingCopyMap= new HashMap(workingCopies.length);
+			for (int i= 0; i < workingCopies.length; ++i) {
+				IWorkingCopy workingCopy= workingCopies[i];
+				IPath wcPath= workingCopy.getOriginalElement().getPath();
+				workingCopyMap.put(wcPath, workingCopy);
+				searchablePaths.add(wcPath);
+			}
+		}
+
+		progressMonitor.beginTask("", searchablePaths.size()); //$NON-NLS-1$
+		
+		for (Iterator i= searchablePaths.iterator(); i.hasNext(); ) {
+
+			if (progressMonitor.isCanceled())
+				throw new InterruptedException();
+
+			IPath path= (IPath) i.next();
+
+			if (!resultCollector.beginParsing(path))
+				continue;
+			
+			Reader reader= null;
+			IPath realPath= null; 
+			IProject project= null;
+			IResource currentResource= null;
+			IPath currentPath= null;
+			
+			progressMonitor.worked(1);
+			
+			if (workspaceRoot != null) {
+				IWorkingCopy workingCopy= null;
+				if (workingCopyMap != null)
+					workingCopy= (IWorkingCopy) workingCopyMap.get(path);
+				if (workingCopy != null) {
+					currentResource= workingCopy.getResource();
+					reader= new CharArrayReader(workingCopy.getContents());
+				} else {
+					currentResource= workspaceRoot.findMember(path, true);
+					if (currentResource != null && currentResource instanceof IFile) {
+						IFile file= (IFile) currentResource;
+						try {
+							reader= new InputStreamReader(file.getContents());
+						} catch (CoreException ex) {
+							continue;
+						}
+					}
+				}
+			}
+
+			if (currentResource == null) {
+				try {
+					reader= new FileReader(path.toFile());
+				} catch (FileNotFoundException ex) {
+					continue;
+				}
+				currentPath= path;
+				realPath= currentPath;
+				project= null;
+			} else {
+				currentPath= null;
+				realPath= currentResource.getLocation();
+				project= currentResource.getProject();
+			}
+			
+			if (currentResource != null)
+				resourceStack.push(currentResource);
+			else
+				resourceStack.push(currentPath);
+				
+			parseMatches(path, reader, realPath, project);
+			
+			resourceStack.pop();
+
+			resultCollector.doneParsing(path);
+
+			if (progressMonitor.isCanceled())
+				throw new InterruptedException();
+		}
+		
+		progressMonitor.done();
+	}
+	
+	private void parseMatches(IPath path, Reader reader, IPath realPath, IProject project) throws InterruptedException {
+		//Get the scanner info
+		IScannerInfo scanInfo = new ScannerInfo();
+		IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project);
+		if (provider != null){
+			IScannerInfo buildScanInfo = provider.getScannerInformation(project);
+			if( buildScanInfo != null )
+				scanInfo = new ScannerInfo(buildScanInfo.getDefinedSymbols(), buildScanInfo.getIncludePaths());
+		}
+		
+		ParserLanguage language = null;
+		if( project != null ){
+			language = CoreModel.getDefault().hasCCNature( project ) ? ParserLanguage.CPP : ParserLanguage.C;
+		} else {
+			//TODO no project, what language do we use?
+			language = ParserLanguage.CPP;
+		}
+		
+		IParser parser = null;
+		try
+		{
+			IScanner scanner = ParserFactory.createScanner( reader, realPath.toOSString(), scanInfo, ParserMode.COMPLETE_PARSE, language, this, ParserUtil.getScannerLogService() );
+			parser  = ParserFactory.createParser( scanner, this, ParserMode.COMPLETE_PARSE, language, ParserUtil.getParserLogService() );
+		}
+		catch( ParserFactoryError pfe )
+		{
+			
+		}
+		
+		if (VERBOSE)
+			verbose("*** New Search for path: " + path); //$NON-NLS-1$
+		  
+		try {
+			parser.parse();
+		}
+		catch(OperationCanceledException ex) {
+			throw new InterruptedException();
+		}
+		catch(Exception ex) {
+			if (VERBOSE){
+				ex.printStackTrace();
+			}
+		}
+		catch(VirtualMachineError vmErr){
+			if (VERBOSE){
+				verbose("TypeMatchLocator VM Error: "); //$NON-NLS-1$
+				vmErr.printStackTrace();
+			}
+		}
+	}
+	
+	private int getElementType(IASTOffsetableNamedElement offsetable) {
+		if (offsetable instanceof IASTClassSpecifier ||
+			offsetable instanceof IASTElaboratedTypeSpecifier) {
+				
+			ASTClassKind kind = null;
+			if (offsetable instanceof IASTClassSpecifier) {
+				kind= ((IASTClassSpecifier)offsetable).getClassKind();
+			} else {
+				kind= ((IASTElaboratedTypeSpecifier)offsetable).getClassKind();
+			}
+			
+			if (kind == ASTClassKind.CLASS) {
+				return ICElement.C_CLASS;
+			} else if (kind == ASTClassKind.STRUCT) {
+				return ICElement.C_STRUCT;
+			} else if (kind == ASTClassKind.UNION) {
+				return ICElement.C_UNION;
+			}
+		} else if ( offsetable instanceof IASTNamespaceDefinition ){
+			return ICElement.C_NAMESPACE;
+		} else if ( offsetable instanceof IASTEnumerationSpecifier ){
+			return ICElement.C_ENUMERATION;
+		} else if ( offsetable instanceof IASTTypedefDeclaration ){
+			return ICElement.C_TYPEDEF;
+		}
+		
+		return 0;
+	}
+	
+}
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeSearchPathCollector.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/cache/TypeSearchPathCollector.java
diff -N browser/org/eclipse/cdt/internal/core/browser/cache/TypeSearchPathCollector.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeSearchPathCollector.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.browser.cache;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.cdt.internal.core.search.IIndexSearchRequestor;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Collects type and dependency paths from search results.
+ */
+public class TypeSearchPathCollector implements IIndexSearchRequestor {
+		
+	public Set typePaths= new HashSet(5);
+	public Set dependencyPaths= new HashSet(5);
+
+	public void acceptClassDeclaration(String resourcePath, char[] simpleTypeName, char[][] enclosingTypeNames) {
+		typePaths.add(resourcePath);
+	}
+
+	public void acceptNamespaceDeclaration(String resourcePath, char[] typeName, char[][] enclosingTypeNames) {
+		typePaths.add(resourcePath);
+	}
+
+	public void acceptIncludeDeclaration(String resourcePath, char[] decodedSimpleName) {
+		dependencyPaths.add(resourcePath);
+	}
+
+	public void acceptConstructorDeclaration(String resourcePath, char[] typeName, int parameterCount) { }
+	public void acceptConstructorReference(String resourcePath, char[] typeName, int parameterCount) { }
+	public void acceptFieldDeclaration(String resourcePath, char[] fieldName) { }
+	public void acceptFieldReference(String resourcePath, char[] fieldName) { }
+	public void acceptInterfaceDeclaration(String resourcePath, char[] simpleTypeName, char[][] enclosingTypeNames, char[] packageName) { }
+	public void acceptFunctionDeclaration(String resourcePath, char[] methodName, int parameterCount) { }
+	public void acceptMethodDeclaration(String resourcePath, char[] methodName, int parameterCount, char[][] enclosingTypeNames) { }
+	public void acceptMethodReference(String resourcePath, char[] methodName, int parameterCount) { }
+	public void acceptPackageReference(String resourcePath, char[] packageName) { }
+	public void acceptVariableDeclaration(String resourcePath, char[] simpleTypeName) { }
+	public void acceptFieldDeclaration(String resourcePath, char[] simpleTypeName, char[][] enclosingTypeNames) { }
+	public void acceptMacroDeclaration(String resourcePath, char[] decodedSimpleName) { }
+	public void acceptSuperTypeReference(String resourcePath, char[] qualification, char[] typeName, char[] enclosingTypeName, char classOrInterface, char[] superQualification, char[] superTypeName, char superClassOrInterface, int modifiers) { }
+	public void acceptSuperTypeReference(String resourcePath, char[] qualification, char[] typeName, char classOrInterface, char[] superQualification, char[] superTypeName, char superClassOrInterface, int modifiers) { }
+	public void acceptTypeReference(String resourcePath, char[] typeName) { }
+	
+	/**
+	 * Returns the paths that have been collected.
+	 */
+	public Set getPaths() {
+		Set pathSet= new HashSet(typePaths.size());
+		for (Iterator i= typePaths.iterator(); i.hasNext(); ) {
+			String path= (String) i.next();
+			pathSet.add(new Path(path));
+		}
+		return pathSet;
+	}
+
+	/**
+	 * Returns the dependency paths that have been collected.
+	 */
+	public Set getDependencyPaths() {
+		Set pathSet= new HashSet(dependencyPaths.size());
+		for (Iterator i= dependencyPaths.iterator(); i.hasNext(); ) {
+			String path= (String) i.next();
+			pathSet.add(new Path(path));
+		}
+		return pathSet;
+	}
+}
Index: browser/org/eclipse/cdt/internal/core/browser/cache/TypeSearchPattern.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/cache/TypeSearchPattern.java
diff -N browser/org/eclipse/cdt/internal/core/browser/cache/TypeSearchPattern.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/cache/TypeSearchPattern.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.browser.cache;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.search.ICSearchConstants;
+import org.eclipse.cdt.core.search.OrPattern;
+import org.eclipse.cdt.core.search.SearchEngine;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+
+
+public final class TypeSearchPattern extends OrPattern {
+	public TypeSearchPattern() {
+		super();
+		addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.NAMESPACE, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
+		addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.CLASS, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
+		addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.STRUCT, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
+		addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.UNION, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
+		addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.ENUM, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
+		addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.TYPEDEF, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
+	}
+	
+	public void addDependencySearch(IPath path) {
+		// convert path to absolute or the search will fail
+		IResource res= CCorePlugin.getWorkspace().getRoot().findMember(path);
+		if (res != null)
+			path= res.getRawLocation();
+		if (path != null)
+			addPattern(createPattern(path.toOSString(), ICSearchConstants.INCLUDE, ICSearchConstants.REFERENCES, ICSearchConstants.EXACT_MATCH, true));
+	}
+}
Index: browser/org/eclipse/cdt/internal/core/browser/util/ArrayUtil.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/util/ArrayUtil.java
diff -N browser/org/eclipse/cdt/internal/core/browser/util/ArrayUtil.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/util/ArrayUtil.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.browser.util;
+
+/**
+ * A helper class which allows you to perform some
+ * simple set operations on int arrays.
+ */
+public class ArrayUtil {
+	private ArrayUtil() {
+	}
+
+	// returns true if set contains elem
+	public static boolean contains(int[] set, int elem) {
+		if (set == null)
+			return false;
+		for (int i= 0; i < set.length; ++i) {
+			if (set[i] == elem)
+				return true;
+		}
+		return false;
+	}
+	
+	// returns true if set contains all of subset
+	public static boolean containsAll(int[] set, int[] subset) {
+		if (set == null || subset == null)
+			return false;
+		for (int i= 0; i < subset.length; ++i) {
+			if (!contains(set, subset[i]))
+				return false;
+		}
+		return true;
+	}
+	
+	// return a copy of fromSet
+	public static int[] clone(int[] fromSet) {
+		if (fromSet == null)
+			return null;
+		int[] newSet= new int[fromSet.length];
+		for (int i= 0; i < fromSet.length; ++i) {
+			newSet[i]= fromSet[i];
+		}
+		return newSet;
+	}
+}
Index: browser/org/eclipse/cdt/internal/core/browser/util/DelegatedProgressMonitor.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/util/DelegatedProgressMonitor.java
diff -N browser/org/eclipse/cdt/internal/core/browser/util/DelegatedProgressMonitor.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/util/DelegatedProgressMonitor.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,228 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.browser.util;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * A wrapper around one or more progress monitors.  Forwards
+ * <code>IProgressMonitor</code> and <code>IProgressMonitorWithBlocking</code>
+ * methods to the delegate monitors.
+ */
+public class DelegatedProgressMonitor implements IProgressMonitor, IProgressMonitorWithBlocking {
+
+	private static int INITIAL_DELEGATE_COUNT = 2;
+	private final ArrayList fDelegateList = new ArrayList(INITIAL_DELEGATE_COUNT);
+	private String fTaskName;
+	private String fSubTask;
+	private int fTotalWork = IProgressMonitor.UNKNOWN;
+	private double fWorked;
+	private boolean fIsBlocked = false;
+	private boolean fIsCanceled = false;
+	
+	/**
+	 * Creates a new delegated monitor.
+	 */
+	public DelegatedProgressMonitor() {
+	}
+	
+	/**
+	 * Creates a new delegated monitor, and adds a delegate.
+	 */
+	public DelegatedProgressMonitor(IProgressMonitor delegate) {
+		addDelegate(delegate);
+	}
+	
+	/*
+	 * @see IProgressMonitor#beginTask
+	 */
+	public synchronized void beginTask(String name, int totalWork) {
+		fTaskName = name;
+		fTotalWork = totalWork;
+		visitDelegates(new IDelegateVisitor() {
+			public void visit(IProgressMonitor delegate) {
+				delegate.beginTask(fTaskName, fTotalWork);
+			}
+		});
+	}
+	
+	/*
+	 * @see IProgressMonitor#done
+	 */
+	public synchronized void done() {
+		visitDelegates(new IDelegateVisitor() {
+			public void visit(IProgressMonitor delegate) {
+				delegate.done();
+			}
+		});
+	}
+	
+	/*
+	 * @see IProgressMonitor#setTaskName
+	 */
+	public synchronized void setTaskName(String name) {
+		fTaskName = name;
+		visitDelegates(new IDelegateVisitor() {
+			public void visit(IProgressMonitor delegate) {
+				delegate.setTaskName(fTaskName);
+			}
+		});
+	}
+
+	/*
+	 * @see IProgressMonitor#subTask
+	 */
+	public synchronized void subTask(String name) {
+		fSubTask = name;
+		visitDelegates(new IDelegateVisitor() {
+			public void visit(IProgressMonitor delegate) {
+				delegate.subTask(fSubTask);
+			}
+		});
+	}
+	
+	/*
+	 * @see IProgressMonitor#worked
+	 */
+	public void worked(int work) {
+		internalWorked(work);
+	}
+	
+	/*
+	 * @see IProgressMonitor#internalWorked
+	 */
+	public synchronized void internalWorked(double internalWork) {
+		fWorked += internalWork;
+		final double fInternalWork = internalWork;
+		visitDelegates(new IDelegateVisitor() {
+			public void visit(IProgressMonitor delegate) {
+				delegate.internalWorked(fInternalWork);
+			}
+		});
+	}
+
+	/*
+	 * @see IProgressMonitor#isCanceled
+	 */
+	public synchronized boolean isCanceled() {
+		visitDelegates(new IDelegateVisitor() {
+			public void visit(IProgressMonitor delegate) {
+				fIsCanceled |= delegate.isCanceled();
+			}
+		});
+		return fIsCanceled;
+	}
+
+	/*
+	 * @see IProgressMonitor#setCanceled
+	 */
+	public synchronized void setCanceled(boolean canceled) {
+		fIsCanceled = canceled;
+		visitDelegates(new IDelegateVisitor() {
+			public void visit(IProgressMonitor delegate) {
+				delegate.setCanceled(fIsCanceled);
+			}
+		});
+	}
+
+	/*
+	 * @see IProgressMonitor#setBlocked
+	 */
+	public synchronized void setBlocked(IStatus reason) {
+		fIsBlocked = true;
+		final IStatus fReason = reason;
+		visitDelegates(new IDelegateVisitor() {
+			public void visit(IProgressMonitor delegate) {
+				if (delegate instanceof IProgressMonitorWithBlocking)
+					((IProgressMonitorWithBlocking) delegate).setBlocked(fReason);
+			}
+		});
+	}
+	
+	/*
+	 * @see IProgressMonitor#clearBlocked
+	 */
+	public synchronized void clearBlocked() {
+		fIsBlocked = false;
+		visitDelegates(new IDelegateVisitor() {
+			public void visit(IProgressMonitor delegate) {
+				if (delegate instanceof IProgressMonitorWithBlocking)
+					((IProgressMonitorWithBlocking) delegate).clearBlocked();
+			}
+		});
+	}
+	
+	/**
+	 * Adds a delegate.
+	 */
+	public synchronized void addDelegate(IProgressMonitor delegate) {
+		if (fDelegateList.indexOf(delegate) == -1) {
+			if (fTaskName != null)
+				syncUp(delegate);
+			fDelegateList.add(delegate);
+		}
+	}
+	
+	/**
+	 * Brings delegate in sync with current progress.
+	 */
+	private void syncUp(IProgressMonitor delegate) {
+		delegate.beginTask(fTaskName, fTotalWork);
+		delegate.internalWorked(fWorked);
+		if (fSubTask != null && fSubTask.length() > 0)
+			delegate.subTask(fSubTask);
+		if (fIsBlocked && delegate instanceof IProgressMonitorWithBlocking)
+			 ((IProgressMonitorWithBlocking) delegate).setBlocked(null);
+	}
+
+	/**
+	 * Removes a delegate.
+	 */
+	public synchronized void removeDelegate(IProgressMonitor delegate) {
+		int index = fDelegateList.indexOf(delegate);
+		if (index != -1) {
+			fDelegateList.remove(index);
+		}
+	}
+
+	/**
+	 * Returns the delegate list.
+	 *
+	 * @return An array of progress monitors added using <code>addDelegate()</code>.
+	 */
+	public synchronized IProgressMonitor[] getDelegates() {
+		return (IProgressMonitor[]) fDelegateList.toArray();
+	}
+
+	/**
+	 * Defines a delegate visitor.
+	 */
+	private static interface IDelegateVisitor {
+		public void visit(IProgressMonitor delegate);
+	}
+
+	/**
+	 * Visits each delegate in the delegates list.
+	 */
+	private void visitDelegates(IDelegateVisitor visitor) {
+		// Clone the delegates since they could remove themselves when called 
+		ArrayList delegatesList = (ArrayList) fDelegateList.clone();
+		for (Iterator i = delegatesList.iterator(); i.hasNext(); ) {
+			IProgressMonitor delegate = (IProgressMonitor) i.next();
+			visitor.visit(delegate);
+		}
+	}
+}
Index: browser/org/eclipse/cdt/internal/core/browser/util/PathUtil.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/util/PathUtil.java
diff -N browser/org/eclipse/cdt/internal/core/browser/util/PathUtil.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/util/PathUtil.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.browser.util;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.runtime.Path;
+
+public class PathUtil {
+	
+	private static boolean fWindows = false;
+	static {
+		String os = System.getProperty("os.name"); //$NON-NLS-1$
+		if (os != null && os.startsWith("Win")) { //$NON-NLS-1$
+			fWindows= true;
+		}
+	}
+	public static boolean isWindowsSystem() {
+		return fWindows;
+	}
+	
+	public static Path getCanonicalPath(String fullPath) {
+		File file = new File(fullPath);
+		try {
+			String canonPath = file.getCanonicalPath();
+			return new Path(canonPath);
+		} catch (IOException ex) {
+		}
+		return new Path(fullPath);
+	}
+}
Index: browser/org/eclipse/cdt/internal/core/browser/util/SimpleStack.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/core/browser/util/SimpleStack.java
diff -N browser/org/eclipse/cdt/internal/core/browser/util/SimpleStack.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/core/browser/util/SimpleStack.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.browser.util;
+
+import java.util.ArrayList;
+
+/**
+ * A helper class which allows you to perform some simple
+ * stack operations.  Avoids the extra overhead of
+ * synchronization in Java.Util.Stack.
+ */
+public class SimpleStack {
+
+	private static int INITIAL_STACK_SIZE = 10;
+	private ArrayList items;
+	private static boolean VERBOSE = false;
+
+    public SimpleStack() {
+    	items = new ArrayList(INITIAL_STACK_SIZE);
+    }
+    
+    public SimpleStack(int initialSize) {
+    	items = new ArrayList(initialSize);
+    }
+    
+    public Object push(Object item) {
+    	items.add(item);
+    	if (VERBOSE)
+    		trace("push on stack: " + item); //$NON-NLS-1$
+    	return item;
+    }
+    
+    public Object pop() {
+    	int top = items.size()-1;
+    	if (top < 0)
+    		return null;
+    	Object item = items.get(top);
+    	items.remove(top);
+    	if (VERBOSE)
+    		trace("pop from stack: " + item); //$NON-NLS-1$
+    	return item;
+    }
+    
+    public Object top() {
+    	int top = items.size()-1;
+    	if (top < 0)
+    		return null;
+    	return items.get(top);
+    }
+    
+    public boolean isEmpty() {
+    	return (items.size() == 0);
+    }
+    
+    public Object[] toArray() {
+    	return items.toArray();
+    }
+
+    public Object[] toArray(Object a[]) {
+    	return items.toArray(a);
+    }
+
+    private static void trace(String msg) {
+	  System.out.println("(" + Thread.currentThread() + ") " + msg);  //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}

Back to the top